origamindee 3.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 (139) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +89 -0
  3. data/COPYING.LESSER +165 -0
  4. data/README.md +131 -0
  5. data/bin/config/pdfcop.conf.yml +236 -0
  6. data/bin/pdf2pdfa +87 -0
  7. data/bin/pdf2ruby +333 -0
  8. data/bin/pdfcop +476 -0
  9. data/bin/pdfdecompress +97 -0
  10. data/bin/pdfdecrypt +91 -0
  11. data/bin/pdfencrypt +113 -0
  12. data/bin/pdfexplode +223 -0
  13. data/bin/pdfextract +277 -0
  14. data/bin/pdfmetadata +143 -0
  15. data/bin/pdfsh +12 -0
  16. data/bin/shell/console.rb +128 -0
  17. data/bin/shell/hexdump.rb +59 -0
  18. data/bin/shell/irbrc +69 -0
  19. data/examples/README.md +34 -0
  20. data/examples/attachments/attachment.rb +38 -0
  21. data/examples/attachments/nested_document.rb +51 -0
  22. data/examples/encryption/encryption.rb +28 -0
  23. data/examples/events/events.rb +72 -0
  24. data/examples/flash/flash.rb +37 -0
  25. data/examples/flash/helloworld.swf +0 -0
  26. data/examples/forms/javascript.rb +54 -0
  27. data/examples/forms/xfa.rb +115 -0
  28. data/examples/javascript/hello_world.rb +22 -0
  29. data/examples/javascript/js_emulation.rb +54 -0
  30. data/examples/loop/goto.rb +32 -0
  31. data/examples/loop/named.rb +33 -0
  32. data/examples/signature/signature.rb +65 -0
  33. data/examples/uri/javascript.rb +56 -0
  34. data/examples/uri/open-uri.rb +21 -0
  35. data/examples/uri/submitform.rb +47 -0
  36. data/lib/origami/3d.rb +364 -0
  37. data/lib/origami/acroform.rb +321 -0
  38. data/lib/origami/actions.rb +318 -0
  39. data/lib/origami/annotations.rb +711 -0
  40. data/lib/origami/array.rb +242 -0
  41. data/lib/origami/boolean.rb +90 -0
  42. data/lib/origami/catalog.rb +418 -0
  43. data/lib/origami/collections.rb +144 -0
  44. data/lib/origami/compound.rb +161 -0
  45. data/lib/origami/destinations.rb +252 -0
  46. data/lib/origami/dictionary.rb +192 -0
  47. data/lib/origami/encryption.rb +1084 -0
  48. data/lib/origami/extensions/fdf.rb +347 -0
  49. data/lib/origami/extensions/ppklite.rb +422 -0
  50. data/lib/origami/filespec.rb +197 -0
  51. data/lib/origami/filters/ascii.rb +211 -0
  52. data/lib/origami/filters/ccitt/tables.rb +267 -0
  53. data/lib/origami/filters/ccitt.rb +357 -0
  54. data/lib/origami/filters/crypt.rb +38 -0
  55. data/lib/origami/filters/dct.rb +54 -0
  56. data/lib/origami/filters/flate.rb +69 -0
  57. data/lib/origami/filters/jbig2.rb +57 -0
  58. data/lib/origami/filters/jpx.rb +47 -0
  59. data/lib/origami/filters/lzw.rb +170 -0
  60. data/lib/origami/filters/predictors.rb +292 -0
  61. data/lib/origami/filters/runlength.rb +129 -0
  62. data/lib/origami/filters.rb +364 -0
  63. data/lib/origami/font.rb +196 -0
  64. data/lib/origami/functions.rb +79 -0
  65. data/lib/origami/graphics/colors.rb +230 -0
  66. data/lib/origami/graphics/instruction.rb +98 -0
  67. data/lib/origami/graphics/path.rb +182 -0
  68. data/lib/origami/graphics/patterns.rb +174 -0
  69. data/lib/origami/graphics/render.rb +62 -0
  70. data/lib/origami/graphics/state.rb +149 -0
  71. data/lib/origami/graphics/text.rb +225 -0
  72. data/lib/origami/graphics/xobject.rb +918 -0
  73. data/lib/origami/graphics.rb +38 -0
  74. data/lib/origami/header.rb +75 -0
  75. data/lib/origami/javascript.rb +713 -0
  76. data/lib/origami/linearization.rb +330 -0
  77. data/lib/origami/metadata.rb +172 -0
  78. data/lib/origami/name.rb +135 -0
  79. data/lib/origami/null.rb +65 -0
  80. data/lib/origami/numeric.rb +181 -0
  81. data/lib/origami/obfuscation.rb +245 -0
  82. data/lib/origami/object.rb +760 -0
  83. data/lib/origami/optionalcontent.rb +183 -0
  84. data/lib/origami/outline.rb +54 -0
  85. data/lib/origami/outputintents.rb +85 -0
  86. data/lib/origami/page.rb +722 -0
  87. data/lib/origami/parser.rb +269 -0
  88. data/lib/origami/parsers/fdf.rb +56 -0
  89. data/lib/origami/parsers/pdf/lazy.rb +176 -0
  90. data/lib/origami/parsers/pdf/linear.rb +122 -0
  91. data/lib/origami/parsers/pdf.rb +118 -0
  92. data/lib/origami/parsers/ppklite.rb +57 -0
  93. data/lib/origami/pdf.rb +1108 -0
  94. data/lib/origami/reference.rb +134 -0
  95. data/lib/origami/signature.rb +702 -0
  96. data/lib/origami/stream.rb +705 -0
  97. data/lib/origami/string.rb +444 -0
  98. data/lib/origami/template/patterns.rb +56 -0
  99. data/lib/origami/template/widgets.rb +151 -0
  100. data/lib/origami/trailer.rb +190 -0
  101. data/lib/origami/tree.rb +62 -0
  102. data/lib/origami/version.rb +23 -0
  103. data/lib/origami/webcapture.rb +100 -0
  104. data/lib/origami/xfa/config.rb +453 -0
  105. data/lib/origami/xfa/connectionset.rb +146 -0
  106. data/lib/origami/xfa/datasets.rb +49 -0
  107. data/lib/origami/xfa/localeset.rb +42 -0
  108. data/lib/origami/xfa/package.rb +59 -0
  109. data/lib/origami/xfa/pdf.rb +73 -0
  110. data/lib/origami/xfa/signature.rb +42 -0
  111. data/lib/origami/xfa/sourceset.rb +43 -0
  112. data/lib/origami/xfa/stylesheet.rb +44 -0
  113. data/lib/origami/xfa/template.rb +1691 -0
  114. data/lib/origami/xfa/xdc.rb +42 -0
  115. data/lib/origami/xfa/xfa.rb +146 -0
  116. data/lib/origami/xfa/xfdf.rb +43 -0
  117. data/lib/origami/xfa/xmpmeta.rb +43 -0
  118. data/lib/origami/xfa.rb +62 -0
  119. data/lib/origami/xreftable.rb +557 -0
  120. data/lib/origami.rb +47 -0
  121. data/test/dataset/calc.pdf +85 -0
  122. data/test/dataset/crypto.pdf +36 -0
  123. data/test/dataset/empty.pdf +49 -0
  124. data/test/test_actions.rb +27 -0
  125. data/test/test_annotations.rb +68 -0
  126. data/test/test_forms.rb +30 -0
  127. data/test/test_native_types.rb +83 -0
  128. data/test/test_object_tree.rb +33 -0
  129. data/test/test_pages.rb +60 -0
  130. data/test/test_pdf.rb +20 -0
  131. data/test/test_pdf_attachment.rb +34 -0
  132. data/test/test_pdf_create.rb +24 -0
  133. data/test/test_pdf_encrypt.rb +102 -0
  134. data/test/test_pdf_parse.rb +134 -0
  135. data/test/test_pdf_parse_lazy.rb +69 -0
  136. data/test/test_pdf_sign.rb +97 -0
  137. data/test/test_streams.rb +184 -0
  138. data/test/test_xrefs.rb +67 -0
  139. metadata +280 -0
@@ -0,0 +1,230 @@
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
20
+
21
+ module Origami
22
+
23
+ module Graphics
24
+
25
+ class InvalidColorError < Error #:nodoc:
26
+ end
27
+
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
130
+
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
197
+
198
+ class PDF::Instruction
199
+
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
204
+
205
+ insn 'G', Real do |canvas, c|
206
+ canvas.gs.set_stroking_color([c], Graphics::Color::Space::DEVICE_GRAY)
207
+ end
208
+
209
+ insn 'g', Real do |canvas, c|
210
+ canvas.gs.set_nonstroking_color([c], Graphics::Color::Space::DEVICE_GRAY)
211
+ end
212
+
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
216
+
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)
219
+ end
220
+
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
224
+
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
228
+ end
229
+
230
+ end
@@ -0,0 +1,98 @@
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
20
+
21
+ module Origami
22
+
23
+ class InvalidPDFInstructionError < Error; end
24
+
25
+ class PDF::Instruction
26
+ using TypeConversion
27
+
28
+ attr_reader :operator
29
+ attr_accessor :operands
30
+
31
+ @insns = Hash.new(operands: [], render: lambda{})
32
+
33
+ def initialize(operator, *operands)
34
+ @operator = operator
35
+ @operands = operands.map!{|arg| arg.is_a?(Origami::Object) ? arg.value : arg}
36
+
37
+ if self.class.has_op?(operator)
38
+ opdef = self.class.get_operands(operator)
39
+
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
45
+ end
46
+
47
+ def render(canvas)
48
+ self.class.get_render_proc(@operator)[canvas, *@operands]
49
+
50
+ self
51
+ end
52
+
53
+ def to_s
54
+ "#{operands.map{|op| op.to_o.to_s}.join(' ')}#{' ' unless operands.empty?}#{operator}\n"
55
+ end
56
+
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
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,182 @@
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
20
+
21
+ module Origami
22
+
23
+ module Graphics
24
+
25
+ module LineCapStyle
26
+ BUTT_CAP = 0
27
+ ROUND_CAP = 1
28
+ PROJECTING_SQUARE_CAP = 2
29
+ end
30
+
31
+ module LineJoinStyle
32
+ MITER_JOIN = 0
33
+ ROUND_JOIN = 1
34
+ BEVEL_JOIN = 2
35
+ end
36
+
37
+ class DashPattern
38
+ attr_accessor :array, :phase
39
+
40
+ def initialize(array, phase = 0)
41
+ @array = array
42
+ @phase = phase
43
+ end
44
+
45
+ def eql?(dash) #:nodoc
46
+ dash.array == @array and dash.phase == @phase
47
+ end
48
+
49
+ def hash #:nodoc:
50
+ [ @array, @phase ].hash
51
+ end
52
+ end
53
+
54
+ class InvalidPathError < Error #:nodoc:
55
+ end
56
+
57
+ class Path
58
+ module Segment
59
+ attr_accessor :from, :to
60
+
61
+ def initialize(from, to)
62
+ @from, @to = from, to
63
+ end
64
+ end
65
+
66
+ class Line
67
+ include Segment
68
+ end
69
+
70
+ attr_accessor :current_point
71
+ attr_reader :segments
72
+
73
+ def initialize
74
+ @segments = []
75
+ @current_point = nil
76
+ @closed = false
77
+ end
78
+
79
+ def is_closed?
80
+ @closed
81
+ end
82
+
83
+ def close!
84
+ from = @current_point
85
+ to = @segments.first.from
86
+
87
+ @segments << Line.new(from, to)
88
+ @segments.freeze
89
+ @closed = true
90
+ end
91
+
92
+ def add_segment(seg)
93
+ raise GraphicsStateError, "Cannot modify closed subpath" if is_closed?
94
+
95
+ @segments << seg
96
+ @current_point = seg.to
97
+ end
98
+ end
99
+ end
100
+
101
+ class PDF::Instruction
102
+ insn 'm', Real, Real do |canvas, x,y|
103
+ canvas.gs.current_path << (subpath = Graphics::Path.new)
104
+ subpath.current_point = [x,y]
105
+ end
106
+
107
+ insn 'l', Real, Real do |canvas, x,y|
108
+ if canvas.gs.current_path.empty?
109
+ raise InvalidPathError, "No current point is defined"
110
+ end
111
+
112
+ subpath = canvas.gs.current_path.last
113
+
114
+ from = subpath.current_point
115
+ to = [x,y]
116
+ subpath.add_segment(Graphics::Path::Line.new(from, to))
117
+ end
118
+
119
+ insn 'h' do |canvas|
120
+ unless canvas.gs.current_path.empty?
121
+ subpath = canvas.gs.current_path.last
122
+ subpath.close! unless subpath.is_closed?
123
+ end
124
+ end
125
+
126
+ insn 're', Real, Real, Real, Real do |canvas, x,y,width,height|
127
+ tx = x + width
128
+ ty = y + height
129
+ canvas.gs.current_path << (subpath = Graphics::Path.new)
130
+ subpath.segments << Graphics::Path::Line.new([x,y], [tx,y])
131
+ subpath.segments << Graphics::Path::Line.new([tx,y], [tx, ty])
132
+ subpath.segments << Graphics::Path::Line.new([tx, ty], [x, ty])
133
+ subpath.close!
134
+ end
135
+
136
+ insn 'S' do |canvas|
137
+ canvas.stroke_path
138
+ end
139
+
140
+ insn 's' do |canvas|
141
+ canvas.gs.current_path.last.close!
142
+ canvas.stroke_path
143
+ end
144
+
145
+ insn 'f' do |canvas|
146
+ canvas.fill_path
147
+ end
148
+
149
+ insn 'F' do |canvas|
150
+ canvas.fill_path
151
+ end
152
+
153
+ insn 'f*' do |canvas|
154
+ canvas.fill_path
155
+ end
156
+
157
+ insn 'B' do |canvas|
158
+ canvas.fill_path
159
+ canvas.stroke_path
160
+ end
161
+
162
+ insn 'B*' do |canvas|
163
+ canvas.fill_path
164
+ canvas.stroke_path
165
+ end
166
+
167
+ insn 'b' do |canvas|
168
+ canvas.gs.current_path.last.close!
169
+ canvas.fill_path
170
+ canvas.stroke_path
171
+ end
172
+
173
+ insn 'b*' do |canvas|
174
+ canvas.gs.current_path.last.close!
175
+ canvas.fill_path
176
+ canvas.stroke_path
177
+ end
178
+
179
+ insn 'n'
180
+ end
181
+
182
+ end
@@ -0,0 +1,174 @@
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
20
+
21
+ module Origami
22
+
23
+ module Graphics
24
+
25
+ module Pattern
26
+ module Type
27
+ TILING = 1
28
+ SHADING = 2
29
+ end
30
+
31
+ def self.included(receiver)
32
+ receiver.field :Type, :Type => Name, :Default => :Pattern
33
+ receiver.field :PatternType, :Type => Integer, :Required => true
34
+ end
35
+
36
+ class Tiling < ContentStream
37
+ include Pattern
38
+ include ResourcesHolder
39
+
40
+ module PaintType
41
+ COLOURED = 1
42
+ UNCOLOURED = 2
43
+ end
44
+
45
+ module Type
46
+ CONSTANT_SPACING = 1
47
+ NO_DISTORTION = 2
48
+ CONSTANT_SPACING_AND_FASTER_TILING = 3
49
+ end
50
+
51
+ field :PatternType, :Type => Integer, :Default => Pattern::Type::TILING, :Required => true
52
+ field :PaintType, :Type => Integer, :Required => true
53
+ field :TilingType, :Type => Integer, :Required => true
54
+ field :BBox, :Type => Rectangle, :Required => true
55
+ field :XStep, :Type => Number, :Required => true
56
+ field :YStep, :Type => Number, :Required => true
57
+ field :Resources, :Type => Resources, :Required => true
58
+ field :Matrix, :Type => Array.of(Number, length: 6), :Default => [ 1, 0, 0, 1, 0, 0 ]
59
+ end
60
+
61
+ class Shading < Dictionary
62
+ include StandardObject
63
+ include Pattern
64
+
65
+ module Type
66
+ FUNCTION_BASED = 1
67
+ AXIAL = 2
68
+ RADIAL = 3
69
+ FREEFORM_TRIANGLE_MESH = 4
70
+ LATTICEFORM_TRIANGLE_MESH = 5
71
+ COONS_PATCH_MESH = 6
72
+ TENSORPRODUCT_PATCH_MESH = 7
73
+ end
74
+
75
+ field :PatternType, :Type => Integer, :Default => Pattern::Type::SHADING, :Required => true
76
+ field :Shading, :Type => [ Dictionary, Stream ], :Required => true
77
+ field :Matrix, :Type => Array.of(Number, length: 6), :Default => [ 1, 0, 0, 1, 0, 0 ]
78
+ field :ExtGState, :Type => ExtGState
79
+
80
+ # Fields common to all shading objects.
81
+ module ShadingObject
82
+ def self.included(receiver)
83
+ receiver.field :ShadingType, :Type => Integer, :Required => true
84
+ receiver.field :ColorSpace, :Type => [ Name, Array ], :Required => true
85
+ receiver.field :Background, :Type => Array
86
+ receiver.field :BBox, :Type => Rectangle
87
+ receiver.field :AntiAlias, :Type => Boolean, :Default => false
88
+ end
89
+ end
90
+
91
+ # Fields common to all Mesh shadings.
92
+ module Mesh
93
+ def self.included(receiver)
94
+ receiver.field :BitsPerCoordinate, :Type => Integer, :Required => true
95
+ receiver.field :BitsPerComponent, :Type => Integer, :Required => true
96
+ receiver.field :Decode, :Type => Array.of(Number), :Required => true
97
+ receiver.field :Function, :Type => [ Dictionary, Stream ]
98
+ end
99
+ end
100
+
101
+ class FunctionBased < Dictionary
102
+ include StandardObject
103
+ include ShadingObject
104
+
105
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::FUNCTION_BASED, :Required => true
106
+ field :Domain, :Type => Array.of(Number, length: 4), :Default => [ 0.0, 1.0, 0.0, 1.0 ]
107
+ field :Matrix, :Type => Array.of(Number, length: 6), :Default => [ 1, 0, 0, 1, 0, 0 ]
108
+ field :Function, :Type => [ Dictionary, Stream ], :Required => true
109
+ end
110
+
111
+ class Axial < Dictionary
112
+ include StandardObject
113
+ include ShadingObject
114
+
115
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::AXIAL, :Required => true
116
+ field :Coords, :Type => Array.of(Number, length: 4), :Required => true
117
+ field :Domain, :Type => Array.of(Number, length: 2), :Default => [ 0.0, 1.0 ]
118
+ field :Function, :Type => [ Dictionary, Stream ], :Required => true
119
+ field :Extend, :Type => Array.of(Boolean, length: 2), :Default => [ false, false ]
120
+ end
121
+
122
+ class Radial < Dictionary
123
+ include StandardObject
124
+ include ShadingObject
125
+
126
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::RADIAL, :Required => true
127
+ field :Coords, :Type => Array.of(Number, length: 6), :Required => true
128
+ field :Domain, :Type => Array.of(Number, length: 2), :Default => [ 0.0, 1.0 ]
129
+ field :Function, :Type => [ Dictionary, Stream ], :Required => true
130
+ field :Extend, :Type => Array.of(Boolean, length: 2), :Default => [ false, false ]
131
+ end
132
+
133
+ class FreeFormTriangleMesh < Stream
134
+ include ShadingObject
135
+ include Mesh
136
+
137
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::FREEFORM_TRIANGLE_MESH, :Required => true
138
+ field :BitsPerFlag, :Type => Integer, :Required => true
139
+ end
140
+
141
+ class LatticeFormTriangleMesh < Stream
142
+ include ShadingObject
143
+ include Mesh
144
+
145
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::LATTICEFORM_TRIANGLE_MESH, :Required => true
146
+ field :VerticesPerRow, :Type => Integer, :Required => true
147
+ end
148
+
149
+ class CoonsPathMesh < Stream
150
+ include ShadingObject
151
+ include Mesh
152
+
153
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::COONS_PATCH_MESH, :Required => true
154
+ field :BitsPerFlag, :Type => Integer, :Required => true
155
+ end
156
+
157
+ class TensorProductPatchMesh < Stream
158
+ include ShadingObject
159
+
160
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::TENSORPRODUCT_PATCH_MESH, :Required => true
161
+ field :BitsPerFlag, :Type => Integer, :Required => true
162
+ end
163
+ end
164
+
165
+ end
166
+ end
167
+
168
+ class PDF::Instruction
169
+ insn 'sh', Name do |canvas, shading|
170
+ canvas.paint_shading(shading)
171
+ end
172
+ end
173
+
174
+ end