origami 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/bin/gui/config.rb +2 -1
  4. data/bin/gui/file.rb +118 -240
  5. data/bin/gui/gtkhex.rb +5 -5
  6. data/bin/gui/hexview.rb +20 -16
  7. data/bin/gui/imgview.rb +1 -1
  8. data/bin/gui/menu.rb +138 -158
  9. data/bin/gui/properties.rb +46 -48
  10. data/bin/gui/signing.rb +183 -214
  11. data/bin/gui/textview.rb +1 -1
  12. data/bin/gui/treeview.rb +13 -7
  13. data/bin/gui/walker.rb +102 -71
  14. data/bin/gui/xrefs.rb +1 -1
  15. data/bin/pdf2ruby +3 -3
  16. data/bin/pdfcop +18 -11
  17. data/bin/pdfextract +14 -5
  18. data/bin/pdfmetadata +3 -3
  19. data/bin/shell/console.rb +8 -8
  20. data/bin/shell/hexdump.rb +4 -4
  21. data/examples/attachments/nested_document.rb +1 -1
  22. data/examples/javascript/hello_world.rb +3 -3
  23. data/lib/origami.rb +0 -1
  24. data/lib/origami/acroform.rb +3 -3
  25. data/lib/origami/array.rb +1 -3
  26. data/lib/origami/boolean.rb +1 -3
  27. data/lib/origami/catalog.rb +3 -9
  28. data/lib/origami/destinations.rb +2 -2
  29. data/lib/origami/dictionary.rb +15 -29
  30. data/lib/origami/encryption.rb +334 -692
  31. data/lib/origami/extensions/fdf.rb +3 -2
  32. data/lib/origami/extensions/ppklite.rb +5 -9
  33. data/lib/origami/filespec.rb +2 -2
  34. data/lib/origami/filters.rb +54 -36
  35. data/lib/origami/filters/ascii.rb +67 -49
  36. data/lib/origami/filters/ccitt.rb +4 -236
  37. data/lib/origami/filters/ccitt/tables.rb +267 -0
  38. data/lib/origami/filters/crypt.rb +1 -1
  39. data/lib/origami/filters/dct.rb +0 -1
  40. data/lib/origami/filters/flate.rb +3 -43
  41. data/lib/origami/filters/lzw.rb +62 -99
  42. data/lib/origami/filters/predictors.rb +135 -105
  43. data/lib/origami/filters/runlength.rb +34 -22
  44. data/lib/origami/graphics.rb +2 -2
  45. data/lib/origami/graphics/colors.rb +89 -63
  46. data/lib/origami/graphics/path.rb +14 -14
  47. data/lib/origami/graphics/patterns.rb +31 -33
  48. data/lib/origami/graphics/render.rb +0 -1
  49. data/lib/origami/graphics/state.rb +9 -9
  50. data/lib/origami/graphics/text.rb +17 -17
  51. data/lib/origami/graphics/xobject.rb +102 -92
  52. data/lib/origami/javascript.rb +91 -68
  53. data/lib/origami/linearization.rb +22 -20
  54. data/lib/origami/metadata.rb +1 -1
  55. data/lib/origami/name.rb +1 -3
  56. data/lib/origami/null.rb +1 -3
  57. data/lib/origami/numeric.rb +3 -13
  58. data/lib/origami/object.rb +100 -72
  59. data/lib/origami/page.rb +24 -28
  60. data/lib/origami/parser.rb +34 -51
  61. data/lib/origami/parsers/fdf.rb +2 -2
  62. data/lib/origami/parsers/pdf.rb +41 -18
  63. data/lib/origami/parsers/pdf/lazy.rb +83 -46
  64. data/lib/origami/parsers/pdf/linear.rb +19 -10
  65. data/lib/origami/parsers/ppklite.rb +1 -1
  66. data/lib/origami/pdf.rb +150 -206
  67. data/lib/origami/reference.rb +4 -6
  68. data/lib/origami/signature.rb +76 -48
  69. data/lib/origami/stream.rb +69 -63
  70. data/lib/origami/string.rb +2 -19
  71. data/lib/origami/trailer.rb +25 -22
  72. data/lib/origami/version.rb +1 -1
  73. data/lib/origami/xfa.rb +6 -4
  74. data/lib/origami/xreftable.rb +29 -29
  75. data/test/test_annotations.rb +16 -38
  76. data/test/test_pdf_attachment.rb +1 -1
  77. data/test/test_pdf_parse.rb +1 -1
  78. data/test/test_xrefs.rb +2 -2
  79. metadata +4 -4
  80. data/lib/origami/export.rb +0 -247
@@ -99,12 +99,12 @@ module Origami
99
99
  end
100
100
 
101
101
  class PDF::Instruction
102
- insn 'm', Real, Real do |canvas, x,y|
102
+ insn 'm', Real, Real do |canvas, x,y|
103
103
  canvas.gs.current_path << (subpath = Graphics::Path.new)
104
104
  subpath.current_point = [x,y]
105
105
  end
106
106
 
107
- insn 'l', Real, Real do |canvas, x,y|
107
+ insn 'l', Real, Real do |canvas, x,y|
108
108
  if canvas.gs.current_path.empty?
109
109
  raise InvalidPathError, "No current point is defined"
110
110
  end
@@ -116,14 +116,14 @@ module Origami
116
116
  subpath.add_segment(Graphics::Path::Line.new(from, to))
117
117
  end
118
118
 
119
- insn 'h' do |canvas|
119
+ insn 'h' do |canvas|
120
120
  unless canvas.gs.current_path.empty?
121
121
  subpath = canvas.gs.current_path.last
122
122
  subpath.close! unless subpath.is_closed?
123
123
  end
124
124
  end
125
125
 
126
- insn 're', Real, Real, Real, Real do |canvas, x,y,width,height|
126
+ insn 're', Real, Real, Real, Real do |canvas, x,y,width,height|
127
127
  tx = x + width
128
128
  ty = y + height
129
129
  canvas.gs.current_path << (subpath = Graphics::Path.new)
@@ -133,50 +133,50 @@ module Origami
133
133
  subpath.close!
134
134
  end
135
135
 
136
- insn 'S' do |canvas|
136
+ insn 'S' do |canvas|
137
137
  canvas.stroke_path
138
138
  end
139
139
 
140
- insn 's' do |canvas|
140
+ insn 's' do |canvas|
141
141
  canvas.gs.current_path.last.close!
142
142
  canvas.stroke_path
143
143
  end
144
144
 
145
- insn 'f' do |canvas|
145
+ insn 'f' do |canvas|
146
146
  canvas.fill_path
147
147
  end
148
148
 
149
- insn 'F' do |canvas|
149
+ insn 'F' do |canvas|
150
150
  canvas.fill_path
151
151
  end
152
152
 
153
- insn 'f*' do |canvas|
153
+ insn 'f*' do |canvas|
154
154
  canvas.fill_path
155
155
  end
156
156
 
157
- insn 'B' do |canvas|
157
+ insn 'B' do |canvas|
158
158
  canvas.fill_path
159
159
  canvas.stroke_path
160
160
  end
161
161
 
162
- insn 'B*' do |canvas|
162
+ insn 'B*' do |canvas|
163
163
  canvas.fill_path
164
164
  canvas.stroke_path
165
165
  end
166
166
 
167
- insn 'b' do |canvas|
167
+ insn 'b' do |canvas|
168
168
  canvas.gs.current_path.last.close!
169
169
  canvas.fill_path
170
170
  canvas.stroke_path
171
171
  end
172
172
 
173
- insn 'b*' do |canvas|
173
+ insn 'b*' do |canvas|
174
174
  canvas.gs.current_path.last.close!
175
175
  canvas.fill_path
176
176
  canvas.stroke_path
177
177
  end
178
178
 
179
- insn 'n'
179
+ insn 'n'
180
180
  end
181
181
 
182
182
  end
@@ -51,11 +51,11 @@ module Origami
51
51
  field :PatternType, :Type => Integer, :Default => Pattern::Type::TILING, :Required => true
52
52
  field :PaintType, :Type => Integer, :Required => true
53
53
  field :TilingType, :Type => Integer, :Required => true
54
- field :BBox, :Type => Array, :Required => true
54
+ field :BBox, :Type => Rectangle, :Required => true
55
55
  field :XStep, :Type => Number, :Required => true
56
56
  field :YStep, :Type => Number, :Required => true
57
57
  field :Resources, :Type => Resources, :Required => true
58
- field :Matrix, :Type => Array, :Default => [ 1, 0, 0, 1, 0, 0 ]
58
+ field :Matrix, :Type => Array.of(Number, length: 6), :Default => [ 1, 0, 0, 1, 0, 0 ]
59
59
  end
60
60
 
61
61
  class Shading < Dictionary
@@ -63,37 +63,48 @@ module Origami
63
63
  include Pattern
64
64
 
65
65
  module Type
66
- FUNCTIONBASED = 1
66
+ FUNCTION_BASED = 1
67
67
  AXIAL = 2
68
68
  RADIAL = 3
69
69
  FREEFORM_TRIANGLE_MESH = 4
70
70
  LATTICEFORM_TRIANGLE_MESH = 5
71
71
  COONS_PATCH_MESH = 6
72
- TENSORPRODUCT_PATCH_MESH = 7
72
+ TENSORPRODUCT_PATCH_MESH = 7
73
73
  end
74
74
 
75
75
  field :PatternType, :Type => Integer, :Default => Pattern::Type::SHADING, :Required => true
76
76
  field :Shading, :Type => [ Dictionary, Stream ], :Required => true
77
- field :Matrix, :Type => Array, :Default => [ 1, 0, 0, 1, 0, 0 ]
78
- field :ExtGState, :Type => Dictionary
77
+ field :Matrix, :Type => Array.of(Number, length: 6), :Default => [ 1, 0, 0, 1, 0, 0 ]
78
+ field :ExtGState, :Type => ExtGState
79
79
 
80
+ # Fields common to all shading objects.
80
81
  module ShadingObject
81
82
  def self.included(receiver)
82
83
  receiver.field :ShadingType, :Type => Integer, :Required => true
83
84
  receiver.field :ColorSpace, :Type => [ Name, Array ], :Required => true
84
85
  receiver.field :Background, :Type => Array
85
- receiver.field :BBox, :Type => Array
86
+ receiver.field :BBox, :Type => Rectangle
86
87
  receiver.field :AntiAlias, :Type => Boolean, :Default => false
87
88
  end
88
89
  end
89
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
+
90
101
  class FunctionBased < Dictionary
91
102
  include StandardObject
92
103
  include ShadingObject
93
104
 
94
- field :ShadingType, :Type => Integer, :Default => Shading::Type::FUNCTIONBASED, :Required => true
95
- field :Domain, :Type => Array, :Default => [ 0.0, 1.0, 0.0, 1.0 ]
96
- field :Matrix, :Type => Array, :Default => [ 1, 0, 0, 1, 0, 0 ]
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 ]
97
108
  field :Function, :Type => [ Dictionary, Stream ], :Required => true
98
109
  end
99
110
 
@@ -102,10 +113,10 @@ module Origami
102
113
  include ShadingObject
103
114
 
104
115
  field :ShadingType, :Type => Integer, :Default => Shading::Type::AXIAL, :Required => true
105
- field :Coords, :Type => Array, :Required => true
106
- field :Domain, :Type => Array, :Default => [ 0.0, 1.0 ]
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 ]
107
118
  field :Function, :Type => [ Dictionary, Stream ], :Required => true
108
- field :Extend, :Type => Array, :Default => [ false, false ]
119
+ field :Extend, :Type => Array.of(Boolean, length: 2), :Default => [ false, false ]
109
120
  end
110
121
 
111
122
  class Radial < Dictionary
@@ -113,54 +124,41 @@ module Origami
113
124
  include ShadingObject
114
125
 
115
126
  field :ShadingType, :Type => Integer, :Default => Shading::Type::RADIAL, :Required => true
116
- field :Coords, :Type => Array, :Required => true
117
- field :Domain, :Type => Array, :Default => [ 0.0, 1.0 ]
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 ]
118
129
  field :Function, :Type => [ Dictionary, Stream ], :Required => true
119
- field :Extend, :Type => Array, :Default => [ false, false ]
130
+ field :Extend, :Type => Array.of(Boolean, length: 2), :Default => [ false, false ]
120
131
  end
121
132
 
122
133
  class FreeFormTriangleMesh < Stream
123
134
  include ShadingObject
135
+ include Mesh
124
136
 
125
137
  field :ShadingType, :Type => Integer, :Default => Shading::Type::FREEFORM_TRIANGLE_MESH, :Required => true
126
- field :BitsPerCoordinate, :Type => Integer, :Required => true
127
- field :BitsPerComponent, :Type => Integer, :Required => true
128
138
  field :BitsPerFlag, :Type => Integer, :Required => true
129
- field :Decode, :Type => Array, :Required => true
130
- field :Function, :Type => [ Dictionary, Stream ]
131
139
  end
132
140
 
133
141
  class LatticeFormTriangleMesh < Stream
134
142
  include ShadingObject
143
+ include Mesh
135
144
 
136
145
  field :ShadingType, :Type => Integer, :Default => Shading::Type::LATTICEFORM_TRIANGLE_MESH, :Required => true
137
- field :BitsPerCoordinate, :Type => Integer, :Required => true
138
- field :BitsPerComponent, :Type => Integer, :Required => true
139
146
  field :VerticesPerRow, :Type => Integer, :Required => true
140
- field :Decode, :Type => Array, :Required => true
141
- field :Function, :Type => [ Dictionary, Stream ]
142
147
  end
143
148
 
144
149
  class CoonsPathMesh < Stream
145
150
  include ShadingObject
151
+ include Mesh
146
152
 
147
153
  field :ShadingType, :Type => Integer, :Default => Shading::Type::COONS_PATCH_MESH, :Required => true
148
- field :BitsPerCoordinate, :Type => Integer, :Required => true
149
- field :BitsPerComponent, :Type => Integer, :Required => true
150
154
  field :BitsPerFlag, :Type => Integer, :Required => true
151
- field :Decode, :Type => Array, :Required => true
152
- field :Function, :Type => [ Dictionary, Stream ]
153
155
  end
154
156
 
155
157
  class TensorProductPatchMesh < Stream
156
158
  include ShadingObject
157
159
 
158
160
  field :ShadingType, :Type => Integer, :Default => Shading::Type::TENSORPRODUCT_PATCH_MESH, :Required => true
159
- field :BitsPerCoordinate, :Type => Integer, :Required => true
160
- field :BitsPerComponent, :Type => Integer, :Required => true
161
161
  field :BitsPerFlag, :Type => Integer, :Required => true
162
- field :Decode, :Type => Array, :Required => true
163
- field :Function, :Type => [ Dictionary, Stream ]
164
162
  end
165
163
  end
166
164
 
@@ -168,7 +166,7 @@ module Origami
168
166
  end
169
167
 
170
168
  class PDF::Instruction
171
- insn 'sh', Name
169
+ insn 'sh', Name
172
170
  end
173
171
 
174
172
  end
@@ -59,4 +59,3 @@ module Origami
59
59
 
60
60
  end
61
61
  end
62
-
@@ -133,17 +133,17 @@ module Origami
133
133
  end #module Graphics
134
134
 
135
135
  class PDF::Instruction
136
- insn 'q' do |canvas| canvas.gs.save; canvas.gs.reset end
137
- insn 'Q' do |canvas| canvas.gs.restore end
138
- insn 'w', Real do |canvas, lw| canvas.gs.line_width = lw end
139
- insn 'J', Real do |canvas, lc| canvas.gs.line_cap = lc end
140
- insn 'j', Real do |canvas, lj| canvas.gs.line_join = lj end
141
- insn 'M', Real do |canvas, ml| canvas.gs.miter_limit = ml end
142
-
143
- insn 'd', Array, Integer do |canvas, array, phase|
136
+ insn 'q' do |canvas| canvas.gs.save; canvas.gs.reset end
137
+ insn 'Q' do |canvas| canvas.gs.restore end
138
+ insn 'w', Real do |canvas, lw| canvas.gs.line_width = lw end
139
+ insn 'J', Real do |canvas, lc| canvas.gs.line_cap = lc end
140
+ insn 'j', Real do |canvas, lj| canvas.gs.line_join = lj end
141
+ insn 'M', Real do |canvas, ml| canvas.gs.miter_limit = ml end
142
+
143
+ insn 'd', Array, Integer do |canvas, array, phase|
144
144
  canvas.gs.dash_pattern = Graphics::DashPattern.new array, phase
145
145
  end
146
146
 
147
- insn 'ri', Name do |canvas, ri| canvas.gs.rendering_intent = ri end
147
+ insn 'ri', Name do |canvas, ri| canvas.gs.rendering_intent = ri end
148
148
  end
149
149
  end
@@ -109,22 +109,22 @@ module Origami
109
109
  #
110
110
  # Text instructions definitions
111
111
  #
112
- insn 'Tc', Real do |canvas, cS| canvas.gs.text_state.char_spacing = cS end
113
- insn 'Tw', Real do |canvas, wS| canvas.gs.text_state.word_spacing = wS end
114
- insn 'Tz', Real do |canvas, s| canvas.gs.text_state.scaling = s end
115
- insn 'TL', Real do |canvas, l| canvas.gs.text_state.leading = l end
112
+ insn 'Tc', Real do |canvas, cS| canvas.gs.text_state.char_spacing = cS end
113
+ insn 'Tw', Real do |canvas, wS| canvas.gs.text_state.word_spacing = wS end
114
+ insn 'Tz', Real do |canvas, s| canvas.gs.text_state.scaling = s end
115
+ insn 'TL', Real do |canvas, l| canvas.gs.text_state.leading = l end
116
116
 
117
- insn 'Tf', Name, Real do |canvas, font, size|
117
+ insn 'Tf', Name, Real do |canvas, font, size|
118
118
  canvas.gs.text_state.font = font
119
119
  canvas.gs.text_state.font_size = size
120
120
  end
121
121
 
122
- insn 'Tr', Integer do |canvas, r| canvas.gs.text_state.rendering_mode = r end
123
- insn 'Ts', Real do |canvas, s| canvas.gs.text_state.text_rise = s end
124
- insn 'BT' do |canvas| canvas.gs.text_state.begin_text_object end
125
- insn 'ET' do |canvas| canvas.gs.text_state.end_text_object end
122
+ insn 'Tr', Integer do |canvas, r| canvas.gs.text_state.rendering_mode = r end
123
+ insn 'Ts', Real do |canvas, s| canvas.gs.text_state.text_rise = s end
124
+ insn 'BT' do |canvas| canvas.gs.text_state.begin_text_object end
125
+ insn 'ET' do |canvas| canvas.gs.text_state.end_text_object end
126
126
 
127
- insn 'Td', Real, Real do |canvas, tx, ty|
127
+ insn 'Td', Real, Real do |canvas, tx, ty|
128
128
  unless canvas.gs.text_state.is_in_text_object?
129
129
  raise TextStateError, "Must be in a text object to use operator : Td"
130
130
  end
@@ -134,7 +134,7 @@ module Origami
134
134
  Matrix.rows([[1,0,0],[0,1,0],[tx, ty, 1]]) * canvas.gs.text_state.text_line_matrix
135
135
  end
136
136
 
137
- insn 'TD', Real, Real do |canvas, tx, ty|
137
+ insn 'TD', Real, Real do |canvas, tx, ty|
138
138
  unless canvas.gs.text_state.is_in_text_object?
139
139
  raise TextStateError, "Must be in a text object to use operator : TD"
140
140
  end
@@ -146,7 +146,7 @@ module Origami
146
146
  Matrix.rows([[1,0,0],[0,1,0],[tx,ty,1]]) * canvas.gs.text_state.text_line_matrix
147
147
  end
148
148
 
149
- insn 'Tm', Real, Real, Real, Real, Real, Real do |canvas, a,b,c,d,e,f,g|
149
+ insn 'Tm', Real, Real, Real, Real, Real, Real do |canvas, a, b, c, d, e, f|
150
150
  unless canvas.gs.text_state.is_in_text_object?
151
151
  raise TextStateError, "Must be in a text object to use operator : Tm"
152
152
  end
@@ -156,7 +156,7 @@ module Origami
156
156
  Matrix.rows([[a,b,0],[c,d,0],[e,f,1]])
157
157
  end
158
158
 
159
- insn 'T*' do |canvas|
159
+ insn 'T*' do |canvas|
160
160
  unless canvas.gs.text_state.is_in_text_object?
161
161
  raise TextStateError, "Must be in a text object to use operator : T*"
162
162
  end
@@ -168,7 +168,7 @@ module Origami
168
168
  Matrix.rows([[1,0,0],[0,1,0],[tx, ty, 1]]) * canvas.gs.text_state.text_line_matrix
169
169
  end
170
170
 
171
- insn 'Tj', String do |canvas, s|
171
+ insn 'Tj', String do |canvas, s|
172
172
  unless canvas.gs.text_state.is_in_text_object?
173
173
  raise TextStateError, "Must be in a text object to use operator : Tj"
174
174
  end
@@ -176,7 +176,7 @@ module Origami
176
176
  canvas.write_text(s)
177
177
  end
178
178
 
179
- insn "'", String do |canvas, s|
179
+ insn "'", String do |canvas, s|
180
180
  unless canvas.gs.text_state.is_in_text_object?
181
181
  raise TextStateError, "Must be in a text object to use operator : '"
182
182
  end
@@ -190,7 +190,7 @@ module Origami
190
190
  canvas.write_text(s)
191
191
  end
192
192
 
193
- insn '"', Real, Real, String do |canvas, w, c, s|
193
+ insn '"', Real, Real, String do |canvas, w, c, s|
194
194
  unless canvas.gs.text_state.is_in_text_object?
195
195
  raise TextStateError, "Must be in a text object to use operator : \""
196
196
  end
@@ -207,7 +207,7 @@ module Origami
207
207
  canvas.write_text(s)
208
208
  end
209
209
 
210
- insn 'TJ', Array do |canvas, arr|
210
+ insn 'TJ', Array do |canvas, arr|
211
211
  arr.each do |g|
212
212
  case g
213
213
  when Fixnum,Float then
@@ -45,7 +45,7 @@ module Origami
45
45
  end
46
46
 
47
47
  def render(engine)
48
- load! if @instructions.nil?
48
+ load!
49
49
 
50
50
  @instructions.each do |instruction|
51
51
  instruction.render(engine)
@@ -67,13 +67,13 @@ module Origami
67
67
  end
68
68
 
69
69
  def instructions
70
- load! if @instructions.nil?
70
+ load!
71
71
 
72
72
  @instructions
73
73
  end
74
74
 
75
75
  def draw_image(name, attr = {})
76
- load! if @instructions.nil?
76
+ load!
77
77
 
78
78
  x, y = attr[:x], attr[:y]
79
79
 
@@ -94,14 +94,14 @@ module Origami
94
94
  # Draw a polygon from a array of coordinates.
95
95
  #
96
96
  def draw_polygon(coords = [], attr = {})
97
- load! if @instructions.nil?
97
+ load!
98
98
 
99
- stroke_color = attr[:stroke_color] || DEFAULT_STROKE_COLOR
100
- fill_color = attr[:fill_color] || DEFAULT_FILL_COLOR
101
- line_cap = attr[:line_cap] || DEFAULT_LINECAP
102
- line_join = attr[:line_join] || DEFAULT_LINEJOIN
103
- line_width = attr[:line_width] || DEFAULT_LINEWIDTH
104
- dash_pattern = attr[:dash] || DEFAULT_DASHPATTERN
99
+ stroke_color = attr.fetch(:stroke_color, DEFAULT_STROKE_COLOR)
100
+ fill_color = attr.fetch(:fill_color, DEFAULT_FILL_COLOR)
101
+ line_cap = attr.fetch(:line_cap, DEFAULT_LINECAP)
102
+ line_join = attr.fetch(:line_join, DEFAULT_LINEJOIN)
103
+ line_width = attr.fetch(:line_width, DEFAULT_LINEWIDTH)
104
+ dash_pattern = attr.fetch(:dash, DEFAULT_DASHPATTERN)
105
105
 
106
106
  stroke = attr[:stroke].nil? ? true : attr[:stroke]
107
107
  fill = attr[:fill].nil? ? false : attr[:fill]
@@ -147,14 +147,14 @@ module Origami
147
147
  # Draw a rectangle at position (_x_,_y_) with defined _width_ and _height_.
148
148
  #
149
149
  def draw_rectangle(x, y, width, height, attr = {})
150
- load! if @instructions.nil?
150
+ load!
151
151
 
152
- stroke_color = attr[:stroke_color] || DEFAULT_STROKE_COLOR
153
- fill_color = attr[:fill_color] || DEFAULT_FILL_COLOR
154
- line_cap = attr[:line_cap] || DEFAULT_LINECAP
155
- line_join = attr[:line_join] || DEFAULT_LINEJOIN
156
- line_width = attr[:line_width] || DEFAULT_LINEWIDTH
157
- dash_pattern = attr[:dash] || DEFAULT_DASHPATTERN
152
+ stroke_color = attr.fetch(:stroke_color, DEFAULT_STROKE_COLOR)
153
+ fill_color = attr.fetch(:fill_color, DEFAULT_FILL_COLOR)
154
+ line_cap = attr.fetch(:line_cap, DEFAULT_LINECAP)
155
+ line_join = attr.fetch(:line_join, DEFAULT_LINEJOIN)
156
+ line_width = attr.fetch(:line_width, DEFAULT_LINEWIDTH)
157
+ dash_pattern = attr.fetch(:dash, DEFAULT_DASHPATTERN)
158
158
 
159
159
  stroke = attr[:stroke].nil? ? true : attr[:stroke]
160
160
  fill = attr[:fill].nil? ? false : attr[:fill]
@@ -195,20 +195,20 @@ module Origami
195
195
  # _attr_:: Formatting attributes.
196
196
  #
197
197
  def write(text, attr = {})
198
- load! if @instructions.nil?
199
-
200
- x,y = attr[:x], attr[:y]
201
- font = attr[:font] || DEFAULT_FONT
202
- size = attr[:size] || DEFAULT_SIZE
203
- leading = attr[:leading] || DEFAULT_LEADING
204
- color = attr[:color] || attr[:fill_color] || DEFAULT_STROKE_COLOR
205
- stroke_color = attr[:stroke_color] || DEFAULT_STROKE_COLOR
206
- line_width = attr[:line_width] || DEFAULT_LINEWIDTH
207
- word_spacing = attr[:word_spacing]
208
- char_spacing = attr[:char_spacing]
209
- scale = attr[:scale]
210
- rise = attr[:rise]
211
- rendering = attr[:rendering]
198
+ load!
199
+
200
+ x, y = attr[:x], attr[:y]
201
+ font = attr.fetch(:font, DEFAULT_FONT)
202
+ size = attr.fetch(:size, DEFAULT_SIZE)
203
+ leading = attr.fetch(:leading, DEFAULT_LEADING)
204
+ color = attr.fetch(:color, attr.fetch(:fill_color, DEFAULT_STROKE_COLOR))
205
+ stroke_color = attr.fetch(:stroke_color, DEFAULT_STROKE_COLOR)
206
+ line_width = attr.fetch(:line_width, DEFAULT_LINEWIDTH)
207
+ word_spacing = attr.fetch(:word_spacing, @canvas.gs.text_state.word_spacing)
208
+ char_spacing = attr.fetch(:char_spacing, @canvas.gs.text_state.char_spacing)
209
+ scale = attr.fetch(:scale, @canvas.gs.text_state.scaling)
210
+ rise = attr.fetch(:rise, @canvas.gs.text_state.text_rise)
211
+ rendering = attr.fetch(:rendering, @canvas.gs.text_state.rendering_mode)
212
212
 
213
213
  @instructions << PDF::Instruction.new('ET').render(@canvas) if (x or y) and @canvas.gs.text_state.is_in_text_object?
214
214
 
@@ -218,12 +218,12 @@ module Origami
218
218
 
219
219
  set_text_font(font, size)
220
220
  set_text_pos(x, y) if x or y
221
- set_text_leading(leading) if leading
222
- set_text_rendering(rendering) if rendering
223
- set_text_rise(rise) if rise
224
- set_text_scale(scale) if scale
225
- set_text_word_spacing(word_spacing) if word_spacing
226
- set_text_char_spacing(char_spacing) if char_spacing
221
+ set_text_leading(leading)
222
+ set_text_rendering(rendering)
223
+ set_text_rise(rise)
224
+ set_text_scale(scale)
225
+ set_text_word_spacing(word_spacing)
226
+ set_text_char_spacing(char_spacing)
227
227
  set_fill_color(color)
228
228
  set_stroke_color(stroke_color)
229
229
  set_line_width(line_width)
@@ -234,14 +234,16 @@ module Origami
234
234
  end
235
235
 
236
236
  def paint_shading(shade)
237
- load! if @instructions.nil?
237
+ load!
238
+
238
239
  @instructions << PDF::Instruction.new('sh', shade).render(@canvas)
239
240
 
240
241
  self
241
242
  end
242
243
 
243
244
  def set_text_font(fontname, size)
244
- load! if @instructions.nil?
245
+ load!
246
+
245
247
  if fontname != @canvas.gs.text_state.font or size != @canvas.gs.text_state.font_size
246
248
  @instructions << PDF::Instruction.new('Tf', fontname, size).render(@canvas)
247
249
  end
@@ -250,14 +252,16 @@ module Origami
250
252
  end
251
253
 
252
254
  def set_text_pos(tx,ty)
253
- load! if @instructions.nil?
255
+ load!
256
+
254
257
  @instructions << PDF::Instruction.new('Td', tx, ty).render(@canvas)
255
258
 
256
259
  self
257
260
  end
258
261
 
259
262
  def set_text_leading(leading)
260
- load! if @instructions.nil?
263
+ load!
264
+
261
265
  if leading != @canvas.gs.text_state.leading
262
266
  @instructions << PDF::Instruction.new('TL', leading).render(@canvas)
263
267
  end
@@ -266,7 +270,8 @@ module Origami
266
270
  end
267
271
 
268
272
  def set_text_rendering(rendering)
269
- load! if @instructions.nil?
273
+ load!
274
+
270
275
  if rendering != @canvas.gs.text_state.rendering_mode
271
276
  @instructions << PDF::Instruction.new('Tr', rendering).render(@canvas)
272
277
  end
@@ -275,7 +280,8 @@ module Origami
275
280
  end
276
281
 
277
282
  def set_text_rise(rise)
278
- load! if @instructions.nil?
283
+ load!
284
+
279
285
  if rise != @canvas.gs.text_state.text_rise
280
286
  @instructions << PDF::Instruction.new('Ts', rise).render(@canvas)
281
287
  end
@@ -284,7 +290,8 @@ module Origami
284
290
  end
285
291
 
286
292
  def set_text_scale(scaling)
287
- load! if @instructions.nil?
293
+ load!
294
+
288
295
  if scale != @canvas.gs.text_state.scaling
289
296
  @instructions << PDF::Instruction.new('Tz', scaling).render(@canvas)
290
297
  end
@@ -293,7 +300,8 @@ module Origami
293
300
  end
294
301
 
295
302
  def set_text_word_spacing(word_spacing)
296
- load! if @instructions.nil?
303
+ load!
304
+
297
305
  if word_spacing != @canvas.gs.text_state.word_spacing
298
306
  @instructions << PDF::Instruction.new('Tw', word_spacing).render(@canvas)
299
307
  end
@@ -302,7 +310,8 @@ module Origami
302
310
  end
303
311
 
304
312
  def set_text_char_spacing(char_spacing)
305
- load! if @instructions.nil?
313
+ load!
314
+
306
315
  if char_spacing != @canvas.gs.text_state.char_spacing
307
316
  @instructions << PDF::Instruction.new('Tc', char_spacing).render(@canvas)
308
317
  end
@@ -311,7 +320,7 @@ module Origami
311
320
  end
312
321
 
313
322
  def set_fill_color(color)
314
- load! if @instructions.nil?
323
+ load!
315
324
 
316
325
  @instructions << ( i =
317
326
  if (color.respond_to? :r and color.respond_to? :g and color.respond_to? :b) or (color.is_a?(::Array) and color.size == 3)
@@ -341,7 +350,7 @@ module Origami
341
350
  end
342
351
 
343
352
  def set_stroke_color(color)
344
- load! if @instructions.nil?
353
+ load!
345
354
 
346
355
  @instructions << ( i =
347
356
  if (color.respond_to? :r and color.respond_to? :g and color.respond_to? :b) or (color.is_a?(::Array) and color.size == 3)
@@ -371,7 +380,8 @@ module Origami
371
380
  end
372
381
 
373
382
  def set_dash_pattern(pattern)
374
- load! if @instructions.nil?
383
+ load!
384
+
375
385
  unless @canvas.gs.dash_pattern.eql? pattern
376
386
  @instructions << PDF::Instruction.new('d', pattern.array, pattern.phase).render(@canvas)
377
387
  end
@@ -380,7 +390,8 @@ module Origami
380
390
  end
381
391
 
382
392
  def set_line_width(width)
383
- load! if @instructions.nil?
393
+ load!
394
+
384
395
  if @canvas.gs.line_width != width
385
396
  @instructions << PDF::Instruction.new('w', width).render(@canvas)
386
397
  end
@@ -389,7 +400,8 @@ module Origami
389
400
  end
390
401
 
391
402
  def set_line_cap(cap)
392
- load! if @instructions.nil?
403
+ load!
404
+
393
405
  if @canvas.gs.line_cap != cap
394
406
  @instructions << PDF::Instruction.new('J', cap).render(@canvas)
395
407
  end
@@ -398,7 +410,8 @@ module Origami
398
410
  end
399
411
 
400
412
  def set_line_join(join)
401
- load! if @instructions.nil?
413
+ load!
414
+
402
415
  if @canvas.gs.line_join != join
403
416
  @instructions << PDF::Instruction.new('j', join).render(@canvas)
404
417
  end
@@ -409,6 +422,8 @@ module Origami
409
422
  private
410
423
 
411
424
  def load!
425
+ return unless @instructions.nil?
426
+
412
427
  decode!
413
428
 
414
429
  code = StringScanner.new self.data
@@ -471,12 +486,12 @@ module Origami
471
486
  end
472
487
 
473
488
  # TODO :nodoc:
474
- def paint_shading(shade)
489
+ def paint_shading(_shade)
475
490
  raise NotImplementedError
476
491
  end
477
492
 
478
493
  # TODO :nodoc:
479
- def set_text_font(font, size)
494
+ def set_text_font(_font, _size)
480
495
  raise NotImplementedError
481
496
  end
482
497
 
@@ -607,7 +622,7 @@ module Origami
607
622
  field :PtData, :Type => Dictionary, :Version => "1.7", :ExtensionLevel => 3
608
623
 
609
624
  def pre_build
610
- self.Resources = Resources.new.pre_build unless has_field?(:Resources)
625
+ self.Resources = Resources.new.pre_build unless self.key?(:Resources)
611
626
 
612
627
  super
613
628
  end
@@ -645,7 +660,6 @@ module Origami
645
660
  else
646
661
  data = File.binread(File.expand_path(path))
647
662
  format ||= File.extname(path)
648
- format.slice!(0) if format and format[0,1] == '.'
649
663
  end
650
664
 
651
665
  image = ImageXObject.new
@@ -656,22 +670,18 @@ module Origami
656
670
  image.setFilter :DCTDecode
657
671
  image.encoded_data = data
658
672
 
659
- image
660
-
661
673
  when 'jp2','jpx','j2k','jpf','jpm','mj2'
662
674
  image.setFilter :JPXDecode
663
675
  image.encoded_data = data
664
676
 
665
- image
666
-
667
677
  when 'jb2', 'jbig', 'jbig2'
668
678
  image.setFilter :JBIG2Decode
669
679
  image.encoded_data = data
670
-
671
- image
672
680
  else
673
681
  raise NotImplementedError, "Unknown file format: '#{format}'"
674
682
  end
683
+
684
+ image
675
685
  end
676
686
 
677
687
  #
@@ -700,35 +710,35 @@ module Origami
700
710
 
701
711
  case cs = self.ColorSpace.value
702
712
  when Color::Space::DEVICE_GRAY
703
- colortype = 0
713
+ color_type = 0
704
714
  components = 1
705
715
  when Color::Space::DEVICE_RGB
706
- colortype = 2
716
+ color_type = 2
707
717
  components = 3
708
718
  when ::Array
709
- cstype = cs[0].is_a?(Reference) ? cs[0].solve : cs[0]
710
- case cstype.value
719
+ cs_type = cs[0]
720
+ case cs_type
711
721
  when :Indexed
712
- colortype = 3
722
+ color_type = 3
713
723
  components = 3
714
- csbase = cs[1].is_a?(Reference) ? cs[1].solve : cs[1]
715
- lookup = cs[3].is_a?(Reference) ? cs[3].solve : cs[3]
724
+ cs_base = cs[1]
725
+ lookup = cs[3]
716
726
 
717
727
  when :ICCBased
718
- iccprofile = cs[1].is_a?(Reference) ? cs[1].solve : cs[1]
728
+ icc_profile = cs[1]
719
729
  raise InvalidColorError,
720
- "Invalid ICC Profile parameter" unless iccprofile.is_a?(Stream)
730
+ "Invalid ICC Profile parameter" unless icc_profile.is_a?(Stream)
721
731
 
722
- case iccprofile.N
732
+ case icc_profile.N
723
733
  when 1
724
- colortype = 0
734
+ color_type = 0
725
735
  components = 1
726
736
  when 3
727
- colortype = 2
737
+ color_type = 2
728
738
  components = 3
729
739
  else
730
740
  raise InvalidColorError,
731
- "Invalid number of components in ICC profile: #{iccprofile.N}"
741
+ "Invalid number of components in ICC profile: #{icc_profile.N}"
732
742
  end
733
743
  else
734
744
  raise InvalidColorError, "Unsupported color space: #{self.ColorSpace}"
@@ -738,7 +748,7 @@ module Origami
738
748
  end
739
749
 
740
750
  bpc = self.BitsPerComponent || 8
741
- w,h = self.Width, self.Height
751
+ w, h = self.Width, self.Height
742
752
  pixels = self.data
743
753
 
744
754
  hdr = [137, 80, 78, 71, 13, 10, 26, 10].pack('C*')
@@ -749,7 +759,7 @@ module Origami
749
759
  'IHDR',
750
760
  [
751
761
  w, h,
752
- bpc, colortype, 0, 0, 0
762
+ bpc, color_type, 0, 0, 0
753
763
  ].pack("N2C5")
754
764
  ]
755
765
 
@@ -788,7 +798,7 @@ module Origami
788
798
  ]
789
799
  end
790
800
 
791
- if colortype == 3
801
+ if color_type == 3
792
802
  lookup =
793
803
  case lookup
794
804
  when Stream then lookup.data
@@ -797,10 +807,10 @@ module Origami
797
807
  raise InvalidColorError, "Invalid indexed palette table"
798
808
  end
799
809
 
800
- raise InvalidColorError, "Invalid base color space" unless csbase
810
+ raise InvalidColorError, "Invalid base color space" unless cs_base
801
811
  palette = ""
802
812
 
803
- case csbase.value
813
+ case cs_base
804
814
  when Color::Space::DEVICE_GRAY
805
815
  lookup.each_byte do |g|
806
816
  palette << Color.gray_to_rgb(g).pack("C3")
@@ -815,13 +825,13 @@ module Origami
815
825
  end
816
826
  when ::Array
817
827
 
818
- case csbase[0].solve.value
828
+ case cs_base[0]
819
829
  when :ICCBased
820
- iccprofile = csbase[1].solve
830
+ icc_profile = cs_base[1]
821
831
  raise InvalidColorError,
822
- "Invalid ICC Profile parameter" unless iccprofile.is_a?(Stream)
832
+ "Invalid ICC Profile parameter" unless icc_profile.is_a?(Stream)
823
833
 
824
- case iccprofile.N
834
+ case icc_profile.N
825
835
  when 1
826
836
  lookup.each_byte do |g|
827
837
  palette << Color.gray_to_rgb(g).pack("C3")
@@ -830,20 +840,20 @@ module Origami
830
840
  palette << lookup[0, (lookup.size / 3) * 3]
831
841
  else
832
842
  raise InvalidColorError,
833
- "Invalid number of components in ICC profile: #{iccprofile.N}"
843
+ "Invalid number of components in ICC profile: #{icc_profile.N}"
834
844
  end
835
845
  else
836
- raise InvalidColorError, "Unsupported color space: #{csbase}"
846
+ raise InvalidColorError, "Unsupported color space: #{cs_base}"
837
847
  end
838
848
  else
839
- raise InvalidColorError, "Unsupported color space: #{csbase}"
849
+ raise InvalidColorError, "Unsupported color space: #{cs_base}"
840
850
  end
841
851
 
842
- if iccprofile
852
+ if icc_profile
843
853
  chunks <<
844
854
  [
845
855
  'iCCP',
846
- 'ICC Profile' + "\x00\x00" + Zlib::Deflate.deflate(iccprofile.data, Zlib::BEST_COMPRESSION)
856
+ 'ICC Profile' + "\x00\x00" + Zlib::Deflate.deflate(icc_profile.data, Zlib::BEST_COMPRESSION)
847
857
  ]
848
858
  end
849
859
 
@@ -855,12 +865,12 @@ module Origami
855
865
 
856
866
  bpr = w
857
867
 
858
- else # colortype != 3
859
- if iccprofile
868
+ else # color_type != 3
869
+ if icc_profile
860
870
  chunks <<
861
871
  [
862
872
  'iCCP',
863
- 'ICC Profile' + "\x00\x00" + Zlib::Deflate.deflate(iccprofile.data, Zlib::BEST_COMPRESSION)
873
+ 'ICC Profile' + "\x00\x00" + Zlib::Deflate.deflate(icc_profile.data, Zlib::BEST_COMPRESSION)
864
874
  ]
865
875
  end
866
876