Class: TTFunk::Table::Glyf::Compound

Inherits:
Object
  • Object
show all
Includes:
Reader
Defined in:
lib/ttfunk/table/glyf/compound.rb

Overview

Composite TrueType glyph.

Defined Under Namespace

Classes: Component

Constant Summary collapse

ARG_1_AND_2_ARE_WORDS =

Flags bit 0: arg1 and arg2 are words.

0x0001
WE_HAVE_A_SCALE =

Flags bit 3: there is a simple scale for the component.

0x0008
MORE_COMPONENTS =

Flags bit 5: at least one more glyph after this one.

0x0020
WE_HAVE_AN_X_AND_Y_SCALE =

Flags bit 6: the x direction will use a different scale from the y direction.

0x0040
WE_HAVE_A_TWO_BY_TWO =

Flags bit 7: there is a 2 by 2 transformation that will be used to scale the component.

0x0080
WE_HAVE_INSTRUCTIONS =

Flags bit 8: following the last component are instructions for the composite character.

0x0100

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, raw) ⇒ Compound

Returns a new instance of Compound.

Parameters:

  • id (Integer)

    glyph ID.

  • raw (String)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 85
85
def initialize(id, raw)
86
  @id = id
87
  @raw = raw
88
  io = StringIO.new(raw)
89
90
  @number_of_contours, @x_min, @y_min, @x_max, @y_max =
91
    io.read(10).unpack('n*').map { |i|
92
      BinUtils.twos_comp_to_int(i, bit_width: 16)
93
    }
94
95
  # Because TTFunk only cares about glyphs insofar as they (1) provide
96
  # a bounding box for each glyph, and (2) can be rewritten into a
97
  # font subset, we don't really care about the rest of the glyph data
98
  # except as a whole. Thus, we don't actually decompose the glyph
99
  # into it's parts--all we really care about are the locations within
100
  # the raw string where the component glyph ids are stored, so that
101
  # when we rewrite this glyph into a subset we can rewrite the
102
  # component glyph-ids so they are correct for the subset.
103
104
  @glyph_ids = []
105
  @glyph_id_offsets = []
106
  offset = 10 # 2 bytes for each of num-contours, min x/y, max x/y
107
108
  loop do
109
    flags, glyph_id = @raw[offset, 4].unpack('n*')
110
    @glyph_ids << glyph_id
111
    @glyph_id_offsets << (offset + 2)
112
113
    break if (flags & MORE_COMPONENTS).zero?
114
115
    offset += 4
116
117
    offset +=
118
      if (flags & ARG_1_AND_2_ARE_WORDS).zero?
119
        2
120
      else
121
        4
122
      end
123
124
    if flags & WE_HAVE_A_TWO_BY_TWO != 0
125
      offset += 8
126
    elsif flags & WE_HAVE_AN_X_AND_Y_SCALE != 0
127
      offset += 4
128
    elsif flags & WE_HAVE_A_SCALE != 0
129
      offset += 2
130
    end
131
  end
132
end

Instance Attribute Details

#glyph_idsObject (readonly)

IDs of compound glyphs.

Source Code
lib/ttfunk/table/glyf/compound.rb, line 62
62
def glyph_ids
63
  @glyph_ids
64
end

#idInteger (readonly)

Glyph ID.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 35
35
def id
36
  @id
37
end

#number_of_contoursInteger (readonly)

Number of contours in this glyph.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 43
43
def number_of_contours
44
  @number_of_contours
45
end

#rawString (readonly)

Binary serialization of this glyph.

Returns:

  • (String)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 39
39
def raw
40
  @raw
41
end

#x_maxInteger (readonly)

Maximum x for coordinate.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 55
55
def x_max
56
  @x_max
57
end

#x_minInteger (readonly)

Minimum x for coordinate.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 47
47
def x_min
48
  @x_min
49
end

#y_maxInteger (readonly)

Maximum y for coordinate.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 59
59
def y_max
60
  @y_max
61
end

#y_minInteger (readonly)

Minimum y for coordinate.

Returns:

  • (Integer)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 51
51
def y_min
52
  @y_min
53
end

Instance Method Details

#compound?true

Is this a composite glyph?

Returns:

  • (true)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 136
136
def compound?
137
  true
138
end

#recode(mapping) ⇒ String

Recode glyph.

Parameters:

  • mapping (Hash{Integer => Integer})

    a hash mapping old glyph IDs to new glyph IDs.

Returns:

  • (String)
Source Code
lib/ttfunk/table/glyf/compound.rb, line 145
145
def recode(mapping)
146
  result = raw.dup
147
  new_ids = glyph_ids.map { |id| mapping[id] }
148
149
  new_ids.zip(@glyph_id_offsets).each do |new_id, offset|
150
    result[offset, 2] = [new_id].pack('n')
151
  end
152
153
  result
154
end