class HexaPDF::Type::FontSimple

Represents a simple PDF font.

A simple font has only single-byte character codes and only supports horizontal metrics.

See: PDF1.7 s9.6

Public Instance Methods

decode(string) click to toggle source

Decodes the given string into an array of character codes.

# File lib/hexapdf/type/font_simple.rb, line 83
def decode(string)
  string.bytes
end
encoding() click to toggle source

Returns the encoding object used for this font.

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

# File lib/hexapdf/type/font_simple.rb, line 58
def encoding
  cache(:encoding) do
    case (val = self[:Encoding])
    when Symbol
      encoding = HexaPDF::Font::Encoding.for_name(val)
      encoding = encoding_from_font if encoding.nil?
      encoding
    when HexaPDF::Dictionary
      encoding = val[:BaseEncoding] && HexaPDF::Font::Encoding.for_name(val[:BaseEncoding])
      encoding ||= if embedded? || symbolic?
                     encoding_from_font
                   else
                     HexaPDF::Font::Encoding.for_name(:StandardEncoding)
                   end
      encoding = difference_encoding(encoding, val[:Differences]) if val.key?(:Differences)
      encoding
    when nil
      encoding_from_font
    else
      raise HexaPDF::Error, "Unknown value for font's encoding: #{self[:Encoding]}"
    end
  end
end
symbolic?() click to toggle source

Returns true if the font is a symbolic font, false if it is not, and nil if it is not known.

# File lib/hexapdf/type/font_simple.rb, line 116
def symbolic?
  self[:FontDescriptor]&.flagged?(:symbolic)
end
to_utf8(code) click to toggle source

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

# File lib/hexapdf/type/font_simple.rb, line 89
def to_utf8(code)
  to_unicode_cmap&.to_unicode(code) || encoding.unicode(code) || missing_unicode_mapping(code)
end
width(code) click to toggle source

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

# File lib/hexapdf/type/font_simple.rb, line 95
def width(code)
  widths = self[:Widths]
  first_char = self[:FirstChar]
  last_char = self[:LastChar]

  if widths && code >= first_char && code <= last_char
    widths[code - first_char]
  elsif widths && key?(:FontDescriptor)
    self[:FontDescriptor][:MissingWidth]
  else
    0
  end
end
word_spacing_applicable?() click to toggle source

Returns whether word spacing is applicable when using this font.

Always returns true for simple fonts.

See: PDF1.7 s9.3.3

# File lib/hexapdf/type/font_simple.rb, line 125
def word_spacing_applicable?
  true
end
writing_mode() click to toggle source

Returns the writing mode which is always :horizontal for simple fonts like Type1.

# File lib/hexapdf/type/font_simple.rb, line 110
def writing_mode
  :horizontal
end

Private Instance Methods

difference_encoding(base_encoding, differences) click to toggle source

Uses the given base encoding and the differences array to create a DifferenceEncoding object.

# File lib/hexapdf/type/font_simple.rb, line 140
def difference_encoding(base_encoding, differences)
  unless differences[0].kind_of?(Integer)
    raise HexaPDF::Error, "Invalid /Differences array in Encoding dict"
  end

  encoding = HexaPDF::Font::Encoding::DifferenceEncoding.new(base_encoding)
  code = nil
  differences.each do |entry|
    case entry
    when Symbol
      encoding.code_to_name[code] = entry
      code += 1
    when Integer
      code = entry
    else
      raise HexaPDF::Error, "Invalid /Differences array in Encoding dict"
    end
  end
  encoding
end
encoding_from_font() click to toggle source

Tries to read the encoding from the embedded font.

This method has to be implemented in subclasses.

# File lib/hexapdf/type/font_simple.rb, line 134
def encoding_from_font
  raise NotImplementedError
end
perform_validation(ignore_missing_font_fields: false) { |"Required field #{field} is not set", false| ... } click to toggle source

Validates the simple font dictionary.

If ignore_missing_font_fields is true, then missing fields are ignored (should only be used for backwards-compatibility regarding the Standard 14 Type1 fonts).

Calls superclass method HexaPDF::Dictionary#perform_validation
# File lib/hexapdf/type/font_simple.rb, line 165
def perform_validation(ignore_missing_font_fields: false)
  super()
  return if ignore_missing_font_fields

  [:FirstChar, :LastChar, :Widths].each do |field|
    yield("Required field #{field} is not set", false) if self[field].nil?
  end

  if key?(:Widths) && key?(:LastChar) && key?(:FirstChar) &&
      self[:Widths].length != (self[:LastChar] - self[:FirstChar] + 1)
    yield("Invalid number of entries in field Widths", false)
  end
end