github.com/pdfcpu/pdfcpu@v0.11.1/pkg/api/test/create_test.go (about) 1 /* 2 Copyright 2019 The pdf Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package test 18 19 import ( 20 "bytes" 21 "path/filepath" 22 "testing" 23 24 "github.com/pdfcpu/pdfcpu/pkg/api" 25 "github.com/pdfcpu/pdfcpu/pkg/pdfcpu" 26 "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/color" 27 "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/draw" 28 "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model" 29 "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types" 30 ) 31 32 var sampleText string = `MOST of the adventures recorded in this book really occurred; one or 33 two were experiences of my own, the rest those of boys who were 34 schoolmates of mine. Huck Finn is drawn from life; Tom Sawyer also, but 35 not from an individual--he is a combination of the characteristics of 36 three boys whom I knew, and therefore belongs to the composite order of 37 architecture. 38 39 The odd superstitions touched upon were all prevalent among children 40 and slaves in the West at the period of this story--that is to say, 41 thirty or forty years ago. 42 43 Although my book is intended mainly for the entertainment of boys and 44 girls, I hope it will not be shunned by men and women on that account, 45 for part of my plan has been to try to pleasantly remind adults of what 46 they once were themselves, and of how they felt and thought and talked, 47 and what queer enterprises they sometimes engaged in.` 48 49 var sampleTextArabic = `حدثت بالفعل معظم المغامرات المسجلة في هذا الكتاب ؛ واحد أو 50 كانت اثنتان من تجربتي الخاصة ، والباقي تجارب الأولاد الذين كانوا كذلك 51 زملائي في المدرسة. هاك فين مستوحى من الحياة ؛ توم سوير أيضا ولكن 52 ليس من فرد - إنه مزيج من خصائص 53 ثلاثة أولاد أعرفهم ، وبالتالي ينتمون إلى الترتيب المركب لـ 54 هندسة معمارية. 55 56 كانت الخرافات الغريبة التي تم التطرق إليها سائدة بين الأطفال 57 والعبيد في الغرب في فترة هذه القصة - أي 58 قبل ثلاثين أو أربعين سنة. 59 60 على الرغم من أن كتابي مخصص بشكل أساسي للترفيه عن الأولاد و 61 الفتيات ، أتمنى ألا يتجنب الرجال والنساء ذلك الحساب ، 62 جزء من خطتي كان محاولة تذكير البالغين بما يحدث 63 كانوا أنفسهم ذات مرة ، وكيف شعروا وفكروا وتحدثوا ، 64 وما هي المؤسسات الكويرية التي شاركوا فيها أحيانًا.` 65 66 var sampleTextHebrew = `רוב ההרפתקאות שתועדו בספר זה באמת התרחשו; אחד או 67 שתיים היו חוויות משלי, והשאר אלה של בנים שהיו 68 חברי לבית הספר שלי. האק פין נשאב מהחיים; גם טום סוייר, אבל 69 לא מאדם - הוא שילוב של המאפיינים של 70 שלושה בנים שהכרתי ולכן שייכים לסדר המורכב של 71 ארכיטקטורה. 72 73 האמונות הטפלות המוזרות בהן נגעו היו כולן רווחות בקרב ילדים 74 ועבדים במערב בתקופת הסיפור הזה - כלומר, 75 לפני שלושים או ארבעים שנה. 76 77 למרות שהספר שלי מיועד בעיקר לבידור של בנים ו 78 בנות, אני מקווה שזה לא יימנע מגברים ונשים בגלל זה, 79 חלק מהתוכנית שלי הייתה לנסות להזכיר למבוגרים בנעימות מה 80 פעם הם היו עצמם, ועל איך שהם הרגישו וחשבו ודיברו, 81 ובאילו מפעלים מוזרים הם עסקו לפעמים.` 82 83 var sampleTextPersian = `بیشتر ماجراهای ثبت شده در این کتاب واقعاً اتفاق افتاده است. یکی یا 84 دو مورد از تجربه های خودم بود ، بقیه از پسران بودند 85 هم مدرسه ای های من. هاک فین از زندگی کشیده شده است. تام سویر نیز ، اما 86 نه از یک فرد - او ترکیبی از ویژگی های است 87 سه پسر که من آنها را می شناختم و بنابراین به ترتیب مرکب تعلق دارند 88 معماری. 89 90 خرافات عجیب و غریب لمس شده همه در میان کودکان شایع بود 91 و بردگان در غرب این دوره از داستان - یعنی اینکه ، 92 سی چهل سال پیش 93 94 اگرچه کتاب من عمدتا برای سرگرمی پسران و 95 دختران ، امیدوارم با این حساب مردان و زنان از آن اجتناب نکنند ، 96 زیرا بخشی از برنامه من این بوده است که سعی کنم چه چیزی را به بزرگسالان یادآوری کنم 97 آنها یک بار خودشان بودند ، و از احساس و تفکر و صحبت کردن ، 98 و بعضی اوقات چه کارهایی را انجام می دادند` 99 100 var sampleTextUrdu = `اس کتاب میں درج کی گئی زیادہ تر مہم جوئی واقعتا؛ پیش آئی ہے۔ ایک یا 101 دو میرے اپنے تجربات تھے ، باقی جو لڑکے تھے 102 میرے اسکول کے ساتھیوں. ہک فن زندگی سے نکالا گیا ہے۔ ٹام ساویر بھی ، لیکن 103 کسی فرد سے نہیں - وہ کی خصوصیات کا ایک مجموعہ ہے 104 تین لڑکے جن کو میں جانتا تھا ، اور اس وجہ سے یہ جامع ترتیب سے ہے 105 فن تعمیر 106 107 بچوں میں عجیب و غریب اندوشواس کا اثر تمام تھا 108 اور اس کہانی کے دور میں مغرب میں غلام۔ 109 تیس یا چالیس سال پہلے کی بات ہے۔ 110 111 اگرچہ میری کتاب بنیادی طور پر لڑکوں اور تفریح کے لئے ہے 112 لڑکیاں ، مجھے امید ہے کہ اس وجہ سے مرد اور خواتین اس سے باز نہیں آئیں گے ، 113 میرے منصوبے کا ایک حص adultsہ یہ رہا ہے کہ بالغوں کو خوشی سے اس کی یاد دلانے کی کیا کوشش کی جائے 114 وہ ایک بار خود تھے ، اور یہ کہ وہ کیسے محسوس کرتے ہیں ، سوچتے اور بات کرتے ہیں ، 115 اور کن کن کن کاروباری اداروں میں وہ کبھی کبھی مشغول رہتے ہیں۔` 116 117 var sampleTextRTL = map[string]string{ 118 "Arabic": sampleTextArabic, 119 "Hebrew": sampleTextHebrew, 120 "Persian": sampleTextPersian, 121 "Urdu": sampleTextUrdu, 122 } 123 124 var sampleText2 = `THE two boys flew on and on, toward the village, speechless with 125 horror. They glanced backward over their shoulders from time to time, 126 apprehensively, as if they feared they might be followed. Every stump 127 that started up in their path seemed a man and an enemy, and made them 128 catch their breath; and as they sped by some outlying cottages that lay 129 near the village, the barking of the aroused watch-dogs seemed to give 130 wings to their feet. 131 132 "If we can only get to the old tannery before we break down!" 133 whispered Tom, in short catches between breaths. "I can't stand it much 134 longer." 135 136 Huckleberry's hard pantings were his only reply, and the boys fixed 137 their eyes on the goal of their hopes and bent to their work to win it. 138 They gained steadily on it, and at last, breast to breast, they burst 139 through the open door and fell grateful and exhausted in the sheltering 140 shadows beyond. By and by their pulses slowed down, and Tom whispered: 141 142 "Huckleberry, what do you reckon'll come of this?"` 143 144 var sampleText3 = `Even the Glorious Fourth was in some sense a failure, for it rained 145 hard, there was no procession in consequence, and the greatest man in 146 the world (as Tom supposed), Mr. Benton, an actual United States 147 Senator, proved an overwhelming disappointment--for he was not 148 twenty-five feet high, nor even anywhere in the neighborhood of it. 149 150 A circus came. The boys played circus for three days afterward in 151 tents made of rag carpeting--admission, three pins for boys, two for 152 girls--and then circusing was abandoned. 153 154 A phrenologist and a mesmerizer came--and went again and left the 155 village duller and drearier than ever. 156 157 There were some boys-and-girls' parties, but they were so few and so 158 delightful that they only made the aching voids between ache the harder. 159 160 Becky Thatcher was gone to her Constantinople home to stay with her 161 parents during vacation--so there was no bright side to life anywhere.` 162 163 func createAndValidate(t *testing.T, xRefTable *model.XRefTable, outFile, msg string) { 164 t.Helper() 165 outDir := "../../samples/basic" 166 outFile = filepath.Join(outDir, outFile) 167 if err := api.CreatePDFFile(xRefTable, outFile, nil); err != nil { 168 t.Fatalf("%s: %v\n", msg, err) 169 } 170 if err := api.ValidateFile(outFile, nil); err != nil { 171 t.Fatalf("%s: %v\n", msg, err) 172 } 173 } 174 175 func TestCreateDemoPDF(t *testing.T) { 176 msg := "TestCreateDemoPDF" 177 mediaBox := types.RectForFormat("A4") 178 p := model.Page{MediaBox: mediaBox, Fm: model.FontMap{}, Buf: new(bytes.Buffer)} 179 pdfcpu.CreateTestPageContent(p) 180 xRefTable, err := pdfcpu.CreateDemoXRef() 181 if err != nil { 182 t.Fatalf("%s: %v\n", msg, err) 183 } 184 rootDict, err := xRefTable.Catalog() 185 if err != nil { 186 t.Fatalf("%s: %v\n", msg, err) 187 } 188 if err = pdfcpu.AddPageTreeWithSamplePage(xRefTable, rootDict, p); err != nil { 189 t.Fatalf("%s: %v\n", msg, err) 190 } 191 createAndValidate(t, xRefTable, "Test.pdf", msg) 192 } 193 194 func TestResourceDictInheritanceDemoPDF(t *testing.T) { 195 // Create a test page proofing resource inheritance. 196 // Resources may be inherited from ANY parent node. 197 // Case in point: fonts 198 msg := "TestResourceDictInheritanceDemoPDF" 199 xRefTable, err := pdfcpu.CreateResourceDictInheritanceDemoXRef() 200 if err != nil { 201 t.Fatalf("%s: %v\n", msg, err) 202 } 203 createAndValidate(t, xRefTable, "ResourceDictInheritanceDemo.pdf", msg) 204 } 205 206 func TestAnnotationDemoPDF(t *testing.T) { 207 msg := "TestAnnotationDemoPDF" 208 xRefTable, err := pdfcpu.CreateAnnotationDemoXRef() 209 if err != nil { 210 t.Fatalf("%s: %v\n", msg, err) 211 } 212 createAndValidate(t, xRefTable, "AnnotationDemo.pdf", msg) 213 } 214 215 func writeTextDemoAlignedWidthAndMargin( 216 xRefTable *model.XRefTable, 217 p model.Page, 218 region *types.Rectangle, 219 hAlign types.HAlignment, 220 w, mLeft, mRight, mTop, mBot float64) { 221 222 buf := p.Buf 223 mediaBox := p.MediaBox 224 225 mediaBB := true 226 227 var cr, cg, cb float32 228 cr, cg, cb = .5, .75, 1. 229 r := mediaBox 230 if region != nil { 231 r = region 232 cr, cg, cb = .75, .75, 1 233 } 234 if mediaBB { 235 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 236 } 237 238 fontName := "Helvetica" 239 k := p.Fm.EnsureKey(fontName) 240 241 td := model.TextDescriptor{ 242 FontName: fontName, 243 Embed: true, 244 FontKey: k, 245 FontSize: 24, 246 ShowMargins: true, 247 MLeft: mLeft, 248 MRight: mRight, 249 MTop: mTop, 250 MBot: mBot, 251 Scale: 1., 252 ScaleAbs: true, 253 HAlign: hAlign, 254 RMode: draw.RMFill, 255 StrokeCol: color.Black, 256 FillCol: color.Black, 257 ShowBackground: true, 258 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 259 ShowBorder: true, 260 ShowLineBB: true, 261 ShowTextBB: true, 262 HairCross: true, 263 } 264 265 td.VAlign, td.X, td.Y, td.Text = types.AlignBaseline, -1, r.Height()*.75, "M\\u(lti\nline\n\nwith empty line" 266 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 267 268 td.VAlign, td.X, td.Y, td.Text = types.AlignBaseline, r.Width()*.75, r.Height()*.25, "Arbitrary\ntext\nlines" 269 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 270 271 // Multilines along the top of the page: 272 td.VAlign, td.X, td.Y, td.Text = types.AlignTop, 0, r.Height(), "0,h (topleft)\nand line2" 273 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 274 275 td.VAlign, td.X, td.Y, td.Text = types.AlignTop, -1, r.Height(), "-1,h (topcenter)\nand line2" 276 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 277 278 td.VAlign, td.X, td.Y, td.Text = types.AlignTop, r.Width(), r.Height(), "w,h (topright)\nand line2" 279 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 280 281 // Multilines along the center of the page: 282 // x = 0 centers the position of multilines horizontally 283 // y = 0 centers the position of multilines vertically and enforces alignMiddle 284 td.VAlign, td.X, td.Y, td.Text = types.AlignBaseline, 0, -1, "0,-1 (left)\nand line2" 285 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 286 287 td.VAlign, td.X, td.Y, td.Text = types.AlignMiddle, -1, -1, "-1,-1 (center)\nand line2" 288 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 289 290 td.VAlign, td.X, td.Y, td.Text = types.AlignBaseline, r.Width(), -1, "w,-1 (right)\nand line2" 291 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 292 293 // Multilines along the bottom of the page: 294 td.VAlign, td.X, td.Y, td.Text = types.AlignBottom, 0, 0, "0,0 (botleft)\nand line2" 295 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 296 297 td.VAlign, td.X, td.Y, td.Text = types.AlignBottom, -1, 0, "-1,0 (botcenter)\nand line2" 298 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 299 300 td.VAlign, td.X, td.Y, td.Text = types.AlignBottom, r.Width(), 0, "w,0 (botright)\nand line2" 301 model.WriteColumn(xRefTable, buf, mediaBox, region, td, w) 302 303 draw.DrawHairCross(buf, 0, 0, r) 304 } 305 306 func createTextDemoAlignedWidthAndMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle, hAlign types.HAlignment, w, mLeft, mRight, mTop, mBot float64) model.Page { 307 p := model.NewPage(mediaBox, nil) 308 var region *types.Rectangle 309 writeTextDemoAlignedWidthAndMargin(xRefTable, p, region, hAlign, w, mLeft, mRight, mTop, mBot) 310 region = types.RectForWidthAndHeight(50, 70, 200, 200) 311 writeTextDemoAlignedWidthAndMargin(xRefTable, p, region, hAlign, w, mLeft, mRight, mTop, mBot) 312 return p 313 } 314 315 func createTextDemoAlignLeft(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 316 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignLeft, 0, 0, 0, 0, 0) 317 } 318 319 func createTextDemoAlignLeftMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 320 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignLeft, 0, 5, 10, 15, 20) 321 } 322 323 func createTextDemoAlignRight(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 324 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignRight, 0, 0, 0, 0, 0) 325 } 326 327 func createTextDemoAlignRightMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 328 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignRight, 0, 5, 10, 15, 20) 329 } 330 331 func createTextDemoAlignCenter(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 332 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignCenter, 0, 0, 0, 0, 0) 333 } 334 335 func createTextDemoAlignCenterMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 336 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignCenter, 0, 5, 10, 15, 20) 337 } 338 339 func createTextDemoAlignJustify(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 340 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignJustify, 0, 0, 0, 0, 0) 341 } 342 343 func createTextDemoAlignJustifyMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 344 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignJustify, 0, 5, 10, 15, 20) 345 } 346 347 func createTextDemoAlignLeftWidth(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 348 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignLeft, 250, 0, 0, 0, 0) 349 } 350 351 func createTextDemoAlignLeftWidthAndMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 352 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignLeft, 250, 5, 10, 15, 20) 353 } 354 355 func createTextDemoAlignRightWidth(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 356 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignRight, 250, 0, 0, 0, 0) 357 } 358 359 func createTextDemoAlignRightWidthAndMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 360 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignRight, 250, 5, 10, 15, 20) 361 } 362 363 func createTextDemoAlignCenterWidth(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 364 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignCenter, 250, 0, 0, 0, 0) 365 } 366 367 func createTextDemoAlignCenterWidthAndMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 368 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignCenter, 250, 5, 40, 15, 20) 369 } 370 371 func createTextDemoAlignJustifyWidth(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 372 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignJustify, 250, 0, 0, 0, 0) 373 } 374 375 func createTextDemoAlignJustifyWidthAndMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 376 return createTextDemoAlignedWidthAndMargin(xRefTable, mediaBox, types.AlignJustify, 250, 5, 10, 15, 20) 377 } 378 379 func writeTextAlignJustifyDemo(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, fontName string) { 380 mediaBox := p.MediaBox 381 buf := p.Buf 382 383 mediaBB := true 384 385 var cr, cg, cb float32 386 cr, cg, cb = .5, .75, 1. 387 r := mediaBox 388 if region != nil { 389 r = region 390 cr, cg, cb = .75, .75, 1 391 } 392 if mediaBB { 393 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 394 } 395 396 k := p.Fm.EnsureKey(fontName) 397 398 td := model.TextDescriptor{ 399 Text: sampleText, 400 FontName: fontName, 401 Embed: true, 402 FontKey: k, 403 FontSize: 12, 404 MLeft: 5, 405 MRight: 5, 406 MTop: 5, 407 MBot: 5, 408 X: -1, 409 Y: -1, 410 Scale: 1., 411 ScaleAbs: true, 412 HAlign: types.AlignJustify, 413 VAlign: types.AlignMiddle, 414 RMode: draw.RMFill, 415 StrokeCol: color.NewSimpleColor(0x206A29), 416 FillCol: color.NewSimpleColor(0x206A29), 417 ShowBackground: true, 418 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 419 ShowBorder: true, 420 ShowLineBB: false, 421 ShowTextBB: true, 422 HairCross: false, 423 } 424 425 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 426 427 draw.DrawHairCross(p.Buf, 0, 0, mediaBox) 428 } 429 430 func writeTextAlignJustifyColumnDemo(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle) { 431 mediaBox := p.MediaBox 432 buf := p.Buf 433 434 mediaBB := true 435 436 var cr, cg, cb float32 437 cr, cg, cb = .5, .75, 1. 438 r := mediaBox 439 if region != nil { 440 r = region 441 cr, cg, cb = .75, .75, 1 442 } 443 if mediaBB { 444 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 445 } 446 447 fontName := "Times-Roman" 448 fontName2 := "Helvetica" 449 k1 := p.Fm.EnsureKey(fontName) 450 k2 := p.Fm.EnsureKey(fontName2) 451 452 td := model.TextDescriptor{ 453 Text: sampleText, 454 Embed: true, 455 MLeft: 5, 456 MRight: 5, 457 MTop: 5, 458 MBot: 5, 459 Scale: 1., 460 ScaleAbs: true, 461 HAlign: types.AlignJustify, 462 RMode: draw.RMFill, 463 StrokeCol: color.Black, 464 FillCol: color.Black, 465 ShowBackground: true, 466 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 467 ShowBorder: true, 468 ShowLineBB: false, 469 ShowTextBB: true, 470 HairCross: false, 471 } 472 473 td.BackgroundCol = color.White 474 td.FillCol = color.Black 475 td.FontName, td.FontKey, td.FontSize = fontName, k1, 9 476 td.ParIndent = true 477 td.VAlign, td.X, td.Y, td.Dx, td.Dy = types.AlignTop, 0, r.Height(), 5, -5 478 model.WriteColumn(xRefTable, buf, mediaBox, region, td, 150) 479 480 td.BackgroundCol = color.Black 481 td.FillCol = color.White 482 td.FontName, td.FontKey, td.FontSize = fontName2, k2, 12 483 td.ParIndent = true 484 td.VAlign, td.X, td.Y, td.Dx, td.Dy = types.AlignTop, -1, -1, 0, 0 485 model.WriteColumn(xRefTable, buf, mediaBox, region, td, 290) 486 487 draw.DrawHairCross(p.Buf, 0, 0, mediaBox) 488 } 489 490 func createTextAlignJustifyDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 491 p := model.NewPage(mediaBox, nil) 492 var region *types.Rectangle 493 fontName := "Times-Roman" 494 writeTextAlignJustifyDemo(xRefTable, p, region, fontName) 495 region = types.RectForWidthAndHeight(0, 0, 200, 200) 496 writeTextAlignJustifyDemo(xRefTable, p, region, fontName) 497 return p 498 } 499 500 func createTextAlignJustifyColumnDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 501 p := model.NewPage(mediaBox, nil) 502 var region *types.Rectangle 503 writeTextAlignJustifyColumnDemo(xRefTable, p, region) 504 region = types.RectForWidthAndHeight(0, 0, 200, 200) 505 writeTextAlignJustifyColumnDemo(xRefTable, p, region) 506 return p 507 } 508 509 func writeTextDemoAnchorsWithOffset(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, dx, dy float64) { 510 mediaBox := p.MediaBox 511 buf := p.Buf 512 513 mediaBB := true 514 515 var cr, cg, cb float32 516 cr, cg, cb = .5, .75, 1. 517 r := mediaBox 518 if region != nil { 519 r = region 520 cr, cg, cb = .75, .75, 1 521 } 522 if mediaBB { 523 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 524 } 525 526 fontName := "Helvetica" 527 k := p.Fm.EnsureKey(fontName) 528 529 td := model.TextDescriptor{ 530 FontName: fontName, 531 Embed: true, 532 FontKey: k, 533 FontSize: 24, 534 MLeft: 10, 535 MRight: 10, 536 MTop: 10, 537 MBot: 10, 538 Scale: 1., 539 ScaleAbs: true, 540 RMode: draw.RMFill, 541 StrokeCol: color.Black, 542 FillCol: color.Black, 543 ShowBackground: true, 544 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 545 ShowBorder: true, 546 ShowLineBB: true, 547 ShowTextBB: true, 548 HairCross: false, 549 } 550 551 td.Dx, td.Dy, td.Text = dx, -dy, "topleft\nandLine2" 552 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopLeft) 553 554 td.Dx, td.Dy, td.Text = 0, -dy, "topcenter\nandLine2" 555 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopCenter) 556 557 td.Dx, td.Dy, td.Text = -dx, -dy, "topright\nandLine2" 558 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopRight) 559 560 td.Dx, td.Dy, td.Text = dx, 0, "left\nandline2" 561 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Left) 562 563 td.Dx, td.Dy, td.Text = 0, 0, "center\nandLine2" 564 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Center) 565 566 td.Dx, td.Dy, td.Text = -dx, 0, "right\nandLine2" 567 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Right) 568 569 td.Dx, td.Dy, td.Text = dx, dy, "botleft\nandLine2" 570 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomLeft) 571 572 td.Dx, td.Dy, td.Text = 0, dy, "botcenter\nandLine2" 573 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomCenter) 574 575 td.Dx, td.Dy, td.Text = -dx, dy, "botright\nandLine2" 576 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomRight) 577 578 draw.DrawHairCross(buf, 0, 0, r) 579 } 580 581 func writeTextDemoAnchors(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle) { 582 writeTextDemoAnchorsWithOffset(xRefTable, p, region, 0, 0) 583 } 584 585 func createTextDemoAnchors(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 586 p := model.NewPage(mediaBox, nil) 587 var region *types.Rectangle 588 writeTextDemoAnchors(xRefTable, p, region) 589 region = types.RectForWidthAndHeight(50, 70, 200, 200) 590 writeTextDemoAnchors(xRefTable, p, region) 591 return p 592 } 593 594 func createTextDemoAnchorsWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 595 p := model.NewPage(mediaBox, nil) 596 dx, dy := 20., 20. 597 var region *types.Rectangle 598 writeTextDemoAnchorsWithOffset(xRefTable, p, region, dx, dy) 599 region = types.RectForWidthAndHeight(50, 70, 200, 200) 600 writeTextDemoAnchorsWithOffset(xRefTable, p, region, dx, dy) 601 return p 602 } 603 604 func writeTextDemoColumnAnchoredWithOffset(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, dx, dy float64) { 605 mediaBox := p.MediaBox 606 buf := p.Buf 607 608 mediaBB := true 609 610 var cr, cg, cb float32 611 cr, cg, cb = .5, .75, 1. 612 r := mediaBox 613 if region != nil { 614 r = region 615 cr, cg, cb = .75, .75, 1 616 } 617 if mediaBB { 618 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 619 } 620 621 wSmall := 100. 622 wBig := 300. 623 624 fontName := "Helvetica" 625 k := p.Fm.EnsureKey(fontName) 626 627 td := model.TextDescriptor{ 628 Text: sampleText, 629 FontName: fontName, 630 Embed: true, 631 FontKey: k, 632 FontSize: 6, 633 MLeft: 5, 634 MRight: 5, 635 MTop: 5, 636 MBot: 5, 637 Scale: 1., 638 ScaleAbs: true, 639 RMode: draw.RMFill, 640 StrokeCol: color.Black, 641 FillCol: color.Black, 642 ShowBackground: true, 643 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 644 ShowBorder: true, 645 ShowLineBB: false, 646 ShowTextBB: true, 647 HairCross: false, 648 } 649 650 td.Dx, td.Dy = dx, -dy 651 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopLeft, wSmall) 652 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopLeft, 0) 653 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopLeft, wBig) 654 655 td.Dx, td.Dy = 0, -dy 656 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopCenter, wSmall) 657 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopCenter, 0) 658 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopCenter, wBig) 659 660 td.Dx, td.Dy = -dx, -dy 661 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopRight, wSmall) 662 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopRight, 0) 663 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.TopRight, wBig) 664 665 td.Dx, td.Dy = dx, 0 666 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Left, wSmall) 667 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Left, 0) 668 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Left, wBig) 669 670 td.Dx, td.Dy = 0, 0 671 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Center, wSmall) 672 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Center, 0) 673 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Center, wBig) 674 675 td.Dx, td.Dy = -dx, 0 676 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Right, wSmall) 677 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Right, 0) 678 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.Right, wBig) 679 680 td.Dx, td.Dy = dx, dy 681 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomLeft, wSmall) 682 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomLeft, 0) 683 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomLeft, wBig) 684 685 td.Dx, td.Dy = 0, dy 686 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomCenter, wSmall) 687 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomCenter, 0) 688 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomCenter, wBig) 689 690 td.Dx, td.Dy = -dx, dy 691 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomRight, wSmall) 692 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomRight, 0) 693 model.WriteColumnAnchored(xRefTable, buf, mediaBox, region, td, types.BottomRight, wBig) 694 695 draw.DrawHairCross(buf, 0, 0, mediaBox) 696 } 697 698 func writeTextDemoColumnAnchored(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle) { 699 writeTextDemoColumnAnchoredWithOffset(xRefTable, p, region, 0, 0) 700 } 701 702 func createTextDemoColumnAnchored(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 703 p := model.NewPage(mediaBox, nil) 704 var region *types.Rectangle 705 writeTextDemoColumnAnchored(xRefTable, p, region) 706 region = types.RectForWidthAndHeight(50, 70, 400, 400) 707 writeTextDemoColumnAnchored(xRefTable, p, region) 708 return p 709 } 710 711 func createTextDemoColumnAnchoredWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 712 p := model.NewPage(mediaBox, nil) 713 var region *types.Rectangle 714 dx, dy := 20., 20. 715 writeTextDemoColumnAnchoredWithOffset(xRefTable, p, region, dx, dy) 716 region = types.RectForWidthAndHeight(50, 70, 400, 400) 717 writeTextDemoColumnAnchoredWithOffset(xRefTable, p, region, dx, dy) 718 return p 719 } 720 721 func writeTextRotateDemoWithOffset(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, dx, dy float64) { 722 mediaBox := p.MediaBox 723 buf := p.Buf 724 725 mediaBB := true 726 727 var cr, cg, cb float32 728 cr, cg, cb = .5, .75, 1. 729 r := mediaBox 730 if region != nil { 731 r = region 732 cr, cg, cb = .75, .75, 1 733 } 734 if mediaBB { 735 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 736 draw.DrawHairCross(buf, 0, 0, r) 737 } 738 739 fillCol := color.Black 740 741 fontName := "Helvetica" 742 k := p.Fm.EnsureKey(fontName) 743 744 td := model.TextDescriptor{ 745 Text: "Hello Gopher!\nLine 2", 746 FontName: fontName, 747 Embed: true, 748 FontKey: k, 749 FontSize: 24, 750 MLeft: 10, 751 MRight: 10, 752 MTop: 10, 753 MBot: 10, 754 Scale: 1., 755 ScaleAbs: true, 756 RMode: draw.RMFill, 757 StrokeCol: color.Black, 758 ShowBackground: true, 759 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 760 ShowBorder: true, 761 ShowLineBB: false, 762 ShowTextBB: true, 763 HairCross: false, 764 } 765 766 td.Dx, td.Dy = dx, -dy 767 td.Rotation, td.FillCol = 0, fillCol 768 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopLeft) 769 td.Rotation, td.FillCol = 45, color.SimpleColor{R: 1} 770 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopLeft) 771 td.Rotation, td.FillCol = 90, color.SimpleColor{R: .5} 772 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopLeft) 773 774 td.Dx, td.Dy = 0, -dy 775 td.Rotation, td.FillCol = 0, fillCol 776 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopCenter) 777 td.Rotation, td.FillCol = 45, color.SimpleColor{G: 1} 778 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopCenter) 779 td.Rotation, td.FillCol = 90, color.SimpleColor{G: .5} 780 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopCenter) 781 782 td.Dx, td.Dy = -dx, -dy 783 td.Rotation, td.FillCol = 0, fillCol 784 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopRight) 785 td.Rotation, td.FillCol = 45, color.SimpleColor{B: 1} 786 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopRight) 787 td.Rotation, td.FillCol = 90, color.SimpleColor{B: .5} 788 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopRight) 789 790 td.Dx, td.Dy = dx, 0 791 td.Rotation, td.FillCol = 0, fillCol 792 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Left) 793 td.Rotation, td.FillCol = 45, color.SimpleColor{R: 1} 794 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Left) 795 td.Rotation, td.FillCol = 90, color.SimpleColor{R: .5} 796 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Left) 797 798 td.Dx, td.Dy = 0, 0 799 td.Rotation, td.FillCol = 0, fillCol 800 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Center) 801 td.Rotation, td.FillCol = 45, color.SimpleColor{G: 1} 802 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Center) 803 td.Rotation, td.FillCol = 90, color.SimpleColor{G: .5} 804 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Center) 805 806 td.Dx, td.Dy = -dx, 0 807 td.Rotation, td.FillCol = 0, fillCol 808 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Right) 809 td.Rotation, td.FillCol = 45, color.SimpleColor{B: 1} 810 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Right) 811 td.Rotation, td.FillCol = 90, color.SimpleColor{B: .5} 812 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Right) 813 814 td.Dx, td.Dy = dx, dy 815 td.Rotation, td.FillCol = 0, fillCol 816 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomLeft) 817 td.Rotation, td.FillCol = 45, color.SimpleColor{R: 1} 818 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomLeft) 819 td.Rotation, td.FillCol = 90, color.SimpleColor{R: .5} 820 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomLeft) 821 822 td.Dx, td.Dy = 0, dy 823 td.Rotation, td.FillCol = 0, fillCol 824 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomCenter) 825 td.Rotation, td.FillCol = 45, color.SimpleColor{G: 1} 826 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomCenter) 827 td.Rotation, td.FillCol = 90, color.SimpleColor{G: .5} 828 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomCenter) 829 830 td.Dx, td.Dy = -dx, dy 831 td.Rotation, td.FillCol = 0, fillCol 832 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomRight) 833 td.Rotation, td.FillCol = 45, color.SimpleColor{B: 1} 834 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomRight) 835 td.Rotation, td.FillCol = 90, color.SimpleColor{B: .5} 836 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomRight) 837 } 838 839 func writeTextRotateDemo(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle) { 840 writeTextRotateDemoWithOffset(xRefTable, p, region, 0, 0) 841 } 842 843 func createTextRotateDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 844 p := model.NewPage(mediaBox, nil) 845 var region *types.Rectangle 846 writeTextRotateDemo(xRefTable, p, region) 847 region = types.RectForWidthAndHeight(150, 150, 300, 300) 848 writeTextRotateDemo(xRefTable, p, region) 849 return p 850 } 851 852 func createTextRotateDemoWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 853 p := model.NewPage(mediaBox, nil) 854 var region *types.Rectangle 855 dx, dy := 20., 20. 856 writeTextRotateDemoWithOffset(xRefTable, p, region, dx, dy) 857 region = types.RectForWidthAndHeight(150, 150, 300, 300) 858 writeTextRotateDemoWithOffset(xRefTable, p, region, dx, dy) 859 return p 860 } 861 862 func writeTextScaleAbsoluteDemoWithOffset(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, dx, dy float64) { 863 mediaBox := p.MediaBox 864 buf := p.Buf 865 866 mediaBB := true 867 868 var cr, cg, cb float32 869 cr, cg, cb = .5, .75, 1. 870 r := mediaBox 871 if region != nil { 872 r = region 873 cr, cg, cb = .75, .75, 1 874 } 875 if mediaBB { 876 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 877 } 878 879 fillCol := color.Black 880 bgCol := color.SimpleColor{R: 1., G: .98, B: .77} 881 882 fontName := "Helvetica" 883 k := p.Fm.EnsureKey(fontName) 884 885 td := model.TextDescriptor{ 886 Text: sampleText, 887 FontName: fontName, 888 Embed: true, 889 FontKey: k, 890 FontSize: 18, 891 MLeft: 5, 892 MRight: 5, 893 MTop: 5, 894 MBot: 5, 895 ScaleAbs: true, 896 RMode: draw.RMFill, 897 StrokeCol: color.Black, 898 ShowBackground: true, 899 BackgroundCol: bgCol, 900 ShowBorder: true, 901 ShowLineBB: false, 902 ShowTextBB: true, 903 HairCross: false, 904 } 905 906 td.HAlign, td.VAlign, td.X, td.Y, td.FontSize = types.AlignJustify, types.AlignMiddle, -1, r.Height()*.72, 9 907 td.Scale, td.FillCol = 1, fillCol 908 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 909 td.Scale, td.FillCol = 1.5, color.SimpleColor{R: 1} 910 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 911 td.Scale, td.FillCol = 2, color.SimpleColor{R: .5} 912 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 913 914 width := 130. 915 916 td.HAlign, td.VAlign, td.X = types.AlignJustify, types.AlignMiddle, r.Width()*.75 917 td.FillCol, td.Text = fillCol, "Justified column\nWidth=130" 918 919 td.FontSize, td.Y = 24, r.Height()*.35 920 td.Scale = 1 921 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 922 td.Scale = 1.5 923 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 924 925 td.FontSize, td.Y = 12, r.Height()*.22 926 td.Scale = 1 927 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 928 td.Scale = 1.5 929 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 930 931 td.FontSize = 9 932 td.Scale, td.Y = 1, r.Height()*.15 933 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 934 td.Scale, td.Y = 1.5, r.Height()*.13 935 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 936 937 td = model.TextDescriptor{ 938 FontName: fontName, 939 Embed: true, 940 FontKey: k, 941 FontSize: 12, 942 MLeft: 5, 943 MRight: 5, 944 MTop: 5, 945 MBot: 5, 946 ScaleAbs: true, 947 RMode: draw.RMFill, 948 StrokeCol: color.Black, 949 ShowBackground: true, 950 BackgroundCol: bgCol, 951 ShowBorder: true, 952 ShowLineBB: false, 953 ShowTextBB: true, 954 HairCross: false, 955 } 956 957 text15 := "Hello Gopher!\nAbsolute Width=1.5" 958 text1 := "Hello Gopher!\nAbsolute Width=1" 959 text5 := "Hello Gopher!\nAbsolute Width=.5" 960 961 td.Dx, td.Dy = dx, -dy 962 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 963 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopLeft) 964 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{R: 1}, text1 965 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopLeft) 966 td.Scale, td.FillCol, td.Text = .5, color.SimpleColor{R: .5}, text5 967 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopLeft) 968 969 td.Dx, td.Dy = 0, -dy 970 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 971 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopCenter) 972 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{G: 1}, text1 973 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopCenter) 974 td.Scale, td.FillCol, td.Text = .5, color.SimpleColor{G: .5}, text5 975 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopCenter) 976 977 td.Dx, td.Dy = -dx, -dy 978 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 979 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopRight) 980 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{B: 1}, text1 981 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopRight) 982 td.Scale, td.FillCol, td.Text = .5, color.SimpleColor{B: .5}, text5 983 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.TopRight) 984 985 td.Dx, td.Dy = dx, 0 986 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 987 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Left) 988 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{R: 1}, text1 989 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Left) 990 td.Scale, td.FillCol = .5, color.SimpleColor{R: .5} 991 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Left) 992 993 td.Dx, td.Dy = 0, 0 994 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 995 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Center) 996 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{G: 1}, text1 997 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Center) 998 td.Scale, td.FillCol, td.Text = .5, color.SimpleColor{G: .5}, text5 999 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Center) 1000 1001 td.Dx, td.Dy = -dx, 0 1002 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 1003 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Right) 1004 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{B: 1}, text1 1005 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Right) 1006 td.Scale, td.FillCol, td.Text = .5, color.SimpleColor{B: .5}, text5 1007 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.Right) 1008 1009 td.Dx, td.Dy = dx, dy 1010 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 1011 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomLeft) 1012 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{R: 1}, text1 1013 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomLeft) 1014 td.Scale, td.FillCol = .5, color.SimpleColor{R: .5} 1015 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomLeft) 1016 1017 td.Dx, td.Dy = 0, dy 1018 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 1019 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomCenter) 1020 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{G: 1}, text1 1021 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomCenter) 1022 td.Scale, td.FillCol, td.Text = .5, color.SimpleColor{G: .5}, text5 1023 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomCenter) 1024 1025 td.Dx, td.Dy = -dx, +dy 1026 td.Scale, td.FillCol, td.Text = 1.5, fillCol, text15 1027 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomRight) 1028 td.Scale, td.FillCol, td.Text = 1, color.SimpleColor{B: 1}, text1 1029 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomRight) 1030 td.Scale, td.FillCol, td.Text = .5, color.SimpleColor{B: .5}, text5 1031 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, r, td, types.BottomRight) 1032 1033 draw.DrawHairCross(buf, 0, 0, r) 1034 } 1035 1036 func writeTextScaleAbsoluteDemo(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle) { 1037 writeTextScaleAbsoluteDemoWithOffset(xRefTable, p, region, 0, 0) 1038 } 1039 1040 func createTextScaleAbsoluteDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1041 p := model.NewPage(mediaBox, nil) 1042 var region *types.Rectangle 1043 writeTextScaleAbsoluteDemo(xRefTable, p, region) 1044 region = types.RectForWidthAndHeight(20, 70, 180, 180) 1045 writeTextScaleAbsoluteDemo(xRefTable, p, region) 1046 return p 1047 } 1048 1049 func createTextScaleAbsoluteDemoWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1050 p := model.NewPage(mediaBox, nil) 1051 dx, dy := 20., 20. 1052 var region *types.Rectangle 1053 writeTextScaleAbsoluteDemoWithOffset(xRefTable, p, region, dx, dy) 1054 region = types.RectForWidthAndHeight(20, 70, 180, 180) 1055 writeTextScaleAbsoluteDemoWithOffset(xRefTable, p, region, dx, dy) 1056 return p 1057 } 1058 1059 func writeTextScaleRelativeDemoWithOffset(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, dx, dy float64) { 1060 mediaBox := p.MediaBox 1061 buf := p.Buf 1062 1063 mediaBB := true 1064 1065 var cr, cg, cb float32 1066 cr, cg, cb = .5, .75, 1. 1067 r := mediaBox 1068 if region != nil { 1069 r = region 1070 cr, cg, cb = .75, .75, 1 1071 } 1072 if mediaBB { 1073 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 1074 } 1075 1076 fillCol := color.Black 1077 bgCol := color.SimpleColor{R: 1., G: .98, B: .77} 1078 1079 fontName := "Helvetica" 1080 k := p.Fm.EnsureKey(fontName) 1081 1082 td := model.TextDescriptor{ 1083 Text: sampleText, 1084 FontName: fontName, 1085 Embed: true, 1086 FontKey: k, 1087 FontSize: 18, 1088 MLeft: 5, 1089 MRight: 5, 1090 MTop: 5, 1091 MBot: 5, 1092 HAlign: types.AlignJustify, 1093 VAlign: types.AlignMiddle, 1094 X: -1, 1095 Y: r.Height() * .73, 1096 ScaleAbs: false, 1097 RMode: draw.RMFill, 1098 StrokeCol: color.Black, 1099 ShowBackground: true, 1100 BackgroundCol: bgCol, 1101 ShowBorder: true, 1102 ShowLineBB: false, 1103 ShowTextBB: true, 1104 HairCross: false, 1105 } 1106 1107 td.FontSize, td.Scale, td.FillCol = 9, .4, fillCol 1108 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 1109 td.FontSize, td.Scale, td.FillCol = 9, .6, color.SimpleColor{R: 1} 1110 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 1111 td.FontSize, td.Scale, td.FillCol = 9, .8, color.SimpleColor{R: .5} 1112 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 1113 1114 width := 130. 1115 1116 td = model.TextDescriptor{ 1117 Text: "Justified column\nWidth=130", 1118 FontName: fontName, 1119 Embed: true, 1120 FontKey: k, 1121 FontSize: 18, 1122 MLeft: 5, 1123 MRight: 5, 1124 MTop: 5, 1125 MBot: 5, 1126 HAlign: types.AlignJustify, 1127 VAlign: types.AlignMiddle, 1128 X: r.Width() * .75, 1129 Y: r.Height() * .25, 1130 ScaleAbs: false, 1131 RMode: draw.RMFill, 1132 StrokeCol: color.Black, 1133 ShowBackground: true, 1134 BackgroundCol: bgCol, 1135 ShowBorder: true, 1136 ShowLineBB: false, 1137 ShowTextBB: true, 1138 HairCross: false, 1139 } 1140 td.Scale, td.FillCol = .5, fillCol 1141 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 1142 td.Scale, td.FillCol = .3, color.SimpleColor{G: 1} 1143 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 1144 td.Scale, td.FillCol = .20, color.SimpleColor{G: .5} 1145 model.WriteColumn(xRefTable, buf, mediaBox, region, td, width) 1146 1147 td = model.TextDescriptor{ 1148 FontName: fontName, 1149 Embed: true, 1150 FontKey: k, 1151 FontSize: 18, 1152 MLeft: 5, 1153 MRight: 5, 1154 MTop: 5, 1155 MBot: 5, 1156 HAlign: types.AlignJustify, 1157 VAlign: types.AlignMiddle, 1158 X: r.Width() * .75, 1159 Y: r.Height() * .25, 1160 ScaleAbs: false, 1161 RMode: draw.RMFill, 1162 StrokeCol: color.Black, 1163 ShowBackground: true, 1164 BackgroundCol: bgCol, 1165 ShowBorder: true, 1166 ShowLineBB: false, 1167 ShowTextBB: true, 1168 HairCross: false, 1169 } 1170 1171 text10 := "Hello Gopher!\nRelative Width=10%" 1172 text20 := "Hello Gopher!\nRelative Width=20%" 1173 text30 := "Hello Gopher!\nRelative Width=30%" 1174 1175 td.Dx, td.Dy = dx, -dy 1176 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1177 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopLeft) 1178 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{R: 1}, text20 1179 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopLeft) 1180 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{R: .5}, text10 1181 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopLeft) 1182 1183 td.Dx, td.Dy = 0, -dy 1184 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1185 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopCenter) 1186 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{G: 1}, text20 1187 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopCenter) 1188 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{G: .5}, text10 1189 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopCenter) 1190 1191 td.Dx, td.Dy = -dx, -dy 1192 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1193 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopRight) 1194 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{B: 1}, text20 1195 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopRight) 1196 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{B: .5}, text10 1197 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.TopRight) 1198 1199 td.Dx, td.Dy = dx, 0 1200 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1201 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Left) 1202 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{R: 1}, text20 1203 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Left) 1204 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{R: .5}, text10 1205 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Left) 1206 1207 td.Dx, td.Dy = 0, 0 1208 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1209 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Center) 1210 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{G: 1}, text20 1211 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Center) 1212 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{G: .5}, text10 1213 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Center) 1214 1215 td.Dx, td.Dy = -dx, 0 1216 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1217 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Right) 1218 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{B: 1}, text20 1219 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Right) 1220 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{B: .5}, text10 1221 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.Right) 1222 1223 td.Dx, td.Dy = dx, dy 1224 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1225 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomLeft) 1226 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{R: 1}, text20 1227 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomLeft) 1228 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{R: .5}, text10 1229 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomLeft) 1230 1231 td.Dx, td.Dy = 0, dy 1232 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1233 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomCenter) 1234 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{G: 1}, text20 1235 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomCenter) 1236 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{G: .5}, text10 1237 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomCenter) 1238 1239 td.Dx, td.Dy = -dx, dy 1240 td.Scale, td.FillCol, td.Text = .3, fillCol, text30 1241 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomRight) 1242 td.Scale, td.FillCol, td.Text = .2, color.SimpleColor{B: 1}, text20 1243 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomRight) 1244 td.Scale, td.FillCol, td.Text = .1, color.SimpleColor{B: .5}, text10 1245 model.WriteMultiLineAnchored(xRefTable, buf, mediaBox, region, td, types.BottomRight) 1246 1247 draw.DrawHairCross(buf, 0, 0, r) 1248 } 1249 1250 func writeTextScaleRelativeDemo(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle) { 1251 writeTextScaleRelativeDemoWithOffset(xRefTable, p, region, 0, 0) 1252 } 1253 1254 func createTextScaleRelativeDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1255 p := model.NewPage(mediaBox, nil) 1256 var region *types.Rectangle 1257 writeTextScaleRelativeDemo(xRefTable, p, region) 1258 region = types.RectForWidthAndHeight(50, 70, 200, 200) 1259 writeTextScaleRelativeDemo(xRefTable, p, region) 1260 return p 1261 } 1262 1263 func createTextScaleRelativeDemoWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1264 p := model.NewPage(mediaBox, nil) 1265 var region *types.Rectangle 1266 dx, dy := 20., 20. 1267 writeTextScaleRelativeDemoWithOffset(xRefTable, p, region, dx, dy) 1268 region = types.RectForWidthAndHeight(50, 70, 200, 200) 1269 writeTextScaleRelativeDemoWithOffset(xRefTable, p, region, dx, dy) 1270 return p 1271 } 1272 1273 func createTextDemoColumns(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1274 p := model.NewPageWithBg(mediaBox, color.NewSimpleColor(0xbeded9)) 1275 fontName := "Times-Roman" 1276 k := p.Fm.EnsureKey(fontName) 1277 td := model.TextDescriptor{ 1278 FontName: fontName, 1279 Embed: true, 1280 FontKey: k, 1281 FontSize: 9, 1282 MLeft: 10, 1283 MRight: 10, 1284 MTop: 10, 1285 MBot: 10, 1286 Scale: 1., 1287 ScaleAbs: true, 1288 RMode: draw.RMFill, 1289 StrokeCol: color.Black, 1290 ShowBackground: true, 1291 BorderWidth: 3, 1292 } 1293 1294 // 1st row: 3 side by side columns using anchors, width and a background color. 1295 1296 width := mediaBox.Width() / 3 1297 td.MinHeight = mediaBox.Height() / 2 1298 1299 // Render left column. 1300 // Draw the bounding box with rounded corners but no borders. 1301 td.Text = sampleText 1302 td.ShowTextBB, td.ShowBorder = true, false 1303 td.BackgroundCol = color.SimpleColor{R: .4, G: .98, B: .77} 1304 td.BorderStyle = types.LJRound 1305 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, nil, td, types.TopLeft, width) 1306 1307 // Render middle column. 1308 // Draw the bounding box with regular corners but no border. 1309 td.Text = sampleText2 1310 td.Dx = -width / 2 1311 td.ShowTextBB, td.ShowBorder = true, false 1312 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1313 td.BorderStyle = types.LJMiter 1314 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, nil, td, types.TopCenter, width) 1315 1316 // Render right column. 1317 // Draw bounding box and a border with rounded corners. 1318 1319 td.Text = sampleText3 1320 td.Dx = 0 1321 td.ShowTextBB, td.ShowBorder = true, true 1322 td.BackgroundCol = color.SimpleColor{R: 1., G: .98, B: .77} 1323 td.BorderCol = color.SimpleColor{R: .2, G: .5, B: .2} 1324 td.BorderStyle = types.LJRound 1325 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, nil, td, types.TopRight, width) 1326 1327 // 2nd row: 3 side by side columns below using relative scaling, 1328 // Indent paragraph beginnings and don't draw the background. 1329 relScaleFactor := .334 1330 td.Dy = mediaBox.Height() / 2 1331 td.Scale = relScaleFactor 1332 td.ScaleAbs = false 1333 td.ParIndent = true 1334 td.ShowBackground, td.ShowBorder = false, true 1335 td.HAlign, td.VAlign = types.AlignJustify, types.AlignTop 1336 1337 // Render left column. 1338 td.Text = sampleText 1339 td.X = 0 1340 td.ShowTextBB = true 1341 td.BorderStyle = types.LJBevel 1342 model.WriteMultiLine(xRefTable, p.Buf, mediaBox, nil, td) 1343 1344 // Render middle column. 1345 td.Text = sampleText2 1346 td.X = mediaBox.Width() / 2 1347 td.Dx = -width / 2 1348 td.ShowTextBB = false 1349 model.WriteMultiLine(xRefTable, p.Buf, mediaBox, nil, td) 1350 1351 // Render right column. 1352 td.Text = sampleText3 1353 td.X = mediaBox.Width() 1354 td.Dx = 0 1355 td.ShowTextBB = true 1356 td.BorderStyle = types.LJMiter 1357 model.WriteMultiLine(xRefTable, p.Buf, mediaBox, nil, td) 1358 1359 draw.DrawHairCross(p.Buf, 0, 0, mediaBox) 1360 1361 return p 1362 } 1363 1364 func writeTextBorderTest(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle) model.Page { 1365 mediaBox := p.MediaBox 1366 buf := p.Buf 1367 1368 mediaBB := true 1369 1370 var cr, cg, cb float32 1371 cr, cg, cb = .5, .75, 1. 1372 r := mediaBox 1373 if region != nil { 1374 r = region 1375 cr, cg, cb = .75, .75, 1 1376 } 1377 if mediaBB { 1378 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 1379 } 1380 1381 fontName := "Times-Roman" 1382 k := p.Fm.EnsureKey(fontName) 1383 td := model.TextDescriptor{ 1384 FontName: fontName, 1385 Embed: true, 1386 FontKey: k, 1387 FontSize: 7, 1388 MLeft: 10, 1389 MRight: 10, 1390 MTop: 10, 1391 MBot: 10, 1392 Scale: 1., 1393 ScaleAbs: true, 1394 RMode: draw.RMFill, 1395 BorderCol: color.NewSimpleColor(0xabe003), 1396 ShowTextBB: true, 1397 } 1398 1399 w := mediaBox.Width() / 2 1400 1401 // no background, no margin, no border 1402 td.Text = sampleText2 1403 td.ShowBackground, td.ShowBorder, td.ShowMargins = false, false, false 1404 td.MBot, td.MTop, td.MLeft, td.MRight = 0, 0, 0, 0 1405 td.BorderWidth = 0 1406 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1407 td.BorderStyle = types.LJMiter 1408 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.TopLeft, w) 1409 1410 // with background, no margin, no border 1411 td.Text = sampleText2 1412 td.ShowBackground, td.ShowBorder, td.ShowMargins = true, false, false 1413 td.MBot, td.MTop, td.MLeft, td.MRight = 0, 0, 0, 0 1414 td.BorderWidth = 0 1415 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1416 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.TopCenter, w) 1417 1418 // with background, with margins, no border 1419 td.Text = sampleText2 1420 td.ShowBackground, td.ShowBorder, td.ShowMargins = true, false, false 1421 td.MBot, td.MTop, td.MLeft, td.MRight = 10, 10, 10, 10 1422 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1423 td.Dy = 100 1424 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.Left, w) 1425 1426 // with background, with margins, show margins, no border 1427 td.Text = sampleText2 1428 td.ShowBackground, td.ShowBorder, td.ShowMargins = true, false, true 1429 td.MBot, td.MTop, td.MLeft, td.MRight = 10, 10, 10, 10 1430 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1431 td.BorderStyle = types.LJMiter 1432 td.Dy = 100 1433 bb := model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.Center, w) 1434 1435 // with background, no margin, with border, without border background 1436 td.Text = sampleText2 1437 td.ShowBackground, td.ShowBorder, td.ShowMargins = true, false, false 1438 td.BorderWidth = 5 1439 td.MBot, td.MTop, td.MLeft, td.MRight = 0, 0, 0, 0 1440 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1441 td.BorderStyle = types.LJRound 1442 td.Dy = -bb.Height() / 2 1443 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.Left, w) 1444 1445 // with background, no margin, with border, with border background 1446 td.Text = sampleText2 1447 td.ShowBackground, td.ShowBorder, td.ShowMargins = true, true, false 1448 td.BorderWidth = 5 1449 td.MBot, td.MTop, td.MLeft, td.MRight = 0, 0, 0, 0 1450 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1451 td.BorderStyle = types.LJRound 1452 td.Dy = -bb.Height() / 2 1453 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.Center, w) 1454 1455 // with background, with margins, with border, with border background 1456 td.Text = sampleText2 1457 td.ShowBackground, td.ShowBorder, td.ShowMargins = true, true, false 1458 td.BorderWidth = 5 1459 td.MBot, td.MTop, td.MLeft, td.MRight = 10, 10, 10, 10 1460 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1461 td.BorderStyle = types.LJRound 1462 td.Dy = 0 1463 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.BottomLeft, w) 1464 1465 // with background, with margins, show margins, with border, with border background 1466 td.Text = sampleText2 1467 td.ShowBackground, td.ShowBorder, td.ShowMargins = true, true, true 1468 td.BorderWidth = 5 1469 td.MBot, td.MTop, td.MLeft, td.MRight = 10, 10, 10, 10 1470 td.BackgroundCol = color.SimpleColor{R: .6, G: .98, B: .77} 1471 td.BorderStyle = types.LJRound 1472 td.Dy = 0 1473 model.WriteColumnAnchored(xRefTable, p.Buf, mediaBox, region, td, types.BottomCenter, w) 1474 1475 draw.DrawHairCross(p.Buf, 0, 0, r) 1476 1477 return p 1478 } 1479 1480 func createTextBorderTest(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1481 p := model.NewPageWithBg(mediaBox, color.NewSimpleColor(0xbeded9)) 1482 var region *types.Rectangle 1483 writeTextBorderTest(xRefTable, p, region) 1484 region = types.RectForWidthAndHeight(70, 200, 200, 200) 1485 writeTextBorderTest(xRefTable, p, region) 1486 return p 1487 } 1488 1489 func createTextBorderNoMarginAlignLeftTest(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1490 p := model.NewPageWithBg(mediaBox, color.NewSimpleColor(0xbeded9)) 1491 fontName := "Times-Roman" 1492 k := p.Fm.EnsureKey(fontName) 1493 td := model.TextDescriptor{ 1494 Text: sampleText2, 1495 FontName: fontName, 1496 Embed: true, 1497 FontKey: k, 1498 FontSize: 12, 1499 Scale: 1., 1500 ScaleAbs: true, 1501 RMode: draw.RMFill, 1502 ShowBackground: true, 1503 BackgroundCol: color.SimpleColor{R: .6, G: .98, B: .77}, 1504 ShowBorder: true, 1505 BorderWidth: 10, 1506 ShowMargins: true, 1507 MLeft: 10, 1508 MRight: 10, 1509 MTop: 10, 1510 MBot: 10, 1511 BorderCol: color.NewSimpleColor(0xabe003), 1512 ShowTextBB: true, 1513 } 1514 1515 td.X, td.Y, td.HAlign, td.VAlign = 100, 450, types.AlignLeft, types.AlignTop 1516 td.MinHeight = 300 1517 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 400) 1518 1519 draw.SetLineWidth(p.Buf, 0) 1520 draw.SetStrokeColor(p.Buf, color.Black) 1521 draw.DrawLineSimple(p.Buf, 100, 0, 100, 600) 1522 draw.DrawLineSimple(p.Buf, 500, 0, 500, 600) 1523 draw.DrawLineSimple(p.Buf, 110, 0, 110, 600) 1524 draw.DrawLineSimple(p.Buf, 490, 0, 490, 600) 1525 draw.DrawLineSimple(p.Buf, 0, 150, 600, 150) 1526 draw.DrawLineSimple(p.Buf, 0, 450, 600, 450) 1527 draw.DrawLineSimple(p.Buf, 0, 160, 600, 160) 1528 draw.DrawLineSimple(p.Buf, 0, 440, 600, 440) 1529 //pdf.DrawHairCross(p.Buf, 0, 0, mediaBox) 1530 return p 1531 } 1532 1533 func createTextBorderNoMarginAlignRightTest(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1534 p := model.NewPageWithBg(mediaBox, color.NewSimpleColor(0xbeded9)) 1535 fontName := "Times-Roman" 1536 k := p.Fm.EnsureKey(fontName) 1537 td := model.TextDescriptor{ 1538 Text: sampleText2, 1539 FontName: fontName, 1540 Embed: true, 1541 FontKey: k, 1542 FontSize: 12, 1543 Scale: 1., 1544 ScaleAbs: true, 1545 RMode: draw.RMFill, 1546 ShowBackground: true, 1547 BackgroundCol: color.SimpleColor{R: .6, G: .98, B: .77}, 1548 ShowBorder: true, 1549 BorderWidth: 10, 1550 ShowMargins: true, 1551 MLeft: 10, 1552 MRight: 10, 1553 MTop: 10, 1554 MBot: 10, 1555 BorderCol: color.NewSimpleColor(0xabe003), 1556 ShowTextBB: true, 1557 } 1558 1559 td.X, td.Y, td.HAlign, td.VAlign = 500, 450, types.AlignRight, types.AlignTop 1560 td.MinHeight = 300 1561 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 400) 1562 1563 draw.SetLineWidth(p.Buf, 0) 1564 draw.SetStrokeColor(p.Buf, color.Black) 1565 draw.DrawLineSimple(p.Buf, 100, 0, 100, 600) 1566 draw.DrawLineSimple(p.Buf, 500, 0, 500, 600) 1567 draw.DrawLineSimple(p.Buf, 110, 0, 110, 600) 1568 draw.DrawLineSimple(p.Buf, 490, 0, 490, 600) 1569 draw.DrawLineSimple(p.Buf, 0, 150, 600, 150) 1570 draw.DrawLineSimple(p.Buf, 0, 450, 600, 450) 1571 draw.DrawLineSimple(p.Buf, 0, 160, 600, 160) 1572 draw.DrawLineSimple(p.Buf, 0, 440, 600, 440) 1573 //pdf.DrawHairCross(p.Buf, 0, 0, mediaBox) 1574 return p 1575 } 1576 1577 func createTextBorderNoMarginAlignCenterTest(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1578 p := model.NewPageWithBg(mediaBox, color.NewSimpleColor(0xbeded9)) 1579 fontName := "Times-Roman" 1580 k := p.Fm.EnsureKey(fontName) 1581 td := model.TextDescriptor{ 1582 Text: sampleText2, 1583 FontName: fontName, 1584 Embed: true, 1585 FontKey: k, 1586 FontSize: 12, 1587 Scale: 1., 1588 ScaleAbs: true, 1589 RMode: draw.RMFill, 1590 ShowBackground: true, 1591 BackgroundCol: color.SimpleColor{R: .6, G: .98, B: .77}, 1592 ShowBorder: true, 1593 BorderWidth: 10, 1594 BorderCol: color.NewSimpleColor(0xabe003), 1595 ShowMargins: true, 1596 MLeft: 10, 1597 MRight: 10, 1598 MTop: 10, 1599 MBot: 10, 1600 ShowTextBB: true, 1601 } 1602 1603 td.X, td.Y, td.HAlign, td.VAlign = 300, 450, types.AlignCenter, types.AlignTop 1604 td.MinHeight = 300 1605 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 400) 1606 1607 draw.SetLineWidth(p.Buf, 0) 1608 draw.SetStrokeColor(p.Buf, color.Black) 1609 draw.DrawLineSimple(p.Buf, 100, 0, 100, 600) 1610 draw.DrawLineSimple(p.Buf, 500, 0, 500, 600) 1611 draw.DrawLineSimple(p.Buf, 110, 0, 110, 600) 1612 draw.DrawLineSimple(p.Buf, 490, 0, 490, 600) 1613 draw.DrawLineSimple(p.Buf, 0, 150, 600, 150) 1614 draw.DrawLineSimple(p.Buf, 0, 450, 600, 450) 1615 draw.DrawLineSimple(p.Buf, 0, 440, 600, 440) 1616 //pdf.DrawHairCross(p.Buf, 0, 0, mediaBox) 1617 return p 1618 } 1619 1620 func createTextBorderNoMarginAlignJustifyTest(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1621 p := model.NewPageWithBg(mediaBox, color.NewSimpleColor(0xbeded9)) 1622 fontName := "Times-Roman" 1623 k := p.Fm.EnsureKey(fontName) 1624 td := model.TextDescriptor{ 1625 Text: sampleText2, 1626 FontName: fontName, 1627 Embed: true, 1628 FontKey: k, 1629 FontSize: 12, 1630 Scale: 1., 1631 ScaleAbs: true, 1632 RMode: draw.RMFill, 1633 ShowBackground: true, 1634 BackgroundCol: color.SimpleColor{R: .6, G: .98, B: .77}, 1635 ShowBorder: true, 1636 BorderWidth: 10, 1637 BorderCol: color.NewSimpleColor(0xabe003), 1638 ShowTextBB: true, 1639 ShowMargins: true, 1640 MLeft: 10, 1641 MRight: 10, 1642 MTop: 10, 1643 MBot: 10, 1644 } 1645 1646 td.X, td.Y, td.HAlign, td.VAlign = 100, 450, types.AlignJustify, types.AlignTop 1647 td.MinHeight = 300 1648 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 400) 1649 1650 draw.SetLineWidth(p.Buf, 0) 1651 draw.SetStrokeColor(p.Buf, color.Black) 1652 draw.DrawLineSimple(p.Buf, 100, 0, 100, 600) 1653 draw.DrawLineSimple(p.Buf, 500, 0, 500, 600) 1654 draw.DrawLineSimple(p.Buf, 110, 0, 110, 600) 1655 draw.DrawLineSimple(p.Buf, 490, 0, 490, 600) 1656 draw.DrawLineSimple(p.Buf, 0, 150, 600, 150) 1657 draw.DrawLineSimple(p.Buf, 0, 450, 600, 450) 1658 draw.DrawLineSimple(p.Buf, 0, 160, 600, 160) 1659 draw.DrawLineSimple(p.Buf, 0, 440, 600, 440) 1660 //pdf.DrawHairCross(p.Buf, 0, 0, mediaBox) 1661 return p 1662 } 1663 1664 func createXRefAndWritePDF(t *testing.T, msg, fileName string, mediaBox *types.Rectangle, f func(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page) { 1665 t.Helper() 1666 xRefTable, err := pdfcpu.CreateDemoXRef() 1667 if err != nil { 1668 t.Fatalf("%s: %v\n", msg, err) 1669 } 1670 1671 p := f(xRefTable, mediaBox) 1672 1673 rootDict, err := xRefTable.Catalog() 1674 if err != nil { 1675 t.Fatalf("%s: %v\n", msg, err) 1676 } 1677 if err = pdfcpu.AddPageTreeWithSamplePage(xRefTable, rootDict, p); err != nil { 1678 t.Fatalf("%s: %v\n", msg, err) 1679 } 1680 1681 outDir := filepath.Join("..", "..", "samples", "basic") 1682 outFile := filepath.Join(outDir, fileName+".pdf") 1683 createAndValidate(t, xRefTable, outFile, msg) 1684 } 1685 1686 func testTextDemoPDF(t *testing.T, msg, fileName string, w, h int, hAlign types.HAlignment) { 1687 t.Helper() 1688 1689 var f1, f2, f3, f4 func(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page 1690 1691 switch hAlign { 1692 case types.AlignLeft: 1693 f1 = createTextDemoAlignLeft 1694 f2 = createTextDemoAlignLeftMargin 1695 f3 = createTextDemoAlignLeftWidth 1696 f4 = createTextDemoAlignLeftWidthAndMargin 1697 case types.AlignCenter: 1698 f1 = createTextDemoAlignCenter 1699 f2 = createTextDemoAlignCenterMargin 1700 f3 = createTextDemoAlignCenterWidth 1701 f4 = createTextDemoAlignCenterWidthAndMargin 1702 case types.AlignRight: 1703 f1 = createTextDemoAlignRight 1704 f2 = createTextDemoAlignRightMargin 1705 f3 = createTextDemoAlignRightWidth 1706 f4 = createTextDemoAlignRightWidthAndMargin 1707 case types.AlignJustify: 1708 f1 = createTextDemoAlignJustify 1709 f2 = createTextDemoAlignJustifyMargin 1710 f3 = createTextDemoAlignJustifyWidth 1711 f4 = createTextDemoAlignJustifyWidthAndMargin 1712 } 1713 1714 mediaBox := types.RectForDim(float64(w), float64(h)) 1715 createXRefAndWritePDF(t, msg, "TextDemo"+fileName, mediaBox, f1) 1716 createXRefAndWritePDF(t, msg, "TextDemo"+fileName+"Margin", mediaBox, f2) 1717 createXRefAndWritePDF(t, msg, "TextDemo"+fileName+"Width", mediaBox, f3) 1718 createXRefAndWritePDF(t, msg, "TextDemo"+fileName+"WidthAndMargin", mediaBox, f4) 1719 } 1720 1721 func TestTextDemoPDF(t *testing.T) { 1722 msg := "TestTextDemoPDF" 1723 w, h := 600, 600 1724 1725 for _, tt := range []struct { 1726 fileName string 1727 w, h int 1728 hAlign types.HAlignment 1729 }{ 1730 {"AlignLeft", w, h, types.AlignLeft}, 1731 {"AlignCenter", w, h, types.AlignCenter}, 1732 {"AlignRight", w, h, types.AlignRight}, 1733 {"AlignJustify", w, h, types.AlignJustify}, 1734 } { 1735 testTextDemoPDF(t, msg, tt.fileName, tt.w, tt.h, tt.hAlign) 1736 } 1737 } 1738 1739 func TestColumnDemoPDF(t *testing.T) { 1740 msg := "TestColumnDemoPDF" 1741 1742 for _, tt := range []struct { 1743 fileName string 1744 w, h int 1745 f func(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page 1746 }{ 1747 {"TestTextAlignJustifyDemo", 600, 600, createTextAlignJustifyDemo}, 1748 {"TestTextAlignJustifyColumnDemo", 600, 600, createTextAlignJustifyColumnDemo}, 1749 {"TextDemoAnchors", 600, 600, createTextDemoAnchors}, 1750 {"TextDemoAnchorsWithOffset", 600, 600, createTextDemoAnchorsWithOffset}, 1751 {"TextDemoColumnAnchored", 1200, 1200, createTextDemoColumnAnchored}, 1752 {"TextDemoColumnAnchoredWithOffset", 1200, 1200, createTextDemoColumnAnchoredWithOffset}, 1753 {"TextRotateDemo", 1200, 1200, createTextRotateDemo}, 1754 {"TextRotateDemoWithOffset", 1200, 1200, createTextRotateDemoWithOffset}, 1755 {"TextScaleAbsoluteDemo", 600, 600, createTextScaleAbsoluteDemo}, 1756 {"TextScaleAbsoluteDemoWithOffset", 600, 600, createTextScaleAbsoluteDemoWithOffset}, 1757 {"TextScaleRelativeDemo", 600, 600, createTextScaleRelativeDemo}, 1758 {"TextScaleRelativeDemoWithOffset", 600, 600, createTextScaleRelativeDemoWithOffset}, 1759 {"TextDemoColumns", 600, 600, createTextDemoColumns}, 1760 {"TextBorderTest", 600, 600, createTextBorderTest}, 1761 {"TextBorderNoMarginAlignLeftTest", 600, 600, createTextBorderNoMarginAlignLeftTest}, 1762 {"TextBorderNoMarginAlignRightTest", 600, 600, createTextBorderNoMarginAlignRightTest}, 1763 {"TextBorderNoMarginAlignCenterTest", 600, 600, createTextBorderNoMarginAlignCenterTest}, 1764 {"TextBorderNoMarginAlignJustifyTest", 600, 600, createTextBorderNoMarginAlignJustifyTest}, 1765 } { 1766 mediaBox := types.RectForDim(float64(tt.w), float64(tt.h)) 1767 createXRefAndWritePDF(t, msg, tt.fileName, mediaBox, tt.f) 1768 } 1769 } 1770 1771 func writecreateTestRTLUserFont(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, fontName, s string) { 1772 mediaBox := p.MediaBox 1773 buf := p.Buf 1774 1775 mediaBB := true 1776 1777 var cr, cg, cb float32 1778 cr, cg, cb = .5, .75, 1. 1779 r := mediaBox 1780 if region != nil { 1781 r = region 1782 cr, cg, cb = .75, .75, 1 1783 } 1784 if mediaBB { 1785 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 1786 } 1787 1788 k := p.Fm.EnsureKey(fontName) 1789 1790 td := model.TextDescriptor{ 1791 Text: s, 1792 FontName: fontName, 1793 Embed: true, 1794 FontKey: k, 1795 FontSize: 12, 1796 RTL: true, 1797 MLeft: 5, 1798 MRight: 5, 1799 MTop: 5, 1800 MBot: 5, 1801 X: mediaBox.Width(), 1802 Y: -1, 1803 Scale: 1., 1804 ScaleAbs: true, 1805 HAlign: types.AlignRight, 1806 VAlign: types.AlignMiddle, 1807 RMode: draw.RMFill, 1808 StrokeCol: color.NewSimpleColor(0x206A29), 1809 FillCol: color.NewSimpleColor(0x206A29), 1810 ShowBackground: true, 1811 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 1812 ShowBorder: true, 1813 ShowLineBB: false, 1814 ShowTextBB: true, 1815 HairCross: false, 1816 } 1817 1818 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 1819 1820 draw.DrawHairCross(p.Buf, 0, 0, mediaBox) 1821 } 1822 1823 func createTestRTLUserFont(xRefTable *model.XRefTable, mediaBox *types.Rectangle, language, fontName string) model.Page { 1824 p := model.NewPage(mediaBox, nil) 1825 var region *types.Rectangle 1826 text := sampleTextRTL[language] 1827 writecreateTestRTLUserFont(xRefTable, p, region, fontName, text) 1828 region = types.RectForWidthAndHeight(10, 10, mediaBox.Width()/4, mediaBox.Height()/4) 1829 writecreateTestRTLUserFont(xRefTable, p, region, fontName, text) 1830 return p 1831 } 1832 1833 func writecreateTestUserFontJustified(xRefTable *model.XRefTable, p model.Page, region *types.Rectangle, rtl bool) { 1834 mediaBox := p.MediaBox 1835 buf := p.Buf 1836 1837 mediaBB := true 1838 1839 var cr, cg, cb float32 1840 cr, cg, cb = .5, .75, 1. 1841 r := mediaBox 1842 if region != nil { 1843 r = region 1844 cr, cg, cb = .75, .75, 1 1845 } 1846 if mediaBB { 1847 draw.FillRectNoBorder(buf, r, color.SimpleColor{R: cr, G: cg, B: cb}) 1848 } 1849 1850 fontName := "Roboto-Regular" 1851 k := p.Fm.EnsureKey(fontName) 1852 1853 td := model.TextDescriptor{ 1854 Text: sampleText, 1855 FontName: fontName, 1856 Embed: true, 1857 FontKey: k, 1858 FontSize: 12, 1859 RTL: rtl, 1860 MLeft: 5, 1861 MRight: 5, 1862 MTop: 5, 1863 MBot: 5, 1864 X: -1, 1865 Y: -1, 1866 Scale: 1., 1867 ScaleAbs: true, 1868 HAlign: types.AlignJustify, 1869 VAlign: types.AlignMiddle, 1870 RMode: draw.RMFill, 1871 StrokeCol: color.NewSimpleColor(0x206A29), 1872 FillCol: color.NewSimpleColor(0x206A29), 1873 ShowBackground: true, 1874 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 1875 ShowBorder: true, 1876 ShowLineBB: false, 1877 ShowTextBB: true, 1878 HairCross: false, 1879 } 1880 1881 model.WriteMultiLine(xRefTable, buf, mediaBox, region, td) 1882 1883 draw.DrawHairCross(p.Buf, 0, 0, mediaBox) 1884 } 1885 1886 func createTestUserFontJustified(xRefTable *model.XRefTable, mediaBox *types.Rectangle, rtl bool) model.Page { 1887 p := model.NewPage(mediaBox, nil) 1888 var region *types.Rectangle 1889 writecreateTestUserFontJustified(xRefTable, p, region, rtl) 1890 return p 1891 } 1892 1893 func createXRefAndWriteJustifiedPDF(t *testing.T, msg, fileName string, mediaBox *types.Rectangle, rtl bool) { 1894 t.Helper() 1895 xRefTable, err := pdfcpu.CreateDemoXRef() 1896 if err != nil { 1897 t.Fatalf("%s: %v\n", msg, err) 1898 } 1899 1900 p := createTestUserFontJustified(xRefTable, mediaBox, rtl) 1901 1902 rootDict, err := xRefTable.Catalog() 1903 if err != nil { 1904 t.Fatalf("%s: %v\n", msg, err) 1905 } 1906 if err = pdfcpu.AddPageTreeWithSamplePage(xRefTable, rootDict, p); err != nil { 1907 t.Fatalf("%s: %v\n", msg, err) 1908 } 1909 1910 outDir := filepath.Join("..", "..", "samples", "basic") 1911 outFile := filepath.Join(outDir, fileName+".pdf") 1912 createAndValidate(t, xRefTable, outFile, msg) 1913 } 1914 1915 func TestUserFontJustified(t *testing.T) { 1916 msg := "TestUserFontJustified" 1917 mediaBox := types.RectForDim(600, 600) 1918 createXRefAndWriteJustifiedPDF(t, msg, "UserFont_Justified", mediaBox, false) 1919 createXRefAndWriteJustifiedPDF(t, msg, "UserFont_JustifiedRightToLeft", mediaBox, true) 1920 } 1921 1922 func createXRefAndWriteRTLPDF(t *testing.T, 1923 msg, fileName string, 1924 mediaBox *types.Rectangle, 1925 language, fontName string, 1926 f func(xRefTable *model.XRefTable, mediaBox *types.Rectangle, language, fontName string) model.Page) { 1927 t.Helper() 1928 1929 xRefTable, err := pdfcpu.CreateDemoXRef() 1930 if err != nil { 1931 t.Fatalf("%s: %v\n", msg, err) 1932 } 1933 1934 p := f(xRefTable, mediaBox, language, fontName) 1935 1936 rootDict, err := xRefTable.Catalog() 1937 if err != nil { 1938 t.Fatalf("%s: %v\n", msg, err) 1939 } 1940 if err = pdfcpu.AddPageTreeWithSamplePage(xRefTable, rootDict, p); err != nil { 1941 t.Fatalf("%s: %v\n", msg, err) 1942 } 1943 outDir := filepath.Join("..", "..", "samples", "basic") 1944 outFile := filepath.Join(outDir, fileName+".pdf") 1945 createAndValidate(t, xRefTable, outFile, msg) 1946 } 1947 1948 func TestUserFontRTL(t *testing.T) { 1949 msg := "TestUserFontRTL" 1950 f := createTestRTLUserFont 1951 mediaBox := types.RectForDim(600, 600) 1952 1953 for _, tt := range []struct { 1954 fileName string 1955 language string 1956 fontName string 1957 }{ 1958 {"UserFont_Arabic", "Arabic", "UnifontMedium"}, 1959 {"UserFont_Hebrew", "Hebrew", "UnifontMedium"}, 1960 {"UserFont_Persian", "Persian", "UnifontMedium"}, 1961 {"UserFont_Urdu", "Urdu", "UnifontMedium"}, 1962 } { 1963 createXRefAndWriteRTLPDF(t, msg, tt.fileName, mediaBox, tt.language, tt.fontName, f) 1964 } 1965 } 1966 1967 func createCJKVDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { 1968 p := model.NewPage(mediaBox, nil) 1969 mb := p.MediaBox 1970 1971 textEnglish := `pdfcpu 1972 Instant PDF processing for all your needs. 1973 Now supporting CJKV!` 1974 1975 textChineseSimple := `pdfcpu 1976 即时处理PDF,满足您的所有需求。 1977 现在支持CJKV字体!` 1978 1979 textJapanese := `pdfcpu 1980 すべてのニーズに対応するインスタントPDF処理。 1981 CJKVフォントがサポートされるようになりました!` 1982 1983 textKorean := `pdfcpu 1984 모든 요구 사항에 맞는 즉각적인 PDF 처리. 1985 이제 CJKV 글꼴을 지원합니다!` 1986 1987 textVietnamese := `pdfcpu 1988 Xử lý PDF tức thì cho mọi nhu cầu của bạn. 1989 Bây giờ với sự hỗ trợ cho các phông chữ CJKV!` 1990 1991 td := model.TextDescriptor{ 1992 FontSize: 24, 1993 Embed: true, 1994 MLeft: 5, 1995 MRight: 5, 1996 MTop: 5, 1997 MBot: 5, 1998 Scale: 1, 1999 ScaleAbs: true, 2000 HAlign: types.AlignLeft, 2001 VAlign: types.AlignMiddle, 2002 RMode: draw.RMFill, 2003 StrokeCol: color.NewSimpleColor(0x206A29), 2004 FillCol: color.NewSimpleColor(0x206A29), 2005 ShowBackground: true, 2006 BackgroundCol: color.SimpleColor{R: 1., G: .98, B: .77}, 2007 ShowBorder: true, 2008 ShowLineBB: false, 2009 ShowTextBB: true, 2010 HairCross: false, 2011 } 2012 2013 td.Text, td.FontName, td.FontKey = textChineseSimple, "UnifontMedium", p.Fm.EnsureKey("UnifontMedium") 2014 td.X, td.Y = 0, mb.Height() 2015 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 3*mb.Width()/4) 2016 2017 td.Text, td.FontName, td.FontKey = textJapanese, "Unifont-JPMedium", p.Fm.EnsureKey("Unifont-JPMedium") 2018 td.X, td.Y = mb.Width(), 2*mb.Height()/3 2019 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 3*mb.Width()/4) 2020 2021 td.Text, td.FontName, td.FontKey = textKorean, "UnifontMedium", p.Fm.EnsureKey("UnifontMedium") 2022 td.X, td.Y = 0, mb.Height()/3 2023 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 3*mb.Width()/4) 2024 2025 td.Text, td.FontName, td.FontKey = textVietnamese, "Roboto-Regular", p.Fm.EnsureKey("Roboto-Regular") 2026 td.X, td.Y = mb.Width(), 0 2027 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 3*mb.Width()/4) 2028 2029 td.Text, td.FontSize, td.ShowTextBB = textEnglish, 24, false 2030 td.X, td.Y, td.HAlign = -1, -1, types.AlignCenter 2031 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 0) 2032 2033 td.FontSize = 80 2034 td.Text, td.HAlign, td.X, td.Y = "C", types.AlignRight, mb.Width(), mb.Height() 2035 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 0) 2036 2037 td.Text, td.HAlign, td.X, td.Y = "J", types.AlignLeft, 0, 2*mb.Height()/3 2038 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 0) 2039 2040 td.Text, td.HAlign, td.X, td.Y = "K", types.AlignRight, mb.Width(), mb.Height()/3 2041 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 0) 2042 2043 td.Text, td.HAlign, td.X, td.Y = "V", types.AlignLeft, 0, 0 2044 model.WriteColumn(xRefTable, p.Buf, mediaBox, nil, td, 0) 2045 2046 return p 2047 } 2048 2049 func TestCJKV(t *testing.T) { 2050 msg := "TestCJKV" 2051 mediaBox := types.RectForDim(600, 600) 2052 xRefTable, err := pdfcpu.CreateDemoXRef() 2053 if err != nil { 2054 t.Fatalf("%s: %v\n", msg, err) 2055 } 2056 2057 p := createCJKVDemo(xRefTable, mediaBox) 2058 2059 rootDict, err := xRefTable.Catalog() 2060 if err != nil { 2061 t.Fatalf("%s: %v\n", msg, err) 2062 } 2063 if err = pdfcpu.AddPageTreeWithSamplePage(xRefTable, rootDict, p); err != nil { 2064 t.Fatalf("%s: %v\n", msg, err) 2065 } 2066 outDir := filepath.Join("..", "..", "samples", "basic") 2067 outFile := filepath.Join(outDir, "UserFont_CJKV.pdf") 2068 createAndValidate(t, xRefTable, outFile, msg) 2069 }