class HexaPDF::Type::FontType0

Represents a composite PDF font.

Composites fonts wrap a descendant CIDFont and use CIDs to identify glyphs. A CID can be encoded in one or more bytes and an associated CMap specifies how this encoding is done. Composite fonts also allow for vertical writing mode and support TrueType as well as OpenType fonts.

See: PDF1.7 s9.7

Public Instance Methods

bounding_box() click to toggle source

Returns the bounding box of the font or nil if it is not found.

# File lib/hexapdf/type/font_type0.rb, line 89
def bounding_box
  descendant_font.bounding_box
end
decode(string) click to toggle source

Decodes the given string into an array of CIDs.

# File lib/hexapdf/type/font_type0.rb, line 71
def decode(string)
  cmap.read_codes(string)
end
descendant_font() click to toggle source

Returns the CID font of this type 0 font.

# File lib/hexapdf/type/font_type0.rb, line 59
def descendant_font
  cache(:descendant_font) do
    document.wrap(self[:DescendantFonts][0])
  end
end
embedded?() click to toggle source

Returns true if the font is embedded.

# File lib/hexapdf/type/font_type0.rb, line 94
def embedded?
  descendant_font.embedded?
end
font_file() click to toggle source

Returns the embeeded font file object or nil if the font is not embedded.

# File lib/hexapdf/type/font_type0.rb, line 99
def font_file
  descendant_font.font_file
end
to_utf8(code) click to toggle source

Returns the UTF-8 string for the given code, or calls the configuration option 'font.on_missing_unicode_mapping' if no mapping was found.

# File lib/hexapdf/type/font_type0.rb, line 77
def to_utf8(code)
  to_unicode_cmap&.to_unicode(code) || ucs2_cmap&.to_unicode(code) ||
    missing_unicode_mapping(code)
end
width(code) click to toggle source

Returns the unscaled width of the given CID in glyph units, or 0 if the width for the code point is missing.

# File lib/hexapdf/type/font_type0.rb, line 84
def width(code)
  descendant_font.width(cmap.to_cid(code))
end
word_spacing_applicable?() click to toggle source

Returns whether word spacing is applicable when using this font.

Note that the return value is cached when accessed the first time.

See: PDF1.7 s9.3.3

# File lib/hexapdf/type/font_type0.rb, line 108
def word_spacing_applicable?
  @word_spacing_applicable ||= ((cmap.read_codes("\x20") && true) rescue false)
end
writing_mode() click to toggle source

Returns the writing mode which is either :horizontal or :vertical.

# File lib/hexapdf/type/font_type0.rb, line 66
def writing_mode
  cmap.wmode == 0 ? :horizontal : :vertical
end

Private Instance Methods

cmap() click to toggle source

Returns the CMap used for decoding strings for this font.

Note that the CMap is cached internally when accessed the first time.

# File lib/hexapdf/type/font_type0.rb, line 117
def cmap
  cache(:cmap) do
    val = self[:Encoding]
    if val.kind_of?(Symbol)
      HexaPDF::Font::CMap.for_name(val.to_s)
    elsif val.kind_of?(HexaPDF::Stream)
      HexaPDF::Font::CMap.parse(val.stream)
    else
      raise HexaPDF::Error, "Unknown value for font's encoding: #{self[:Encoding]}"
    end
  end
end
ucs2_cmap() click to toggle source

Returns the UCS-2 CMap used for extracting text when no ToUnicode CMap is available, or nil if the UCS-2 CMap could not be determined.

Note that the CMap is cached internally when accessed the first time.

See: PDF1.7 s9.10.2

# File lib/hexapdf/type/font_type0.rb, line 136
def ucs2_cmap
  cache(:ucs2_cmap) do
    encoding = self[:Encoding]
    system_info = descendant_font[:CIDSystemInfo]
    registry = system_info[:Registry]
    ordering = system_info[:Ordering]
    if (encoding.kind_of?(Symbol) && HexaPDF::Font::CMap.predefined?(encoding.to_s) &&
      encoding != :"Identity-H" && encoding != :"Identity-V") ||
        (registry == "Adobe" && ['GB1', 'CNS1', 'Japan1', 'Korea1'].include?(ordering))
      HexaPDF::Font::CMap.for_name("#{registry}-#{ordering}-UCS2")
    end
  end
end