File: string_width.rb

package info (click to toggle)
ruby-ttfunk 1.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,472 kB
  • sloc: ruby: 7,954; makefile: 7
file content (44 lines) | stat: -rw-r--r-- 1,133 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# frozen_string_literal: true

# Everything you never wanted to know about glyphs:
# http://chanae.walon.org/pub/ttf/ttf_glyphs.htm

# this code is a substantial reworking of:
# https://github.com/prawnpdf/ttfunk/blob/master/examples/metrics.rb

require 'ttfunk'

class Font
  attr_reader :file

  def initialize(path_to_file)
    @file = TTFunk::File.open(path_to_file)
  end

  def width_of(string)
    string.chars.sum { |char| character_width(char) }
  end

  def character_width(character)
    width_in_units = horizontal_metrics.for(glyph_id(character)).advance_width
    Float(width_in_units) / units_per_em
  end

  def units_per_em
    @units_per_em ||= file.header.units_per_em
  end

  def horizontal_metrics
    @horizontal_metrics ||= file.horizontal_metrics
  end

  def glyph_id(character)
    character_code = character.unpack1('U*')
    file.cmap.unicode.first[character_code]
  end
end

# >> din = Font.new("#{File.dirname(__FILE__)}/../../fonts/DIN/DINPro-Light.ttf")
# >> din.width_of("Hypertension")
# => 5.832
# which is correct! Hypertension in that font takes up about 5.832 em! It's over by maybe ... 0.015.