Class: HarfBuzz::Font

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

Overview

Wraps hb_font_t — a sized, positioned font instance

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(face) ⇒ Font

Creates a Font from a Face

Parameters:

  • face (Face)

    Font face

Raises:



10
11
12
13
14
15
16
# File 'lib/harfbuzz/font.rb', line 10

def initialize(face)
  @face = face
  @ptr = C.hb_font_create(face.ptr)
  raise AllocationError, "Failed to create font" if @ptr.null?

  register_finalizer
end

Instance Attribute Details

#ptrObject (readonly)

Returns the value of attribute ptr.



6
7
8
# File 'lib/harfbuzz/font.rb', line 6

def ptr
  @ptr
end

Class Method Details

.define_finalizer(obj, ptr) ⇒ Object



399
400
401
402
# File 'lib/harfbuzz/font.rb', line 399

def self.define_finalizer(obj, ptr)
  destroy = C.method(:hb_font_destroy)
  ObjectSpace.define_finalizer(obj, proc { destroy.call(ptr) })
end

.emptyFont

Returns the singleton empty font

Returns:



43
44
45
# File 'lib/harfbuzz/font.rb', line 43

def self.empty
  wrap_borrowed(C.hb_font_get_empty)
end

.wrap_borrowed(ptr) ⇒ Object



384
385
386
387
388
389
# File 'lib/harfbuzz/font.rb', line 384

def self.wrap_borrowed(ptr)
  obj = allocate
  obj.instance_variable_set(:@ptr, ptr)
  obj.instance_variable_set(:@borrowed, true)
  obj
end

.wrap_owned(ptr) ⇒ Object



377
378
379
380
381
382
# File 'lib/harfbuzz/font.rb', line 377

def self.wrap_owned(ptr)
  obj = allocate
  obj.instance_variable_set(:@ptr, ptr)
  obj.send(:register_finalizer)
  obj
end

Instance Method Details

#create_sub_fontFont

Creates a sub-font of this font

Returns:



36
37
38
39
# File 'lib/harfbuzz/font.rb', line 36

def create_sub_font
  ptr = C.hb_font_create_sub_font(@ptr)
  self.class.wrap_owned(ptr)
end

#draw_glyph(glyph, draw_funcs) ⇒ Object

Draws the outline of a glyph using DrawFuncs callbacks

Parameters:

  • glyph (Integer)

    Glyph ID

  • draw_funcs (DrawFuncs)

    Draw callbacks object



360
361
362
# File 'lib/harfbuzz/font.rb', line 360

def draw_glyph(glyph, draw_funcs)
  C.hb_font_draw_glyph(@ptr, glyph, draw_funcs.ptr, nil)
end

#extents_for_direction(dir) ⇒ C::HbFontExtentsT

Returns font extents for a direction

Parameters:

  • dir (Symbol)

    Direction (:ltr, :rtl, :ttb, :btt)

Returns:



351
352
353
354
355
# File 'lib/harfbuzz/font.rb', line 351

def extents_for_direction(dir)
  extents = C::HbFontExtentsT.new
  C.hb_font_get_extents_for_direction(@ptr, dir, extents)
  extents
end

#faceFace

Returns the face this font was created from (borrowed reference)

Returns:



49
50
51
52
# File 'lib/harfbuzz/font.rb', line 49

def face
  ptr = C.hb_font_get_face(@ptr)
  Face.wrap_borrowed(ptr)
end

#funcs=(funcs) ⇒ Object

Sets the font funcs (setter alias for set_funcs without font_data)

Parameters:



30
31
32
# File 'lib/harfbuzz/font.rb', line 30

def funcs=(funcs)
  set_funcs(funcs)
end

#glyph(cp, variation_selector = 0) ⇒ Integer?

Returns glyph ID for a codepoint (with optional variation selector)

Parameters:

  • cp (Integer)

    Unicode codepoint

  • variation_selector (Integer) (defaults to: 0)

    Variation selector codepoint (0 = none)

Returns:

  • (Integer, nil)

    Glyph ID or nil if not found



196
197
198
199
200
# File 'lib/harfbuzz/font.rb', line 196

def glyph(cp, variation_selector = 0)
  glyph_ptr = FFI::MemoryPointer.new(:uint32)
  ok = C.hb_font_get_glyph(@ptr, cp, variation_selector, glyph_ptr)
  ok.zero? ? nil : glyph_ptr.read_uint32
end

#glyph_advance_for_direction(glyph, dir) ⇒ Array<Integer>

Returns glyph advance for a direction as [x, y]

Parameters:

  • glyph (Integer)

    Glyph ID

  • dir (Symbol)

    Direction (:ltr, :rtl, :ttb, :btt)

Returns:

  • (Array<Integer>)

    [x_advance, y_advance]



341
342
343
344
345
346
# File 'lib/harfbuzz/font.rb', line 341

def glyph_advance_for_direction(glyph, dir)
  x_ptr = FFI::MemoryPointer.new(:int32)
  y_ptr = FFI::MemoryPointer.new(:int32)
  C.hb_font_get_glyph_advance_for_direction(@ptr, glyph, dir, x_ptr, y_ptr)
  [x_ptr.read_int32, y_ptr.read_int32]
end

#glyph_contour_point(glyph, idx) ⇒ Array<Integer>?

Returns a contour point for a glyph

Parameters:

  • glyph (Integer)

    Glyph ID

  • idx (Integer)

    Contour point index

Returns:

  • (Array<Integer>, nil)

    [x, y] or nil



312
313
314
315
316
317
# File 'lib/harfbuzz/font.rb', line 312

def glyph_contour_point(glyph, idx)
  x_ptr = FFI::MemoryPointer.new(:int32)
  y_ptr = FFI::MemoryPointer.new(:int32)
  ok = C.hb_font_get_glyph_contour_point(@ptr, glyph, idx, x_ptr, y_ptr)
  ok.zero? ? nil : [x_ptr.read_int32, y_ptr.read_int32]
end

#glyph_extents(glyph) ⇒ C::HbGlyphExtentsT?

Returns glyph extents

Parameters:

  • glyph (Integer)

    Glyph ID

Returns:



302
303
304
305
306
# File 'lib/harfbuzz/font.rb', line 302

def glyph_extents(glyph)
  extents = C::HbGlyphExtentsT.new
  ok = C.hb_font_get_glyph_extents(@ptr, glyph, extents)
  ok.zero? ? nil : extents
end

#glyph_from_name(name) ⇒ Integer?

Returns the glyph ID for a name

Parameters:

  • name (String)

    Glyph name

Returns:

  • (Integer, nil)

    Glyph ID or nil



331
332
333
334
335
# File 'lib/harfbuzz/font.rb', line 331

def glyph_from_name(name)
  glyph_ptr = FFI::MemoryPointer.new(:uint32)
  ok = C.hb_font_get_glyph_from_name(@ptr, name, name.bytesize, glyph_ptr)
  ok.zero? ? nil : glyph_ptr.read_uint32
end

#glyph_h_advance(glyph) ⇒ Integer

Returns Horizontal advance in font units.

Parameters:

  • glyph (Integer)

    Glyph ID

Returns:

  • (Integer)

    Horizontal advance in font units



237
238
239
# File 'lib/harfbuzz/font.rb', line 237

def glyph_h_advance(glyph)
  C.hb_font_get_glyph_h_advance(@ptr, glyph)
end

#glyph_h_advances(glyphs) ⇒ Array<Integer>

Returns horizontal advances for multiple glyphs

Parameters:

  • glyphs (Array<Integer>)

    Glyph IDs

Returns:

  • (Array<Integer>)

    Advances



250
251
252
253
254
255
256
257
# File 'lib/harfbuzz/font.rb', line 250

def glyph_h_advances(glyphs)
  count = glyphs.size
  glyph_ptr = FFI::MemoryPointer.new(:uint32, count)
  glyph_ptr.put_array_of_uint32(0, glyphs)
  advance_ptr = FFI::MemoryPointer.new(:int32, count)
  C.hb_font_get_glyph_h_advances(@ptr, count, glyph_ptr, 4, advance_ptr, 4)
  advance_ptr.read_array_of_int32(count)
end

#glyph_h_kerning(left, right) ⇒ Integer

Returns horizontal kerning between two glyphs

Parameters:

  • left (Integer)

    Left glyph ID

  • right (Integer)

    Right glyph ID

Returns:

  • (Integer)

    Kerning value



295
296
297
# File 'lib/harfbuzz/font.rb', line 295

def glyph_h_kerning(left, right)
  C.hb_font_get_glyph_h_kerning(@ptr, left, right)
end

#glyph_h_origin(glyph) ⇒ Array<Integer>?

Returns horizontal origin for a glyph

Parameters:

  • glyph (Integer)

    Glyph ID

Returns:

  • (Array<Integer>, nil)

    [x, y] or nil



274
275
276
277
278
279
# File 'lib/harfbuzz/font.rb', line 274

def glyph_h_origin(glyph)
  x_ptr = FFI::MemoryPointer.new(:int32)
  y_ptr = FFI::MemoryPointer.new(:int32)
  ok = C.hb_font_get_glyph_h_origin(@ptr, glyph, x_ptr, y_ptr)
  ok.zero? ? nil : [x_ptr.read_int32, y_ptr.read_int32]
end

#glyph_name(glyph) ⇒ String?

Returns the glyph name

Parameters:

  • glyph (Integer)

    Glyph ID

Returns:

  • (String, nil)

    Glyph name or nil



322
323
324
325
326
# File 'lib/harfbuzz/font.rb', line 322

def glyph_name(glyph)
  buf = FFI::MemoryPointer.new(:char, 64)
  ok = C.hb_font_get_glyph_name(@ptr, glyph, buf, 64)
  ok.zero? ? nil : buf.read_string
end

#glyph_v_advance(glyph) ⇒ Integer

Returns Vertical advance in font units.

Parameters:

  • glyph (Integer)

    Glyph ID

Returns:

  • (Integer)

    Vertical advance in font units



243
244
245
# File 'lib/harfbuzz/font.rb', line 243

def glyph_v_advance(glyph)
  C.hb_font_get_glyph_v_advance(@ptr, glyph)
end

#glyph_v_advances(glyphs) ⇒ Array<Integer>

Returns vertical advances for multiple glyphs

Parameters:

  • glyphs (Array<Integer>)

    Glyph IDs

Returns:

  • (Array<Integer>)

    Advances



262
263
264
265
266
267
268
269
# File 'lib/harfbuzz/font.rb', line 262

def glyph_v_advances(glyphs)
  count = glyphs.size
  glyph_ptr = FFI::MemoryPointer.new(:uint32, count)
  glyph_ptr.put_array_of_uint32(0, glyphs)
  advance_ptr = FFI::MemoryPointer.new(:int32, count)
  C.hb_font_get_glyph_v_advances(@ptr, count, glyph_ptr, 4, advance_ptr, 4)
  advance_ptr.read_array_of_int32(count)
end

#glyph_v_origin(glyph) ⇒ Array<Integer>?

Returns vertical origin for a glyph

Parameters:

  • glyph (Integer)

    Glyph ID

Returns:

  • (Array<Integer>, nil)

    [x, y] or nil



284
285
286
287
288
289
# File 'lib/harfbuzz/font.rb', line 284

def glyph_v_origin(glyph)
  x_ptr = FFI::MemoryPointer.new(:int32)
  y_ptr = FFI::MemoryPointer.new(:int32)
  ok = C.hb_font_get_glyph_v_origin(@ptr, glyph, x_ptr, y_ptr)
  ok.zero? ? nil : [x_ptr.read_int32, y_ptr.read_int32]
end

#immutable?Boolean

Returns true if font is immutable.

Returns:

  • (Boolean)

    true if font is immutable



181
182
183
# File 'lib/harfbuzz/font.rb', line 181

def immutable?
  C.from_hb_bool(C.hb_font_is_immutable(@ptr))
end

#inspectObject



373
374
375
# File 'lib/harfbuzz/font.rb', line 373

def inspect
  "#<HarfBuzz::Font scale=#{scale} ppem=#{ppem} immutable=#{immutable?}>"
end

#make_immutable!self

Makes the font immutable (thread-safe to share after this)

Returns:

  • (self)


187
188
189
190
# File 'lib/harfbuzz/font.rb', line 187

def make_immutable!
  C.hb_font_make_immutable(@ptr)
  self
end

#nominal_glyph(cp) ⇒ Integer?

Returns glyph ID for a nominal (non-variation) codepoint

Parameters:

  • cp (Integer)

    Unicode codepoint

Returns:

  • (Integer, nil)

    Glyph ID or nil if not found



205
206
207
208
209
# File 'lib/harfbuzz/font.rb', line 205

def nominal_glyph(cp)
  glyph_ptr = FFI::MemoryPointer.new(:uint32)
  ok = C.hb_font_get_nominal_glyph(@ptr, cp, glyph_ptr)
  ok.zero? ? nil : glyph_ptr.read_uint32
end

#nominal_glyphs(codepoints) ⇒ Array<Integer>

Returns nominal glyph IDs for multiple codepoints in a single call

Parameters:

  • codepoints (Array<Integer>)

    Unicode codepoints

Returns:

  • (Array<Integer>)

    Glyph IDs (0 for unmapped codepoints)



214
215
216
217
218
219
220
221
222
223
# File 'lib/harfbuzz/font.rb', line 214

def nominal_glyphs(codepoints)
  count = codepoints.size
  return [] if count.zero?

  cp_ptr = FFI::MemoryPointer.new(:uint32, count)
  cp_ptr.put_array_of_uint32(0, codepoints)
  glyph_ptr = FFI::MemoryPointer.new(:uint32, count)
  C.hb_font_get_nominal_glyphs(@ptr, count, cp_ptr, 4, glyph_ptr, 4)
  glyph_ptr.read_array_of_uint32(count)
end

#paint_glyph(glyph, paint_funcs, palette_index: 0, foreground: 0xFF000000) ⇒ Object

Paints a glyph using PaintFuncs callbacks

Parameters:

  • glyph (Integer)

    Glyph ID

  • paint_funcs (PaintFuncs)

    Paint callbacks object

  • palette_index (Integer) (defaults to: 0)

    Color palette index (default 0)

  • foreground (Integer) (defaults to: 0xFF000000)

    Foreground color as RGBA uint32 (default 0xFF000000)



369
370
371
# File 'lib/harfbuzz/font.rb', line 369

def paint_glyph(glyph, paint_funcs, palette_index: 0, foreground: 0xFF000000)
  C.hb_font_paint_glyph(@ptr, glyph, paint_funcs.ptr, nil, palette_index, foreground)
end

#ppemArray<Integer>

Returns pixels per em as [x_ppem, y_ppem]

Returns:

  • (Array<Integer>)


72
73
74
75
76
77
# File 'lib/harfbuzz/font.rb', line 72

def ppem
  x_ptr = FFI::MemoryPointer.new(:uint)
  y_ptr = FFI::MemoryPointer.new(:uint)
  C.hb_font_get_ppem(@ptr, x_ptr, y_ptr)
  [x_ptr.read_uint, y_ptr.read_uint]
end

#ppem=(xy) ⇒ Object

Sets pixels per em

Parameters:

  • xy (Array<Integer>)

    [x_ppem, y_ppem]



81
82
83
84
# File 'lib/harfbuzz/font.rb', line 81

def ppem=(xy)
  x, y = xy
  C.hb_font_set_ppem(@ptr, x, y)
end

#ptemFloat

Returns Points per em.

Returns:

  • (Float)

    Points per em



87
88
89
# File 'lib/harfbuzz/font.rb', line 87

def ptem
  C.hb_font_get_ptem(@ptr)
end

#ptem=(pt) ⇒ Object

Parameters:

  • pt (Float)

    Points per em



92
93
94
# File 'lib/harfbuzz/font.rb', line 92

def ptem=(pt)
  C.hb_font_set_ptem(@ptr, pt)
end

#scaleArray<Integer>

Returns scale as [x_scale, y_scale]

Returns:

  • (Array<Integer>)


56
57
58
59
60
61
# File 'lib/harfbuzz/font.rb', line 56

def scale
  x_ptr = FFI::MemoryPointer.new(:int)
  y_ptr = FFI::MemoryPointer.new(:int)
  C.hb_font_get_scale(@ptr, x_ptr, y_ptr)
  [x_ptr.read_int, y_ptr.read_int]
end

#scale=(xy) ⇒ Object

Sets font scale

Parameters:

  • xy (Array<Integer>, Integer)

    [x, y] or single value for both



65
66
67
68
# File 'lib/harfbuzz/font.rb', line 65

def scale=(xy)
  x, y = Array(xy).length == 2 ? xy : [xy, xy]
  C.hb_font_set_scale(@ptr, x, y)
end

#set_funcs(funcs, font_data: FFI::Pointer::NULL) ⇒ self

Attaches a FontFuncs callback table to this font

Parameters:

  • funcs (FontFuncs)

    Font funcs object (should be immutable)

  • font_data (FFI::Pointer) (defaults to: FFI::Pointer::NULL)

    User data pointer passed to callbacks (optional)

Returns:

  • (self)


22
23
24
25
26
# File 'lib/harfbuzz/font.rb', line 22

def set_funcs(funcs, font_data: FFI::Pointer::NULL)
  C.hb_font_set_funcs(@ptr, funcs.ptr, font_data, nil)
  @funcs = funcs  # keep alive
  self
end

#set_variation(tag, value) ⇒ Object

Sets a single variation axis value

Parameters:

  • tag (Integer)

    Axis tag

  • value (Float)

    Axis value



138
139
140
# File 'lib/harfbuzz/font.rb', line 138

def set_variation(tag, value)
  C.hb_font_set_variation(@ptr, tag, value)
end

#synthetic_boldArray

Returns synthetic bold as [x_embolden, y_embolden, in_place]

Returns:

  • (Array)


98
99
100
101
102
103
104
# File 'lib/harfbuzz/font.rb', line 98

def synthetic_bold
  x_ptr = FFI::MemoryPointer.new(:float)
  y_ptr = FFI::MemoryPointer.new(:float)
  ip_ptr = FFI::MemoryPointer.new(:int)
  C.hb_font_get_synthetic_bold(@ptr, x_ptr, y_ptr, ip_ptr)
  [x_ptr.read_float, y_ptr.read_float, C.from_hb_bool(ip_ptr.read_int)]
end

#synthetic_bold=(xyz) ⇒ Object

Sets synthetic bold

Parameters:

  • xyz (Array)

    [x_embolden, y_embolden, in_place]



108
109
110
111
# File 'lib/harfbuzz/font.rb', line 108

def synthetic_bold=(xyz)
  x, y, ip = xyz
  C.hb_font_set_synthetic_bold(@ptr, x, y, C.to_hb_bool(ip))
end

#synthetic_slantFloat

Returns Synthetic slant.

Returns:

  • (Float)

    Synthetic slant



114
115
116
# File 'lib/harfbuzz/font.rb', line 114

def synthetic_slant
  C.hb_font_get_synthetic_slant(@ptr)
end

#synthetic_slant=(slant) ⇒ Object

Parameters:

  • slant (Float)

    Synthetic slant



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

def synthetic_slant=(slant)
  C.hb_font_set_synthetic_slant(@ptr, slant)
end

#var_coords_designArray<Float>

Returns design-space variation coordinates

Returns:

  • (Array<Float>)


152
153
154
155
156
157
158
159
# File 'lib/harfbuzz/font.rb', line 152

def var_coords_design
  count_ptr = FFI::MemoryPointer.new(:uint)
  coords_ptr = C.hb_font_get_var_coords_design(@ptr, count_ptr)
  count = count_ptr.read_uint
  return [] if coords_ptr.null? || count.zero?

  coords_ptr.read_array_of_float(count)
end

#var_coords_design=(coords) ⇒ Object

Sets design-space variation coordinates

Parameters:

  • coords (Array<Float>)


144
145
146
147
148
# File 'lib/harfbuzz/font.rb', line 144

def var_coords_design=(coords)
  ptr = FFI::MemoryPointer.new(:float, coords.size)
  ptr.put_array_of_float(0, coords)
  C.hb_font_set_var_coords_design(@ptr, ptr, coords.size)
end

#var_coords_normalizedArray<Integer>

Returns normalized variation coordinates

Returns:

  • (Array<Integer>)


171
172
173
174
175
176
177
178
# File 'lib/harfbuzz/font.rb', line 171

def var_coords_normalized
  count_ptr = FFI::MemoryPointer.new(:uint)
  coords_ptr = C.hb_font_get_var_coords_normalized(@ptr, count_ptr)
  count = count_ptr.read_uint
  return [] if coords_ptr.null? || count.zero?

  coords_ptr.read_array_of_int32(count)
end

#var_coords_normalized=(coords) ⇒ Object

Sets normalized variation coordinates

Parameters:

  • coords (Array<Integer>)


163
164
165
166
167
# File 'lib/harfbuzz/font.rb', line 163

def var_coords_normalized=(coords)
  ptr = FFI::MemoryPointer.new(:int32, coords.size)
  ptr.put_array_of_int32(0, coords)
  C.hb_font_set_var_coords_normalized(@ptr, ptr, coords.size)
end

#variation_glyph(cp, selector) ⇒ Integer?

Returns glyph ID for a variation sequence

Parameters:

  • cp (Integer)

    Unicode codepoint

  • selector (Integer)

    Variation selector

Returns:

  • (Integer, nil)

    Glyph ID or nil if not found



229
230
231
232
233
# File 'lib/harfbuzz/font.rb', line 229

def variation_glyph(cp, selector)
  glyph_ptr = FFI::MemoryPointer.new(:uint32)
  ok = C.hb_font_get_variation_glyph(@ptr, cp, selector, glyph_ptr)
  ok.zero? ? nil : glyph_ptr.read_uint32
end

#variations=(variations) ⇒ Object

Sets variation axis values from an array of Variation objects

Parameters:



125
126
127
128
129
130
131
132
133
# File 'lib/harfbuzz/font.rb', line 125

def variations=(variations)
  structs = variations.map(&:to_struct)
  ptr = FFI::MemoryPointer.new(C::HbVariationT, structs.size)
  structs.each_with_index do |s, i|
    ptr.put_bytes(i * C::HbVariationT.size,
                  s.to_ptr.read_bytes(C::HbVariationT.size))
  end
  C.hb_font_set_variations(@ptr, ptr, structs.size)
end