Class: Prawn::Fonts::TTF

Inherits:
Prawn::Font show all
Defined in:
lib/prawn/fonts/ttf.rb

Overview

Note:

You shouldn’t use this class directly.

TrueType font.

Direct Known Subclasses

DFont, OTF, TTC

Defined Under Namespace

Classes: Error, NoPostscriptName, NoUnicodeCMap

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, name, options = {}) ⇒ TTF

Returns a new instance of TTF.

Parameters:

  • document (Prawn::Document)
  • name (String)

    font file path

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :family (String)
  • :style (Symbol)


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/prawn/fonts/ttf.rb', line 134

def initialize(document, name, options = {})
  super

  @ttf = read_ttf_file
  @subsets =
    if full_font_embedding
      FullFontSubsetsCollection.new(@ttf)
    else
      TTFunk::SubsetCollection.new(@ttf)
    end
  @italic_angle = nil

  @attributes = {}
  @bounding_boxes = {}
  @char_widths = {}
  @has_kerning_data = @ttf.kerning.exists? && @ttf.kerning.tables.any?

  @ascender = Integer(@ttf.ascent * scale_factor)
  @descender = Integer(@ttf.descent * scale_factor)
  @line_gap = Integer(@ttf.line_gap * scale_factor)
end

Instance Attribute Details

#subsetsObject (readonly)

Returns the value of attribute subsets.



58
59
60
# File 'lib/prawn/fonts/ttf.rb', line 58

def subsets
  @subsets
end

#ttfTTFunk::File (readonly)

TTFunk font.

Returns:

  • (TTFunk::File)


57
58
59
# File 'lib/prawn/fonts/ttf.rb', line 57

def ttf
  @ttf
end

Instance Method Details

#basenameString

Base name of the font.

Returns:

  • (String)


240
241
242
# File 'lib/prawn/fonts/ttf.rb', line 240

def basename
  @basename ||= @ttf.name.postscript_name
end

#bboxArray(Number, Number, Number, Number)

The font bbox.

Returns:

  • (Array(Number, Number, Number, Number))


184
185
186
# File 'lib/prawn/fonts/ttf.rb', line 184

def bbox
  @bbox ||= @ttf.bbox.map { |i| Integer(i * scale_factor) }
end

#character_count(str) ⇒ Integer

Returns the number of characters in ‘str` (a UTF-8-encoded string).

Parameters:

  • str (String)

Returns:

  • (Integer)


354
355
356
# File 'lib/prawn/fonts/ttf.rb', line 354

def character_count(str)
  str.length
end

#compute_width_of(string, options = {}) ⇒ Number

Compute width of a string at the specified size, optionally with kerning applied.

Parameters:

  • string (String)

    must be encoded as UTF-8

  • options (Hash{Symbol => any}) (defaults to: {})

Options Hash (options):

  • :size (Number)
  • :kerning (Boolean) — default: false

Returns:

  • (Number)


164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/prawn/fonts/ttf.rb', line 164

def compute_width_of(string, options = {})
  scale = (options[:size] || size) / 1000.0
  if options[:kerning]
    kern(string).reduce(0) { |s, r|
      if r.is_a?(Numeric)
        s - r
      else
        r.reduce(s) { |a, e| a + character_width_by_code(e) }
      end
    } * scale
  else
    string.codepoints.reduce(0) { |s, r|
      s + character_width_by_code(r)
    } * scale
  end
end

#encode_text(text, options = {}) ⇒ Array<Array(0, (String, Array)>]

Perform any changes to the string that need to happen before it is rendered to the canvas. Returns an array of subset “chunks”, where the even-numbered indices are the font subset number, and the following entry element is either a string or an array (for kerned text).

Parameters:

  • text (String)

    must be in UTF-8 encoding

  • options (Hash{Symbol => any}) (defaults to: {})

Options Hash (options):

  • :kerning (Boolean)

Returns:

  • (Array<Array(0, (String, Array)>])

    Array<Array(0, (String, Array)>]



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/prawn/fonts/ttf.rb', line 204

def encode_text(text, options = {})
  text = text.chomp

  if options[:kerning]
    last_subset = nil
    kern(text).reduce([]) do |result, element|
      if element.is_a?(Numeric)
        unless result.last[1].is_a?(Array)
          result.last[1] = [result.last[1]]
        end
        result.last[1] << element
        result
      else
        encoded = @subsets.encode(element)

        if encoded.first[0] == last_subset
          result.last[1] << encoded.first[1]
          encoded.shift
        end

        if encoded.any?
          last_subset = encoded.last[0]
          result + encoded
        else
          result
        end
      end
    end
  else
    @subsets.encode(text.unpack('U*'))
  end
end

#glyph_present?(char) ⇒ Boolean

Does this font has a glyph for the character?

Parameters:

  • char (String)

Returns:

  • (Boolean)


345
346
347
348
# File 'lib/prawn/fonts/ttf.rb', line 345

def glyph_present?(char)
  code = char.codepoints.first
  cmap[code].positive?
end

#has_kerning_data?Boolean

Does this font contain kerning data.

Returns:

  • (Boolean)


191
192
193
# File 'lib/prawn/fonts/ttf.rb', line 191

def has_kerning_data? # rubocop: disable Naming/PredicateName
  @has_kerning_data
end

#normalize_encoding(text) ⇒ String

Normlize text to a compatible encoding.

Parameters:

  • text (String)

Returns:

  • (String)


325
326
327
328
329
330
331
# File 'lib/prawn/fonts/ttf.rb', line 325

def normalize_encoding(text)
  text.encode(::Encoding::UTF_8)
rescue StandardError
  raise Prawn::Errors::IncompatibleStringEncoding,
    "Encoding #{text.encoding} can not be transparently converted to UTF-8. " \
      'Please ensure the encoding of the string you are attempting to use is set correctly'
end

#to_utf8(text) ⇒ String

Encode text to UTF-8.

Parameters:

  • text (String)

Returns:

  • (String)


337
338
339
# File 'lib/prawn/fonts/ttf.rb', line 337

def to_utf8(text)
  text.encode('UTF-8')
end

#unicode?true

Does this font support Unicode?

Returns:

  • (true)


63
64
65
# File 'lib/prawn/fonts/ttf.rb', line 63

def unicode?
  true
end