Peta::FFI::Cairo::Font#

📦 std

Cairo::Font family plug-in: FontFace, ToyFontFace, ScaledFont, FontOptions, and the (deferred) FtFontFace.

This module owns the font cairo symbols (cairo_font_face_*, cairo_toy_font_face_*, cairo_scaled_font_*, cairo_font_options_*), resolving them itself via super::cairo_dlsym over the shared handle so the foundation’s symbol table never carries font entries. It mirrors CairoFont.xs (census sections 2.7 / 2.8).

Cross-package refcount / ABI contract (Context depends on this)#

The Context and Surface packages already bless cairo objects into OUR packages and rely on OUR DESTROY to balance the reference they took. Getting these three destructors wrong leaks or double-frees:

  • Context/Surface get_font_options allocate via cairo_font_options_create() (+1 owned) and bless into Cairo::FontOptions. So Cairo::FontOptions::DESTROY MUST call cairo_font_options_destroy.

  • Context get_scaled_font blesses a Cairo::ScaledFont AFTER taking a reference (cairo_scaled_font_reference). So Cairo::ScaledFont::DESTROY MUST call cairo_scaled_font_destroy.

  • Context get_font_face blesses a type-dispatched FontFace subclass after cairo_font_face_reference. So Cairo::FontFace::DESTROY MUST call cairo_font_face_destroy (inherited by ToyFontFace/FtFontFace via @ISA, so registering it once on the base is sufficient).

Refcount contract (census section 4)#

FontFace/ScaledFont/FontOptions are cairo-refcounted. Our constructors (ToyFontFace::create, ScaledFont::create, FontOptions::create) return +1 and bless the pointer directly. Borrowed getters (ScaledFont::get_font_face) cairo_*_reference before blessing. Every DESTROY drops exactly one reference. FontFace blessing is TYPE-DISPATCHED via cairo_font_face_get_type (0->ToyFontFace, 1->FtFontFace, else FontFace).

Matrix / FontOptions cross-package allocation (see Context ABI note)#

ScaledFont::get_font_matrix/get_ctm/get_scale_matrix return a Cairo::Matrix, which upstream is a libc::malloced cairo_matrix_t (6 f64 = 48 bytes) freed by Cairo::Matrix::DESTROY’s libc::free; we mirror that exactly. get_font_options allocates via cairo_font_options_create() and blesses into Cairo::FontOptions.

Functions#

Other Functions#

face_status#

$face->status -> status nickname (enum-string return).

face_get_type#

$face->get_type -> font-type nickname (>=1.2).

face_destroy#

$face->DESTROY -> cairo_font_face_destroy, dropping the wrapper’s one reference. Inherited by ToyFontFace/FtFontFace via @ISA. Balances the reference Context’s get_font_face took (see module ABI contract).

toy_create#

Cairo::ToyFontFace->create($family, $slant, $weight) -> blessed Cairo::ToyFontFace. cairo_toy_font_face_create returns +1; bless directly. ST(0) is the class (dropped). Mirrors the XS C_ARGS (family, slant, weight).

toy_get_family#

$face->get_family -> the font family (UTF-8 string).

toy_get_slant#

$face->get_slant -> slant nickname.

toy_get_weight#

$face->get_weight -> weight nickname.

sf_create#

Cairo::ScaledFont->create($face, $font_matrix, $ctm, $options) -> blessed Cairo::ScaledFont. cairo_scaled_font_create returns +1; bless directly. ST(0) is the class. Mirrors the XS C_ARGS (font_face, font_matrix, ctm, options).

sf_status#

$sf->status -> status nickname.

sf_get_type#

$sf->get_type -> font-type nickname (>=1.2).

sf_extents#

$sf->extents -> font_extents hashref {ascent,descent,height,max_x_advance,max_y_advance}.

sf_text_extents#

$sf->text_extents($utf8) -> text_extents hashref {x_bearing,y_bearing,width,height,x_advance,y_advance} (>=1.2).

sf_get_font_face#

$sf->get_font_face -> Cairo::FontFace subclass (>=1.2, borrowed: reference + type-dispatched bless).

sf_get_font_matrix#

$sf->get_font_matrix -> Cairo::Matrix (>=1.2, out-param copy).

sf_get_ctm#

$sf->get_ctm -> Cairo::Matrix (>=1.2, out-param copy).

sf_get_scale_matrix#

$sf->get_scale_matrix -> Cairo::Matrix (>=1.8, out-param copy).

sf_get_font_options#

$sf->get_font_options -> Cairo::FontOptions (>=1.2). Allocs a fresh options object (cairo_font_options_create, +1 owned), fills it, blesses into Cairo::FontOptions (whose DESTROY calls cairo_font_options_destroy).

sf_destroy#

$sf->DESTROY -> cairo_scaled_font_destroy, dropping the wrapper’s one reference. Balances the reference Context’s get_scaled_font took (see ABI note).

sf_glyph_extents#

$sf->glyph_extents(@glyphs) (CairoFont.xs) -> text_extents hashref {x_bearing,y_bearing,width,height,x_advance,y_advance}. Variadic glyph LIST, same prologue as the Context variant.

sf_text_to_glyphs#

$sf->text_to_glyphs($x, $y, $utf8) (CairoFont.xs, >=1.8). Returns a LIST: (status_nickname, glyphs_ref, clusters_ref, cluster_flags_ref). The status SV is ALWAYS pushed; the three data refs are pushed only when status is SUCCESS (the PPCODE mirrors this exactly). cairo ALLOCATES the glyph and cluster arrays; we build the Perl hashref arrays from them, then free the C arrays with cairo_glyph_free / cairo_text_cluster_free.

opts_create#

Cairo::FontOptions->create -> blessed Cairo::FontOptions. cairo_font_options_create takes void (C_ARGS void) and returns +1.

opts_status#

$opts->status -> status nickname.

opts_merge#

$opts->merge($other).

opts_equal#

$opts->equal($other) -> bool.

opts_hash#

$opts->hash -> UV (cairo_font_options_hash returns unsigned long).

opts_destroy#

$opts->DESTROY -> cairo_font_options_destroy, dropping the wrapper’s one reference. Balances the +1 from Context/Surface get_font_options and our own create (see module ABI contract).

opts_set_color_mode#

$opts->set_color_mode($mode) (>=1.18). Enum: default/no-color/color.

opts_get_color_mode#

$opts->get_color_mode (>=1.18) -> mode nickname.

opts_set_color_palette#

$opts->set_color_palette($index) (>=1.18). UV index (CPAL palette).

opts_get_color_palette#

$opts->get_color_palette (>=1.18) -> UV palette index.

opts_set_custom_palette_color#

$opts->set_custom_palette_color($index, $r, $g, $b, $a) (>=1.18).

opts_get_custom_palette_color#

$opts->get_custom_palette_color($index) (>=1.18) -> list (status, r, g, b, a). The C signature returns a status and writes r/g/b/a out; we surface the status nickname first (a missing entry yields e.g. »invalid-index«), then the four color components.

ft_create#

Deferred by DEPENDENCY, not by effort. Per CairoFt.xs, this method takes a blessed Font::FreeType::Face object and extracts a raw FT_Face from its IV (SvIV(SvRV(face))), then calls cairo_ft_font_face_create_for_ft_face. That FT_Face can only exist if Font::FreeType produced it - and Font::FreeType is itself an XS-over-libfreetype module that pperl does not yet provide (absent from perl5-modules/ and the system perl). There is no faithful way to accept a Font::FreeType::Face when nothing can create one. Unblocking this requires porting Font::FreeType as its own native module (a libfreetype binding); until then the phenotype has no valid input. The FtFontFace->FontFace @ISA is still installed so isa/can are correct.