origami 2.0.0 → 2.0.1

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 (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