Module: HarfBuzz

Defined in:
lib/harfbuzz.rb,
lib/harfbuzz.rb,
lib/harfbuzz.rb,
lib/harfbuzz/map.rb,
lib/harfbuzz/set.rb,
lib/harfbuzz/blob.rb,
lib/harfbuzz/face.rb,
lib/harfbuzz/font.rb,
lib/harfbuzz/c/map.rb,
lib/harfbuzz/c/set.rb,
lib/harfbuzz/error.rb,
lib/harfbuzz/flags.rb,
lib/harfbuzz/buffer.rb,
lib/harfbuzz/c/base.rb,
lib/harfbuzz/c/blob.rb,
lib/harfbuzz/c/draw.rb,
lib/harfbuzz/c/face.rb,
lib/harfbuzz/c/font.rb,
lib/harfbuzz/ot/var.rb,
lib/harfbuzz/subset.rb,
lib/harfbuzz/c/enums.rb,
lib/harfbuzz/c/paint.rb,
lib/harfbuzz/c/shape.rb,
lib/harfbuzz/feature.rb,
lib/harfbuzz/library.rb,
lib/harfbuzz/ot/font.rb,
lib/harfbuzz/ot/math.rb,
lib/harfbuzz/ot/meta.rb,
lib/harfbuzz/ot/name.rb,
lib/harfbuzz/version.rb,
lib/harfbuzz/c/buffer.rb,
lib/harfbuzz/c/common.rb,
lib/harfbuzz/c/ot/var.rb,
lib/harfbuzz/c/subset.rb,
lib/harfbuzz/ot/color.rb,
lib/harfbuzz/ot/shape.rb,
lib/harfbuzz/c/ot/font.rb,
lib/harfbuzz/c/ot/math.rb,
lib/harfbuzz/c/ot/meta.rb,
lib/harfbuzz/c/ot/name.rb,
lib/harfbuzz/c/structs.rb,
lib/harfbuzz/c/unicode.rb,
lib/harfbuzz/c/version.rb,
lib/harfbuzz/ot/layout.rb,
lib/harfbuzz/variation.rb,
lib/harfbuzz/aat/layout.rb,
lib/harfbuzz/c/ot/color.rb,
lib/harfbuzz/c/ot/shape.rb,
lib/harfbuzz/draw_funcs.rb,
lib/harfbuzz/font_funcs.rb,
lib/harfbuzz/glyph_info.rb,
lib/harfbuzz/ot/metrics.rb,
lib/harfbuzz/shape_plan.rb,
lib/harfbuzz/c/ot/layout.rb,
lib/harfbuzz/paint_funcs.rb,
lib/harfbuzz/c/aat/layout.rb,
lib/harfbuzz/c/font_funcs.rb,
lib/harfbuzz/c/ot/metrics.rb,
lib/harfbuzz/c/shape_plan.rb,
lib/harfbuzz/unicode_funcs.rb,
lib/harfbuzz/glyph_position.rb,
lib/harfbuzz/shaping_result.rb,
sig/harfbuzz.rbs

Overview

HarfBuzz Ruby FFI Bindings

This module provides complete Ruby bindings for the HarfBuzz text shaping engine. It uses FFI to provide both low-level C API access (HarfBuzz::C) and high-level Ruby-friendly interfaces.

Examples:

Basic shaping

blob = HarfBuzz::Blob.from_file!("font.ttf")
face = HarfBuzz::Face.new(blob, 0)
font = HarfBuzz::Font.new(face)
buffer = HarfBuzz::Buffer.new
buffer.add_utf8("Hello")
buffer.guess_segment_properties
HarfBuzz.shape(font, buffer)

Defined Under Namespace

Modules: AAT, C, Flags, OT, Subset Classes: AllocationError, Blob, Buffer, DrawFuncs, Error, Face, Feature, FeatureParseError, Font, FontFuncs, GlyphInfo, GlyphPosition, InvalidArgumentError, LibraryNotFoundError, Map, PaintFuncs, Set, ShapePlan, ShapingResult, SubsetError, UnavailableError, UnicodeFuncs, Variation, VariationParseError

Constant Summary collapse

VERSION =

Returns:

  • (String)
"1.1.0"

Class Method Summary collapse

Class Method Details

.color_alpha(color) ⇒ Integer

Color component extraction

Parameters:

  • color (Integer)

Returns:

  • (Integer)


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

def self.color_alpha(color)
  C.hb_color_get_alpha(color)
end

.color_blue(color) ⇒ Integer

Extracts the blue component from an RGBA color value

Parameters:

  • color (Integer)

    RGBA color as uint32

Returns:

  • (Integer)

    Blue (0-255)



219
220
221
# File 'lib/harfbuzz.rb', line 219

def self.color_blue(color)
  C.hb_color_get_blue(color)
end

.color_green(color) ⇒ Integer

Extracts the green component from an RGBA color value

Parameters:

  • color (Integer)

    RGBA color as uint32

Returns:

  • (Integer)

    Green (0-255)



212
213
214
# File 'lib/harfbuzz.rb', line 212

def self.color_green(color)
  C.hb_color_get_green(color)
end

.color_red(color) ⇒ Integer

Extracts the red component from an RGBA color value

Parameters:

  • color (Integer)

    RGBA color as uint32

Returns:

  • (Integer)

    Red (0-255)



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

def self.color_red(color)
  C.hb_color_get_red(color)
end

.default_languageFFI::Pointer

Returns the default language

Returns:

  • (FFI::Pointer)

    Default language pointer



162
163
164
# File 'lib/harfbuzz.rb', line 162

def self.default_language
  C.hb_language_get_default
end

.direction(str) ⇒ Symbol

Direction

Parameters:

  • str (String)

Returns:

  • (Symbol)


149
150
151
# File 'lib/harfbuzz.rb', line 149

def self.direction(str)
  C.hb_direction_from_string(str, str.bytesize)
end

.language(str) ⇒ FFI::Pointer

Language

Parameters:

  • str (String)

Returns:

  • (FFI::Pointer)


156
157
158
# File 'lib/harfbuzz.rb', line 156

def self.language(str)
  C.hb_language_from_string(str, str.bytesize)
end

.language_matches?(lang1, lang2) ⇒ Boolean

Checks if two language tags match (BCP 47 prefix comparison)

Parameters:

  • lang1 (FFI::Pointer)

    First language pointer

  • lang2 (FFI::Pointer)

    Second language pointer

Returns:

  • (Boolean)

    true if languages match



177
178
179
# File 'lib/harfbuzz.rb', line 177

def self.language_matches?(lang1, lang2)
  C.from_hb_bool(C.hb_language_matches(lang1, lang2))
end

.language_to_s(lang) ⇒ String

Returns the BCP 47 string representation of a language pointer

Parameters:

  • lang (FFI::Pointer)

    Language pointer (from HarfBuzz.language)

Returns:

  • (String)

    BCP 47 language tag string



169
170
171
# File 'lib/harfbuzz.rb', line 169

def self.language_to_s(lang)
  C.hb_language_to_string(lang)
end

.library_pathString

Library path override

Returns:

  • (String)


8
9
10
# File 'lib/harfbuzz/library.rb', line 8

def self.library_path
  @library_path ||= detect_library
end

.library_path=(path) ⇒ String

Sets the library path explicitly

Parameters:

  • path (String)

    Path to the HarfBuzz shared library

Returns:

  • (String)


14
15
16
# File 'lib/harfbuzz/library.rb', line 14

def self.library_path=(path)
  @library_path = path
end

.script(str) ⇒ Integer

Script

Parameters:

  • str (String)

Returns:

  • (Integer)


184
185
186
# File 'lib/harfbuzz.rb', line 184

def self.script(str)
  C.hb_script_from_string(str, str.bytesize)
end

.script_from_tag(tag) ⇒ Integer

Converts an ISO 15924 OpenType tag to a script value

Parameters:

  • tag (Integer)

    ISO 15924 tag (e.g., HarfBuzz.tag("Arab"))

Returns:

  • (Integer)

    Script value



191
192
193
# File 'lib/harfbuzz.rb', line 191

def self.script_from_tag(tag)
  C.hb_script_from_iso15924_tag(tag)
end

.script_horizontal_direction(script) ⇒ Symbol

Returns the horizontal direction for a script

Parameters:

  • script (Integer)

    Script value

Returns:

  • (Symbol)

    Direction symbol (:ltr or :rtl)



226
227
228
# File 'lib/harfbuzz.rb', line 226

def self.script_horizontal_direction(script)
  C.hb_script_get_horizontal_direction(script)
end

.shape(font, buffer, features = [], shapers: nil) ⇒ void

This method returns an undefined value.

Shaping

Parameters:

  • font (Font)
  • buffer (Buffer)
  • features (Array[Feature]) (defaults to: [])
  • shapers: (Array[String], nil) (defaults to: nil)


235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/harfbuzz.rb', line 235

def self.shape(font, buffer, features = [], shapers: nil)
  features_ptr = build_features_ptr(features)

  if shapers
    shapers_ptrs = shapers.map { |s| FFI::MemoryPointer.from_string(s) }
    shapers_ptrs << FFI::Pointer::NULL
    shapers_ptr = FFI::MemoryPointer.new(:pointer, shapers_ptrs.size)
    shapers_ptrs.each_with_index { |p, i| shapers_ptr[i].put_pointer(0, p) }
    C.hb_shape_full(font.ptr, buffer.ptr, features_ptr, features.size, shapers_ptr)
  else
    C.hb_shape(font.ptr, buffer.ptr, features_ptr, features.size)
  end
end

.shape_text(text, font_path:, features: [], direction: nil, script: nil, language: nil) ⇒ ShapingResult

High-level shaping convenience method

Parameters:

  • text (String)

    Text to shape

  • font_path (String)

    Path to font file

  • features (Array<Feature, String>, Hash) (defaults to: [])

    Features to apply

  • direction (Symbol, nil) (defaults to: nil)

    Text direction (:ltr, :rtl, etc.)

  • script (Integer, nil) (defaults to: nil)

    Script value

  • language (String, nil) (defaults to: nil)

    BCP 47 language tag (e.g., "en")

Returns:



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/harfbuzz.rb', line 274

def self.shape_text(text, font_path:, features: [], direction: nil, script: nil, language: nil)
  blob = Blob.from_file!(font_path)
  face = Face.new(blob, 0)
  font = Font.new(face)

  buffer = Buffer.new
  buffer.add_utf8(text)
  buffer.direction = direction if direction
  buffer.script = script if script
  buffer.language = self.language(language) if language
  buffer.guess_segment_properties

  parsed_features = case features
                    when Array
                      features.map { |f| f.is_a?(Feature) ? f : Feature.from_string(f.to_s) }
                    when Hash
                      Feature.from_hash(features)
                    else
                      []
                    end

  shape(font, buffer, parsed_features)
  ShapingResult.new(buffer: buffer, font: font)
end

.shapersArray<String>

Returns the list of available shapers

Returns:

  • (Array<String>)

    List of shaper names



251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/harfbuzz.rb', line 251

def self.shapers
  ptr = C.hb_shape_list_shapers
  result = []
  i = 0
  loop do
    p = ptr.get_pointer(i * FFI::Pointer.size)
    break if p.null?

    result << p.read_string
    i += 1
  end
  result
end

.tag(str) ⇒ Integer

OpenType tag conversions

Parameters:

  • (String, Symbol, Integer)

Returns:

  • (Integer)


128
129
130
131
132
133
134
135
# File 'lib/harfbuzz.rb', line 128

def self.tag(str)
  case str
  when Integer then str
  when Symbol  then tag(str.to_s)
  when String  then C.hb_tag_from_string(str, str.bytesize)
  else raise InvalidArgumentError, "Cannot convert #{str.class} to tag"
  end
end

.tag_to_s(tag) ⇒ String

Converts an OpenType tag (uint32) to a 4-character string

Parameters:

  • tag (Integer)

    Tag as uint32

Returns:

  • (String)

    4-character tag string



140
141
142
143
144
# File 'lib/harfbuzz.rb', line 140

def self.tag_to_s(tag)
  buf = FFI::MemoryPointer.new(:char, 4)
  C.hb_tag_to_string(tag, buf)
  buf.read_bytes(4)
end

.version[Integer, Integer, Integer]

HarfBuzz library version

Returns:

  • ([Integer, Integer, Integer])


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

def self.version
  major_ptr = FFI::MemoryPointer.new(:uint)
  minor_ptr = FFI::MemoryPointer.new(:uint)
  micro_ptr = FFI::MemoryPointer.new(:uint)

  C.hb_version(major_ptr, minor_ptr, micro_ptr)

  [major_ptr.read_uint, minor_ptr.read_uint, micro_ptr.read_uint]
end

.version_atleast?(major, minor, micro) ⇒ Boolean Also known as: version_at_least?

Checks if the library version is at least the specified version

Parameters:

  • major (Integer)

    Major version

  • minor (Integer)

    Minor version

  • micro (Integer)

    Micro version

Returns:

  • (Boolean)

    true if version >= specified



117
118
119
# File 'lib/harfbuzz.rb', line 117

def self.version_atleast?(major, minor, micro)
  C.from_hb_bool(C.hb_version_atleast(major, minor, micro))
end

.version_stringString

Returns the HarfBuzz library version as a string

Returns:

  • (String)

    Version string (e.g., "8.3.0")



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

def self.version_string
  C.hb_version_string
end