origami-docspring 2.2.0 → 2.3.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/examples/attachments/attachment.rb +7 -8
  4. data/examples/attachments/nested_document.rb +6 -5
  5. data/examples/encryption/encryption.rb +5 -4
  6. data/examples/events/events.rb +7 -6
  7. data/examples/flash/flash.rb +10 -9
  8. data/examples/forms/javascript.rb +14 -13
  9. data/examples/forms/xfa.rb +67 -66
  10. data/examples/javascript/hello_world.rb +6 -5
  11. data/examples/javascript/js_emulation.rb +26 -26
  12. data/examples/loop/goto.rb +12 -11
  13. data/examples/loop/named.rb +17 -16
  14. data/examples/signature/signature.rb +11 -11
  15. data/examples/uri/javascript.rb +25 -24
  16. data/examples/uri/open-uri.rb +5 -4
  17. data/examples/uri/submitform.rb +11 -10
  18. data/lib/origami/3d.rb +330 -334
  19. data/lib/origami/acroform.rb +267 -268
  20. data/lib/origami/actions.rb +266 -278
  21. data/lib/origami/annotations.rb +659 -670
  22. data/lib/origami/array.rb +192 -196
  23. data/lib/origami/boolean.rb +66 -70
  24. data/lib/origami/catalog.rb +360 -363
  25. data/lib/origami/collections.rb +132 -133
  26. data/lib/origami/compound.rb +125 -129
  27. data/lib/origami/destinations.rb +226 -237
  28. data/lib/origami/dictionary.rb +155 -154
  29. data/lib/origami/encryption.rb +967 -923
  30. data/lib/origami/extensions/fdf.rb +270 -275
  31. data/lib/origami/extensions/ppklite.rb +323 -328
  32. data/lib/origami/filespec.rb +170 -173
  33. data/lib/origami/filters/ascii.rb +162 -167
  34. data/lib/origami/filters/ccitt/tables.rb +248 -252
  35. data/lib/origami/filters/ccitt.rb +309 -312
  36. data/lib/origami/filters/crypt.rb +31 -34
  37. data/lib/origami/filters/dct.rb +47 -50
  38. data/lib/origami/filters/flate.rb +57 -60
  39. data/lib/origami/filters/jbig2.rb +50 -53
  40. data/lib/origami/filters/jpx.rb +40 -43
  41. data/lib/origami/filters/lzw.rb +151 -155
  42. data/lib/origami/filters/predictors.rb +250 -255
  43. data/lib/origami/filters/runlength.rb +111 -115
  44. data/lib/origami/filters.rb +319 -325
  45. data/lib/origami/font.rb +173 -177
  46. data/lib/origami/functions.rb +62 -66
  47. data/lib/origami/graphics/colors.rb +203 -208
  48. data/lib/origami/graphics/instruction.rb +79 -81
  49. data/lib/origami/graphics/path.rb +141 -144
  50. data/lib/origami/graphics/patterns.rb +156 -160
  51. data/lib/origami/graphics/render.rb +51 -47
  52. data/lib/origami/graphics/state.rb +144 -142
  53. data/lib/origami/graphics/text.rb +185 -188
  54. data/lib/origami/graphics/xobject.rb +818 -804
  55. data/lib/origami/graphics.rb +25 -26
  56. data/lib/origami/header.rb +63 -65
  57. data/lib/origami/javascript.rb +718 -651
  58. data/lib/origami/linearization.rb +284 -285
  59. data/lib/origami/metadata.rb +156 -135
  60. data/lib/origami/name.rb +98 -100
  61. data/lib/origami/null.rb +49 -51
  62. data/lib/origami/numeric.rb +133 -135
  63. data/lib/origami/obfuscation.rb +180 -182
  64. data/lib/origami/object.rb +634 -631
  65. data/lib/origami/optionalcontent.rb +147 -149
  66. data/lib/origami/outline.rb +46 -48
  67. data/lib/origami/outputintents.rb +76 -77
  68. data/lib/origami/page.rb +637 -596
  69. data/lib/origami/parser.rb +214 -221
  70. data/lib/origami/parsers/fdf.rb +44 -45
  71. data/lib/origami/parsers/pdf/lazy.rb +147 -154
  72. data/lib/origami/parsers/pdf/linear.rb +104 -109
  73. data/lib/origami/parsers/pdf.rb +109 -107
  74. data/lib/origami/parsers/ppklite.rb +44 -46
  75. data/lib/origami/pdf.rb +886 -896
  76. data/lib/origami/reference.rb +116 -120
  77. data/lib/origami/signature.rb +617 -625
  78. data/lib/origami/stream.rb +560 -558
  79. data/lib/origami/string.rb +366 -368
  80. data/lib/origami/template/patterns.rb +50 -52
  81. data/lib/origami/template/widgets.rb +111 -114
  82. data/lib/origami/trailer.rb +153 -157
  83. data/lib/origami/tree.rb +55 -57
  84. data/lib/origami/version.rb +19 -19
  85. data/lib/origami/webcapture.rb +87 -90
  86. data/lib/origami/xfa/config.rb +409 -414
  87. data/lib/origami/xfa/connectionset.rb +113 -117
  88. data/lib/origami/xfa/datasets.rb +38 -42
  89. data/lib/origami/xfa/localeset.rb +33 -37
  90. data/lib/origami/xfa/package.rb +49 -52
  91. data/lib/origami/xfa/pdf.rb +54 -59
  92. data/lib/origami/xfa/signature.rb +33 -37
  93. data/lib/origami/xfa/sourceset.rb +34 -38
  94. data/lib/origami/xfa/stylesheet.rb +35 -39
  95. data/lib/origami/xfa/template.rb +1630 -1634
  96. data/lib/origami/xfa/xdc.rb +33 -37
  97. data/lib/origami/xfa/xfa.rb +132 -123
  98. data/lib/origami/xfa/xfdf.rb +34 -38
  99. data/lib/origami/xfa/xmpmeta.rb +34 -38
  100. data/lib/origami/xfa.rb +50 -53
  101. data/lib/origami/xreftable.rb +462 -462
  102. data/lib/origami.rb +37 -38
  103. data/test/test_actions.rb +22 -20
  104. data/test/test_annotations.rb +54 -52
  105. data/test/test_forms.rb +23 -21
  106. data/test/test_native_types.rb +82 -78
  107. data/test/test_object_tree.rb +25 -24
  108. data/test/test_pages.rb +43 -41
  109. data/test/test_pdf.rb +2 -0
  110. data/test/test_pdf_attachment.rb +23 -21
  111. data/test/test_pdf_create.rb +16 -15
  112. data/test/test_pdf_encrypt.rb +69 -66
  113. data/test/test_pdf_parse.rb +131 -129
  114. data/test/test_pdf_parse_lazy.rb +53 -53
  115. data/test/test_pdf_sign.rb +67 -67
  116. data/test/test_streams.rb +145 -143
  117. data/test/test_xrefs.rb +46 -45
  118. metadata +64 -8
@@ -1,230 +1,225 @@
1
- =begin
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This file is part of Origami, PDF manipulation framework for Ruby
5
+ # Copyright (C) 2016 Guillaume Delugré.
6
+ #
7
+ # Origami is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # Origami is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with Origami. If not, see <http://www.gnu.org/licenses/>.
19
+ #
2
20
 
3
- This file is part of Origami, PDF manipulation framework for Ruby
4
- Copyright (C) 2016 Guillaume Delugré.
21
+ module Origami
22
+ module Graphics
23
+ class InvalidColorError < Error # :nodoc:
24
+ end
5
25
 
6
- Origami is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU Lesser General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
26
+ module Color
27
+ module Intent
28
+ ABSOLUTE = :AbsoluteColorimetric
29
+ RELATIVE = :RelativeColorimetric
30
+ SATURATION = :Saturation
31
+ PERCEPTUAL = :Perceptual
32
+ end
33
+
34
+ module BlendMode
35
+ NORMAL = :Normal
36
+ COMPATIBLE = :Compatible
37
+ MULTIPLY = :Multiply
38
+ SCREEN = :Screen
39
+ OVERLAY = :Overlay
40
+ DARKEN = :Darken
41
+ LIGHTEN = :Lighten
42
+ COLORDODGE = :ColorDodge
43
+ COLORBURN = :ColorBurn
44
+ HARDLIGHT = :HardLight
45
+ SOFTLIGHT = :SoftLight
46
+ DIFFERENCE = :Difference
47
+ EXCLUSION = :Exclusion
48
+ end
49
+
50
+ module Space
51
+ DEVICE_GRAY = :DeviceGray
52
+ DEVICE_RGB = :DeviceRGB
53
+ DEVICE_CMYK = :DeviceCMYK
54
+ end
55
+
56
+ def self.cmyk_to_rgb(c, m, y, k)
57
+ r = 1 - ((c * (1 - k) + k))
58
+ g = 1 - ((m * (1 - k) + k))
59
+ b = 1 - ((y * (1 - k) + k))
60
+
61
+ [r, g, b]
62
+ end
63
+
64
+ def self.gray_to_rgb(g)
65
+ [g, g, g]
66
+ end
67
+
68
+ #
69
+ # Class representing an embedded ICC Profile stream.
70
+ #
71
+ class ICCProfile < Stream
72
+ field :N, Type: Integer, Required: true, Version: '1.3'
73
+ field :Alternate, Type: [Name, Array]
74
+ field :Range, Type: Array
75
+ field :Metadata, Type: Stream, Version: '1.4'
76
+ end
77
+
78
+ class GrayScale
79
+ attr_accessor :g
80
+
81
+ def initialize(g)
82
+ @g = g
83
+ end
84
+ end
10
85
 
11
- Origami is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU Lesser General Public License for more details.
86
+ class RGB
87
+ attr_accessor :r, :g, :b
15
88
 
16
- You should have received a copy of the GNU Lesser General Public License
17
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
89
+ def initialize(r, g, b)
90
+ @r, @g, @b = r, g, b
91
+ end
92
+ end
18
93
 
19
- =end
94
+ class CMYK
95
+ attr_accessor :c, :m, :y, :k
20
96
 
21
- module Origami
97
+ def initialize(c, m, y, k)
98
+ @c, @m, @y, @k = c, m, y, k
99
+ end
100
+ end
101
+
102
+ def self.to_a(color)
103
+ return color if color.is_a?(::Array)
104
+
105
+ if %i[r g b].all? { |c| color.respond_to?(c) }
106
+ r = color.r.to_f / 255
107
+ g = color.g.to_f / 255
108
+ b = color.b.to_f / 255
109
+ [r, g, b]
110
+
111
+ elsif %i[c m y k].all? { |c| color.respond_to?(c) }
112
+ c = color.c
113
+ m = color.m
114
+ y = color.y
115
+ k = color.k
116
+ [c, m, y, k]
117
+
118
+ elsif color.respond_to?(:g)
119
+ g = color.g
120
+ [g]
121
+
122
+ else
123
+ raise TypeError, "Invalid color : #{color}"
124
+ end
125
+ end
126
+ end
22
127
 
23
- module Graphics
128
+ class State
129
+ def set_stroking_color(color, space = @stroking_color_space)
130
+ check_color(space, color)
24
131
 
25
- class InvalidColorError < Error #:nodoc:
26
- end
132
+ @stroking_colorspace = space
133
+ @stroking_color = color
134
+ end
27
135
 
28
- module Color
29
-
30
- module Intent
31
- ABSOLUTE = :AbsoluteColorimetric
32
- RELATIVE = :RelativeColorimetric
33
- SATURATION = :Saturation
34
- PERCEPTUAL = :Perceptual
35
- end
36
-
37
- module BlendMode
38
- NORMAL = :Normal
39
- COMPATIBLE = :Compatible
40
- MULTIPLY = :Multiply
41
- SCREEN = :Screen
42
- OVERLAY = :Overlay
43
- DARKEN = :Darken
44
- LIGHTEN = :Lighten
45
- COLORDODGE = :ColorDodge
46
- COLORBURN = :ColorBurn
47
- HARDLIGHT = :HardLight
48
- SOFTLIGHt = :SoftLight
49
- DIFFERENCE = :Difference
50
- EXCLUSION = :Exclusion
51
- end
52
-
53
- module Space
54
- DEVICE_GRAY = :DeviceGray
55
- DEVICE_RGB = :DeviceRGB
56
- DEVICE_CMYK = :DeviceCMYK
57
- end
58
-
59
- def self.cmyk_to_rgb(c, m, y, k)
60
- r = 1 - (( c * ( 1 - k ) + k ))
61
- g = 1 - (( m * ( 1 - k ) + k ))
62
- b = 1 - (( y * ( 1 - k ) + k ))
63
-
64
- [ r, g, b ]
65
- end
66
-
67
- def self.gray_to_rgb(g)
68
- [ g, g, g ]
69
- end
70
-
71
- #
72
- # Class representing an embedded ICC Profile stream.
73
- #
74
- class ICCProfile < Stream
75
- field :N, :Type => Integer, :Required => true, :Version => '1.3'
76
- field :Alternate, :Type => [ Name, Array ]
77
- field :Range, :Type => Array
78
- field :Metadata, :Type => Stream, :Version => '1.4'
79
- end
80
-
81
- class GrayScale
82
- attr_accessor :g
83
-
84
- def initialize(g)
85
- @g = g
86
- end
87
- end
88
-
89
- class RGB
90
- attr_accessor :r,:g,:b
91
-
92
- def initialize(r,g,b)
93
- @r,@g,@b = r,g,b
94
- end
95
- end
96
-
97
- class CMYK
98
- attr_accessor :c,:m,:y,:k
99
-
100
- def initialize(c,m,y,k)
101
- @c,@m,@y,@k = c,m,y,k
102
- end
103
- end
104
-
105
- def Color.to_a(color)
106
- return color if color.is_a?(::Array)
107
-
108
- if %i(r g b).all? {|c| color.respond_to?(c)}
109
- r = color.r.to_f / 255
110
- g = color.g.to_f / 255
111
- b = color.b.to_f / 255
112
- return [r, g, b]
113
-
114
- elsif %i(c m y k).all? {|c| color.respond_to?(c)}
115
- c = color.c
116
- m = color.m
117
- y = color.y
118
- k = color.k
119
- return [c,m,y,k]
120
-
121
- elsif color.respond_to?(:g)
122
- g = color.g
123
- return [g]
124
-
125
- else
126
- raise TypeError, "Invalid color : #{color}"
127
- end
128
- end
129
- end
136
+ def set_nonstroking_color(color, space = @nonstroking_colorspace)
137
+ check_color(space, color)
130
138
 
131
- class State
132
- def set_stroking_color(color, space = @stroking_color_space)
133
- check_color(space, color)
134
-
135
- @stroking_colorspace = space
136
- @stroking_color = color
137
- end
138
-
139
- def set_nonstroking_color(color, space = @nonstroking_colorspace)
140
- check_color(space, color)
141
-
142
- @nonstroking_colorspace = space
143
- @nonstroking_color = color
144
- end
145
-
146
- def set_stroking_colorspace(space)
147
- check_color_space(space, @stroking_color)
148
-
149
- @stroking_color_space = space
150
- end
151
-
152
- def set_nonstroking_colorspace(space)
153
- check_color_space(space, @nonstroking_color)
154
-
155
- @nonstroking_color_space = space
156
- end
157
-
158
- private
159
-
160
- def check_color_space(space)
161
- case space
162
- when Color::Space::DEVICE_GRAY, Color::Space::DEVICE_RGB, Color::Space::DEVICE_CMYK
163
- else
164
- raise InvalidColorError, "Unknown color space #{space}"
165
- end
166
- end
167
-
168
- def check_color(space, color)
169
- valid_color =
170
- case space
171
- when Color::Space::DEVICE_GRAY
172
- check_gray_color(color)
173
- when Color::Space::DEVICE_RGB
174
- check_rgb_color(color)
175
- when Color::Space::DEVICE_CMYK
176
- check_cmyk_color(color)
177
- else
178
- raise InvalidColorError, "Unknown color space #{space}"
179
- end
180
-
181
- raise InvalidColorError, "Invalid color #{color.inspect} for #{space}" unless valid_color
182
- end
183
-
184
- def check_gray_color(color)
185
- color.is_a?(::Array) and color.length == 1 and (0..1).include?(color[0])
186
- end
187
-
188
- def check_rgb_color(color)
189
- color.is_a?(::Array) and color.length == 3 and color.all? {|c| (0..1).include?(c) }
190
- end
191
-
192
- def check_cmyk_color(color)
193
- color.is_a?(::Array) and color.length == 4 and color.all? {|c| (0..1).include?(c) }
194
- end
195
- end
196
- end
139
+ @nonstroking_colorspace = space
140
+ @nonstroking_color = color
141
+ end
197
142
 
198
- class PDF::Instruction
143
+ def set_stroking_colorspace(space)
144
+ check_color_space(space, @stroking_color)
199
145
 
200
- insn 'CS', Name do |canvas, cs| canvas.gs.set_stroking_colorspace(cs) end
201
- insn 'cs', Name do |canvas, cs| canvas.gs.set_nonstroking_colorspace(cs) end
202
- insn 'SC', '*' do |canvas, *c| canvas.gs.set_stroking_color(c) end
203
- insn 'sc', '*' do |canvas, *c| canvas.gs.set_nonstroking_color(c) end
146
+ @stroking_color_space = space
147
+ end
204
148
 
205
- insn 'G', Real do |canvas, c|
206
- canvas.gs.set_stroking_color([c], Graphics::Color::Space::DEVICE_GRAY)
207
- end
149
+ def set_nonstroking_colorspace(space)
150
+ check_color_space(space, @nonstroking_color)
208
151
 
209
- insn 'g', Real do |canvas, c|
210
- canvas.gs.set_nonstroking_color([c], Graphics::Color::Space::DEVICE_GRAY)
211
- end
152
+ @nonstroking_color_space = space
153
+ end
212
154
 
213
- insn 'RG', Real, Real, Real do |canvas, r, g, b|
214
- canvas.gs.set_stroking_color([r, g, b], Graphics::Color::Space::DEVICE_RGB)
215
- end
155
+ private
216
156
 
217
- insn 'rg', Real, Real, Real do |canvas, r, g, b|
218
- canvas.gs.set_nonstroking_color([r, g, b], Graphics::Color::Space::DEVICE_RGB)
157
+ def check_color_space(space)
158
+ case space
159
+ when Color::Space::DEVICE_GRAY, Color::Space::DEVICE_RGB, Color::Space::DEVICE_CMYK
160
+ else
161
+ raise InvalidColorError, "Unknown color space #{space}"
219
162
  end
163
+ end
164
+
165
+ def check_color(space, color)
166
+ valid_color =
167
+ case space
168
+ when Color::Space::DEVICE_GRAY
169
+ check_gray_color(color)
170
+ when Color::Space::DEVICE_RGB
171
+ check_rgb_color(color)
172
+ when Color::Space::DEVICE_CMYK
173
+ check_cmyk_color(color)
174
+ else
175
+ raise InvalidColorError, "Unknown color space #{space}"
176
+ end
177
+
178
+ raise InvalidColorError, "Invalid color #{color.inspect} for #{space}" unless valid_color
179
+ end
180
+
181
+ def check_gray_color(color)
182
+ color.is_a?(::Array) and color.length == 1 and (0..1).include?(color[0])
183
+ end
184
+
185
+ def check_rgb_color(color)
186
+ color.is_a?(::Array) and color.length == 3 and color.all? { |c| (0..1).include?(c) }
187
+ end
188
+
189
+ def check_cmyk_color(color)
190
+ color.is_a?(::Array) and color.length == 4 and color.all? { |c| (0..1).include?(c) }
191
+ end
192
+ end
193
+ end
220
194
 
221
- insn 'K', Real, Real, Real, Real do |canvas, c, m, y, k|
222
- canvas.gs.set_stroking_color([c, m, y, k], Graphics::Color::Space::DEVICE_CMYK)
223
- end
195
+ class PDF::Instruction
196
+ insn 'CS', Name do |canvas, cs| canvas.gs.set_stroking_colorspace(cs) end
197
+ insn 'cs', Name do |canvas, cs| canvas.gs.set_nonstroking_colorspace(cs) end
198
+ insn 'SC', '*' do |canvas, *c| canvas.gs.set_stroking_color(c) end
199
+ insn 'sc', '*' do |canvas, *c| canvas.gs.set_nonstroking_color(c) end
224
200
 
225
- insn 'k', Real, Real, Real, Real do |canvas, c, m, y, k|
226
- canvas.gs.set_nonstroking_color([c, m, y, k], Graphics::Color::Space::DEVICE_CMYK)
227
- end
201
+ insn 'G', Real do |canvas, c|
202
+ canvas.gs.set_stroking_color([c], Graphics::Color::Space::DEVICE_GRAY)
228
203
  end
229
204
 
205
+ insn 'g', Real do |canvas, c|
206
+ canvas.gs.set_nonstroking_color([c], Graphics::Color::Space::DEVICE_GRAY)
207
+ end
208
+
209
+ insn 'RG', Real, Real, Real do |canvas, r, g, b|
210
+ canvas.gs.set_stroking_color([r, g, b], Graphics::Color::Space::DEVICE_RGB)
211
+ end
212
+
213
+ insn 'rg', Real, Real, Real do |canvas, r, g, b|
214
+ canvas.gs.set_nonstroking_color([r, g, b], Graphics::Color::Space::DEVICE_RGB)
215
+ end
216
+
217
+ insn 'K', Real, Real, Real, Real do |canvas, c, m, y, k|
218
+ canvas.gs.set_stroking_color([c, m, y, k], Graphics::Color::Space::DEVICE_CMYK)
219
+ end
220
+
221
+ insn 'k', Real, Real, Real, Real do |canvas, c, m, y, k|
222
+ canvas.gs.set_nonstroking_color([c, m, y, k], Graphics::Color::Space::DEVICE_CMYK)
223
+ end
224
+ end
230
225
  end
@@ -1,98 +1,96 @@
1
- =begin
2
-
3
- This file is part of Origami, PDF manipulation framework for Ruby
4
- Copyright (C) 2016 Guillaume Delugré.
5
-
6
- Origami is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU Lesser General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- Origami is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU Lesser General Public License for more details.
15
-
16
- You should have received a copy of the GNU Lesser General Public License
17
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- =end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This file is part of Origami, PDF manipulation framework for Ruby
5
+ # Copyright (C) 2016 Guillaume Delugré.
6
+ #
7
+ # Origami is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # Origami is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with Origami. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
20
 
21
21
  module Origami
22
+ class InvalidPDFInstructionError < Error; end
22
23
 
23
- class InvalidPDFInstructionError < Error; end
24
-
25
- class PDF::Instruction
26
- using TypeConversion
24
+ class PDF::Instruction
25
+ using TypeConversion
27
26
 
28
- attr_reader :operator
29
- attr_accessor :operands
27
+ attr_reader :operator
28
+ attr_accessor :operands
30
29
 
31
- @insns = Hash.new(operands: [], render: lambda{})
30
+ @insns = Hash.new { |h, k| h[k] = {operands: [], render: lambda {}} }
32
31
 
33
- def initialize(operator, *operands)
34
- @operator = operator
35
- @operands = operands.map!{|arg| arg.is_a?(Origami::Object) ? arg.value : arg}
32
+ def initialize(operator, *operands)
33
+ @operator = operator
34
+ @operands = operands.map! { |arg| arg.is_a?(Origami::Object) ? arg.value : arg }
36
35
 
37
- if self.class.has_op?(operator)
38
- opdef = self.class.get_operands(operator)
36
+ if self.class.has_op?(operator)
37
+ opdef = self.class.get_operands(operator)
39
38
 
40
- if not opdef.include?('*') and opdef.size != operands.size
41
- raise InvalidPDFInstructionError,
42
- "Numbers of operands mismatch for #{operator}: #{operands.inspect}"
43
- end
44
- end
39
+ if !opdef.include?('*') && (opdef.size != operands.size)
40
+ raise InvalidPDFInstructionError,
41
+ "Numbers of operands mismatch for #{operator}: #{operands.inspect}"
45
42
  end
43
+ end
44
+ end
46
45
 
47
- def render(canvas)
48
- self.class.get_render_proc(@operator)[canvas, *@operands]
46
+ def render(canvas)
47
+ self.class.get_render_proc(@operator)[canvas, *@operands]
49
48
 
50
- self
51
- end
49
+ self
50
+ end
52
51
 
53
- def to_s
54
- "#{operands.map{|op| op.to_o.to_s}.join(' ')}#{' ' unless operands.empty?}#{operator}\n"
55
- end
52
+ def to_s
53
+ "#{operands.map { |op| op.to_o.to_s }.join(" ")}#{" " unless operands.empty?}#{operator}\n"
54
+ end
56
55
 
57
- class << self
58
- def insn(operator, *operands, &render_proc)
59
- @insns[operator] = {}
60
- @insns[operator][:operands] = operands
61
- @insns[operator][:render] = render_proc || lambda{}
62
- end
63
-
64
- def has_op?(operator)
65
- @insns.has_key? operator
66
- end
67
-
68
- def get_render_proc(operator)
69
- @insns[operator][:render]
70
- end
71
-
72
- def get_operands(operator)
73
- @insns[operator][:operands]
74
- end
75
-
76
- def parse(stream)
77
- operands = []
78
- while type = Object.typeof(stream, true)
79
- operands.push type.parse(stream)
80
- end
81
-
82
- if not stream.eos?
83
- if stream.scan(/(?<operator>[[:graph:]&&[^\[\]<>()%\/]]+)/).nil?
84
- raise InvalidPDFInstructionError, "Operator: #{(stream.peek(10) + '...').inspect}"
85
- end
86
-
87
- operator = stream['operator']
88
- PDF::Instruction.new(operator, *operands)
89
- else
90
- unless operands.empty?
91
- raise InvalidPDFInstructionError, "No operator given for operands: #{operands.map(&:to_s).join(' ')}"
92
- end
93
- end
94
- end
56
+ class << self
57
+ def insn(operator, *operands, &render_proc)
58
+ @insns[operator] = {}
59
+ @insns[operator][:operands] = operands
60
+ @insns[operator][:render] = render_proc || lambda {}
61
+ end
62
+
63
+ def has_op?(operator)
64
+ @insns.has_key? operator
65
+ end
66
+
67
+ def get_render_proc(operator)
68
+ @insns[operator][:render]
69
+ end
70
+
71
+ def get_operands(operator)
72
+ @insns[operator][:operands]
73
+ end
74
+
75
+ def parse(stream)
76
+ operands = []
77
+ while type = Object.typeof(stream, true)
78
+ operands.push type.parse(stream)
95
79
  end
96
80
 
81
+ if !stream.eos?
82
+ if stream.scan(/(?<operator>[[:graph:]&&[^\[\]<>()%\/]]+)/).nil?
83
+ raise InvalidPDFInstructionError, "Operator: #{(stream.peek(10) + "...").inspect}"
84
+ end
85
+
86
+ operator = stream['operator']
87
+ PDF::Instruction.new(operator, *operands)
88
+ else
89
+ unless operands.empty?
90
+ raise InvalidPDFInstructionError, "No operator given for operands: #{operands.map(&:to_s).join(" ")}"
91
+ end
92
+ end
93
+ end
97
94
  end
95
+ end
98
96
  end