Class: HexaPDF::Font::TrueTypeWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/hexapdf/font/true_type_wrapper.rb

Overview

This class wraps a generic TrueType font object and provides the methods needed for working with the font in a PDF context.

TrueType fonts can be represented in two ways in PDF: As a simple font with Subtype TrueType or as a composite font using a Type2 CIDFont. The wrapper only supports the composite font case because:

  • By using a composite font more than 256 characters can be encoded with one font object.

  • Fonts for vertical writing can potentially be used.

  • The PDF specification recommends using a composite font (see PDF1.7 s9.9 at the end).

Additionally, TrueType fonts are always embedded.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, font, subset: true) ⇒ TrueTypeWrapper

Creates a new object wrapping the TrueType font for the PDF document.

If subset is true, the font is subset.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 121

def initialize(document, font, subset: true)
  @document = document
  @wrapped_font = font
  @subsetter = (subset ? HexaPDF::Font::TrueType::Subsetter.new(font) : nil)

  @cmap = font[:cmap].preferred_table
  if @cmap.nil?
    raise HexaPDF::Error, "No mapping table for Unicode characters found for TTF " \
      "font #{font.full_name}"
  end
  @dict = build_font_dict
  @document.register_listener(:complete_objects, &method(:complete_font_dict))

  @id_to_glyph = {}
  @codepoint_to_glyph = {}
  @encoded_glyphs = {}
end

Instance Attribute Details

#dictObject (readonly)

Returns the PDF font dictionary representing the wrapped font.



116
117
118
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 116

def dict
  @dict
end

#wrapped_fontObject (readonly)

Returns the wrapped TrueType font object.



113
114
115
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 113

def wrapped_font
  @wrapped_font
end

Instance Method Details

#decode_utf8(str) ⇒ Object

Returns an array of glyph objects representing the characters in the UTF-8 encoded string.



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 172

def decode_utf8(str)
  str.codepoints.map! do |c|
    @codepoint_to_glyph[c] ||=
      begin
        if (gid = @cmap[c])
          glyph(gid, +'' << c)
        else
          @document.config['font.on_missing_glyph'].call(+'' << c, font_type, @wrapped_font)
        end
      end
  end
end

#encode(glyph) ⇒ Object

Encodes the glyph and returns the code string.



186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 186

def encode(glyph)
  (@encoded_glyphs[glyph.id] ||=
    begin
      if glyph.kind_of?(InvalidGlyph)
        raise HexaPDF::Error, "Glyph for #{glyph.str.inspect} missing"
      end
      if @subsetter
        [[@subsetter.use_glyph(glyph.id)].pack('n'), glyph]
      else
        [[glyph.id].pack('n'), glyph]
      end
    end)[0]
end

#font_typeObject

Returns the type of the font, i.e. :TrueType.



140
141
142
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 140

def font_type
  :TrueType
end

#glyph(id, str = nil) ⇒ Object

Returns a Glyph object for the given glyph ID.

The optional argument str should be the string representation of the glyph. Only use it if it is known,

Note: Although this method is public, it should normally not be used by application code!



160
161
162
163
164
165
166
167
168
169
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 160

def glyph(id, str = nil)
  @id_to_glyph[id] ||=
    begin
      if id >= 0 && id < @wrapped_font[:maxp].num_glyphs
        Glyph.new(@wrapped_font, id, str || (+'' << (@cmap.gid_to_code(id) || 0xFFFD)))
      else
        @document.config['font.on_missing_glyph'].call("\u{FFFD}", font_type, @wrapped_font)
      end
    end
end

#scaling_factorObject

Returns the scaling factor for converting font units into PDF units.



145
146
147
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 145

def scaling_factor
  @scaling_factor ||= 1000.0 / @wrapped_font[:head].units_per_em
end

#subset?Boolean

Returns true if the wrapped TrueType font will be subset.



150
151
152
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 150

def subset?
  !@subsetter.nil?
end