lib/origami/page.rb in origami-1.2.5 vs lib/origami/page.rb in origami-1.2.6
- old
+ new
@@ -25,10 +25,13 @@
module Origami
class PDF
+ #
+ # Appends a page or list of pages to the end of the page tree.
+ #
def append_page(page = Page.new, *more)
raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
pages = [ page ].concat(more).map! do |pg|
if pg.pdf and pg.pdf != self
@@ -50,10 +53,13 @@
end
self
end
+ #
+ # Inserts a page at position _index_ into the document.
+ #
def insert_page(index, page)
raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
# Page from another document must be exported.
page = page.export if page.pdf and page.pdf != self
@@ -106,99 +112,138 @@
end
module ResourcesHolder
- def add_extgstate(name, extgstate)
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
-
- target.ExtGState ||= {}
- target.ExtGState[name] = extgstate
-
- self
+ def add_extgstate(extgstate, name = nil)
+ add_resource(Resources::EXTGSTATE, extgstate, name)
end
- def add_colorspace(name, colorspace)
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
-
- csdir = target[:ColorSpace] ||= {}
- (csdir.is_a?(Reference) ? csdir.solve : csdir)[name] = colorspace
+ def add_colorspace(colorspace, name = nil)
+ add_resource(Resources::COLORSPACE, colorspace, name)
+ end
- self
+ def add_pattern(pattern, name = nil)
+ add_resource(Resources::PATTERN, pattern, name)
end
- def add_pattern(name, pattern)
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
+ def add_shading(shading, name = nil)
+ add_resource(Resources::SHADING, shading, name)
+ end
- target.Pattern ||= {}
- target.Pattern[name] = pattern
-
- self
+ def add_xobject(xobject, name = nil)
+ add_resource(Resources::XOBJECT, xobject, name)
end
- def add_shading(name, shading)
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
+ def add_font(font, name = nil)
+ add_resource(Resources::FONT, font, name)
+ end
- target.Shading ||= {}
- target.Shading[name] = shading
-
- self
+ def add_properties(properties, name = nil)
+ add_resource(Resources::PROPERTIES, properties, name)
end
- def add_xobject(name, xobject)
+ def add_resource(type, rsrc, name = nil)
+ return existing if not name and existing = ls_resources(type).key(rsrc)
+
+ name = new_id(type) unless name
target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
- target.XObject ||= {}
- target.XObject[name] = xobject
-
- self
+ rsrc_dict = target.send(type) || (target[type] = Dictionary.new)
+ rsrc_dict[name] = rsrc
+
+ name
end
-
- def add_font(name, font)
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
- target.Font ||= {}
- target.Font[name] = font
+ def ls_resources(type)
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
- self
+ rsrc = {}
+ (target.send(type) || {}).each_pair do |name, obj|
+ rsrc[name.value] = obj.solve
+ end
+
+ rsrc
end
- def add_properties(name, properties)
- target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
+ def extgstates; ls_resources(Resources::EXTGSTATE) end
+ def colorspaces; ls_resources(Resources::COLORSPACE) end
+ def patterns; ls_resources(Resources::PATTERN) end
+ def shadings; ls_resources(Resources::SHADING) end
+ def xobjects; ls_resources(Resources::XOBJECT) end
+ def fonts; ls_resources(Resources::FONT) end
+ def properties; ls_resources(Resources::PROPERTIES) end
+ def resources;
+ self.extgstates.
+ merge self.colorspaces.
+ merge self.patterns.
+ merge self.shadings.
+ merge self.xobjects.
+ merge self.fonts.
+ merge self.properties
+ end
- target.Properties ||= {}
- target.Properties[name] = properties
-
- self
+ private
+
+ def new_id(type, prefix = nil) #:nodoc:
+ prefix ||=
+ {
+ Resources::EXTGSTATE => 'ExtG',
+ Resources::COLORSPACE => 'CS',
+ Resources::PATTERN => 'P',
+ Resources::SHADING => 'Sh',
+ Resources::XOBJECT => 'Im',
+ Resources::FONT => 'F',
+ Resources::PROPERTIES => 'Pr'
+ }[type]
+
+ rsrc = ls_resources(type)
+ n = '1'
+
+ while rsrc.include? (prefix + n).to_sym
+ n.next!
+ end
+
+ (prefix + n).to_sym
end
-
+
+ def new_extgstate_id; new_id(Resources::EXTGSTATE) end
+ def new_colorspace_id; new_id(Resources::COLORSPACE) end
+ def new_pattern_id; new_id(Resources::PATTERN) end
+ def new_shading_id; new_id(Resources::SHADING) end
+ def new_xobject_id; new_id(Resources::XOBJECT) end
+ def new_font_id; new_name(Resources::FONT) end
+ def new_properties_id; new_name(Resources::PROPERTIES) end
end
#
# Class representing a Resources Dictionary for a Page.
#
class Resources < Dictionary
include StandardObject
include ResourcesHolder
- field :ExtGState, :Type => Dictionary
- field :ColorSpace, :Type => Dictionary
- field :Pattern, :Type => Dictionary
- field :Shading, :Type => Dictionary, :Version => "1.3"
- field :XObject, :Type => Dictionary
- field :Font, :Type => Dictionary
+ EXTGSTATE = :ExtGState
+ COLORSPACE = :ColorSpace
+ PATTERN = :Pattern
+ SHADING = :Shading
+ XOBJECT = :XObject
+ FONT = :Font
+ PROPERTIES = :Properties
+
+ field EXTGSTATE, :Type => Dictionary
+ field COLORSPACE, :Type => Dictionary
+ field PATTERN, :Type => Dictionary
+ field SHADING, :Type => Dictionary, :Version => "1.3"
+ field XOBJECT, :Type => Dictionary
+ field FONT, :Type => Dictionary
field :ProcSet, :Type => Array
- field :Properties, :Type => Dictionary, :Version => "1.2"
+ field PROPERTIES, :Type => Dictionary, :Version => "1.2"
def pre_build
- unless self.Font
- fnt = Font::Type1::Standard::Helvetica.new.pre_build
- fnt.Name = :F1
-
- add_font(fnt.Name, fnt)
- end
+ add_font(Font::Type1::Standard::Helvetica.new.pre_build) unless self.Font
super
end
end
@@ -345,30 +390,59 @@
pageset.each do |node|
node.Parent = self
end
end
end
+
+ # Forward declaration.
+ class ContentStream < Stream; end
#
# Class representing a Page in the PDF document.
#
class Page < Dictionary
include StandardObject
include ResourcesHolder
+
+ module Format
+ A0 = Rectangle[:width => 2384, :height => 3370]
+ A1 = Rectangle[:width => 1684, :height => 2384]
+ A2 = Rectangle[:width => 1191, :height => 1684]
+ A3 = Rectangle[:width => 842, :height => 1191]
+ A4 = Rectangle[:width => 595, :height => 842]
+ A5 = Rectangle[:width => 420, :height => 595]
+ A6 = Rectangle[:width => 298, :height => 420]
+ A7 = Rectangle[:width => 210, :height => 298]
+ A8 = Rectangle[:width => 147, :height => 210]
+ A9 = Rectangle[:width => 105, :height => 147]
+ A10 = Rectangle[:width => 74, :height => 105]
+
+ B0 = Rectangle[:width => 2836, :height => 4008]
+ B1 = Rectangle[:width => 2004, :height => 2835]
+ B2 = Rectangle[:width => 1417, :height => 2004]
+ B3 = Rectangle[:width => 1001, :height => 1417]
+ B4 = Rectangle[:width => 709, :height => 1001]
+ B5 = Rectangle[:width => 499, :height => 709]
+ B6 = Rectangle[:width => 354, :height => 499]
+ B7 = Rectangle[:width => 249, :height => 354]
+ B8 = Rectangle[:width => 176, :height => 249]
+ B9 = Rectangle[:width => 125, :height => 176]
+ B10 = Rectangle[:width => 88, :height => 125]
+ end
field :Type, :Type => Name, :Default => :Page, :Required => true
field :Parent, :Type => Dictionary, :Required => true
field :LastModified, :Type => String, :Version => "1.3"
- field :Resources, :Type => Dictionary, :Required => true
- field :MediaBox, :Type => Array, :Default => Rectangle[ :llx => 0, :lly => 0, :urx => 795, :ury => 842 ], :Required => true
+ field :Resources, :Type => Resources, :Required => true
+ field :MediaBox, :Type => Array, :Default => Format::A4, :Required => true
field :CropBox, :Type => Array
field :BleedBox, :Type => Array, :Version => "1.3"
field :TrimBox, :Type => Array, :Version => "1.3"
field :ArtBox, :Type => Array, :Version => "1.3"
field :BoxColorInfo, :Type => Dictionary, :Version => "1.4"
- field :Contents, :Type => [ Stream, Array ]
+ field :Contents, :Type => [ ContentStream, Array ]
field :Rotate, :Type => Integer, :Default => 0
field :Group, :Type => Dictionary, :Version => "1.4"
field :Thumb, :Type => Stream
field :B, :Type => Array, :Version => "1.1"
field :Dur, :Type => Integer, :Version => "1.1"
@@ -391,21 +465,10 @@
super(hash)
set_indirect(true)
end
- def render(engine) #:nodoc:
- contents = self.Contents
- return unless contents.is_a? Stream
-
- unless contents.is_a? ContentStream
- contents = ContentStream.new(contents.data)
- end
-
- contents.render(engine)
- end
-
def pre_build
self.Resources = Resources.new.pre_build unless self.has_key?(:Resources)
super
end
@@ -592,5 +655,6 @@
field :Prev, :Type => Dictionary
field :Dur, :Type => Number
end
end
+