Repository URL to install this package:
|
Version:
1.0.0.rc3.2 ▾
|
# encoding: utf-8
#
# pdf_object.rb : Handles Ruby to PDF object serialization
#
# Copyright April 2008, Gregory Brown. All Rights Reserved.
#
# This is free software. Please see the LICENSE and COPYING files for details.
# Top level Module
#
module Prawn
module Core #:nodoc:
module_function
if "".respond_to?(:encode)
# Ruby 1.9+
def utf8_to_utf16(str)
utf16 = "\xFE\xFF".force_encoding("UTF-16BE") + str.encode("UTF-16BE")
end
# encodes any string into a hex representation. The result is a string
# with only 0-9 and a-f characters. That result is valid ASCII so tag
# it as such to account for behaviour of different ruby VMs
def string_to_hex(str)
str.unpack("H*").first.force_encoding("ascii")
end
else
# Ruby 1.8
def utf8_to_utf16(str)
utf16 = "\xFE\xFF"
str.codepoints do |cp|
if cp < 0x10000 # Basic Multilingual Plane
utf16 << [cp].pack("n")
else
# pull out high/low 10 bits
hi, lo = (cp - 0x10000).divmod(2**10)
# encode a surrogate pair
utf16 << [0xD800 + hi, 0xDC00 + lo].pack("n*")
end
end
utf16
end
def string_to_hex(str)
str.unpack("H*").first
end
end
# Serializes Ruby objects to their PDF equivalents. Most primitive objects
# will work as expected, but please note that Name objects are represented
# by Ruby Symbol objects and Dictionary objects are represented by Ruby hashes
# (keyed by symbols)
#
# Examples:
#
# PdfObject(true) #=> "true"
# PdfObject(false) #=> "false"
# PdfObject(1.2124) #=> "1.2124"
# PdfObject("foo bar") #=> "(foo bar)"
# PdfObject(:Symbol) #=> "/Symbol"
# PdfObject(["foo",:bar, [1,2]]) #=> "[foo /bar [1 2]]"
#
def PdfObject(obj, in_content_stream = false)
case(obj)
when NilClass then "null"
when TrueClass then "true"
when FalseClass then "false"
when Numeric
if (str = String(obj)) =~ /e/i
# scientific notation is not supported in PDF
sprintf("%.16f", obj).gsub(/\.?0+\z/, "")
else
str
end
when Array
"[" << obj.map { |e| PdfObject(e, in_content_stream) }.join(' ') << "]"
when Prawn::Core::LiteralString
obj = obj.gsub(/[\\\n\r\t\b\f\(\)]/n) { |m| "\\#{m}" }
"(#{obj})"
when Time
obj = obj.strftime("D:%Y%m%d%H%M%S%z").chop.chop + "'00'"
obj = obj.gsub(/[\\\n\r\t\b\f\(\)]/n) { |m| "\\#{m}" }
"(#{obj})"
when Prawn::Core::ByteString
"<" << obj.unpack("H*").first << ">"
when String
obj = utf8_to_utf16(obj) unless in_content_stream
"<" << string_to_hex(obj) << ">"
when Symbol
"/" + obj.to_s.unpack("C*").map { |n|
if n < 33 || n > 126 || [35,40,41,47,60,62].include?(n)
"#" + n.to_s(16).upcase
else
[n].pack("C*")
end
}.join
when Hash
output = "<< "
obj.each do |k,v|
unless String === k || Symbol === k
raise Prawn::Errors::FailedObjectConversion,
"A PDF Dictionary must be keyed by names"
end
output << PdfObject(k.to_sym, in_content_stream) << " " <<
PdfObject(v, in_content_stream) << "\n"
end
output << ">>"
when Prawn::Core::Reference
obj.to_s
when Prawn::Core::NameTree::Node
PdfObject(obj.to_hash)
when Prawn::Core::NameTree::Value
PdfObject(obj.name) + " " + PdfObject(obj.value)
when Prawn::OutlineRoot, Prawn::OutlineItem
PdfObject(obj.to_hash)
else
raise Prawn::Errors::FailedObjectConversion,
"This object cannot be serialized to PDF (#{obj.inspect})"
end
end
end
end