origami 1.0.2

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 (108) hide show
  1. data/COPYING.LESSER +165 -0
  2. data/README +77 -0
  3. data/VERSION +1 -0
  4. data/bin/config/pdfcop.conf.yml +237 -0
  5. data/bin/gui/about.rb +46 -0
  6. data/bin/gui/config.rb +132 -0
  7. data/bin/gui/file.rb +385 -0
  8. data/bin/gui/hexdump.rb +74 -0
  9. data/bin/gui/hexview.rb +91 -0
  10. data/bin/gui/imgview.rb +72 -0
  11. data/bin/gui/menu.rb +392 -0
  12. data/bin/gui/properties.rb +132 -0
  13. data/bin/gui/signing.rb +635 -0
  14. data/bin/gui/textview.rb +107 -0
  15. data/bin/gui/treeview.rb +409 -0
  16. data/bin/gui/walker.rb +282 -0
  17. data/bin/gui/xrefs.rb +79 -0
  18. data/bin/pdf2graph +121 -0
  19. data/bin/pdf2ruby +353 -0
  20. data/bin/pdfcocoon +104 -0
  21. data/bin/pdfcop +455 -0
  22. data/bin/pdfdecompress +104 -0
  23. data/bin/pdfdecrypt +95 -0
  24. data/bin/pdfencrypt +112 -0
  25. data/bin/pdfextract +221 -0
  26. data/bin/pdfmetadata +123 -0
  27. data/bin/pdfsh +13 -0
  28. data/bin/pdfwalker +7 -0
  29. data/bin/shell/.irbrc +104 -0
  30. data/bin/shell/console.rb +136 -0
  31. data/bin/shell/hexdump.rb +83 -0
  32. data/origami.rb +36 -0
  33. data/origami/3d.rb +239 -0
  34. data/origami/acroform.rb +321 -0
  35. data/origami/actions.rb +299 -0
  36. data/origami/adobe/fdf.rb +259 -0
  37. data/origami/adobe/ppklite.rb +489 -0
  38. data/origami/annotations.rb +775 -0
  39. data/origami/array.rb +187 -0
  40. data/origami/boolean.rb +101 -0
  41. data/origami/catalog.rb +486 -0
  42. data/origami/destinations.rb +213 -0
  43. data/origami/dictionary.rb +188 -0
  44. data/origami/docmdp.rb +96 -0
  45. data/origami/encryption.rb +1293 -0
  46. data/origami/export.rb +283 -0
  47. data/origami/file.rb +222 -0
  48. data/origami/filters.rb +250 -0
  49. data/origami/filters/ascii.rb +189 -0
  50. data/origami/filters/ccitt.rb +515 -0
  51. data/origami/filters/crypt.rb +47 -0
  52. data/origami/filters/dct.rb +61 -0
  53. data/origami/filters/flate.rb +112 -0
  54. data/origami/filters/jbig2.rb +63 -0
  55. data/origami/filters/jpx.rb +53 -0
  56. data/origami/filters/lzw.rb +195 -0
  57. data/origami/filters/predictors.rb +276 -0
  58. data/origami/filters/runlength.rb +117 -0
  59. data/origami/font.rb +209 -0
  60. data/origami/functions.rb +93 -0
  61. data/origami/graphics.rb +33 -0
  62. data/origami/graphics/colors.rb +191 -0
  63. data/origami/graphics/instruction.rb +126 -0
  64. data/origami/graphics/path.rb +154 -0
  65. data/origami/graphics/patterns.rb +180 -0
  66. data/origami/graphics/state.rb +164 -0
  67. data/origami/graphics/text.rb +224 -0
  68. data/origami/graphics/xobject.rb +493 -0
  69. data/origami/header.rb +90 -0
  70. data/origami/linearization.rb +318 -0
  71. data/origami/metadata.rb +114 -0
  72. data/origami/name.rb +170 -0
  73. data/origami/null.rb +75 -0
  74. data/origami/numeric.rb +188 -0
  75. data/origami/obfuscation.rb +233 -0
  76. data/origami/object.rb +527 -0
  77. data/origami/outline.rb +59 -0
  78. data/origami/page.rb +559 -0
  79. data/origami/parser.rb +268 -0
  80. data/origami/parsers/fdf.rb +45 -0
  81. data/origami/parsers/pdf.rb +27 -0
  82. data/origami/parsers/pdf/linear.rb +113 -0
  83. data/origami/parsers/ppklite.rb +86 -0
  84. data/origami/pdf.rb +1144 -0
  85. data/origami/reference.rb +113 -0
  86. data/origami/signature.rb +474 -0
  87. data/origami/stream.rb +575 -0
  88. data/origami/string.rb +416 -0
  89. data/origami/trailer.rb +173 -0
  90. data/origami/webcapture.rb +87 -0
  91. data/origami/xfa.rb +3027 -0
  92. data/origami/xreftable.rb +447 -0
  93. data/templates/patterns.rb +66 -0
  94. data/templates/widgets.rb +173 -0
  95. data/templates/xdp.rb +92 -0
  96. data/tests/dataset/test.dummycrt +28 -0
  97. data/tests/dataset/test.dummykey +27 -0
  98. data/tests/tc_actions.rb +32 -0
  99. data/tests/tc_annotations.rb +85 -0
  100. data/tests/tc_pages.rb +37 -0
  101. data/tests/tc_pdfattach.rb +24 -0
  102. data/tests/tc_pdfencrypt.rb +110 -0
  103. data/tests/tc_pdfnew.rb +32 -0
  104. data/tests/tc_pdfparse.rb +98 -0
  105. data/tests/tc_pdfsig.rb +37 -0
  106. data/tests/tc_streams.rb +129 -0
  107. data/tests/ts_pdf.rb +45 -0
  108. metadata +193 -0
@@ -0,0 +1,180 @@
1
+ =begin
2
+
3
+ = File
4
+ graphics/patterns.rb
5
+
6
+ = Info
7
+ This file is part of Origami, PDF manipulation framework for Ruby
8
+ Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
9
+ All right reserved.
10
+
11
+ Origami is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU Lesser General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ Origami is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU Lesser General Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ =end
25
+
26
+ module Origami
27
+
28
+ module Graphics
29
+
30
+ module Pattern
31
+
32
+ module Type
33
+ TILING = 1
34
+ SHADING = 2
35
+ end
36
+
37
+ def self.included(receiver)
38
+ receiver.field :Type, :Type => Name, :Default => :Pattern
39
+ receiver.field :PatternType, :Type => Integer, :Required => true
40
+ end
41
+
42
+ class Tiling < ContentStream
43
+ include Pattern
44
+
45
+ module PaintType
46
+ COLOURED = 1
47
+ UNCOLOURED = 2
48
+ end
49
+
50
+ module Type
51
+ CONSTANT_SPACING = 1
52
+ NO_DISTORTION = 2
53
+ CONSTANT_SPACING_AND_FASTER_TILING = 3
54
+ end
55
+
56
+ field :PatternType, :Type => Integer, :Default => Pattern::Type::TILING, :Required => true
57
+ field :PaintType, :Type => Integer, :Required => true
58
+ field :TilingType, :Type => Integer, :Required => true
59
+ field :BBox, :Type => Array, :Required => true
60
+ field :XStep, :Type => Number, :Required => true
61
+ field :YStep, :Type => Number, :Required => true
62
+ field :Resources, :Type => Dictionary, :Required => true
63
+ field :Matrix, :Type => Array, :Default => [ 1, 0, 0, 1, 0, 0 ]
64
+
65
+ end
66
+
67
+ class Shading < Dictionary
68
+ include StandardObject
69
+ include Pattern
70
+
71
+ module Type
72
+ FUNCTIONBASED = 1
73
+ AXIAL = 2
74
+ RADIAL = 3
75
+ FREEFORM_TRIANGLE_MESH = 4
76
+ LATTICEFORM_TRIANGLE_MESH = 5
77
+ COONS_PATCH_MESH = 6
78
+ TENSORPRODUCT_PATCH_MESH = 7
79
+ end
80
+
81
+ field :PatternType, :Type => Integer, :Default => Pattern::Type::SHADING, :Required => true
82
+ field :Shading, :Type => [ Dictionary, Stream ], :Required => true
83
+ field :Matrix, :Type => Array, :Default => [ 1, 0, 0, 1, 0, 0 ]
84
+ field :ExtGState, :Type => Dictionary
85
+
86
+ module ShadingObject
87
+ def self.included(receiver)
88
+ receiver.field :ShadingType, :Type => Integer, :Required => true
89
+ receiver.field :ColorSpace, :Type => [ Name, Array ], :Required => true
90
+ receiver.field :Background, :Type => Array
91
+ receiver.field :BBox, :Type => Array
92
+ receiver.field :AntiAlias, :Type => Boolean, :Default => false
93
+ end
94
+ end
95
+
96
+ class FunctionBased < Dictionary
97
+ include StandardObject
98
+ include ShadingObject
99
+
100
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::FUNCTIONBASED, :Required => true
101
+ field :Domain, :Type => Array, :Default => [ 0.0, 1.0, 0.0, 1.0 ]
102
+ field :Matrix, :Type => Array, :Default => [ 1, 0, 0, 1, 0, 0 ]
103
+ field :Function, :Type => [ Dictionary, Stream ], :Required => true
104
+ end
105
+
106
+ class Axial < Dictionary
107
+ include StandardObject
108
+ include ShadingObject
109
+
110
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::AXIAL, :Required => true
111
+ field :Coords, :Type => Array, :Required => true
112
+ field :Domain, :Type => Array, :Default => [ 0.0, 1.0 ]
113
+ field :Function, :Type => [ Dictionary, Stream ], :Required => true
114
+ field :Extend, :Type => Array, :Default => [ false, false ]
115
+ end
116
+
117
+ class Radial < Dictionary
118
+ include StandardObject
119
+ include ShadingObject
120
+
121
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::RADIAL, :Required => true
122
+ field :Coords, :Type => Array, :Required => true
123
+ field :Domain, :Type => Array, :Default => [ 0.0, 1.0 ]
124
+ field :Function, :Type => [ Dictionary, Stream ], :Required => true
125
+ field :Extend, :Type => Array, :Default => [ false, false ]
126
+ end
127
+
128
+ class FreeFormTriangleMesh < Stream
129
+ include ShadingObject
130
+
131
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::FREEFORM_TRIANGLE_MESH, :Required => true
132
+ field :BitsPerCoordinate, :Type => Integer, :Required => true
133
+ field :BitsPerComponent, :Type => Integer, :Required => true
134
+ field :BitsPerFlag, :Type => Integer, :Required => true
135
+ field :Decode, :Type => Array, :Required => true
136
+ field :Function, :Type => [ Dictionary, Stream ]
137
+ end
138
+
139
+ class LatticeFormTriangleMesh < Stream
140
+ include ShadingObject
141
+
142
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::LATTICEFORM_TRIANGLE_MESH, :Required => true
143
+ field :BitsPerCoordinate, :Type => Integer, :Required => true
144
+ field :BitsPerComponent, :Type => Integer, :Required => true
145
+ field :VerticesPerRow, :Type => Integer, :Required => true
146
+ field :Decode, :Type => Array, :Required => true
147
+ field :Function, :Type => [ Dictionary, Stream ]
148
+ end
149
+
150
+ class CoonsPathMesh < Stream
151
+ include ShadingObject
152
+
153
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::COONS_PATCH_MESH, :Required => true
154
+ field :BitsPerCoordinate, :Type => Integer, :Required => true
155
+ field :BitsPerComponent, :Type => Integer, :Required => true
156
+ field :BitsPerFlag, :Type => Integer, :Required => true
157
+ field :Decode, :Type => Array, :Required => true
158
+ field :Function, :Type => [ Dictionary, Stream ]
159
+ end
160
+
161
+ class TensorProductPatchMesh < Stream
162
+ include ShadingObject
163
+
164
+ field :ShadingType, :Type => Integer, :Default => Shading::Type::TENSORPRODUCT_PATCH_MESH, :Required => true
165
+ field :BitsPerCoordinate, :Type => Integer, :Required => true
166
+ field :BitsPerComponent, :Type => Integer, :Required => true
167
+ field :BitsPerFlag, :Type => Integer, :Required => true
168
+ field :Decode, :Type => Array, :Required => true
169
+ field :Function, :Type => [ Dictionary, Stream ]
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ class PDF::Instruction
176
+ insn 'sh', Name
177
+ end
178
+
179
+ end
180
+
@@ -0,0 +1,164 @@
1
+ =begin
2
+
3
+ = File
4
+ graphics/state.rb
5
+
6
+ = Info
7
+ This file is part of Origami, PDF manipulation framework for Ruby
8
+ Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
9
+ All right reserved.
10
+
11
+ Origami is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU Lesser General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ Origami is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU Lesser General Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ =end
25
+
26
+ require 'matrix'
27
+
28
+ module Origami
29
+
30
+ module Graphics
31
+
32
+ class GraphicsStateError < Exception #:nodoc:
33
+ end
34
+
35
+ class State
36
+
37
+ #
38
+ # Device-independent parameters.
39
+ #
40
+ attr_accessor :ctm
41
+ attr_accessor :clipping_path
42
+ attr_accessor :stroking_colorspace, :nonstroking_colorspace, :stroking_color, :nonstroking_color
43
+ attr_accessor :text_state
44
+ attr_accessor :line_width, :line_cap, :line_join, :miter_limit, :dash_pattern
45
+ attr_accessor :rendering_intent
46
+ attr_accessor :stroke_adjustment
47
+ attr_accessor :blend_mode, :soft_mask, :alpha_constant, :alpha_source
48
+
49
+ attr_reader :current_path
50
+
51
+ def initialize
52
+
53
+ @stack = []
54
+ @current_path = []
55
+ @text_state = Text::State.new
56
+
57
+ self.reset
58
+ end
59
+
60
+ def reset
61
+
62
+ @ctm = Matrix.identity(3)
63
+ @clipping_path = nil
64
+ @stroking_colorspace = @nonstroking_colorspace = Color::Space::DEVICE_GRAY
65
+ @stroking_color = @nonstroking_color = [ 0.0 ] #black
66
+ @text_state.reset
67
+ @line_width = 1.0
68
+ @line_cap = LineCapStyle::BUTT_CAP
69
+ @line_join = LineJoinStyle::MITER_JOIN
70
+ @miter_limit = 10.0
71
+ @dash_pattern = DashPattern.new([], 0)
72
+ @rendering_intent = RenderingIntent::RELATIVE_COLORIMETRIC
73
+ @stroke_adjustment = false
74
+ @blend_mode = BlendMode::NORMAL
75
+ @soft_mask = :None
76
+ @alpha_constant = 1.0
77
+ @alpha_source = false
78
+
79
+ end
80
+
81
+ def save
82
+ context =
83
+ [
84
+ @ctm, @clipping_path,
85
+ @stroking_colorspace, @nonstroking_colorspace,
86
+ @stroking_color, @nonstroking_color,
87
+ @text_state, @line_width, @line_cap, @line_join,
88
+ @miter_limit, @dash_pattern, @rendering_intent,
89
+ @stroke_adjustment,
90
+ @blend_mode, @soft_mask, @alpha_constant, @alpha_source
91
+ ]
92
+ @stack.push(context)
93
+ end
94
+
95
+ def restore
96
+ raise GraphicsStateError, "Cannot restore context : empty stack" if @stack.empty?
97
+
98
+ @ctm, @clipping_path,
99
+ @stroking_colorspace, @nonstroking_colorspace,
100
+ @stroking_color, @nonstroking_color,
101
+ @text_state, @line_width, @line_cap, @line_join,
102
+ @miter_limit, @dash_pattern, @rendering_intent,
103
+ @stroke_adjustment,
104
+ @blend_mode, @soft_mask, @alpha_constant, @alpha_source = @stack.pop
105
+ end
106
+
107
+ end
108
+
109
+ #
110
+ # Generic Graphic state
111
+ # 4.3.4 Graphics State Parameter Dictionaries p219
112
+ #
113
+ class ExtGState < Dictionary
114
+
115
+ include StandardObject
116
+
117
+ field :Type, :Type => Name, :Default => :ExtGState, :Required => true
118
+ field :LW, :Type => Integer, :Version => "1.3"
119
+ field :LC, :Type => Integer, :Version => "1.3"
120
+ field :LJ, :Type => Integer, :Version => "1.3"
121
+ field :ML, :Type => Number, :Version => "1.3"
122
+ field :D, :Type => Array, :Version => "1.3"
123
+ field :RI, :Type => Name, :Version => "1.3"
124
+ field :OP, :Type => Boolean
125
+ field :op, :Type => Boolean, :Version => "1.3"
126
+ field :OPM, :Type => Number, :Version => "1.3"
127
+ field :Font, :Type => Array, :Version => "1.3"
128
+ field :BG, :Type => Object
129
+ field :BG2, :Type => Object, :Version => "1.3"
130
+ field :UCR, :Type => Object
131
+ field :UCR2, :Type => Object, :Version => "1.3"
132
+ field :TR, :Type => Object
133
+ field :TR2, :Type => Object, :Version => "1.3"
134
+ field :HT, :Type => [ Dictionary, Name, Stream ]
135
+ field :FL, :Type => Number, :Version => "1.3"
136
+ field :SM, :Type => Number, :Version => "1.3"
137
+ field :SA, :Type => Boolean
138
+ field :BM, :Type => [ Name, Array ], :Version => "1.4"
139
+ field :SMask, :Type => [ Dictionary, Array ], :Version => "1.4"
140
+ field :CA, :Type => Number
141
+ field :ca, :Type => Number, :Version => "1.4"
142
+ field :AIS, :Type => Boolean, :Version => "1.4"
143
+ field :TK, :Type => Boolean, :Version => "1.4"
144
+
145
+ end # class ExtGState
146
+
147
+ end #module Graphics
148
+
149
+ class PDF::Instruction
150
+ insn 'q' do |gs| gs.save; gs.reset end
151
+ insn 'Q' do |gs| gs.restore end
152
+ insn 'w', Real do |gs, lw| gs.line_width = lw end
153
+ insn 'J', Real do |gs, lc| gs.line_cap = lc end
154
+ insn 'j', Real do |gs, lj| gs.line_join = lj end
155
+ insn 'M', Real do |gs, ml| gs.miter_limit = ml end
156
+
157
+ insn 'd', Array, Integer do |gs, array, phase|
158
+ gs.dash_pattern = Graphics::DashPattern.new array, phase
159
+ end
160
+
161
+ insn 'ri', Name do |gs, ri| gs.rendering_intent = ri end
162
+ end
163
+ end
164
+
@@ -0,0 +1,224 @@
1
+ =begin
2
+
3
+ = File
4
+ graphics/text.rb
5
+
6
+ = Info
7
+ This file is part of Origami, PDF manipulation framework for Ruby
8
+ Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
9
+ All right reserved.
10
+
11
+ Origami is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU Lesser General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ Origami is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU Lesser General Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ =end
25
+
26
+ module Origami
27
+
28
+ module Text
29
+
30
+ OPERATORS =
31
+ [
32
+ 'Tc', 'Tw', 'Tz', 'TL', 'Tf', 'Tr', 'Ts', # Text state
33
+ 'BT', 'ET', # Text objects
34
+ 'Td', 'TD', 'Tm', 'T*', # Positioning
35
+ 'Tj', "'", '"', 'TJ' # Showing
36
+ ]
37
+
38
+ module Rendering
39
+ FILL = 0
40
+ STROKE = 1
41
+ FILL_AND_STROKE = 2
42
+ INVISIBLE = 3
43
+ FILL_AND_CLIP = 4
44
+ STROKE_AND_CLIP = 5
45
+ FILL_AND_STROKE_AND_CLIP = 6
46
+ CLIP = 7
47
+ end
48
+
49
+ class TextStateError < Exception #:nodoc:
50
+ end
51
+
52
+ class State
53
+
54
+ attr_accessor :char_spacing, :word_spacing, :scaling, :leading
55
+ attr_accessor :font, :font_size
56
+ attr_accessor :rendering_mode
57
+ attr_accessor :text_rise, :text_knockout
58
+
59
+ attr_accessor :text_matrix, :text_line_matrix, :text_rendering_matrix
60
+
61
+ def initialize
62
+ self.reset
63
+ end
64
+
65
+ def reset
66
+
67
+ @char_spacing = 0
68
+ @word_spacing = 0
69
+ @scaling = 100
70
+ @leading = 0
71
+ @font = nil
72
+ @font_size = nil
73
+ @rendering_mode = Rendering::FILL
74
+ @text_rise = 0
75
+ @text_knockout = true
76
+
77
+ #
78
+ # Text objects
79
+ #
80
+
81
+ @text_object = false
82
+ @text_matrix =
83
+ @text_line_matrix =
84
+ @text_rendering_matrix = nil
85
+
86
+ end
87
+
88
+ def is_in_text_object?
89
+ @text_object
90
+ end
91
+
92
+ def begin_text_object
93
+ if is_in_text_object?
94
+ raise TextStateError,
95
+ "Cannot start a text object within an existing text object."
96
+ end
97
+
98
+ @text_object = true
99
+ @text_matrix =
100
+ @text_line_matrix =
101
+ @text_rendering_matrix = Matrix.identity(3)
102
+ end
103
+
104
+ def end_text_object
105
+ unless is_in_text_object?
106
+ raise TextStateError,
107
+ "Cannot end text object : no previous text object has begun."
108
+ end
109
+
110
+ @text_object = false
111
+ @text_matrix =
112
+ @text_line_matrix =
113
+ @text_rendering_matrix = nil
114
+ end
115
+
116
+ end #class State
117
+
118
+ end #module Text
119
+
120
+ class PDF::Instruction
121
+ # Text instructions definitions
122
+ insn 'Tc', Real do |gs, cS| gs.text_state.char_spacing = cS end
123
+ insn 'Tw', Real do |gs, wS| gs.text_state.word_spacing = wS end
124
+ insn 'Tz', Real do |gs, s| gs.text_state.scaling = s end
125
+ insn 'TL', Real do |gs, l| gs.text_state.leading = l end
126
+
127
+ insn 'Tf', Name, Real do |gs, font, size|
128
+ gs.text_state.font = font
129
+ gs.text_state.font_size = size
130
+ end
131
+
132
+ insn 'Tr', Integer do |gs, r| gs.text_state.rendering_mode = r end
133
+ insn 'Ts', Real do |gs, s| gs.text_state.text_rise = s end
134
+ insn 'BT' do |gs| gs.text_state.begin_text_object end
135
+ insn 'ET' do |gs| gs.text_state.end_text_object end
136
+
137
+ insn 'Td', Real, Real do |gs, tx, ty|
138
+ unless gs.text_state.is_in_text_object?
139
+ raise TextStateError,
140
+ "Must be in a text object to use operator : Td"
141
+ end
142
+
143
+ gs.text_state.text_matrix =
144
+ gs.text_state.text_line_matrix =
145
+ Matrix.rows([[1,0,0],[0,1,0],[tx, ty, 1]]) * gs.text_state.text_line_matrix
146
+ end
147
+
148
+ insn 'TD', Real, Real do |gs, tx, ty|
149
+ unless gs.text_state.is_in_text_object?
150
+ raise TextStateError,
151
+ "Must be in a text object to use operator : TD"
152
+ end
153
+
154
+ gs.text_state.leading = -ty
155
+
156
+ gs.text_state.text_matrix =
157
+ gs.text_state.text_line_matrix =
158
+ Matrix.rows([[1,0,0],[0,1,0],[tx,ty,1]]) * gs.text_state.text_line_matrix
159
+ end
160
+
161
+ insn 'Tm', Real, Real, Real, Real, Real, Real do |gs, a,b,c,d,e,f,g|
162
+ unless gs.text_state.is_in_text_object?
163
+ raise TextStateError,
164
+ "Must be in a text object to use operator : Tm"
165
+ end
166
+
167
+ gs.text_state.text_matrix =
168
+ gs.text_state.text_line_matrix =
169
+ Matrix.rows([[a,b,0],[c,d,0],[e,f,1]])
170
+ end
171
+
172
+ insn 'T*' do |gs|
173
+ unless gs.text_state.is_in_text_object?
174
+ raise TextStateError,
175
+ "Must be in a text object to use operator : T*"
176
+ end
177
+
178
+ tx, ty = 0, -gs.text_state.leading
179
+
180
+ gs.text_state.text_matrix =
181
+ gs.text_state.text_line_matrix =
182
+ Matrix.rows([[1,0,0],[0,1,0],[tx, ty, 1]]) * gs.text_state.text_line_matrix
183
+ end
184
+
185
+ insn 'Tj', String do |gs, s|
186
+ unless gs.text_state.is_in_text_object?
187
+ raise TextStateError,
188
+ "Must be in a text object to use operator : Tj"
189
+ end
190
+ end
191
+
192
+ insn "'", String do |gs, s|
193
+ unless gs.text_state.is_in_text_object?
194
+ raise TextStateError,
195
+ "Must be in a text object to use operator : '"
196
+ end
197
+
198
+ tx, ty = 0, -gs.text_state.leading
199
+
200
+ gs.text_state.text_matrix =
201
+ gs.text_state.text_line_matrix =
202
+ Matrix.rows([[1,0,0],[0,1,0],[tx, ty, 1]]) * gs.text_state.text_line_matrix
203
+ end
204
+
205
+ insn '"', Real, Real, String do |gs, w, c, s|
206
+ unless gs.text_state.is_in_text_object?
207
+ raise TextStateError,
208
+ "Must be in a text object to use operator : \""
209
+ end
210
+
211
+ gs.text_state.word_spacing = w
212
+ gs.text_state.char_spacing = c
213
+
214
+ tx, ty = 0, -gs.text_state.leading
215
+
216
+ gs.text_state.text_matrix =
217
+ gs.text_state.text_line_matrix =
218
+ Matrix.rows([[1,0,0],[0,1,0],[tx, ty, 1]]) * gs.text_state.text_line_matrix
219
+ end
220
+
221
+ insn 'TJ', Array
222
+ end
223
+
224
+ end