pdf-writer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. data/ChangeLog +44 -0
  2. data/LICENCE +118 -0
  3. data/README +32 -0
  4. data/bin/loader +54 -0
  5. data/bin/manual +22 -0
  6. data/bin/manual.bat +2 -0
  7. data/demo/chunkybacon.rb +28 -0
  8. data/demo/code.rb +63 -0
  9. data/demo/colornames.rb +843 -0
  10. data/demo/demo.rb +65 -0
  11. data/demo/gettysburg.rb +58 -0
  12. data/demo/hello.rb +18 -0
  13. data/demo/individual-i.rb +81 -0
  14. data/demo/pac.rb +62 -0
  15. data/demo/pagenumber.rb +67 -0
  16. data/demo/qr-language.rb +573 -0
  17. data/demo/qr-library.rb +371 -0
  18. data/images/chunkybacon.jpg +0 -0
  19. data/images/chunkybacon.png +0 -0
  20. data/images/pdfwriter-icon.jpg +0 -0
  21. data/images/pdfwriter-small.jpg +0 -0
  22. data/lib/pdf/charts.rb +13 -0
  23. data/lib/pdf/charts/stddev.rb +431 -0
  24. data/lib/pdf/grid.rb +135 -0
  25. data/lib/pdf/math.rb +108 -0
  26. data/lib/pdf/quickref.rb +330 -0
  27. data/lib/pdf/simpletable.rb +946 -0
  28. data/lib/pdf/techbook.rb +890 -0
  29. data/lib/pdf/writer.rb +2661 -0
  30. data/lib/pdf/writer/arc4.rb +63 -0
  31. data/lib/pdf/writer/fontmetrics.rb +201 -0
  32. data/lib/pdf/writer/fonts/Courier-Bold.afm +342 -0
  33. data/lib/pdf/writer/fonts/Courier-BoldOblique.afm +342 -0
  34. data/lib/pdf/writer/fonts/Courier-Oblique.afm +342 -0
  35. data/lib/pdf/writer/fonts/Courier.afm +342 -0
  36. data/lib/pdf/writer/fonts/Helvetica-Bold.afm +2827 -0
  37. data/lib/pdf/writer/fonts/Helvetica-BoldOblique.afm +2827 -0
  38. data/lib/pdf/writer/fonts/Helvetica-Oblique.afm +3051 -0
  39. data/lib/pdf/writer/fonts/Helvetica.afm +3051 -0
  40. data/lib/pdf/writer/fonts/MustRead.html +1 -0
  41. data/lib/pdf/writer/fonts/Symbol.afm +213 -0
  42. data/lib/pdf/writer/fonts/Times-Bold.afm +2588 -0
  43. data/lib/pdf/writer/fonts/Times-BoldItalic.afm +2384 -0
  44. data/lib/pdf/writer/fonts/Times-Italic.afm +2667 -0
  45. data/lib/pdf/writer/fonts/Times-Roman.afm +2419 -0
  46. data/lib/pdf/writer/fonts/ZapfDingbats.afm +225 -0
  47. data/lib/pdf/writer/graphics.rb +727 -0
  48. data/lib/pdf/writer/graphics/imageinfo.rb +365 -0
  49. data/lib/pdf/writer/lang.rb +43 -0
  50. data/lib/pdf/writer/lang/en.rb +77 -0
  51. data/lib/pdf/writer/object.rb +23 -0
  52. data/lib/pdf/writer/object/action.rb +40 -0
  53. data/lib/pdf/writer/object/annotation.rb +42 -0
  54. data/lib/pdf/writer/object/catalog.rb +39 -0
  55. data/lib/pdf/writer/object/contents.rb +68 -0
  56. data/lib/pdf/writer/object/destination.rb +40 -0
  57. data/lib/pdf/writer/object/encryption.rb +53 -0
  58. data/lib/pdf/writer/object/font.rb +76 -0
  59. data/lib/pdf/writer/object/fontdescriptor.rb +34 -0
  60. data/lib/pdf/writer/object/fontencoding.rb +39 -0
  61. data/lib/pdf/writer/object/image.rb +168 -0
  62. data/lib/pdf/writer/object/info.rb +55 -0
  63. data/lib/pdf/writer/object/outline.rb +30 -0
  64. data/lib/pdf/writer/object/outlines.rb +30 -0
  65. data/lib/pdf/writer/object/page.rb +195 -0
  66. data/lib/pdf/writer/object/pages.rb +115 -0
  67. data/lib/pdf/writer/object/procset.rb +46 -0
  68. data/lib/pdf/writer/object/viewerpreferences.rb +74 -0
  69. data/lib/pdf/writer/ohash.rb +58 -0
  70. data/lib/pdf/writer/oreader.rb +25 -0
  71. data/lib/pdf/writer/state.rb +48 -0
  72. data/lib/pdf/writer/strokestyle.rb +138 -0
  73. data/manual.pwd +5151 -0
  74. metadata +147 -0
@@ -0,0 +1,225 @@
1
+ StartFontMetrics 4.1
2
+ Comment Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.
3
+ Comment Creation Date: Thu May 1 15:14:13 1997
4
+ Comment UniqueID 43082
5
+ Comment VMusage 45775 55535
6
+ FontName ZapfDingbats
7
+ FullName ITC Zapf Dingbats
8
+ FamilyName ZapfDingbats
9
+ Weight Medium
10
+ ItalicAngle 0
11
+ IsFixedPitch false
12
+ CharacterSet Special
13
+ FontBBox -1 -143 981 820
14
+ UnderlinePosition -100
15
+ UnderlineThickness 50
16
+ Version 002.000
17
+ Notice Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.
18
+ EncodingScheme FontSpecific
19
+ StdHW 28
20
+ StdVW 90
21
+ StartCharMetrics 202
22
+ C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
23
+ C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ;
24
+ C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ;
25
+ C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ;
26
+ C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ;
27
+ C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ;
28
+ C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ;
29
+ C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ;
30
+ C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ;
31
+ C 41 ; WX 690 ; N a117 ; B 34 138 655 553 ;
32
+ C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ;
33
+ C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ;
34
+ C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ;
35
+ C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ;
36
+ C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ;
37
+ C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ;
38
+ C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ;
39
+ C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ;
40
+ C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ;
41
+ C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ;
42
+ C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ;
43
+ C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ;
44
+ C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ;
45
+ C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ;
46
+ C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ;
47
+ C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ;
48
+ C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ;
49
+ C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ;
50
+ C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ;
51
+ C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ;
52
+ C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ;
53
+ C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ;
54
+ C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ;
55
+ C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ;
56
+ C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ;
57
+ C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ;
58
+ C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ;
59
+ C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ;
60
+ C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ;
61
+ C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ;
62
+ C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ;
63
+ C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ;
64
+ C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ;
65
+ C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ;
66
+ C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ;
67
+ C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ;
68
+ C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ;
69
+ C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ;
70
+ C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ;
71
+ C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ;
72
+ C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ;
73
+ C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ;
74
+ C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ;
75
+ C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ;
76
+ C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ;
77
+ C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ;
78
+ C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ;
79
+ C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ;
80
+ C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ;
81
+ C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ;
82
+ C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ;
83
+ C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ;
84
+ C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ;
85
+ C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ;
86
+ C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ;
87
+ C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ;
88
+ C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ;
89
+ C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ;
90
+ C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ;
91
+ C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ;
92
+ C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ;
93
+ C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ;
94
+ C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ;
95
+ C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ;
96
+ C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ;
97
+ C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ;
98
+ C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ;
99
+ C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ;
100
+ C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ;
101
+ C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ;
102
+ C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ;
103
+ C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ;
104
+ C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ;
105
+ C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ;
106
+ C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ;
107
+ C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ;
108
+ C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ;
109
+ C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ;
110
+ C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ;
111
+ C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ;
112
+ C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ;
113
+ C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ;
114
+ C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ;
115
+ C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ;
116
+ C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ;
117
+ C 128 ; WX 390 ; N a89 ; B 35 -14 356 705 ;
118
+ C 129 ; WX 390 ; N a90 ; B 35 -14 355 705 ;
119
+ C 130 ; WX 317 ; N a93 ; B 35 0 283 692 ;
120
+ C 131 ; WX 317 ; N a94 ; B 35 0 283 692 ;
121
+ C 132 ; WX 276 ; N a91 ; B 35 0 242 692 ;
122
+ C 133 ; WX 276 ; N a92 ; B 35 0 242 692 ;
123
+ C 134 ; WX 509 ; N a205 ; B 35 0 475 692 ;
124
+ C 135 ; WX 509 ; N a85 ; B 35 0 475 692 ;
125
+ C 136 ; WX 410 ; N a206 ; B 35 0 375 692 ;
126
+ C 137 ; WX 410 ; N a86 ; B 35 0 375 692 ;
127
+ C 138 ; WX 234 ; N a87 ; B 35 -14 199 705 ;
128
+ C 139 ; WX 234 ; N a88 ; B 35 -14 199 705 ;
129
+ C 140 ; WX 334 ; N a95 ; B 35 0 299 692 ;
130
+ C 141 ; WX 334 ; N a96 ; B 35 0 299 692 ;
131
+ C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ;
132
+ C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ;
133
+ C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ;
134
+ C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ;
135
+ C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ;
136
+ C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ;
137
+ C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ;
138
+ C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ;
139
+ C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ;
140
+ C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ;
141
+ C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ;
142
+ C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ;
143
+ C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ;
144
+ C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ;
145
+ C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ;
146
+ C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ;
147
+ C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ;
148
+ C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ;
149
+ C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ;
150
+ C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ;
151
+ C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ;
152
+ C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ;
153
+ C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ;
154
+ C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ;
155
+ C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ;
156
+ C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ;
157
+ C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ;
158
+ C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ;
159
+ C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ;
160
+ C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ;
161
+ C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ;
162
+ C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ;
163
+ C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ;
164
+ C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ;
165
+ C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ;
166
+ C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ;
167
+ C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ;
168
+ C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ;
169
+ C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ;
170
+ C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ;
171
+ C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ;
172
+ C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ;
173
+ C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ;
174
+ C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ;
175
+ C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ;
176
+ C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ;
177
+ C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ;
178
+ C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ;
179
+ C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ;
180
+ C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ;
181
+ C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ;
182
+ C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ;
183
+ C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ;
184
+ C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ;
185
+ C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ;
186
+ C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ;
187
+ C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ;
188
+ C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ;
189
+ C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ;
190
+ C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ;
191
+ C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ;
192
+ C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ;
193
+ C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ;
194
+ C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ;
195
+ C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ;
196
+ C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ;
197
+ C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ;
198
+ C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ;
199
+ C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ;
200
+ C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ;
201
+ C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ;
202
+ C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ;
203
+ C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ;
204
+ C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ;
205
+ C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ;
206
+ C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ;
207
+ C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ;
208
+ C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ;
209
+ C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ;
210
+ C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ;
211
+ C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ;
212
+ C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ;
213
+ C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ;
214
+ C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ;
215
+ C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ;
216
+ C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ;
217
+ C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ;
218
+ C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ;
219
+ C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ;
220
+ C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ;
221
+ C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ;
222
+ C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ;
223
+ C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ;
224
+ EndCharMetrics
225
+ EndFontMetrics
@@ -0,0 +1,727 @@
1
+ #--
2
+ # PDF::Writer for Ruby.
3
+ # http://rubyforge.org/projects/ruby-pdf/
4
+ # Copyright 2003 - 2005 Austin Ziegler.
5
+ #
6
+ # Licensed under a MIT-style licence. See LICENCE in the main distribution
7
+ # for full licensing information.
8
+ #
9
+ # $Id: graphics.rb,v 1.10 2005/06/08 12:16:11 austin Exp $
10
+ #++
11
+ # Points for use in the drawing of polygons.
12
+ class PDF::Writer::PolygonPoint
13
+ def initialize(x, y, connector = :line)
14
+ @x, @y, @connector = x, y, connector
15
+ end
16
+
17
+ attr_reader :x, :y, :connector
18
+ end
19
+
20
+ # This module contains graphics primitives. Objects that include this
21
+ # module must respond to #add_content.
22
+ #
23
+ # The PDF::Writer coordinate system is in PDF userspace units. The
24
+ # coordinate system in PDF::Writer is slightly different than might be
25
+ # expected, in that <tt>(0, 0)</tt> is at the lower left-hand corner of
26
+ # the canvas (page), not the normal top left-hand corner of the canvas.
27
+ # (See the diagram below.)
28
+ #
29
+ # Y Y
30
+ # 0+-----+X
31
+ # | |
32
+ # | |
33
+ # | |
34
+ # 0+-----+X
35
+ # 0 0
36
+ #
37
+ # Each primitive provided below indicates the <em>New Point</em>, or the
38
+ # coordinates new drawing point at the completion of the drawing
39
+ # operation. Drawing operations themselves do *not* draw or fill the path.
40
+ # This must be done by one of the stroke or fill operators, #stroke,
41
+ # #close_stroke, #fill, #close_fill, #fill_stroke, or #close_fill_stroke.
42
+ #
43
+ # Drawing operations return +self+ (the canvas) so that operations may be
44
+ # chained.
45
+ module PDF::Writer::Graphics
46
+ # Close the current path by appending a straight line segment from the
47
+ # drawing point to the starting point of the path. If the path is
48
+ # closed, this does nothing. This operator terminates the current
49
+ # subpath.
50
+ def close
51
+ add_content(" h")
52
+ self
53
+ end
54
+
55
+ # Stroke the path. This operation terminates a path object and draws it.
56
+ def stroke
57
+ add_content(" S")
58
+ self
59
+ end
60
+
61
+ # Close the current path by appending a straight line segment from the
62
+ # drawing point to the starting point of the path, and then stroke it.
63
+ # This does the same as #close followed by #stroke.
64
+ def close_stroke
65
+ add_content(" s")
66
+ self
67
+ end
68
+
69
+ # Fills the path. Open subpaths are implicitly closed before being
70
+ # filled. PDF offers two methods for determining the fill region. The
71
+ # first is called the "nonzero winding number" and is the default fill.
72
+ # The second is called "even-odd".
73
+ #
74
+ # Use the even-odd rule (called with <tt>#fill(:even_odd)</tt>) with
75
+ # caution, as this will cause certain portions of the path to be
76
+ # considered outside of the fill region, resulting in interesting cutout
77
+ # patterns.
78
+ def fill(rule = nil)
79
+ if :even_odd == rule
80
+ add_content(" f*")
81
+ else
82
+ add_content(" f")
83
+ end
84
+ self
85
+ end
86
+
87
+ # Close the current path by appending a straight line segment from the
88
+ # drawing point to the starting point of the path, and then fill it.
89
+ # This does the same as #close followed by #fill.
90
+ #
91
+ # See #fill for more information on fill rules.
92
+ def close_fill(rule = nil)
93
+ close
94
+ fill(rule)
95
+ self
96
+ end
97
+
98
+ # Fills and then strokes the path. Open subpaths are implicitly closed
99
+ # before being filled. This is the same as constructing two identical
100
+ # path objects, calling #fill on one and #stroke on the other. Paths
101
+ # filled and stroked in this manner are treated as if they were one
102
+ # object for PDF transparency purposes (the PDF transparency model is
103
+ # not yet supported by PDF::Writer).
104
+ #
105
+ # See #fill for more information on fill rules.
106
+ def fill_stroke(rule = nil)
107
+ if :even_odd == rule
108
+ add_content(" B*")
109
+ else
110
+ add_content(" B")
111
+ end
112
+ self
113
+ end
114
+
115
+ # Closes, fills and then strokes the path. Open subpaths are explicitly
116
+ # closed before being filled (as if #close and then #fill_stroke had
117
+ # been called). This is the same as constructing two identical path
118
+ # objects, calling #fill on one and #stroke on the other. Paths filled
119
+ # and stroked in this manner are treated as if they were one object for
120
+ # PDF transparency purposes (PDF transparency is not yet supported by
121
+ # PDF::Writer).
122
+ #
123
+ # See #fill for more information on fill rules.
124
+ def close_fill_stroke(rule = nil)
125
+ if :even_odd == rule
126
+ add_content(" b*")
127
+ else
128
+ add_content(" b")
129
+ end
130
+ self
131
+ end
132
+
133
+ # Move the drawing point to the specified coordinates <tt>(x, y)</tt>.
134
+ #
135
+ # New Point:: <tt>(x, y)</tt>
136
+ # Subpath:: New
137
+ def move_to(x, y)
138
+ add_content("\n%.3f %.3f m" % [ x, y ])
139
+ self
140
+ end
141
+
142
+ # Draw a straight line from the drawing point to <tt>(x, y)</tt>.
143
+ #
144
+ # New Point:: <tt>(x, y)</tt>
145
+ # Subpath:: Current
146
+ def line_to(x, y)
147
+ add_content("\n%.3f %.3f l" % [ x, y ])
148
+ self
149
+ end
150
+
151
+ # Draws a cubic Bezier curve from the drawing point to <tt>(x2, y2)</tt>
152
+ # using <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt> as the control points
153
+ # for the curve.
154
+ #
155
+ # New Point:: <tt>(x2, y2)</tt>
156
+ # Subpath:: Current
157
+ def curve_to(x0, y0, x1, y1, x2, y2)
158
+ add_content("\n%.3f %.3f %.3f %.3f %.3f %.3f c" % [ x0, y0, x1, y1, x2, y2 ])
159
+ self
160
+ end
161
+
162
+ # Draws a cubic Bezier curve from the drawing point to <tt>(x1, y1)</tt>
163
+ # using the drawing point and <tt>(x0, y0)</tt> as the control points
164
+ # for the curve.
165
+ #
166
+ # New Point:: <tt>(x1, y1)</tt>
167
+ # Subpath:: Current
168
+ def scurve_to(x0, y0, x1, y1)
169
+ add_content("\n%.3f %.3f %.3f %.3f v" % [ x0, y0, x1, y1 ])
170
+ self
171
+ end
172
+
173
+ # Draws a cubic Bezier curve from the drawing point to <tt>(x1, y1)</tt>
174
+ # using <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt> as the control points
175
+ # for the curve.
176
+ #
177
+ # New Point:: <tt>(x1, y1)</tt>
178
+ # Subpath:: Current
179
+ def ecurve_to(x0, y0, x1, y1)
180
+ add_content("\n%.3f %.3f %.3f %.3f y" % [ x0, y0, x1, y1 ])
181
+ self
182
+ end
183
+
184
+ # Draw a straight line from <tt>(x0, y0)</tt> to <tt>(x1, y1)</tt>. The
185
+ # line is a new subpath.
186
+ #
187
+ # New Point:: <tt>(x1, y1)</tt>.
188
+ # Subpath:: New
189
+ def line(x0, y0, x1, y1)
190
+ move_to(x0, y0).line_to(x1, y1)
191
+ end
192
+
193
+ # Draw a cubic Bezier curve from <tt>(x0, y0)</tt> to <tt>(x3, y3)</tt>
194
+ # using <tt>(x1, y1)</tt> and <tt>(x2, y2)</tt> as control points.
195
+ #
196
+ # New Point:: <tt>(x3, y3)</tt>
197
+ # Subpath:: New
198
+ def curve(x0, y0, x1, y1, x2, y2, x3, y3)
199
+ move_to(x0, y0).curve_to(x1, y1, x2, y2, x3, y3)
200
+ end
201
+
202
+ # Draw a cubic Bezier curve from <tt>(x0, y0)</tt> to <tt>(x2, y2)</tt>
203
+ # using <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt> as control points.
204
+ #
205
+ # New Point:: <tt>(x2, y2)</tt>
206
+ # Subpath:: New
207
+ def scurve(x0, y0, x1, y1, x2, y2)
208
+ move_to(x0, y0).scurve_to(x1, y1, x2, y2)
209
+ end
210
+
211
+ # Draw a cubic Bezier curve from <tt>(x0, y0)</tt> to <tt>(x2, y2)</tt>
212
+ # using <tt>(x1, y1)</tt> and <tt>(x2, y2)</tt> as control points.
213
+ #
214
+ # New Point:: <tt>(x2, y2)</tt>
215
+ # Subpath:: New
216
+ def ecurve(x0, y0, x1, y1, x2, y2)
217
+ move_to(x0, y0).ecurve_to(x1, y1, x2, y2)
218
+ end
219
+
220
+ # This constant is used to approximate a symmetrical arc using a cubic
221
+ # Bezier curve.
222
+ KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0)
223
+
224
+ # Draws a circle of radius +r+ with the centre-point at <tt>(x, y)</tt>
225
+ # as a complete subpath. The drawing point will be moved to the
226
+ # centre-point upon completion of the drawing the circle.
227
+ def circle_at(x, y, r)
228
+ ellipse_at(x, y, r, r)
229
+ end
230
+
231
+ # Draws an ellipse of +x+ radius <tt>r1</tt> and +y+ radius <tt>r2</tt>
232
+ # with the centre-point at <tt>(x, y)</tt> as a complete subpath. The
233
+ # drawing point will be moved to the centre-point upon completion of the
234
+ # drawing the ellipse.
235
+ def ellipse_at(x, y, r1, r2 = r1)
236
+ l1 = r1 * KAPPA
237
+ l2 = r2 * KAPPA
238
+ move_to(x + r1, y)
239
+ # Upper right hand corner
240
+ curve_to(x + r1, y + l1, x + l2, y + r2, x, y + r2)
241
+ # Upper left hand corner
242
+ curve_to(x - l2, y + r2, x - r1, y + l1, x - r1, y)
243
+ # Lower left hand corner
244
+ curve_to(x - r1, y - l1, x - l2, y - r2, x, y - r2)
245
+ # Lower right hand corner
246
+ curve_to(x + l2, y - r2, x + r1, y - l1, x + r1, y)
247
+ move_to(x, y)
248
+ end
249
+
250
+ # Draw an ellipse centered at <tt>(x, y)</tt> with +x+ radius
251
+ # <tt>r1</tt> and +y+ radius <tt>r2</tt>. A partial ellipse can be drawn
252
+ # by specifying the starting and finishing angles.
253
+ #
254
+ # New Point:: <tt>(x, y)</tt>
255
+ # Subpath:: New
256
+ def ellipse2_at(x, y, r1, r2 = r1, start = 0, stop = 359.99, segments = 8)
257
+ segments = 2 if segments < 2
258
+
259
+ start = PDF::Math.deg2rad(start)
260
+ stop = PDF::Math.deg2rad(stop)
261
+
262
+ arc = stop - start
263
+ segarc = arc / segments.to_f
264
+ dtm = segarc / 3.0
265
+
266
+ theta = start
267
+ a0 = x + r1 * Math.cos(theta)
268
+ b0 = y + r2 * Math.sin(theta)
269
+ c0 = -r1 * Math.sin(theta)
270
+ d0 = r2 * Math.cos(theta)
271
+
272
+ move_to(a0, b0)
273
+
274
+ (1..segments).each do |ii|
275
+ theta = ii * segarc + start
276
+
277
+ a1 = x + r1 * Math.cos(theta)
278
+ b1 = y + r2 * Math.sin(theta)
279
+ c1 = -r1 * Math.sin(theta)
280
+ d1 = r2 * Math.cos(theta)
281
+
282
+ curve_to(a0 + (c0 * dtm),
283
+ b0 + (d0 * dtm),
284
+ a1 - (c1 * dtm),
285
+ b1 - (d1 * dtm), a1, b1)
286
+
287
+ a0 = a1
288
+ b0 = b1
289
+ c0 = c1
290
+ d0 = d1
291
+ end
292
+
293
+ move_to(x, y)
294
+ self
295
+ end
296
+
297
+ # Draws an ellipse segment. Draws a closed partial ellipse.
298
+ #
299
+ # New Point:: <tt>(x, y)</tt>
300
+ # Subpath:: New
301
+ def segment_at(x, y, r1, r2 = r1, start = 0, stop = 360, segments = 8)
302
+ ellipse2_at(x, y, r1, r2, start, stop, segments)
303
+
304
+ start = PDF::Math.deg2rad(start)
305
+ stop = PDF::Math.deg2rad(stop)
306
+
307
+ ax = x + r1 * Math.cos(start)
308
+ ay = y + r2 * Math.sin(start)
309
+ bx = x + r1 * Math.cos(stop)
310
+ by = y + r2 * Math.sin(stop)
311
+
312
+ move_to(ax, ay)
313
+ line_to(x, y)
314
+ line_to(bx, by)
315
+ move_to(x, y)
316
+ self
317
+ end
318
+
319
+ # Draw a polygon. +points+ is an array of PolygonPoint objects, or an
320
+ # array that can be converted to an array of PolygonPoint objects with
321
+ # <tt>PDF::Writer::PolygonPoint.new(*value)</tt>.
322
+ #
323
+ # New Point:: <tt>(points[-1].x, points[-1].y)</tt>
324
+ # Subpath:: New
325
+ def polygon(points)
326
+ points = points.map { |pp|
327
+ pp.kind_of?(Array) ? PDF::Writer::PolygonPoint.new(*pp) : pp
328
+ }
329
+
330
+ point = points.shift
331
+
332
+ move_to(point.x, point.y)
333
+
334
+ while not points.empty?
335
+ point = points.shift
336
+
337
+ case point.connector
338
+ when :curve
339
+ c1 = point
340
+ c2 = points.shift
341
+ point = points.shift
342
+
343
+ curve_to(c1.x, c1.y, c2.x, c2.y, point.x, point.y)
344
+ when :scurve
345
+ c1 = point
346
+ point = points.shift
347
+ scurve_to(c1.x, c1.y, point.x, point.y)
348
+ when :ecurve
349
+ c1 = point
350
+ point = points.shift
351
+ ecurve_to(c1.x, c1.y, point.x, point.y)
352
+ else
353
+ line_to(point.x, point.y)
354
+ end
355
+ end
356
+
357
+ self
358
+ end
359
+
360
+ # Draw a rectangle. The first corner is <tt>(x, y)</tt> and the second
361
+ # corner is <tt>(x + w, y - h)</tt>.
362
+ #
363
+ # New Point:: <tt>(x + w, y - h)</tt>
364
+ # Subpath:: Current
365
+ def rectangle(x, y, w, h = w)
366
+ add_content("\n%.3f %.3f %.3f %.3f re" % [ x, y, w, h ])
367
+ self
368
+ end
369
+
370
+ # Draw a rounded rectangle with corners <tt>(x, y)</tt> and <tt>(x + w,
371
+ # y - h)</tt> and corner radius +r+. The radius should be significantly
372
+ # smaller than +h+ and +w+.
373
+ #
374
+ # New Point:: <tt>(x + w, y - h)</tt>
375
+ # Subpath:: New
376
+ def rounded_rectangle(x, y, w, h, r)
377
+ x1 = x
378
+ x2 = x1 + w
379
+ y1 = y
380
+ y2 = y1 - h
381
+
382
+ r1 = r
383
+ r2 = r / 2.0
384
+
385
+ points = [
386
+ [ x1 + r1, y1, :line ],
387
+ [ x2 - r1, y1, :line ],
388
+ [ x2 - r2, y1, :curve ], # cp1
389
+ [ x2, y1 - r2, ], # cp2
390
+ [ x2, y1 - r1, ], # ep
391
+ [ x2, y2 + r1, :line ],
392
+ [ x2, y2 + r2, :curve ], # cp1
393
+ [ x2 - r2, y2, ], # cp2
394
+ [ x2 - r1, y2, ], # ep
395
+ [ x1 + r1, y2, :line ],
396
+ [ x1 + r2, y2, :curve ], # cp1
397
+ [ x1, y2 + r2, ], # cp2
398
+ [ x1, y2 + r1, ], # ep
399
+ [ x1, y1 - r1, :line ],
400
+ [ x1, y1 - r2, :curve ], # cp1
401
+ [ x1 + r2, y1, ], # cp2
402
+ [ x1 + r1, y1, ], # ep
403
+ ]
404
+ polygon(points)
405
+ move_to(x2, y2)
406
+ self
407
+ end
408
+
409
+ # Draws a star centered on <tt>(x, y)</tt> with +rays+ portions of
410
+ # +length+ from the centre. Stars with an odd number of rays should have
411
+ # the top ray pointing toward the top of the document. This will not
412
+ # create a "star" with fewer than four points.
413
+ #
414
+ # New Point:: <tt>(cx, cy)</tt>
415
+ # Subpath:: New
416
+ def star(cx, cy, length, rays = 5)
417
+ rays = 4 if rays < 4
418
+ points = []
419
+ part = Math::PI / rays.to_f
420
+
421
+ 0.step((rays * 4), 2) do |ray|
422
+ if ((ray / 2) % 2 == 0)
423
+ dist = length / 2.0
424
+ else
425
+ dist = length
426
+ end
427
+
428
+ x = cx + Math.cos((1.5 + ray / 2.0) * part) * dist
429
+ y = cy + Math.sin((1.5 + ray / 2.0) * part) * dist
430
+ points << [ x, y ]
431
+ end
432
+
433
+ polygon(points)
434
+ move_to(cx, cy)
435
+ self
436
+ end
437
+
438
+ # This sets the line drawing style. This *must* be a
439
+ # PDF::Writer::StrokeStyle object.
440
+ def stroke_style(style)
441
+ stroke_style!(style) if @current_stroke_style.nil? or style != @current_stroke_style
442
+ end
443
+
444
+ # Forces the line drawing style to be set, even if it's the same as the
445
+ # current color. Emits the current stroke style if +nil+ is provided.
446
+ def stroke_style!(style = nil)
447
+ @current_stroke_style = style if style
448
+ add_content "\n#{@current_stroke_style.render}" if @current_stroke_style
449
+ end
450
+
451
+ # Returns the current stroke style.
452
+ def stroke_style?
453
+ @current_stroke_style
454
+ end
455
+
456
+ # Set the text rendering style. This may be one of the following
457
+ # options:
458
+ #
459
+ # 0:: fill
460
+ # 1:: stroke
461
+ # 2:: fill then stroke
462
+ # 3:: invisible
463
+ # 4:: fill and add to clipping path
464
+ # 5:: stroke and add to clipping path
465
+ # 6:: fill and stroke and add to clipping path
466
+ # 7:: add to clipping path
467
+ def text_render_style(style)
468
+ text_render_style!(style) unless @current_text_render_style and style == @current_text_render_style
469
+ end
470
+
471
+ # Forces the text rendering style to be set, even if it's the same as
472
+ # the current style.
473
+ def text_render_style!(style)
474
+ @current_text_render_style = style
475
+ end
476
+
477
+ # Reutnrs the current text rendering style.
478
+ def text_render_style?
479
+ @current_text_render_style
480
+ end
481
+
482
+ # Sets the color for fill operations.
483
+ def fill_color(color)
484
+ fill_color!(color) if @current_fill_color.nil? or color != @current_fill_color
485
+ end
486
+
487
+ # Forces the color for fill operations to be set, even if the color
488
+ # is the same as the current color. Does nothing if +nil+ is provided.
489
+ def fill_color!(color = nil)
490
+ if color
491
+ @current_fill_color = color
492
+ add_content "\n#{@current_fill_color.pdf_fill}"
493
+ end
494
+ end
495
+
496
+ # Returns the current fill color.
497
+ def fill_color?
498
+ @current_fill_color
499
+ end
500
+
501
+ # Sets the color for stroke operations.
502
+ def stroke_color(color)
503
+ stroke_color!(color) if @current_stroke_color.nil? or color != @current_stroke_color
504
+ end
505
+
506
+ # Forces the color for stroke operations to be set, even if the color
507
+ # is the same as the current color. Does nothing if +nil+ is provided.
508
+ def stroke_color!(color = nil)
509
+ if color
510
+ @current_stroke_color = color
511
+ add_content "\n#{@current_stroke_color.pdf_stroke}"
512
+ end
513
+ end
514
+
515
+ # Returns the current stroke color.
516
+ def stroke_color?
517
+ @current_stroke_color
518
+ end
519
+
520
+ # Add an image from a file to the current page at position <tt>(x,
521
+ # y)</tt> (the upper left-hand corner of the image). The image will be
522
+ # scaled to +width+ by +height+ units. The image may be a PNG or JPEG
523
+ # image.
524
+ #
525
+ # The +image+ parameter may be a filename or an object that returns the
526
+ # full image data when #read is called with no parameters (such as an IO
527
+ # object). If 'open-uri' is loaded, then the image name may be an URI.
528
+ def add_image_from_file(image, x, y, width = nil, height = nil)
529
+ data = nil
530
+
531
+ if image.respond_to?(:read)
532
+ data = image.read
533
+ else
534
+ open(image, 'rb') { |ff| data = ff.read }
535
+ end
536
+
537
+ add_image(data, x, y, width, height)
538
+ end
539
+
540
+ # Add an image from a loaded image (JPEG or PNG) resource at position
541
+ # <tt>(x, y)</tt> (the upper left-hand corner of the image) and scaled
542
+ # to +width+ by +height+ units. If provided, +image_info+ is a
543
+ # PDF::Writer::Graphics::ImageInfo object.
544
+ def add_image(image, x, y, width = nil, height = nil, image_info = nil)
545
+ unless image.kind_of?(PDF::Writer::External::Image)
546
+ image_info ||= PDF::Writer::Graphics::ImageInfo.new(image)
547
+
548
+ tt = Time.now
549
+ @images << tt
550
+ id = @images.index(tt)
551
+ label = "I#{id}"
552
+ image_obj = PDF::Writer::External::Image.new(self, image, image_info, label)
553
+ @images[id] = image_obj
554
+ else
555
+ label = image.label
556
+ image_obj = image
557
+ image_info ||= image.image_info
558
+ end
559
+
560
+ if width.nil? and height.nil?
561
+ width = image_info.width
562
+ height = image_info.height
563
+ end
564
+
565
+ width ||= height / image_info.height.to_f * image_info.width
566
+ height ||= width * image_info.height / image_info.width.to_f
567
+
568
+ tt = "\nq\n%.3f 0 0 %.3f %.3f %.3f cm\n/%s Do\nQ"
569
+ add_content(tt % [ width, height, x, y, label ])
570
+ image_obj
571
+ end
572
+
573
+ # Add an image easily to a PDF document. +image+ is the name of a JPG or
574
+ # PNG image. +options+ is a Hash:
575
+ #
576
+ # <tt>:pad</tt>:: The number of PDF userspace units that will
577
+ # be on all sides of the image. The default is
578
+ # <tt>5</tt> units.
579
+ # <tt>:width</tt>:: The desired width of the image. The image
580
+ # will be resized to this width with the
581
+ # aspect ratio kept. If unspecified, the
582
+ # image's natural width will be used.
583
+ # <tt>:resize</tt>:: How to resize the image, either :width
584
+ # (resizes the image to be as wide as the
585
+ # margins) or :full (resizes the image to be
586
+ # as large as possible). May be a numeric
587
+ # value, used as a multiplier for the image
588
+ # size (e.g., 0.5 will shrink the image to
589
+ # half-sized). If this and <tt>:width</tt> are
590
+ # unspecified, the image's natural size will be
591
+ # used. Mutually exclusive with the
592
+ # <tt>:width<tt> option.
593
+ # <tt>:justification</tt>:: The placement of the image. May be :center,
594
+ # :right, or :left. Defaults to :left.
595
+ # <tt>:border</tt>:: The border options. No default border. If
596
+ # specified, must be either +true+, which uses
597
+ # the default border, or a Hash.
598
+ #
599
+ # Image borders are specified as a hash with two options:
600
+ #
601
+ # <tt>:color</tt>:: The colour of the border. Defaults to 50% grey.
602
+ # <tt>:style</tt>:: The stroke style of the border. This must be a
603
+ # StrokeStyle object and defaults to the default line.
604
+ def image(image, options = {})
605
+ width = options[:width]
606
+ pad = options[:pad] || 5
607
+ resize = options[:resize]
608
+ just = options[:justification] || :left
609
+ border = options[:border]
610
+
611
+ if image.kind_of?(PDF::Writer::External::Image)
612
+ info = image.image_info
613
+ image_data = image
614
+ else
615
+ if image.respond_to?(:read)
616
+ image_data = image.read
617
+ else
618
+ image_data = open(image, "rb") { |file| file.read }
619
+ end
620
+ info = PDF::Writer::Graphics::ImageInfo.new(image_data)
621
+ end
622
+
623
+ raise "Unsupported Image Type" unless %w(JPEG PNG).include?(info.format)
624
+
625
+ width = info.width if width.nil?
626
+ aspect = info.width.to_f / info.height.to_f
627
+
628
+ # Get the maximum width of the image on insertion.
629
+ if @columns_on
630
+ max_width = @columns[:width] - (pad * 2)
631
+ else
632
+ max_width = @page_width - (pad * 2) - @left_margin - @right_margin
633
+ end
634
+
635
+ if resize == :full or resize == :width or width > max_width
636
+ width = max_width
637
+ end
638
+
639
+ # Keep the height in an appropriate aspect ratio of the width.
640
+ height = (width / aspect.to_f)
641
+
642
+ # Resize the image.
643
+ if resize.kind_of?(Numeric)
644
+ width *= resize
645
+ height *= resize
646
+ end
647
+
648
+ # Resize the image *again*, if it is wider than what is available.
649
+ if width > max_width
650
+ height = (width / aspect.to_f)
651
+ end
652
+
653
+ # If the height is greater than the available space:
654
+ havail = @y - @bottom_margin - (pad * 2)
655
+ if height > havail
656
+ # If the image is to be resized to :full (remaining space
657
+ # available), adjust the image size appropriately. Otherwise, start
658
+ # a new page and flow to the next page.
659
+ if resize == :full
660
+ height = havail
661
+ width = (height * aspect)
662
+ else
663
+ start_new_page
664
+ end
665
+ end
666
+
667
+ # Find the x and y positions.
668
+ y = @y - pad - height
669
+ x = @left_margin + pad
670
+
671
+ if (width < max_width)
672
+ case just
673
+ when :center
674
+ x += (max_width - width) / 2.0
675
+ when :right
676
+ x += (max_width - width)
677
+ end
678
+ end
679
+
680
+ image_obj = add_image(image_data, x, y, width, height, info)
681
+
682
+ if border
683
+ border = {} if true == border
684
+ border[:color] ||= Color::Grey50
685
+ border[:style] ||= PDF::Writer::StrokeStyle::DEFAULT
686
+
687
+ save_state
688
+ stroke_color border[:color]
689
+ stroke_style border[:style]
690
+ rectangle(x, y - pad, width, height - pad).stroke
691
+ restore_state
692
+ end
693
+
694
+ @y = @y - pad - height
695
+
696
+ image_obj
697
+ end
698
+
699
+ # Translate the coordinate system axis by the specified user space
700
+ # coordinates.
701
+ def translate_axis(x, y)
702
+ add_content("\n1 0 0 1 %.3f %.3f cm" % [ x, y ])
703
+ self
704
+ end
705
+
706
+ # Rotate the axis of the coordinate system by the specified clockwise
707
+ # angle.
708
+ def rotate_axis(angle)
709
+ rad = PDF::Math.deg2rad(angle)
710
+ add_content("\n1 %.3f %.3f 1 0 0 cm" % [ rad, -rad ])
711
+ self
712
+ end
713
+
714
+ # Scale the coordinate system axis by the specified factors.
715
+ def scale_axis(x = 1, y = 1)
716
+ add_content("\n%.3f 0 0 %.3f 0 0 cm" % [ x, y ])
717
+ self
718
+ end
719
+
720
+ # Skew the coordinate system axis by the specified angles.
721
+ def skew_axis(xangle = 0, yangle = 0)
722
+ xr = PDF::Math.deg2rad(xangle)
723
+ yr = PDF::Math.deg2rad(yangle)
724
+ add_content("\n1 %.3f %.3f 1 0 0 cm" % [ xr, -yr ])
725
+ self
726
+ end
727
+ end