class PDF::Reader::Font
Represents a single font PDF object and provides some useful methods for extracting info. Mainly used for converting text to UTF-8.
Attributes
basefont[R]
cid_default_width[R]
cid_widths[R]
descendantfonts[RW]
encoding[RW]
first_char[R]
font_descriptor[R]
last_char[R]
subtype[RW]
tounicode[RW]
widths[R]
Public Class Methods
new(ohash = nil, obj = nil)
click to toggle source
# File lib/pdf/reader/font.rb, line 38 def initialize(ohash = nil, obj = nil) if ohash.nil? || obj.nil? $stderr.puts "DEPREACTION WARNING - PDF::Reader::Font.new should be called with 2 args" return end @ohash = ohash @tounicode = nil extract_base_info(obj) extract_descriptor(obj) extract_descendants(obj) @width_calc = build_width_calculator @encoding ||= PDF::Reader::Encoding.new(:StandardEncoding) end
Public Instance Methods
basefont=(font)
click to toggle source
# File lib/pdf/reader/font.rb, line 54 def basefont=(font) $stderr.puts "Font#basefont= is deprecated and will be removed in the 2.0 release" @encoding ||= default_encoding(font) @basefont = font end
glyph_width(code_point)
click to toggle source
looks up the specified codepoint and returns a value that is in (pdf) glyph space, which is 1000 glyph units = 1 text space unit
# File lib/pdf/reader/font.rb, line 74 def glyph_width(code_point) if code_point.is_a?(String) code_point = code_point.unpack(encoding.unpack).first end @cached_widths ||= {} @cached_widths[code_point] ||= @width_calc.glyph_width(code_point) end
to_utf8(params)
click to toggle source
# File lib/pdf/reader/font.rb, line 60 def to_utf8(params) if @tounicode to_utf8_via_cmap(params) else to_utf8_via_encoding(params) end end
unpack(data)
click to toggle source
# File lib/pdf/reader/font.rb, line 68 def unpack(data) data.unpack(encoding.unpack) end
Private Instance Methods
build_width_calculator()
click to toggle source
# File lib/pdf/reader/font.rb, line 96 def build_width_calculator if @subtype == :Type0 PDF::Reader::WidthCalculator::TypeZero.new(self) elsif @subtype == :Type1 if @font_descriptor.nil? PDF::Reader::WidthCalculator::BuiltIn.new(self) else PDF::Reader::WidthCalculator::TypeOneOrThree .new(self) end elsif @subtype == :Type3 PDF::Reader::WidthCalculator::TypeOneOrThree.new(self) elsif @subtype == :TrueType PDF::Reader::WidthCalculator::TrueType.new(self) elsif @subtype == :CIDFontType0 || @subtype == :CIDFontType2 PDF::Reader::WidthCalculator::Composite.new(self) else PDF::Reader::WidthCalculator::TypeOneOrThree.new(self) end end
default_encoding(font_name)
click to toggle source
# File lib/pdf/reader/font.rb, line 85 def default_encoding(font_name) case font_name.to_s when "Symbol" then PDF::Reader::Encoding.new(:SymbolEncoding) when "ZapfDingbats" then PDF::Reader::Encoding.new(:ZapfDingbatsEncoding) else PDF::Reader::Encoding.new(:StandardEncoding) end end
extract_base_info(obj)
click to toggle source
# File lib/pdf/reader/font.rb, line 116 def extract_base_info(obj) @subtype = @ohash.object(obj[:Subtype]) @basefont = @ohash.object(obj[:BaseFont]) if @ohash.object(obj[:Encoding]) @encoding = PDF::Reader::Encoding.new(@ohash.object(obj[:Encoding])) else @encoding = default_encoding(@basefont) end @widths = @ohash.object(obj[:Widths]) || [] @first_char = @ohash.object(obj[:FirstChar]) @last_char = @ohash.object(obj[:LastChar]) # CID Fonts are not required to have a W or DW entry, if they don't exist, # the default cid width = 1000, see Section 9.7.4.1 PDF 32000-1:2008 pp 269 @cid_widths = @ohash.object(obj[:W]) || [] @cid_default_width = @ohash.object(obj[:DW]) || 1000 if obj[:ToUnicode] # ToUnicode is optional for Type1 and Type3 stream = @ohash.object(obj[:ToUnicode]) @tounicode = PDF::Reader::CMap.new(stream.unfiltered_data) end end
extract_descendants(obj)
click to toggle source
# File lib/pdf/reader/font.rb, line 151 def extract_descendants(obj) return unless obj[:DescendantFonts] # per PDF 32000-1:2008 pp. 280 :DescendentFonts is: # A one-element array specifying the CIDFont dictionary that is the # descendant of this Type 0 font. descendants = @ohash.object(obj[:DescendantFonts]) @descendantfonts = descendants.map { |desc| PDF::Reader::Font.new(@ohash, @ohash.object(desc)) } end
extract_descriptor(obj)
click to toggle source
# File lib/pdf/reader/font.rb, line 140 def extract_descriptor(obj) if obj[:FontDescriptor] # create a font descriptor object if we can, in other words, unless this is # a CID Font fd = @ohash.object(obj[:FontDescriptor]) @font_descriptor = PDF::Reader::FontDescriptor.new(@ohash, fd) else @font_descriptor = nil end end
to_utf8_via_cmap(params)
click to toggle source
# File lib/pdf/reader/font.rb, line 162 def to_utf8_via_cmap(params) if params.class == Fixnum [ @tounicode.decode(params) || PDF::Reader::Encoding::UNKNOWN_CHAR ].flatten.pack("U*") elsif params.class == String params.unpack(encoding.unpack).map { |c| @tounicode.decode(c) || PDF::Reader::Encoding::UNKNOWN_CHAR }.flatten.pack("U*") elsif params.class == Array params.collect { |param| to_utf8_via_cmap(param) } else params end end
to_utf8_via_encoding(params)
click to toggle source
# File lib/pdf/reader/font.rb, line 178 def to_utf8_via_encoding(params) if encoding.kind_of?(String) raise UnsupportedFeatureError, "font encoding '#{encoding}' currently unsupported" end if params.class == Fixnum encoding.int_to_utf8_string(params) elsif params.class == String encoding.to_utf8(params) elsif params.class == Array params.collect { |param| to_utf8_via_encoding(param) } else params end end