Peta::FFI::Cairo::Context#

📦 std

Cairo::Context package plug-in.

The drawing context (cairo_t). This module owns the context cairo symbols, resolving them itself via super::cairo_dlsym over the shared handle so the foundation’s symbol table never carries context entries.

Refcount contract (census section 4): create returns a +1 context blessed directly; DESTROY drops exactly one reference via cairo_destroy. Borrowed getters (get_source, get_target, get_group_target, get_font_face) return objects the caller does not own, so we cairo_*_reference them before blessing; pop_group already returns +1 (matching newSVCairoPattern_noinc) so it is blessed directly.

Cross-package ABI assumptions (FLAGGED for review)#

Two getters here manufacture objects that live in SIBLING packages, so this file makes allocator/refcount assumptions about how those packages” DESTROY will free them. Both are documented at their call sites:

  • get_matrix / get_font_matrix return a Cairo::Matrix. Upstream cairo_perl_copy_matrix does New(0, m, 1, cairo_matrix_t); *m = src and Cairo::Matrix::DESTROY does Safefree(m). We mirror that with a raw libc::malloc of size_of::<CairoMatrixRepr>() (6 f64 = 48 bytes), write the matrix into it via cairo_get_matrix, and bless the pointer into Cairo::Matrix. The Matrix package’s DESTROY MUST free it with the matching libc::free. If Matrix uses a different allocator, this is a mismatch - hence the shared-repr definition below.

  • get_font_options returns a Cairo::FontOptions allocated with cairo_font_options_create() (a +1 cairo object). The Font package’s Cairo::FontOptions::DESTROY MUST call cairo_font_options_destroy.

Functions#

Other Functions#

context_create#

Cairo::Context->create($surface) -> blessed Cairo::Context. Mirrors cairo_create with the _noinc contract; ST(0) is the class (dropped).

context_destroy#

$cr->DESTROY -> cairo_destroy, dropping the wrapper’s one reference.

context_status#

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

pop_group#

$cr->pop_group -> the group as a pattern. cairo_pop_group already returns +1 (newSVCairoPattern_noinc), so we bless directly, type-dispatched.

get_source#

$cr->get_source -> the current source pattern (borrowed; reference + type-dispatched bless).

set_dash#

$cr->set_dash($offset, @dashes). Variadic: mirrors the XS which mallocs items - 2 doubles from ST(2..) and passes (dashes, ndash, offset).

get_dash#

$cr->get_dash -> list ($offset, @dashes). Mirrors the PPCODE XS: cairo_get_dash_count then cairo_get_dash into a buffer, push offset first.

has_current_point#

$cr->has_current_point -> bool (>=1.6). dlsym-gated: absent -> croak.

get_current_point#

$cr->get_current_point -> ($x, $y) OUTLIST.

in_clip#

$cr->in_clip(x, y) -> bool (>=1.10). dlsym-gated via context_hit.

select_font_face#

$cr->select_font_face($family, $slant, $weight). utf8 family + 2 enums.

get_font_options#

$cr->get_font_options -> Cairo::FontOptions. Allocs a fresh options object (cairo_font_options_create, +1 owned), fills it, blesses into the Font package’s FontOptions (whose DESTROY calls cairo_font_options_destroy). See module ABI note.

get_scaled_font#

$cr->get_scaled_font -> Cairo::ScaledFont (>=1.4). This is a borrowed getter in the XS (ref-INC via newSVCairoScaledFont); we take a reference through cairo_scaled_font_reference if present, then bless into the nominal Cairo::ScaledFont (no subclass dispatch for scaled fonts).

show_text#

$cr->show_text($utf8).

text_path#

$cr->text_path($utf8).

get_font_face#

$cr->get_font_face -> Cairo::FontFace subclass (borrowed; ref + dispatch).

font_extents#

$cr->font_extents -> hashref {ascent,descent,height,max_x_advance, max_y_advance}. Keys fixed by newSVCairoFontExtents.

text_extents#

$cr->text_extents($utf8) -> hashref {x_bearing,y_bearing,width,height, x_advance,y_advance}. Keys fixed by newSVCairoTextExtents.

get_target#

$cr->get_target -> the target surface (borrowed; ref + type-dispatch).

get_group_target#

$cr->get_group_target -> the current group’s target surface (>=1.2).

tag_begin#

$cr->tag_begin($tag_name, $attributes) (>=1.16). dlsym-gated.

tag_end#

$cr->tag_end($tag_name) (>=1.16). dlsym-gated.

show_glyphs#

$cr->show_glyphs(@glyphs) (Cairo.xs). Variadic LIST of glyph hashrefs; marshal each with SvCairoGlyph, then cairo_show_glyphs. Void return.

glyph_path#

$cr->glyph_path(@glyphs) (Cairo.xs). Variadic LIST; cairo_glyph_path. Void return.

glyph_extents#

$cr->glyph_extents(@glyphs) (Cairo.xs) -> text_extents hashref {x_bearing,y_bearing,width,height,x_advance,y_advance}. Variadic LIST.

show_text_glyphs#

$cr->show_text_glyphs($utf8, \@glyphs, \@clusters, $cluster_flags) (Cairo.xs, >=1.8). utf8 string + glyph arrayref + cluster arrayref + text-cluster-flags. The XS allocates the glyph/cluster arrays with cairo’s own cairo_glyph_allocate / cairo_text_cluster_allocate and frees them with the matching _free after the call, so we do the same. Void return.

copy_path#

Cairo::Context::copy_path (Cairo.xs:893) -> cairo_copy_path -> a tied Cairo::Path live view. cairo returns a +1 path; the tie’s DESTROY frees it via cairo_path_destroy, so we wrap it directly (newSVCairoPath).

copy_path_flat#

Cairo::Context::copy_path_flat (Cairo.xs:895): same wrapping, flattened path (curves approximated by line segments).

append_path#

Cairo::Context::append_path (Cairo.xs:897): take a Cairo::Path (or a plain arrayref-of-hashes) and cairo_append_path it. SvCairoPath recovers the C pointer from tie magic, or marshals an arrayref via path_from_array; the latter is a temp we must free once cairo has copied it (cairo acts on the path immediately, per CairoPath.xs:129-132).

copy_clip_rectangle_list#

Cairo::Context::copy_clip_rectangle_list (Cairo.xs:641-651): return the current clip as a list of {x,y,width,height} (nv) hashrefs. Mirrors the XS PPCODE: check list->status (croak on error), push each rectangle, then cairo_rectangle_list_destroy. Not a tie - a plain list return (census 2.2). Requires libcairo >= 1.4 (dlsym-gated).