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, pdf_object: nil, subset: true) ⇒ TrueTypeWrapper

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

The optional argument pdf_object can be used to set the PDF font object that this wrapper should be associated with. If no object is set, a suitable one is automatically created.

If subset is true, the font is subset.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 127

def initialize(document, font, pdf_object: nil, subset: true)
  @wrapped_font = font
  @missing_glyph_callable = document.config['font.on_missing_glyph']

  @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
  @pdf_object = pdf_object || create_pdf_object(document)

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

Instance Attribute Details

#pdf_objectObject (readonly)

Returns the PDF object associated with the wrapper.



119
120
121
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 119

def pdf_object
  @pdf_object
end

#wrapped_fontObject (readonly)

Returns the wrapped TrueType font object.



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

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.



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 178

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

#encode(glyph) ⇒ Object

Encodes the glyph and returns the code string.



192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 192

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.



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

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!



166
167
168
169
170
171
172
173
174
175
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 166

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
        @missing_glyph_callable.call("\u{FFFD}", font_type, @wrapped_font)
      end
    end
end

#scaling_factorObject

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



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

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.

Returns:

  • (Boolean)


156
157
158
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 156

def subset?
  !@subsetter.nil?
end