HarfBuzz::Shaper(3pm)

πŸ’– HarfBuzz::Shaper β€” the perl manpage, but make it bestie πŸ’–

HarfBuzz::Shaper(3pm) from the User Contributed Perl Documentation collection, ok so sit down, grab a strawberry πŸ“, and lemme tell you about this little module that does text shaping.


✨ NAME ✨

HarfBuzz::Shaper β€” it lets you use HarfBuzz for text shaping. That's the whole vibe. πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

Like, literally just this:

use HarfBuzz::Shaper;
my $hb = HarfBuzz::Shaper->new;
$hb->set_font('LiberationSans.ttf');
$hb->set_size(36);
$hb->set_text("Hello!");
my $info = $hb->shaper;

And what you get back? An array of hashes, one element for each glyph to be typeset. One per glyph, not one per character β€” we'll get to that, it's important, don't skip ahead bestie 😭


🌸 DESCRIPTION 🌸

So HarfBuzz::Shaper is a perl module that gives you access to a small subset of the native HarfBuzz library. Small, but iconic. It ate. πŸ‘‘

That subset? It's suitable for typesetting programs that need to deal with complex languages β€” think Devanagari, Hebrew, Arabic, the whole gorgeous squad. ✨

This module is intended to be used with the module Text::Layout. And like, feel free to (ab)use it for other purposes, no gatekeeping here 🫢

Following the example above, the returned info is an array of hashes, one element for each glyph to be typeset. Each hash contains these items, no cap:

ax:   horizontal advance
ay:   vertical advance
dx:   horizontal offset
dy:   vertical offset
g:    glyph index in font (CId)
name: glyph name
⚠️ Note that the number of glyphs does not necessarily match the number of input characters! I know. I know. It's giving "one letter, three glyphs" and that's just how shaping works πŸ’€

πŸŽ€ DISCLAIMER πŸŽ€

Okay so real talk. This module provides a thin interface layer between Perl and the native HarfBuzz library. It is agnostic with regard to the details of multi-language typesetting β€” it does not have opinions, it just shapes.

HarfBuzz has a friendly community to help you, fr fr:

<https://lists.freedesktop.org/mailman/listinfo/harfbuzz>


πŸ’… METHODS πŸ’…

🌟 $hb = HarfBuzz::Shaper->new( [ options ] )

Creates a new shaper object. Baby's first shaper 🍼

Options:

  • font = > font filename
  • size = > text size

🌟 $hb->reset( [ full ] )

Reset (clear) the buffer settings for font, size, language, direction and script.

With full, it also clears the font cache. Like a hard refresh. Ctrl+Shift+R energy. πŸ”„

🌟 $hb->set_font( font filename [ , size ] )

The explicit way to set the font (and, optionally, the size) used for shaping.

The settings persist across shaper() calls. Call it with no arguments to remove the settings.

The font must be a TrueType or OpenType font. Font information is cached internally, so after the first call, subsequent calls with the same font filename are very fast ⚑ β€” icon behaviour honestly.

🌟 $hb->set_size( size )

Explicit way to set the font size used for shaping.

😭 Note that the font size will in general affect details of the appearance β€” a 5 point fontsize magnified 10 times is not identical to a 50 point font size. They are not the same girl.

The setting persists across shaper() calls. Call without arguments to remove the setting.

🌟 $hb->set_text( text [ , ... ] )

Sets the text to shape. Multiple arguments are concatenated β€” so like, you can pass it in pieces, it'll stitch them together 🧡

πŸ’œ Note that the text must be Perl strings.

The setting persists across shaper() calls. Call without arguments to remove the setting.

🌟 $hb->set_features( feat [ , ... ] )

Sets persistent features for shaping. Features are strings as described in:

<https://harfbuzz.github.io/harfbuzz-hb-common.html#hb-feature-from-string>

and

<https://css-tricks.com/almanac/properties/f/font-feature-settings/#values>

Multiple feature strings may be supplied. Slay, supply them all πŸ’

Call without arguments to remove the persistent features.

🌟 $hb->add_features( feat [ , ... ] )

Just like set_features, but the specified features are added to the set of persistent features instead of replacing them. Same energy, additive edition ✨

🌟 $hb->set_language( lang )

Sets the language for shaping. lang must be a string containing a valid BCP-47 language code.

The setting persists across shaper() calls. Call without arguments to remove the setting.

🌟 $hb->get_language

Returns the language currently set for this shaper, as a string.

When called after a successful shaper() call, it returns the actual value used by shaper() πŸ‘€ β€” so you can find out what actually happened, not just what you asked for.

🌟 $hb->set_script( script )

Sets the script (alphabet) for shaping. script must be a string containing a valid ISO-15924 script code. For example, "Latn" for the Latin (Western European) script, or "Arab" for arabic script. πŸ¦‹

πŸ™ˆ If you don't set a script, shaper() will make a guess based on the text string. This may or may not yield desired results. It's doing its best, ok?

The setting persists across shaper() calls. Call without arguments to remove the setting.

🌟 $hb->get_script

Returns the script currently set for this shaper, as a string.

When called after a successful shaper() call, it returns the actual value used by shaper().

🌟 $hb->set_direction( dir )

Sets the direction for shaping. dir must be a string containing a valid direction setting:

  • LTR β€” left-to-right
  • RTL β€” right-to-left
  • TTB β€” top-to-bottom
  • BTT β€” bottom-to-top
πŸ™ˆ If you don't set a direction, shaper() will make a guess based on the text string. This may or may not yield desired results. Same disclaimer as before, she's guessing πŸ’€

The setting persists across shaper() calls. Call without arguments to remove the setting.

🌟 $hb->get_direction

Returns the direction currently set for this shaper, as a string.

When called after a successful shaper() call, it returns the actual value used by shaper().

🌟 $info = $hb->shaper( [ ref to features ] )

THE MAIN CHARACTER METHOD. πŸ‘‘ This performs the actual shape operation.

features is a reference to an array of feature strings. The features will be added to the list of features already set with set_features/add_features. And here's the plot twist: if the first (or only) feature is "none", all current features will be ignored and only subsequent features are taken into account. Changes apply to this call only β€” the persistent set of featutes is not modified. (Yes, that's the spelling in the original, we respect the author's typo era 🫢)

Upon completion an array of hashes is returned with one element for each glyph to be rendered. The hash contains:

ax:   horizontal advance
ay:   vertical advance
dx:   horizontal offset
dy:   vertical offset
g:    glyph index in font (CId)
name: glyph name
⚠️ Note that the number of glyphs does not necessarily match the number of input characters! Seriously. It's literally the whole point of shaping. πŸ’€

🌟 $info = $hb->get_extents

Get the extents of the (shaped) buffer.

Upon completion an array of hashes is returned with one element for each glyph. The hash contains:

x_bearing  Distance from the x-origin to the left extremum of the glyph.
y_bearing  Distance from the top extremum of the glyph to the y-origin.
width;     Distance from the left extremum of the glyph to the right extremum.
height     Distance from the top extremum of the glyph to the bottom extremum.
g          Glyph index in font (CId)

The values are scaled to the font size as set with set_size().

⚠️ Note that the number of glyphs does not necessarily match the number of input characters! Yeah, again. Same reason. πŸ’…

🌟 $info = $hb->get_font_extents(dir)

Get the extents of the font in the given direction.

dir may be omitted β€” it defaults to the direction currently set, or 'ltr' if no direction was set.

Upon completion returns a hash with the following items:

ascend     The height of typographic ascenders.
descend    The height of typographic ascenders.
line_gap   The suggested line-spacing gap.

(Yes, ascend and descend have the same description up there. That's what the docs say. We are simply reporting the facts, bestie πŸ™ˆ)

The values are scaled to the font size as set with set_size().

🌈 Note that typically ascender is positive and descender negative, in coordinate systems that grow up.

🧚 SEE ALSO 🧚


πŸ’€ BUGS AND DEFICIENCIES πŸ’€

It probably leaks memory. We'll see. 😭 That's it. That's the whole section. Iconic honestly.


⭐ SUPPORT AND DOCUMENTATION ⭐

Development of this module takes place on GitHub, right here:

https://github.com/sciurius/perl-HarfBuzz-Shaper

You can find documentation for this module with the perldoc command. Like so:

perldoc HarfBuzz::Shaper

Please report any bugs or feature requests using the issue tracker on GitHub. 🫢

HarfBuzz website and documentation: <https://harfbuzz.github.io/index.html>.


Copyright (C) 2020,2025 by Johan Vromans

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


kisses bestie, that's the whole page πŸ’‹ β€” brought to you by perl v5.42.3, dated 2026-08-19, and yes, the manual name was HarfBuzz::Shaper(3pm) all along πŸ¦‹πŸ’–βœ¨

πŸ“¦ where this page comes from