gamba 2.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 (163) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +80 -0
  3. data/COPYING +2 -0
  4. data/GPLv2 +339 -0
  5. data/GPLv3 +674 -0
  6. data/LICENSE +65 -0
  7. data/LICENSE-prawn-svg +21 -0
  8. data/README.md +148 -0
  9. data/data/fonts/Courier-Bold.afm +342 -0
  10. data/data/fonts/Courier-BoldOblique.afm +342 -0
  11. data/data/fonts/Courier-Oblique.afm +342 -0
  12. data/data/fonts/Courier.afm +342 -0
  13. data/data/fonts/Helvetica-Bold.afm +2827 -0
  14. data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
  15. data/data/fonts/Helvetica-Oblique.afm +3051 -0
  16. data/data/fonts/Helvetica.afm +3051 -0
  17. data/data/fonts/MustRead.html +19 -0
  18. data/data/fonts/Symbol.afm +213 -0
  19. data/data/fonts/Times-Bold.afm +2588 -0
  20. data/data/fonts/Times-BoldItalic.afm +2384 -0
  21. data/data/fonts/Times-Italic.afm +2667 -0
  22. data/data/fonts/Times-Roman.afm +2419 -0
  23. data/data/fonts/ZapfDingbats.afm +225 -0
  24. data/lib/gamba/annotations.rb +21 -0
  25. data/lib/gamba/combine.rb +307 -0
  26. data/lib/gamba/document/bounding_box.rb +193 -0
  27. data/lib/gamba/document/column_box.rb +91 -0
  28. data/lib/gamba/document/internals.rb +264 -0
  29. data/lib/gamba/document/span.rb +25 -0
  30. data/lib/gamba/document.rb +268 -0
  31. data/lib/gamba/encoding.rb +13 -0
  32. data/lib/gamba/errors.rb +39 -0
  33. data/lib/gamba/font.rb +228 -0
  34. data/lib/gamba/fonts/afm.rb +171 -0
  35. data/lib/gamba/fonts/otf.rb +50 -0
  36. data/lib/gamba/fonts/ttf.rb +413 -0
  37. data/lib/gamba/graphic_state.rb +84 -0
  38. data/lib/gamba/graphics/color.rb +174 -0
  39. data/lib/gamba/graphics/patterns.rb +100 -0
  40. data/lib/gamba/graphics/style.rb +159 -0
  41. data/lib/gamba/graphics.rb +212 -0
  42. data/lib/gamba/grid.rb +216 -0
  43. data/lib/gamba/images/image.rb +271 -0
  44. data/lib/gamba/images/png_decoder.rb +65 -0
  45. data/lib/gamba/images.rb +115 -0
  46. data/lib/gamba/measurement_extensions.rb +40 -0
  47. data/lib/gamba/measurements.rb +62 -0
  48. data/lib/gamba/outline.rb +148 -0
  49. data/lib/gamba/page.rb +125 -0
  50. data/lib/gamba/page_geometry.rb +27 -0
  51. data/lib/gamba/pdf/decryption.rb +165 -0
  52. data/lib/gamba/pdf/outline_node.rb +53 -0
  53. data/lib/gamba/pdf/reader.rb +616 -0
  54. data/lib/gamba/pdf/reference.rb +31 -0
  55. data/lib/gamba/pdf/writer.rb +105 -0
  56. data/lib/gamba/pdf.rb +87 -0
  57. data/lib/gamba/pdf_a/srgb_profile.rb +61 -0
  58. data/lib/gamba/pdf_a.rb +132 -0
  59. data/lib/gamba/repeater.rb +79 -0
  60. data/lib/gamba/security.rb +111 -0
  61. data/lib/gamba/stamp.rb +76 -0
  62. data/lib/gamba/table/cell/kinds.rb +246 -0
  63. data/lib/gamba/table/cell.rb +331 -0
  64. data/lib/gamba/table/cells.rb +208 -0
  65. data/lib/gamba/table.rb +298 -0
  66. data/lib/gamba/text/box.rb +16 -0
  67. data/lib/gamba/text/formatted/arranger.rb +217 -0
  68. data/lib/gamba/text/formatted/box.rb +312 -0
  69. data/lib/gamba/text/formatted/fragment.rb +205 -0
  70. data/lib/gamba/text/formatted/line_wrap.rb +205 -0
  71. data/lib/gamba/text/formatted/parser.rb +150 -0
  72. data/lib/gamba/text/formatted/wrap.rb +103 -0
  73. data/lib/gamba/text.rb +310 -0
  74. data/lib/gamba/transformation_stack.rb +43 -0
  75. data/lib/gamba/true_type/cff_subset.rb +157 -0
  76. data/lib/gamba/true_type/file.rb +372 -0
  77. data/lib/gamba/true_type/open_type_layout.rb +189 -0
  78. data/lib/gamba/true_type/simple_subsets.rb +108 -0
  79. data/lib/gamba/true_type/subset.rb +206 -0
  80. data/lib/gamba/version.rb +10 -0
  81. data/lib/gamba/view.rb +28 -0
  82. data/lib/gamba.rb +124 -0
  83. data/lib/pdf/core.rb +4 -0
  84. data/lib/prawn/measurement_extensions.rb +4 -0
  85. data/lib/prawn/svg/attributes/clip_path.rb +46 -0
  86. data/lib/prawn/svg/attributes/mask.rb +16 -0
  87. data/lib/prawn/svg/attributes/opacity.rb +30 -0
  88. data/lib/prawn/svg/attributes/space.rb +10 -0
  89. data/lib/prawn/svg/attributes/stroke.rb +50 -0
  90. data/lib/prawn/svg/attributes/transform.rb +10 -0
  91. data/lib/prawn/svg/attributes.rb +6 -0
  92. data/lib/prawn/svg/calculators/arc_to_bezier_curve.rb +57 -0
  93. data/lib/prawn/svg/calculators/aspect_ratio.rb +60 -0
  94. data/lib/prawn/svg/calculators/document_sizing.rb +103 -0
  95. data/lib/prawn/svg/calculators/path_length.rb +168 -0
  96. data/lib/prawn/svg/calculators/pixels.rb +57 -0
  97. data/lib/prawn/svg/color.rb +240 -0
  98. data/lib/prawn/svg/css/font_face_parser.rb +72 -0
  99. data/lib/prawn/svg/css/font_family_parser.rb +39 -0
  100. data/lib/prawn/svg/css/font_parser.rb +46 -0
  101. data/lib/prawn/svg/css/selector_parser.rb +180 -0
  102. data/lib/prawn/svg/css/stylesheets.rb +233 -0
  103. data/lib/prawn/svg/css/values_parser.rb +68 -0
  104. data/lib/prawn/svg/document.rb +169 -0
  105. data/lib/prawn/svg/elements/anchor.rb +10 -0
  106. data/lib/prawn/svg/elements/base.rb +315 -0
  107. data/lib/prawn/svg/elements/bbox_scaling.rb +78 -0
  108. data/lib/prawn/svg/elements/call_duplicator.rb +37 -0
  109. data/lib/prawn/svg/elements/circle.rb +19 -0
  110. data/lib/prawn/svg/elements/clip_path.rb +26 -0
  111. data/lib/prawn/svg/elements/container.rb +10 -0
  112. data/lib/prawn/svg/elements/direct_render_base.rb +28 -0
  113. data/lib/prawn/svg/elements/ellipse.rb +20 -0
  114. data/lib/prawn/svg/elements/gradient.rb +183 -0
  115. data/lib/prawn/svg/elements/ignored.rb +5 -0
  116. data/lib/prawn/svg/elements/image.rb +178 -0
  117. data/lib/prawn/svg/elements/line.rb +27 -0
  118. data/lib/prawn/svg/elements/marker.rb +72 -0
  119. data/lib/prawn/svg/elements/mask.rb +65 -0
  120. data/lib/prawn/svg/elements/path.rb +294 -0
  121. data/lib/prawn/svg/elements/pattern.rb +150 -0
  122. data/lib/prawn/svg/elements/polygon.rb +25 -0
  123. data/lib/prawn/svg/elements/polyline.rb +23 -0
  124. data/lib/prawn/svg/elements/rect.rb +64 -0
  125. data/lib/prawn/svg/elements/root.rb +22 -0
  126. data/lib/prawn/svg/elements/switch.rb +92 -0
  127. data/lib/prawn/svg/elements/text.rb +99 -0
  128. data/lib/prawn/svg/elements/text_component.rb +352 -0
  129. data/lib/prawn/svg/elements/text_node.rb +308 -0
  130. data/lib/prawn/svg/elements/text_path.rb +153 -0
  131. data/lib/prawn/svg/elements/use.rb +142 -0
  132. data/lib/prawn/svg/elements/viewport.rb +29 -0
  133. data/lib/prawn/svg/elements.rb +46 -0
  134. data/lib/prawn/svg/extension.rb +25 -0
  135. data/lib/prawn/svg/font.rb +20 -0
  136. data/lib/prawn/svg/font_metrics.rb +144 -0
  137. data/lib/prawn/svg/font_registry.rb +315 -0
  138. data/lib/prawn/svg/funciri.rb +14 -0
  139. data/lib/prawn/svg/gradient_renderer.rb +332 -0
  140. data/lib/prawn/svg/gradients.rb +53 -0
  141. data/lib/prawn/svg/interface.rb +72 -0
  142. data/lib/prawn/svg/length.rb +43 -0
  143. data/lib/prawn/svg/link_renderer.rb +40 -0
  144. data/lib/prawn/svg/loaders/data.rb +17 -0
  145. data/lib/prawn/svg/loaders/file.rb +111 -0
  146. data/lib/prawn/svg/loaders/web.rb +24 -0
  147. data/lib/prawn/svg/paint.rb +67 -0
  148. data/lib/prawn/svg/pathable.rb +153 -0
  149. data/lib/prawn/svg/pattern_renderer.rb +112 -0
  150. data/lib/prawn/svg/pdfmatrix.rb +39 -0
  151. data/lib/prawn/svg/percentage.rb +24 -0
  152. data/lib/prawn/svg/properties.rb +329 -0
  153. data/lib/prawn/svg/renderer.rb +249 -0
  154. data/lib/prawn/svg/state.rb +24 -0
  155. data/lib/prawn/svg/transform_parser.rb +78 -0
  156. data/lib/prawn/svg/ttc.rb +35 -0
  157. data/lib/prawn/svg/ttf.rb +95 -0
  158. data/lib/prawn/svg/url_loader.rb +46 -0
  159. data/lib/prawn/svg/version.rb +5 -0
  160. data/lib/prawn/table.rb +4 -0
  161. data/lib/prawn-svg.rb +52 -0
  162. data/lib/prawn.rb +3 -0
  163. metadata +263 -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,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PDF::Core
4
+ module Annotations
5
+ def annotate(options)
6
+ options = options.merge(Type: :Annot)
7
+ options[:F] ||= Gamba::PdfA::PRINT_FLAG if pdf_a?
8
+ options[:Dest] = PDF::Core::LiteralString.new(options[:Dest]) if options[:Dest].is_a?(String)
9
+ (page.dictionary.data[:Annots] ||= []) << ref!(options)
10
+ options
11
+ end
12
+
13
+ def text_annotation(rect, contents, options = {})
14
+ annotate(options.merge(Subtype: :Text, Rect: rect, Contents: contents))
15
+ end
16
+
17
+ def link_annotation(rect, options = {})
18
+ annotate(options.merge(Subtype: :Link, Rect: rect))
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,307 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamba
4
+ # Each page keeps its resources and content streams as they were encoded; only the page dictionaries and the
5
+ # document structure are written anew. Outlines, forms and tagged structure of the sources are not carried over.
6
+ class Combine
7
+ BOXES = %i[MediaBox CropBox BleedBox TrimBox ArtBox].freeze
8
+ DEFAULT_MEDIA_BOX = [0.0, 0.0, 612.0, 792.0].freeze
9
+ # A quarter turn counterclockwise, the way combine_pdf turns a page to the requested orientation.
10
+ QUARTER_TURN = ->(width, height) { [0.0, 1.0, -1.0, 0.0, height, 0.0] }
11
+ ROTATIONS = {
12
+ 90 => ->(width, height) { [0.0, -1.0, 1.0, 0.0, 0.0, width] },
13
+ 180 => ->(width, height) { [-1.0, 0.0, 0.0, -1.0, width, height] },
14
+ 270 => QUARTER_TURN
15
+ }.freeze
16
+ # References followed to tell whether two objects are the same: a chain deeper than this is copied unshared,
17
+ # instead of overflowing the stack on a file that links its objects into a list as long as it likes.
18
+ MAX_DESCRIBED_DEPTH = 32
19
+
20
+ # page_size: a name from PDF::Core::PageGeometry::SIZES or [width, height] in points; each page is scaled to fit
21
+ # it, keeping its proportions, from the lower left corner. orientation: :portrait or :landscape; a page the other
22
+ # way round turns a quarter. A page /Rotate is applied to its content first. With neither, pages are copied
23
+ # untouched.
24
+ def initialize(page_size: nil, orientation: nil)
25
+ @orientation = orientation&.to_sym
26
+ raise ArgumentError, "orientation must be :portrait or :landscape" unless [nil, :portrait, :landscape].include?(@orientation)
27
+
28
+ @page_size = page_size_in_points(page_size)
29
+ end
30
+
31
+ def call(sources)
32
+ @objects = []
33
+ @kids = []
34
+ @identifiers = {}
35
+ @shared = {}
36
+ @pages_reference = reference({Type: :Pages})
37
+ root = reference({Type: :Catalog, Pages: @pages_reference})
38
+ info = reference({Producer: "Gamba"})
39
+ version = sources.map { copy_pages(PDF::Core::Reader.new(source_bytes(_1))) }.max || 1.3
40
+ @pages_reference.data.merge!(Kids: @kids, Count: @kids.size)
41
+ PDF::Core::Writer.call(objects: @objects, root:, info:, version:)
42
+ end
43
+
44
+ private
45
+
46
+ def page_size_in_points(page_size)
47
+ return nil if page_size.nil?
48
+
49
+ width, height = page_size.is_a?(Array) ? page_size : PDF::Core::PageGeometry::SIZES.fetch(page_size.to_s.upcase) { raise ArgumentError, "Unknown page size #{page_size.inspect}" }
50
+ # With an orientation, the size follows it, as Prawn's page_layout does; without, it is used as given.
51
+ width, height = [width, height].minmax if @orientation
52
+ width, height = height, width if @orientation == :landscape
53
+ [width.to_f, height.to_f]
54
+ end
55
+
56
+ def source_bytes(source)
57
+ source.respond_to?(:read) ? source.read : source.to_s
58
+ end
59
+
60
+ def reference(data)
61
+ PDF::Core::Reference.new(@objects.size + 1, data).tap { @objects << _1 }
62
+ end
63
+
64
+ # Page references first, so a link from one page to another lands on the copy instead of dragging the old tree.
65
+ def copy_pages(reader)
66
+ @reader = reader
67
+ @copies = {}
68
+ @pending = []
69
+ @content_identifiers = {}
70
+ @description_depth = 0
71
+ pages = reader.pages.map do |source_reference, page|
72
+ copy = reference(nil)
73
+ if source_reference.is_a?(PDF::Core::Reader::Ref)
74
+ @copies[source_reference.number] = copy
75
+ @content_identifiers[source_reference.number] = nil
76
+ end
77
+ [copy, page]
78
+ end
79
+ annotations_to_move = []
80
+ pages.each do |copy, page|
81
+ matrix, *sizes = transformation(page)
82
+ copy.data = copy_value(matrix ? page.except(:Parent, :B, *BOXES, :Rotate, :Contents) : page.except(:Parent, :B))
83
+ copy.data[:Parent] = @pages_reference
84
+ if matrix
85
+ reshape(copy.data, page, matrix, *sizes)
86
+ annotations_to_move << [copy.data[:Annots], matrix] if copy.data[:Annots]
87
+ end
88
+ @kids << copy
89
+ end
90
+ copy_pending
91
+ moved = {}.compare_by_identity
92
+ annotations_to_move.each { |annotations, matrix| move_annotations(annotations, matrix, moved) }
93
+ reader.version
94
+ end
95
+
96
+ def copy_value(value)
97
+ case value
98
+ when PDF::Core::Reader::Ref
99
+ @copies[value.number] ||= begin
100
+ identifier = content_identifier(value.number)
101
+ identifier ? (@shared[identifier] ||= pending_copy(value.number)) : pending_copy(value.number)
102
+ end
103
+ when Hash then value.transform_values { copy_value(_1) }
104
+ when Array then value.map { copy_value(_1) }
105
+ else value
106
+ end
107
+ end
108
+
109
+ def pending_copy(number)
110
+ reference(nil).tap { @pending << [number, _1] }
111
+ end
112
+
113
+ # Objects with the same content, references included, are written once: the fonts, images and glyph procedures a
114
+ # carrier repeats on every label. Pages, and annotations (whose place is their own), are never shared.
115
+ def content_identifier(number)
116
+ return @content_identifiers[number] if @content_identifiers.key?(number)
117
+ return nil if @description_depth >= MAX_DESCRIBED_DEPTH
118
+
119
+ @content_identifiers[number] = nil # an object reached again while describing it stays unshared
120
+ @description_depth += 1
121
+ begin
122
+ value = @reader.object(number)
123
+ key = if value.is_a?(PDF::Core::Reader::Stream)
124
+ description = describe(value.dictionary.except(:Length))
125
+ [description, value.data] if description
126
+ elsif !(value.is_a?(Hash) && value.key?(:Rect))
127
+ describe(value)
128
+ end
129
+ ensure
130
+ @description_depth -= 1
131
+ end
132
+ @content_identifiers[number] = key && (@identifiers[key] ||= @identifiers.size)
133
+ end
134
+
135
+ def describe(value, description = +"")
136
+ case value
137
+ when PDF::Core::Reader::Ref
138
+ identifier = content_identifier(value.number)
139
+ identifier && description << "R" << identifier.to_s << " "
140
+ when Hash
141
+ description << "<<"
142
+ value.each { |key, entry| describe(entry, description << PDF::Core.escape_name(key.name) << " ") || (return nil) }
143
+ description << ">>"
144
+ when Array
145
+ description << "["
146
+ value.each { describe(_1, description) || (return nil) }
147
+ description << "]"
148
+ when PDF::Core::ByteString then description << "(" << value.bytesize.to_s << ":" << value << ")"
149
+ when PDF::Core::Name then description << PDF::Core.escape_name(value.value) << " "
150
+ when PDF::Core::Real then description << value.source << " "
151
+ else description << value.inspect << " "
152
+ end
153
+ end
154
+
155
+ def copy_pending
156
+ until @pending.empty?
157
+ number, copy = @pending.pop
158
+ value = @reader.object(number)
159
+ if value.is_a?(PDF::Core::Reader::Stream)
160
+ dictionary = value.dictionary.except(:Length)
161
+ # The writer packs streams without bytes as plain objects: keep one byte of data instead.
162
+ dictionary = dictionary.except(:Filter, :DecodeParms) if value.data.empty?
163
+ copy.data = copy_value(dictionary)
164
+ copy.stream = value.data.empty? ? +" " : +value.data
165
+ else
166
+ copy.data = copy_value(value)
167
+ end
168
+ end
169
+ end
170
+
171
+ # The matrix that draws the page's visible box at its new place, and the new page's size; nil when it stays put.
172
+ def transformation(page)
173
+ return nil unless @page_size || @orientation
174
+
175
+ media = box(page[:MediaBox]) || DEFAULT_MEDIA_BOX
176
+ crop = box(page[:CropBox])
177
+ visible = crop ? intersection(crop, media) : media
178
+ left, bottom, right, top = visible
179
+ width = right - left
180
+ height = top - bottom
181
+ rotation = number(page[:Rotate]).to_i % 360
182
+ rotation = 0 unless (rotation % 90).zero?
183
+ shown_width, shown_height = (rotation % 180).zero? ? [width, height] : [height, width]
184
+ turn = @orientation && shown_width != shown_height && (shown_width > shown_height) != (@orientation == :landscape)
185
+ final_width, final_height = turn ? [shown_height, shown_width] : [shown_width, shown_height]
186
+ # Four decimals, as combine_pdf writes it: the same labels print the same.
187
+ scale = @page_size ? [@page_size[0] / final_width, @page_size[1] / final_height].min.round(4) : 1.0
188
+ page_width, page_height = @page_size || [final_width, final_height]
189
+ return nil if rotation.zero? && !turn && visible == media && left.zero? && bottom.zero? && [width, height] == [page_width, page_height]
190
+
191
+ matrix = [1.0, 0.0, 0.0, 1.0, -left, -bottom]
192
+ matrix = multiply(matrix, ROTATIONS.fetch(rotation).call(width, height)) unless rotation.zero?
193
+ matrix = multiply(matrix, QUARTER_TURN.call(shown_width, shown_height)) if turn
194
+ matrix = multiply(matrix, [scale, 0.0, 0.0, scale, 0.0, 0.0])
195
+ [matrix, page_width, page_height, final_width * scale, final_height * scale]
196
+ end
197
+
198
+ # The old content, clipped to the visible box, drawn through the matrix on a page of the new size.
199
+ def reshape(dictionary, page, matrix, width, height, content_width, content_height)
200
+ dictionary[:MediaBox] = [0, 0, width, height]
201
+ prefix = reference({})
202
+ prefix.stream = "q\n0 0 #{PDF::Core.real(content_width)} #{PDF::Core.real(content_height)} re W n\n#{PDF::Core.real_params(matrix)} cm\n"
203
+ suffix = reference({})
204
+ suffix.stream = +"\nQ\n"
205
+ dictionary[:Contents] = [prefix, *contents(page[:Contents]), suffix]
206
+ end
207
+
208
+ def contents(value)
209
+ resolved = @reader.resolve(value)
210
+ value = resolved if resolved.is_a?(Array)
211
+ Array(value).filter_map { |content| copy_value(content) if content.is_a?(PDF::Core::Reader::Ref) }
212
+ end
213
+
214
+ # Annotation rectangles follow the content they sit on.
215
+ # An annotation listed by two pages, or an /Annots array two pages share, moves once.
216
+ def move_annotations(annotations, matrix, moved)
217
+ annotations = annotations.data if annotations.is_a?(PDF::Core::Reference)
218
+ Array(annotations).each do |annotation|
219
+ dictionary = annotation.is_a?(PDF::Core::Reference) ? annotation.data : annotation
220
+ next if moved.key?(dictionary) || !dictionary.is_a?(Hash) || !(rectangle = plain_box(dictionary[:Rect]))
221
+
222
+ moved[dictionary] = true
223
+ corners = [apply(matrix, rectangle[0], rectangle[1]), apply(matrix, rectangle[2], rectangle[3])]
224
+ xs, ys = corners.transpose
225
+ dictionary[:Rect] = [xs.min, ys.min, xs.max, ys.max]
226
+ turn_appearances(dictionary, matrix) unless matrix[1].zero? && matrix[2].zero? && matrix[0].positive?
227
+ end
228
+ end
229
+
230
+ # Viewers fit an appearance's box into its Rect without turning it: a turned page turns its appearances
231
+ # through their /Matrix. They are copies, so a form also drawn elsewhere keeps its own.
232
+ def turn_appearances(annotation, matrix)
233
+ appearances = annotation[:AP]
234
+ appearances = appearances.data if appearances.is_a?(PDF::Core::Reference)
235
+ return unless appearances.is_a?(Hash)
236
+
237
+ linear = [*matrix.first(4), 0.0, 0.0]
238
+ annotation[:AP] = appearances.transform_values do |appearance|
239
+ states = (appearance.is_a?(PDF::Core::Reference) && !appearance.stream?) ? appearance.data : appearance
240
+ next turned_form(appearance, linear) unless states.is_a?(Hash)
241
+
242
+ states.transform_values { turned_form(_1, linear) }
243
+ end
244
+ end
245
+
246
+ def turned_form(form, linear)
247
+ return form unless form.is_a?(PDF::Core::Reference) && form.stream? && form.data.is_a?(Hash)
248
+
249
+ own = plain_matrix(form.data[:Matrix])
250
+ return form unless own
251
+
252
+ reference(form.data.merge(Matrix: multiply(own, linear))).tap { |copy| copy.stream = form.stream }
253
+ end
254
+
255
+ def plain_matrix(values)
256
+ return [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] if values.nil?
257
+ return nil unless values.is_a?(Array) && values.size == 6
258
+
259
+ numbers = values.map { numeric(_1) }
260
+ numbers.all? ? numbers : nil
261
+ end
262
+
263
+ def box(value)
264
+ values = @reader.resolve(value)
265
+ return nil unless values.is_a?(Array) && values.size == 4
266
+
267
+ numbers = values.map { number(_1) }
268
+ return nil if numbers.any?(&:nil?) || numbers[0] == numbers[2] || numbers[1] == numbers[3]
269
+
270
+ left, right = [numbers[0], numbers[2]].minmax
271
+ bottom, top = [numbers[1], numbers[3]].minmax
272
+ [left, bottom, right, top]
273
+ end
274
+
275
+ def plain_box(values)
276
+ return nil unless values.is_a?(Array) && values.size == 4
277
+
278
+ numbers = values.map { numeric(_1) }
279
+ numbers.any?(&:nil?) ? nil : numbers
280
+ end
281
+
282
+ def number(value)
283
+ numeric(@reader.resolve(value))
284
+ end
285
+
286
+ def numeric(value)
287
+ (value.is_a?(PDF::Core::Real) || value.is_a?(Numeric)) ? value.to_f : nil
288
+ end
289
+
290
+ def intersection(crop, media)
291
+ left, bottom = [crop[0], media[0]].max, [crop[1], media[1]].max
292
+ right, top = [crop[2], media[2]].min, [crop[3], media[3]].min
293
+ (right > left && top > bottom) ? [left, bottom, right, top] : media
294
+ end
295
+
296
+ def multiply(first, second)
297
+ a, b, c, d, e, f = first
298
+ a2, b2, c2, d2, e2, f2 = second
299
+ [a * a2 + b * c2, a * b2 + b * d2, c * a2 + d * c2, c * b2 + d * d2, e * a2 + f * c2 + e2, e * b2 + f * d2 + f2]
300
+ end
301
+
302
+ def apply(matrix, x, y)
303
+ a, b, c, d, e, f = matrix
304
+ [a * x + c * y + e, b * x + d * y + f]
305
+ end
306
+ end
307
+ end