Module: PDF::Core
- Defined in:
- lib/pdf/core.rb,
lib/pdf/core/page.rb,
lib/pdf/core/text.rb,
lib/pdf/core/utils.rb,
lib/pdf/core/stream.rb,
lib/pdf/core/filters.rb,
lib/pdf/core/renderer.rb,
lib/pdf/core/name_tree.rb,
lib/pdf/core/reference.rb,
lib/pdf/core/pdf_object.rb,
lib/pdf/core/annotations.rb,
lib/pdf/core/byte_string.rb,
lib/pdf/core/filter_list.rb,
lib/pdf/core/destinations.rb,
lib/pdf/core/object_store.rb,
lib/pdf/core/outline_item.rb,
lib/pdf/core/outline_root.rb,
lib/pdf/core/page_geometry.rb,
lib/pdf/core/document_state.rb,
lib/pdf/core/graphics_state.rb,
lib/pdf/core/literal_string.rb
Overview
PDF::Core is concerned with low-level PDF functions such as serialization, content streams and such.
It’s extracted from Prawn but at the moment is not entirely independent.
Defined Under Namespace
Modules: Annotations, Destinations, Errors, Filters, NameTree, PageGeometry, Text, Utils Classes: ByteString, DocumentState, FilterList, GraphicState, GraphicStateStack, LiteralString, ObjectStore, OutlineItem, OutlineRoot, Page, Reference, Renderer, Stream
Constant Summary collapse
- ESCAPED_NAME_CHARACTERS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Characters to escape in name objects
(1..32).to_a + [35, 40, 41, 47, 60, 62] + (127..255).to_a
- STRING_ESCAPE_MAP =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
How to escape special characters in literal strings
{ '(' => '\(', ')' => '\)', '\\' => '\\\\', "\r" => '\r' }.freeze
Class Method Summary collapse
-
.pdf_object(obj, in_content_stream = false) ⇒ String
Serializes Ruby objects to their PDF equivalents.
-
.real(num) ⇒ String
Serializes floating number into a string.
-
.real_params(array) ⇒ String
Serializes a n array of numbers.
-
.string_to_hex(str) ⇒ String
Encodes any string into a hex representation.
-
.utf8_to_utf16(str) ⇒ String
private
Converts string to UTF-16BE encoding as expected by PDF.
Class Method Details
.pdf_object(obj, in_content_stream = false) ⇒ String
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:
pdf_object(true) #=> "true"
pdf_object(false) #=> "false"
pdf_object(1.2124) #=> "1.2124"
pdf_object('foo bar') #=> "(foo bar)"
pdf_object(:Symbol) #=> "/Symbol"
pdf_object(['foo',:bar, [1,2]]) #=> "[foo /bar [1 2]]"
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/pdf/core/pdf_object.rb', line 77 def pdf_object(obj, in_content_stream = false) case obj when NilClass then 'null' when TrueClass then 'true' when FalseClass then 'false' when Numeric num_string = obj.is_a?(Integer) ? String(obj) : real(obj) # Truncate trailing fraction zeroes num_string.sub!(/(\d*)((\.0*$)|(\.0*[1-9]*)0*$)/, '\1\4') num_string when Array "[#{obj.map { |e| pdf_object(e, in_content_stream) }.join(' ')}]" when PDF::Core::LiteralString obj = obj.gsub(/[\\\r()]/, STRING_ESCAPE_MAP) "(#{obj})" when Time obj = "#{obj.strftime('D:%Y%m%d%H%M%S%z').chop.chop}'00'" obj = obj.gsub(/[\\\r()]/, STRING_ESCAPE_MAP) "(#{obj})" when PDF::Core::ByteString "<#{obj.unpack1('H*')}>" when String obj = utf8_to_utf16(obj) unless in_content_stream "<#{string_to_hex(obj)}>" when Symbol (@symbol_str_cache ||= {})[obj] ||= (+'/') << obj.to_s.unpack('C*').map { |n| if ESCAPED_NAME_CHARACTERS.include?(n) "##{n.to_s(16).upcase}" else n.chr end }.join when ::Hash output = +'<< ' obj .sort_by { |k, _v| k.to_s } .each do |(k, v)| unless k.is_a?(String) || k.is_a?(Symbol) raise PDF::Core::Errors::FailedObjectConversion, 'A PDF Dictionary must be keyed by names' end output << pdf_object(k.to_sym, in_content_stream) << ' ' << pdf_object(v, in_content_stream) << "\n" end output << '>>' when PDF::Core::Reference obj.to_s when PDF::Core::NameTree::Node, PDF::Core::OutlineRoot, PDF::Core::OutlineItem pdf_object(obj.to_hash) when PDF::Core::NameTree::Value "#{pdf_object(obj.name)} #{pdf_object(obj.value)}" else raise PDF::Core::Errors::FailedObjectConversion, "This object cannot be serialized to PDF (#{obj.inspect})" end end |
.real(num) ⇒ String
Serializes floating number into a string
11 12 13 14 15 |
# File 'lib/pdf/core/pdf_object.rb', line 11 def real(num) result = format('%.5f', num) result.sub!(/((?<!\.)0)+\z/, '') result end |
.real_params(array) ⇒ String
Serializes a n array of numbers. This is specifically for use in PDF content streams.
22 23 24 |
# File 'lib/pdf/core/pdf_object.rb', line 22 def real_params(array) array.map { |e| real(e) }.join(' ') end |
.string_to_hex(str) ⇒ String
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.
42 43 44 |
# File 'lib/pdf/core/pdf_object.rb', line 42 def string_to_hex(str) str.unpack1('H*').force_encoding(::Encoding::US_ASCII) end |
.utf8_to_utf16(str) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Converts string to UTF-16BE encoding as expected by PDF.
31 32 33 34 |
# File 'lib/pdf/core/pdf_object.rb', line 31 def utf8_to_utf16(str) (+"\xFE\xFF").force_encoding(::Encoding::UTF_16BE) << str.encode(::Encoding::UTF_16BE) end |