origami 1.2.5 → 1.2.6

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 (54) hide show
  1. checksums.yaml +7 -0
  2. data/bin/gui/config.rb +0 -4
  3. data/bin/gui/imgview.rb +2 -2
  4. data/bin/gui/menu.rb +11 -3
  5. data/bin/gui/treeview.rb +9 -3
  6. data/bin/pdfexplode +220 -0
  7. data/bin/pdfextract +3 -0
  8. data/lib/origami/acroform.rb +2 -2
  9. data/lib/origami/actions.rb +62 -35
  10. data/lib/origami/annotations.rb +3 -2
  11. data/lib/origami/array.rb +27 -4
  12. data/lib/origami/boolean.rb +2 -2
  13. data/lib/origami/catalog.rb +45 -45
  14. data/lib/origami/dictionary.rb +87 -14
  15. data/lib/origami/encryption.rb +46 -24
  16. data/lib/origami/file.rb +1 -2
  17. data/lib/origami/filters/ccitt.rb +118 -66
  18. data/lib/origami/filters/flate.rb +5 -1
  19. data/lib/origami/filters.rb +84 -2
  20. data/lib/origami/font.rb +71 -71
  21. data/lib/origami/graphics/patterns.rb +2 -1
  22. data/lib/origami/graphics/xobject.rb +123 -1
  23. data/lib/origami/javascript.rb +2 -1
  24. data/lib/origami/name.rb +2 -2
  25. data/lib/origami/null.rb +2 -2
  26. data/lib/origami/numeric.rb +11 -3
  27. data/lib/origami/object.rb +37 -16
  28. data/lib/origami/page.rb +135 -71
  29. data/lib/origami/parser.rb +11 -4
  30. data/lib/origami/parsers/pdf/linear.rb +1 -0
  31. data/lib/origami/parsers/pdf.rb +10 -0
  32. data/lib/origami/pdf.rb +10 -70
  33. data/lib/origami/reference.rb +4 -5
  34. data/lib/origami/signature.rb +22 -8
  35. data/lib/origami/stream.rb +41 -20
  36. data/lib/origami/string.rb +15 -6
  37. data/lib/origami/trailer.rb +9 -5
  38. data/lib/origami.rb +19 -0
  39. data/samples/actions/loop/loopgoto.rb +1 -1
  40. data/samples/actions/loop/loopnamed.rb +2 -2
  41. data/samples/actions/named/named.rb +1 -1
  42. data/samples/actions/samba/smbrelay.rb +1 -1
  43. data/samples/actions/triggerevents/trigger.rb +13 -13
  44. data/samples/actions/webbug/webbug-browser.rb +1 -1
  45. data/samples/actions/webbug/webbug-js.rb +1 -1
  46. data/samples/actions/webbug/webbug-reader.rb +1 -1
  47. data/samples/attachments/attach.rb +2 -2
  48. data/samples/exploits/cve-2008-2992-utilprintf.rb +1 -1
  49. data/samples/exploits/cve-2009-0927-geticon.rb +1 -1
  50. data/samples/exploits/exploit_customdictopen.rb +2 -2
  51. data/samples/exploits/getannots.rb +1 -1
  52. data/samples/javascript/js.rb +2 -2
  53. data/test/ts_pdf.rb +23 -23
  54. metadata +71 -86
@@ -441,6 +441,127 @@ module Origami
441
441
 
442
442
  end #class ContentStream
443
443
 
444
+ class Page < Dictionary
445
+
446
+ def render(engine) #:nodoc:
447
+ contents = self.Contents
448
+ contents = [ contents ] unless contents.is_a? Array
449
+
450
+ contents.each do |stream|
451
+ stream = stream.cast_to(ContentStream) unless stream.is_a? ContentStream
452
+
453
+ stream.render(engine)
454
+ end
455
+ end
456
+
457
+ # TODO :nodoc:
458
+ def draw_image
459
+ raise NotImplementedError
460
+ end
461
+
462
+ # See ContentStream#draw_line.
463
+ def draw_line(from, to, attr = {})
464
+ last_content_stream.draw_line(from, to, attr); self
465
+ end
466
+
467
+ # See ContentStream#draw_polygon.
468
+ def draw_polygon(coords = [], attr = {})
469
+ last_content_stream.draw_polygon(coords, attr); self
470
+ end
471
+
472
+ # See ContentStream#draw_rectangle.
473
+ def draw_rectangle(x, y, width, height, attr = {})
474
+ last_content_stream.draw_rectangle(x, y, width, height, attr); self
475
+ end
476
+
477
+ # See ContentStream#write.
478
+ def write(text, attr = {})
479
+ last_content_stream.write(text, attr); self
480
+ end
481
+
482
+ # TODO :nodoc:
483
+ def paint_shading(shade)
484
+ raise NotImplementedError
485
+ end
486
+
487
+ # TODO :nodoc:
488
+ def set_text_font(font, size)
489
+ raise NotImplementedError
490
+ end
491
+
492
+ # See ContentStream#set_text_pos.
493
+ def set_text_pos(tx, ty)
494
+ last_content_stream.set_text_pos(tx, ty); self
495
+ end
496
+
497
+ # See ContentStream#set_text_leading.
498
+ def set_text_leading(leading)
499
+ last_content_stream.set_text_leading(leading); self
500
+ end
501
+
502
+ # See ContentStream#set_text_rendering.
503
+ def set_text_rendering(rendering)
504
+ last_content_stream.set_text_rendering(rendering); self
505
+ end
506
+
507
+ # See ContentStream#set_text_rise.
508
+ def set_text_rise(rise)
509
+ last_content_stream.set_text_rise(rise); self
510
+ end
511
+
512
+ # See ContentStream#set_text_scale.
513
+ def set_text_scale(scaling)
514
+ last_content_stream.set_text_scale(scaling); self
515
+ end
516
+
517
+ # See ContentStream#set_text_word_spacing.
518
+ def set_text_word_spacing(word_spacing)
519
+ last_content_stream.set_text_word_spacing(word_spacing); self
520
+ end
521
+
522
+ # See ContentStream#set_text_char_spacing.
523
+ def set_text_char_spacing(char_spacing)
524
+ last_content_stream.set_text_char_spacing(char_spacing); self
525
+ end
526
+
527
+ # See ContentStream#set_fill_color.
528
+ def set_fill_color(color)
529
+ last_content_stream.set_fill_color(color); self
530
+ end
531
+
532
+ # See ContentStream#set_stroke_color.
533
+ def set_stroke_color(color)
534
+ last_content_stream.set_stroke_color(color); self
535
+ end
536
+
537
+ # See ContentStream#set_dash_pattern.
538
+ def set_dash_pattern(pattern)
539
+ last_content_stream.set_dash_pattern(pattern); self
540
+ end
541
+
542
+ # See ContentStream#set_line_width.
543
+ def set_line_width(width)
544
+ last_content_stream.set_line_width(width); self
545
+ end
546
+
547
+ # See ContentStream#set_line_cap.
548
+ def set_line_cap(cap)
549
+ last_content_stream.set_line_cap(cap); self
550
+ end
551
+
552
+ # See ContentStream#set_line_join.
553
+ def set_line_join(join)
554
+ last_content_stream.set_line_join(join); self
555
+ end
556
+
557
+ private
558
+
559
+ def last_content_stream #:nodoc:
560
+ contents = (self.Contents ||= ContentStream.new)
561
+ contents.is_a?(Array) ? contents.last : contents
562
+ end
563
+ end # class Page
564
+
444
565
  module Graphics
445
566
 
446
567
  module XObject
@@ -451,12 +572,13 @@ module Origami
451
572
 
452
573
  class FormXObject < ContentStream
453
574
  include XObject
575
+ include ResourcesHolder
454
576
 
455
577
  field :Subtype, :Type => Name, :Default => :Form, :Required => true
456
578
  field :FormType, :Type => Integer, :Default => 1
457
579
  field :BBox, :Type => Array, :Required => true
458
580
  field :Matrix, :Type => Array, :Default => [1, 0, 0, 1, 0, 0]
459
- field :Resources, :Type => Dictionary, :Version => "1.2"
581
+ field :Resources, :Type => Resources, :Version => "1.2"
460
582
  field :Group, :Type => Dictionary, :Version => "1.4"
461
583
  field :Ref, :Type => Dictionary, :Version => "1.4"
462
584
  field :Metadata, :Type => Stream, :Version => "1.4"
@@ -273,7 +273,8 @@ module Origami
273
273
  def modDate; @doc.mod_date.to_s end
274
274
  end
275
275
 
276
- def initialize(engine, pdf)
276
+ def initialize(*args)
277
+ engine, pdf = args # XXX: Bypass therubyracer bug #238. Temporary.
277
278
  super(engine)
278
279
 
279
280
  @pdf = pdf
data/lib/origami/name.rb CHANGED
@@ -107,7 +107,7 @@ module Origami
107
107
  super(TOKENS.first + Name.expand(@value))
108
108
  end
109
109
 
110
- def self.parse(stream) #:nodoc:
110
+ def self.parse(stream, parser = nil) #:nodoc:
111
111
 
112
112
  offset = stream.pos
113
113
 
@@ -163,7 +163,7 @@ module Origami
163
163
  end
164
164
  end
165
165
 
166
- def real_type ; Name end
166
+ def self.native_type ; Name end
167
167
 
168
168
  end
169
169
 
data/lib/origami/null.rb CHANGED
@@ -43,7 +43,7 @@ module Origami
43
43
  super
44
44
  end
45
45
 
46
- def self.parse(stream) #:nodoc:
46
+ def self.parse(stream, parser = nil) #:nodoc:
47
47
 
48
48
  offset = stream.pos
49
49
 
@@ -68,7 +68,7 @@ module Origami
68
68
  super(TOKENS.first)
69
69
  end
70
70
 
71
- def real_type ; Null end
71
+ def self.native_type ; Null end
72
72
 
73
73
  end
74
74
 
@@ -92,7 +92,15 @@ module Origami
92
92
  super(value.to_s)
93
93
  end
94
94
 
95
- def real_type ; Number end
95
+ module ClassMethods #:nodoc:all
96
+ def native_type; Number end
97
+ end
98
+
99
+ def self.included(receiver) #:nodoc:
100
+ receiver.extend(ClassMethods)
101
+ end
102
+
103
+ def self.native_type; Number end #:nodoc:
96
104
  end
97
105
 
98
106
  #
@@ -121,7 +129,7 @@ module Origami
121
129
  super(i)
122
130
  end
123
131
 
124
- def self.parse(stream) #:nodoc:
132
+ def self.parse(stream, parser = nil) #:nodoc:
125
133
 
126
134
  offset = stream.pos
127
135
 
@@ -169,7 +177,7 @@ module Origami
169
177
  super(f)
170
178
  end
171
179
 
172
- def self.parse(stream) #:nodoc:
180
+ def self.parse(stream, parser = nil) #:nodoc:
173
181
 
174
182
  offset = stream.pos
175
183
 
@@ -39,14 +39,6 @@ class Array #:nodoc:
39
39
  def to_o
40
40
  Origami::Array.new(self)
41
41
  end
42
-
43
- def shuffle
44
- sort_by { rand }
45
- end
46
-
47
- def shuffle!
48
- self.replace shuffle
49
- end
50
42
  end
51
43
 
52
44
  class Float #:nodoc:
@@ -110,7 +102,7 @@ module Origami
110
102
  #
111
103
  module StandardObject #:nodoc:
112
104
 
113
- DEFAULT_ATTRIBUTES = { :Type => Object, :Version => "1.1" } #:nodoc:
105
+ DEFAULT_ATTRIBUTES = { :Type => Object, :Version => "1.2" } #:nodoc:
114
106
 
115
107
  def self.included(receiver) #:nodoc:
116
108
  receiver.instance_variable_set(:@fields, Hash.new(DEFAULT_ATTRIBUTES))
@@ -126,8 +118,11 @@ module Origami
126
118
  def fields
127
119
  @fields
128
120
  end
129
-
121
+
130
122
  def field(name, attributes)
123
+ if attributes[:Required] == true and attributes.has_key?(:Default) and attributes[:Type] == Name
124
+ self.add_type_info(self, name, attributes[:Default])
125
+ end
131
126
 
132
127
  if not @fields.has_key?(name)
133
128
  @fields[name] = attributes
@@ -160,6 +155,11 @@ module Origami
160
155
  fields
161
156
  end
162
157
 
158
+ def hint_type(name)
159
+ if @fields.has_key?(name)
160
+ @fields[name][:Type]
161
+ end
162
+ end
163
163
  end
164
164
 
165
165
  def pre_build #:nodoc:
@@ -168,7 +168,7 @@ module Origami
168
168
  do_type_check if Origami::OPTIONS[:enable_type_checking] == true
169
169
 
170
170
  super
171
- end
171
+ end
172
172
 
173
173
  #
174
174
  # Check if an attribute is set in the current Object.
@@ -218,7 +218,7 @@ module Origami
218
218
 
219
219
  if not self[field].nil? and not attributes[:Type].nil?
220
220
  types = attributes[:Type].is_a?(::Array) ? attributes[:Type] : [ attributes[:Type] ]
221
- if not self[field].is_a?(Reference) and types.all? {|type| not self[field].is_a?(type)}
221
+ if not self[field].is_a?(Reference) and types.all? {|type| not self[field].is_a?(type.native_type)}
222
222
  puts "Warning: in object #{self.class}, field `#{field.to_s}' has unexpected type #{self[field].class}"
223
223
  end
224
224
  end
@@ -289,6 +289,7 @@ module Origami
289
289
  @no = @generation = 0
290
290
  @pdf = nil
291
291
  end
292
+
292
293
  @indirect = bool
293
294
  self
294
295
  end
@@ -329,6 +330,8 @@ module Origami
329
330
  def copy
330
331
  saved_pdf = @pdf
331
332
  saved_parent = @parent
333
+
334
+ saved_xref_cache = @xref_cache
332
335
  @pdf = @parent = nil # do not process parent object and document in the copy
333
336
 
334
337
  # Perform the recursive copy (quite dirty).
@@ -337,7 +340,8 @@ module Origami
337
340
  # restore saved values
338
341
  @pdf = saved_pdf
339
342
  @parent = saved_parent
340
- copyobj.set_pdf(saved_pdf)
343
+
344
+ copyobj.set_pdf(saved_pdf) if copyobj.is_indirect?
341
345
  copyobj.parent = parent
342
346
 
343
347
  copyobj
@@ -403,6 +407,7 @@ module Origami
403
407
  exported_obj.no = exported_obj.generation = 0
404
408
  exported_obj.set_pdf(nil) if exported_obj.is_indirect?
405
409
  exported_obj.parent = nil
410
+ exported_obj.xref_cache.clear
406
411
 
407
412
  exported_obj
408
413
  end
@@ -539,7 +544,7 @@ module Origami
539
544
  nil
540
545
  end
541
546
 
542
- def parse(stream) #:nodoc:
547
+ def parse(stream, parser = nil) #:nodoc:
543
548
  offset = stream.pos
544
549
 
545
550
  #
@@ -562,7 +567,7 @@ module Origami
562
567
  end
563
568
 
564
569
  begin
565
- newObj = type.parse(stream)
570
+ newObj = type.parse(stream, parser)
566
571
  rescue Exception => e
567
572
  raise InvalidObjectError,
568
573
  "Failed to parse object (no:#{no},gen:#{gen})\n\t -> [#{e.class}] #{e.message}"
@@ -602,7 +607,23 @@ module Origami
602
607
  def type
603
608
  self.class.to_s.split("::").last.to_sym
604
609
  end
605
- alias real_type type
610
+
611
+ def self.native_type; Origami::Object end #:nodoc:
612
+
613
+ #
614
+ # Returns the native PDF type of this Object.
615
+ #
616
+ def native_type
617
+ self.class.native_type
618
+ end
619
+
620
+ def cast_to(type) #:nodoc:
621
+ if type.native_type != self.native_type
622
+ raise TypeError, "Incompatible cast from #{self.class} to #{type}"
623
+ end
624
+
625
+ self
626
+ end
606
627
 
607
628
  #
608
629
  # Outputs this object into PDF code.
data/lib/origami/page.rb CHANGED
@@ -27,6 +27,9 @@ module Origami
27
27
 
28
28
  class PDF
29
29
 
30
+ #
31
+ # Appends a page or list of pages to the end of the page tree.
32
+ #
30
33
  def append_page(page = Page.new, *more)
31
34
  raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
32
35
 
@@ -52,6 +55,9 @@ module Origami
52
55
  self
53
56
  end
54
57
 
58
+ #
59
+ # Inserts a page at position _index_ into the document.
60
+ #
55
61
  def insert_page(index, page)
56
62
  raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
57
63
 
@@ -108,69 +114,105 @@ module Origami
108
114
 
109
115
  module ResourcesHolder
110
116
 
111
- def add_extgstate(name, extgstate)
112
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
113
-
114
- target.ExtGState ||= {}
115
- target.ExtGState[name] = extgstate
116
-
117
- self
117
+ def add_extgstate(extgstate, name = nil)
118
+ add_resource(Resources::EXTGSTATE, extgstate, name)
118
119
  end
119
120
 
120
- def add_colorspace(name, colorspace)
121
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
122
-
123
- csdir = target[:ColorSpace] ||= {}
124
- (csdir.is_a?(Reference) ? csdir.solve : csdir)[name] = colorspace
121
+ def add_colorspace(colorspace, name = nil)
122
+ add_resource(Resources::COLORSPACE, colorspace, name)
123
+ end
125
124
 
126
- self
125
+ def add_pattern(pattern, name = nil)
126
+ add_resource(Resources::PATTERN, pattern, name)
127
127
  end
128
128
 
129
- def add_pattern(name, pattern)
130
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
129
+ def add_shading(shading, name = nil)
130
+ add_resource(Resources::SHADING, shading, name)
131
+ end
131
132
 
132
- target.Pattern ||= {}
133
- target.Pattern[name] = pattern
134
-
135
- self
133
+ def add_xobject(xobject, name = nil)
134
+ add_resource(Resources::XOBJECT, xobject, name)
136
135
  end
137
136
 
138
- def add_shading(name, shading)
139
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
137
+ def add_font(font, name = nil)
138
+ add_resource(Resources::FONT, font, name)
139
+ end
140
140
 
141
- target.Shading ||= {}
142
- target.Shading[name] = shading
143
-
144
- self
141
+ def add_properties(properties, name = nil)
142
+ add_resource(Resources::PROPERTIES, properties, name)
145
143
  end
146
144
 
147
- def add_xobject(name, xobject)
148
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
145
+ def add_resource(type, rsrc, name = nil)
146
+ return existing if not name and existing = ls_resources(type).key(rsrc)
149
147
 
150
- target.XObject ||= {}
151
- target.XObject[name] = xobject
152
-
153
- self
154
- end
155
-
156
- def add_font(name, font)
148
+ name = new_id(type) unless name
157
149
  target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
158
150
 
159
- target.Font ||= {}
160
- target.Font[name] = font
161
-
162
- self
151
+ rsrc_dict = target.send(type) || (target[type] = Dictionary.new)
152
+ rsrc_dict[name] = rsrc
153
+
154
+ name
163
155
  end
164
156
 
165
- def add_properties(name, properties)
157
+ def ls_resources(type)
166
158
  target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
159
+
160
+ rsrc = {}
161
+ (target.send(type) || {}).each_pair do |name, obj|
162
+ rsrc[name.value] = obj.solve
163
+ end
167
164
 
168
- target.Properties ||= {}
169
- target.Properties[name] = properties
170
-
171
- self
165
+ rsrc
166
+ end
167
+
168
+ def extgstates; ls_resources(Resources::EXTGSTATE) end
169
+ def colorspaces; ls_resources(Resources::COLORSPACE) end
170
+ def patterns; ls_resources(Resources::PATTERN) end
171
+ def shadings; ls_resources(Resources::SHADING) end
172
+ def xobjects; ls_resources(Resources::XOBJECT) end
173
+ def fonts; ls_resources(Resources::FONT) end
174
+ def properties; ls_resources(Resources::PROPERTIES) end
175
+ def resources;
176
+ self.extgstates.
177
+ merge self.colorspaces.
178
+ merge self.patterns.
179
+ merge self.shadings.
180
+ merge self.xobjects.
181
+ merge self.fonts.
182
+ merge self.properties
183
+ end
184
+
185
+ private
186
+
187
+ def new_id(type, prefix = nil) #:nodoc:
188
+ prefix ||=
189
+ {
190
+ Resources::EXTGSTATE => 'ExtG',
191
+ Resources::COLORSPACE => 'CS',
192
+ Resources::PATTERN => 'P',
193
+ Resources::SHADING => 'Sh',
194
+ Resources::XOBJECT => 'Im',
195
+ Resources::FONT => 'F',
196
+ Resources::PROPERTIES => 'Pr'
197
+ }[type]
198
+
199
+ rsrc = ls_resources(type)
200
+ n = '1'
201
+
202
+ while rsrc.include? (prefix + n).to_sym
203
+ n.next!
204
+ end
205
+
206
+ (prefix + n).to_sym
172
207
  end
173
-
208
+
209
+ def new_extgstate_id; new_id(Resources::EXTGSTATE) end
210
+ def new_colorspace_id; new_id(Resources::COLORSPACE) end
211
+ def new_pattern_id; new_id(Resources::PATTERN) end
212
+ def new_shading_id; new_id(Resources::SHADING) end
213
+ def new_xobject_id; new_id(Resources::XOBJECT) end
214
+ def new_font_id; new_name(Resources::FONT) end
215
+ def new_properties_id; new_name(Resources::PROPERTIES) end
174
216
  end
175
217
 
176
218
  #
@@ -181,22 +223,25 @@ module Origami
181
223
  include StandardObject
182
224
  include ResourcesHolder
183
225
 
184
- field :ExtGState, :Type => Dictionary
185
- field :ColorSpace, :Type => Dictionary
186
- field :Pattern, :Type => Dictionary
187
- field :Shading, :Type => Dictionary, :Version => "1.3"
188
- field :XObject, :Type => Dictionary
189
- field :Font, :Type => Dictionary
226
+ EXTGSTATE = :ExtGState
227
+ COLORSPACE = :ColorSpace
228
+ PATTERN = :Pattern
229
+ SHADING = :Shading
230
+ XOBJECT = :XObject
231
+ FONT = :Font
232
+ PROPERTIES = :Properties
233
+
234
+ field EXTGSTATE, :Type => Dictionary
235
+ field COLORSPACE, :Type => Dictionary
236
+ field PATTERN, :Type => Dictionary
237
+ field SHADING, :Type => Dictionary, :Version => "1.3"
238
+ field XOBJECT, :Type => Dictionary
239
+ field FONT, :Type => Dictionary
190
240
  field :ProcSet, :Type => Array
191
- field :Properties, :Type => Dictionary, :Version => "1.2"
241
+ field PROPERTIES, :Type => Dictionary, :Version => "1.2"
192
242
 
193
243
  def pre_build
194
- unless self.Font
195
- fnt = Font::Type1::Standard::Helvetica.new.pre_build
196
- fnt.Name = :F1
197
-
198
- add_font(fnt.Name, fnt)
199
- end
244
+ add_font(Font::Type1::Standard::Helvetica.new.pre_build) unless self.Font
200
245
 
201
246
  super
202
247
  end
@@ -347,6 +392,9 @@ module Origami
347
392
  end
348
393
  end
349
394
  end
395
+
396
+ # Forward declaration.
397
+ class ContentStream < Stream; end
350
398
 
351
399
  #
352
400
  # Class representing a Page in the PDF document.
@@ -355,18 +403,44 @@ module Origami
355
403
 
356
404
  include StandardObject
357
405
  include ResourcesHolder
406
+
407
+ module Format
408
+ A0 = Rectangle[:width => 2384, :height => 3370]
409
+ A1 = Rectangle[:width => 1684, :height => 2384]
410
+ A2 = Rectangle[:width => 1191, :height => 1684]
411
+ A3 = Rectangle[:width => 842, :height => 1191]
412
+ A4 = Rectangle[:width => 595, :height => 842]
413
+ A5 = Rectangle[:width => 420, :height => 595]
414
+ A6 = Rectangle[:width => 298, :height => 420]
415
+ A7 = Rectangle[:width => 210, :height => 298]
416
+ A8 = Rectangle[:width => 147, :height => 210]
417
+ A9 = Rectangle[:width => 105, :height => 147]
418
+ A10 = Rectangle[:width => 74, :height => 105]
419
+
420
+ B0 = Rectangle[:width => 2836, :height => 4008]
421
+ B1 = Rectangle[:width => 2004, :height => 2835]
422
+ B2 = Rectangle[:width => 1417, :height => 2004]
423
+ B3 = Rectangle[:width => 1001, :height => 1417]
424
+ B4 = Rectangle[:width => 709, :height => 1001]
425
+ B5 = Rectangle[:width => 499, :height => 709]
426
+ B6 = Rectangle[:width => 354, :height => 499]
427
+ B7 = Rectangle[:width => 249, :height => 354]
428
+ B8 = Rectangle[:width => 176, :height => 249]
429
+ B9 = Rectangle[:width => 125, :height => 176]
430
+ B10 = Rectangle[:width => 88, :height => 125]
431
+ end
358
432
 
359
433
  field :Type, :Type => Name, :Default => :Page, :Required => true
360
434
  field :Parent, :Type => Dictionary, :Required => true
361
435
  field :LastModified, :Type => String, :Version => "1.3"
362
- field :Resources, :Type => Dictionary, :Required => true
363
- field :MediaBox, :Type => Array, :Default => Rectangle[ :llx => 0, :lly => 0, :urx => 795, :ury => 842 ], :Required => true
436
+ field :Resources, :Type => Resources, :Required => true
437
+ field :MediaBox, :Type => Array, :Default => Format::A4, :Required => true
364
438
  field :CropBox, :Type => Array
365
439
  field :BleedBox, :Type => Array, :Version => "1.3"
366
440
  field :TrimBox, :Type => Array, :Version => "1.3"
367
441
  field :ArtBox, :Type => Array, :Version => "1.3"
368
442
  field :BoxColorInfo, :Type => Dictionary, :Version => "1.4"
369
- field :Contents, :Type => [ Stream, Array ]
443
+ field :Contents, :Type => [ ContentStream, Array ]
370
444
  field :Rotate, :Type => Integer, :Default => 0
371
445
  field :Group, :Type => Dictionary, :Version => "1.4"
372
446
  field :Thumb, :Type => Stream
@@ -393,17 +467,6 @@ module Origami
393
467
  set_indirect(true)
394
468
  end
395
469
 
396
- def render(engine) #:nodoc:
397
- contents = self.Contents
398
- return unless contents.is_a? Stream
399
-
400
- unless contents.is_a? ContentStream
401
- contents = ContentStream.new(contents.data)
402
- end
403
-
404
- contents.render(engine)
405
- end
406
-
407
470
  def pre_build
408
471
  self.Resources = Resources.new.pre_build unless self.has_key?(:Resources)
409
472
 
@@ -594,3 +657,4 @@ module Origami
594
657
  end
595
658
 
596
659
  end
660
+
@@ -134,6 +134,9 @@ module Origami
134
134
  attr_accessor :options
135
135
 
136
136
  def initialize(options = {}) #:nodoc:
137
+
138
+ # Type information for indirect objects.
139
+ @deferred_casts = {}
137
140
 
138
141
  #Default options values
139
142
  @options =
@@ -178,12 +181,12 @@ module Origami
178
181
  @data.pos = pos
179
182
 
180
183
  begin
181
- obj = Object.parse(@data)
184
+ obj = Object.parse(@data, self)
182
185
  return if obj.nil?
183
186
 
184
187
  trace "Read #{obj.type} object#{
185
- if obj.type != obj.real_type
186
- " (" + obj.real_type.to_s.split('::').last + ")"
188
+ if obj.class != obj.native_type
189
+ " (" + obj.native_type.to_s.split('::').last + ")"
187
190
  end
188
191
  }, #{obj.reference}"
189
192
 
@@ -237,7 +240,7 @@ module Origami
237
240
 
238
241
  begin
239
242
  info "...Parsing trailer..."
240
- trailer = Trailer.parse(@data)
243
+ trailer = Trailer.parse(@data, self)
241
244
 
242
245
  @options[:callback].call(trailer)
243
246
  trailer
@@ -252,6 +255,10 @@ module Origami
252
255
  end
253
256
  end
254
257
 
258
+ def defer_type_cast(reference, type) #:nodoc:
259
+ @deferred_casts[reference] = type
260
+ end
261
+
255
262
  def target_filename
256
263
  @filename
257
264
  end