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.
- checksums.yaml +7 -0
- data/bin/gui/config.rb +0 -4
- data/bin/gui/imgview.rb +2 -2
- data/bin/gui/menu.rb +11 -3
- data/bin/gui/treeview.rb +9 -3
- data/bin/pdfexplode +220 -0
- data/bin/pdfextract +3 -0
- data/lib/origami/acroform.rb +2 -2
- data/lib/origami/actions.rb +62 -35
- data/lib/origami/annotations.rb +3 -2
- data/lib/origami/array.rb +27 -4
- data/lib/origami/boolean.rb +2 -2
- data/lib/origami/catalog.rb +45 -45
- data/lib/origami/dictionary.rb +87 -14
- data/lib/origami/encryption.rb +46 -24
- data/lib/origami/file.rb +1 -2
- data/lib/origami/filters/ccitt.rb +118 -66
- data/lib/origami/filters/flate.rb +5 -1
- data/lib/origami/filters.rb +84 -2
- data/lib/origami/font.rb +71 -71
- data/lib/origami/graphics/patterns.rb +2 -1
- data/lib/origami/graphics/xobject.rb +123 -1
- data/lib/origami/javascript.rb +2 -1
- data/lib/origami/name.rb +2 -2
- data/lib/origami/null.rb +2 -2
- data/lib/origami/numeric.rb +11 -3
- data/lib/origami/object.rb +37 -16
- data/lib/origami/page.rb +135 -71
- data/lib/origami/parser.rb +11 -4
- data/lib/origami/parsers/pdf/linear.rb +1 -0
- data/lib/origami/parsers/pdf.rb +10 -0
- data/lib/origami/pdf.rb +10 -70
- data/lib/origami/reference.rb +4 -5
- data/lib/origami/signature.rb +22 -8
- data/lib/origami/stream.rb +41 -20
- data/lib/origami/string.rb +15 -6
- data/lib/origami/trailer.rb +9 -5
- data/lib/origami.rb +19 -0
- data/samples/actions/loop/loopgoto.rb +1 -1
- data/samples/actions/loop/loopnamed.rb +2 -2
- data/samples/actions/named/named.rb +1 -1
- data/samples/actions/samba/smbrelay.rb +1 -1
- data/samples/actions/triggerevents/trigger.rb +13 -13
- data/samples/actions/webbug/webbug-browser.rb +1 -1
- data/samples/actions/webbug/webbug-js.rb +1 -1
- data/samples/actions/webbug/webbug-reader.rb +1 -1
- data/samples/attachments/attach.rb +2 -2
- data/samples/exploits/cve-2008-2992-utilprintf.rb +1 -1
- data/samples/exploits/cve-2009-0927-geticon.rb +1 -1
- data/samples/exploits/exploit_customdictopen.rb +2 -2
- data/samples/exploits/getannots.rb +1 -1
- data/samples/javascript/js.rb +2 -2
- data/test/ts_pdf.rb +23 -23
- 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 =>
|
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"
|
data/lib/origami/javascript.rb
CHANGED
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
|
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
|
71
|
+
def self.native_type ; Null end
|
72
72
|
|
73
73
|
end
|
74
74
|
|
data/lib/origami/numeric.rb
CHANGED
@@ -92,7 +92,15 @@ module Origami
|
|
92
92
|
super(value.to_s)
|
93
93
|
end
|
94
94
|
|
95
|
-
|
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
|
|
data/lib/origami/object.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
112
|
-
|
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(
|
121
|
-
|
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
|
-
|
125
|
+
def add_pattern(pattern, name = nil)
|
126
|
+
add_resource(Resources::PATTERN, pattern, name)
|
127
127
|
end
|
128
128
|
|
129
|
-
def
|
130
|
-
|
129
|
+
def add_shading(shading, name = nil)
|
130
|
+
add_resource(Resources::SHADING, shading, name)
|
131
|
+
end
|
131
132
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
self
|
133
|
+
def add_xobject(xobject, name = nil)
|
134
|
+
add_resource(Resources::XOBJECT, xobject, name)
|
136
135
|
end
|
137
136
|
|
138
|
-
def
|
139
|
-
|
137
|
+
def add_font(font, name = nil)
|
138
|
+
add_resource(Resources::FONT, font, name)
|
139
|
+
end
|
140
140
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
self
|
141
|
+
def add_properties(properties, name = nil)
|
142
|
+
add_resource(Resources::PROPERTIES, properties, name)
|
145
143
|
end
|
146
144
|
|
147
|
-
def
|
148
|
-
|
145
|
+
def add_resource(type, rsrc, name = nil)
|
146
|
+
return existing if not name and existing = ls_resources(type).key(rsrc)
|
149
147
|
|
150
|
-
|
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.
|
160
|
-
|
161
|
-
|
162
|
-
|
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
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
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 =>
|
363
|
-
field :MediaBox, :Type => Array, :Default =>
|
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 => [
|
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
|
+
|
data/lib/origami/parser.rb
CHANGED
@@ -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.
|
186
|
-
" (" + obj.
|
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
|