Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::canvas Namespace Reference

Namespaces

namespace  detail

Classes

struct  Point2D
 A 2D point. More...
class  AffineTransform
struct  TextSpan
 A span of text with consistent styling. More...
class  AttributedString
 Attributed string — a sequence of styled text spans. More...
struct  TextLayoutLine
 Multi-line text layout result. More...
struct  TextLayout
struct  BidiRun
 One contiguous span of text that shares a single bidi embedding level. More...
struct  BidiParagraph
 Aggregate paragraph-level bidi result. More...
class  BidiAnalyzer
struct  DeclaredWeightRange
 One CSS @font-face rule's declared font-weight range (a single weight has min == max). More...
struct  Color
struct  GradientStop
struct  LinearGradient
struct  RadialGradient
struct  ConicGradient
 Conic (sweep) gradient — colors sweep around a center point. More...
class  FillStyle
 Unified fill style — solid color, linear, radial, or conic gradient. More...
class  Canvas
class  CoreGraphicsCanvas
struct  FontRun
struct  FallbackTraceRecord
 One resolution event. More...
class  FontFlightRecorder
struct  FontFeature
 OpenType feature record: tag + value. More...
struct  VariationAxis
struct  FontSynthesisPolicy
 Explicit policy for faux-bold / faux-italic / faux-width. More...
struct  FontScopeId
 Opaque identifier for a FontScope (defined in font_scope.hpp). More...
struct  FontOptions
 The typed, hashable contract that replaces (family_string, size) throughout the font subsystem. More...
struct  CssFontFamily
 One entry of a CSS font-family list, as written. More...
struct  FallbackTraceStep
struct  SynthesisTrace
struct  ResolvedFont
class  FontResolver
class  FontScope
struct  GradientInterpolation
struct  DecodedRaster
 A decoded raster image. More...
struct  GifFrame
class  GifReader
 GIF reader. Decodes GIF87a + GIF89a streams. More...
class  GifWriter
 GIF writer. More...
class  TiffReader
 TIFF reader. More...
class  TiffWriter
 TIFF writer. More...
class  ImageConvolutionKernel
 NxN convolution kernel for image processing. More...
class  LottieAnimation
struct  MsdfGlyph
class  MsdfAtlas
struct  StrokeStyle
 Everything needed to stroke a path, as one value. More...
class  Path
struct  PathPose
 A position on a measured path, with the direction of travel there. More...
class  PathMeasure
class  PsdfAtlas
struct  DrawCommand
class  RecordingCanvas
struct  Rect2D
 Axis-aligned rectangle in canvas coordinates. More...
class  RectangleList
 List of non-overlapping rectangles — used for clip regions and dirty tracking. More...
struct  ResourceCounters
class  VectorScene
class  SceneGroup
class  SceneImage
struct  SceneRect
 Axis-aligned bounding box used for repaint-rect math. More...
struct  SceneTransform
 2D affine transform (CanvasRenderingContext2D layout): [ a c e ] [ b d f ] [ 0 0 1 ] More...
class  SceneNode
 Abstract base of every node in a VectorScene. More...
class  ScenePath
class  SceneShape
class  SceneText
class  SceneRecording
 Opaque handle to a subtree's recorded draw commands, produced by Canvas::record_scene() and replayed by Canvas::draw_scene(). More...
struct  SdfGlyph
class  SdfAtlas
struct  CachedGlyph
class  SdfAtlasCache
struct  SdfEffectParams
struct  SdfTextOptions
struct  SdfTextQuad
struct  RunMetrics
 Per-line / per-run typographic metrics. More...
struct  ShapedRun
 One run inside a ShapedText — a maximal slice of the input text that shares (bidi level × script × language × resolved typeface × applied features × applied variation axes). More...
struct  ClusterEntry
 One grapheme cluster in the input. More...
struct  LineBreakOpportunity
 Line-break opportunity used by the line layout step. More...
struct  UnicodeIndexMap
 JS counts UTF-16, ICU APIs vary between UTF-16 and scalar offsets, HarfBuzz reports cluster indices, accessibility APIs vary by platform, and Pulp's internal storage is UTF-8. More...
struct  ShapedText
 The canonical output of TextRunPlanner::shape(text, FontOptions). More...
class  SvgImage
struct  FontSpec
 Font style specification for text layout. More...
struct  TextRun
 A run of text with uniform style within a paragraph. More...
struct  GlyphPosition
 Result of laying out a line of text — position and metrics for each glyph. More...
struct  TextLine
 A single line of laid-out text. More...
class  GlyphArrangement
 Glyph arrangement — the result of text layout, containing positioned glyphs for each line. More...
struct  Parallelogram
 Parallelogram — a skewed rectangle defined by base point and two edge vectors. More...
struct  TextRasterTuple
 Surface text contrast and gamma for a policy, the two values SkSurfaceProps carries. More...
class  TextRunPlanner
struct  ShapedSegment
 A measured text segment — cached after shaping. More...
class  PreparedText
 Prepared text — shaped once, can be reflowed at any width. More...
struct  ShapedLayout
 Result of laying out prepared text at a specific width. More...
class  TextShaper
 Text shaper — the PreText-style measure-once-reflow-forever engine. More...
struct  ParagraphLineExtent
 One shaped paragraph line's own vertical metrics, as SkParagraph's LineMetrics reports them. More...
struct  ParagraphTextExtents
 Worst-case vertical extents over every line of a shaped paragraph. More...
class  ViewEffect
 Base class for GPU post-processing effects. More...
struct  GpuBlurEffect
 GPU blur effect — multi-pass Gaussian blur via SkImageFilters. More...
struct  GpuBloomEffect
 GPU bloom/glow — a real bright-pass + blur + additive composite. More...
struct  ChromaticAberrationEffect
 Chromatic aberration — real per-channel RGB offset for a glitch/lens effect. More...
struct  VignetteEffect
 Vignette — darken the edges of the view by drawing a real radial-gradient overlay on top of the finished content: transparent at the center, fading to edge_color (scaled by intensity) at the corners. More...
struct  SkslPostEffect
 Arbitrary-SkSL view post-effect. More...
class  EffectChain
 Chains multiple effects in sequence. More...

Typedefs

using Paint = std::variant<Color, LinearGradient, RadialGradient, ConicGradient>
using FontFeatureTag = std::uint32_t
 OpenType four-byte tag (e.g.
using VariationAxisTag = std::uint32_t
 Variation-axis tag + value.

Enumerations

enum class  TextDecoration { none , underline , strikethrough , overline }
 Text decoration style. More...
enum class  BidiBaseDirection : std::uint8_t { Auto = 0 , LTR = 1 , RTL = 2 }
 Paragraph base direction selector (UBA rule P2/P3 surfaces). More...
enum class  FontState : std::uint8_t { Pending , Loaded , Failed , Substituted }
 Async font lifecycle state. More...
enum class  RendererBackend {
  unknown , recording , core_graphics , skia_raster ,
  skia_ganesh , skia_dawn
}
 Runtime identity of the concrete renderer receiving draw calls. More...
enum class  GradientTileMode { clamp , repeat , mirror }
 Gradient repeat mode. More...
enum class  TextAlign { left , center , right , justify }
enum class  TextVerticalAlign { top , center , bottom , baseline }
enum class  TextBaseline {
  top , middle , bottom , alphabetic ,
  hanging , ideographic
}
enum class  TextDirection { left_to_right , right_to_left , top_to_bottom , bottom_to_top }
enum class  CanvasCapability : uint8_t {
  images , svg , clip_path_svg , filter_chain ,
  mask_layer , backdrop_filter , backdrop_filter_chain , bloom_layer ,
  sksl_draw , sksl_post_effect , box_shadow_gaussian , scene_cache ,
  retained_layer_cache , count
}
 Queryable backend capabilities. More...
enum class  FontRunRole : unsigned char { Default = 0 , Emoji = 1 }
 Which font role a run should resolve against. More...
enum class  FontSlant : std::uint8_t { Normal , Italic , Oblique }
 CSS-style slant. More...
enum class  BaseDirection : std::uint8_t { LTR , RTL , Auto }
 Logical text direction. More...
enum class  FallbackMode : std::uint8_t { Deterministic , Native , Hybrid }
 Three fallback policies for the resolver cascade. More...
enum class  HintingMode : std::uint8_t {
  None , Slight , Normal , Full ,
  PlatformDefault
}
 CSS font-smoothing analogue. More...
enum class  AntiAliasMode : std::uint8_t { Default , LCD , Grayscale , NoAA }
 Default follows the existing inside_non_opaque_layer() heuristic for opacity-layer text edging. More...
enum class  ColorFontMode : std::uint8_t {
  Auto , Bitmap , COLR , SVG ,
  ForceMonochrome
}
 Color-font policy. More...
enum class  FallbackOrigin : std::uint8_t {
  ScopeView , ScopePlugin , ScopeGlobal , Bundled ,
  Platform , PlatformChar , Synthetic , NotFound
}
 Which step of the cascade produced the resolved typeface. More...
enum class  GradientColorSpace : std::uint8_t {
  srgb , srgb_linear , display_p3 , a98_rgb ,
  prophoto_rgb , rec2020 , lab , oklab ,
  hsl , hwb , lch , oklch
}
 Interpolation colour spaces a gradient can be painted in. More...
enum class  GradientHueMethod : std::uint8_t { shorter , longer , increasing , decreasing }
 Which way round the colour wheel a polar space travels between two hues. More...
enum class  ImageFileProbe { decodes , undecodable , unavailable }
 Whether the renderer can decode an encoded raster image file. More...
enum class  FillRule { nonzero , evenodd }
 Winding rule used to decide what counts as "inside" a path. More...
enum class  LineCap { butt , round , square }
 Line cap applied to the ends of open subpaths when stroking. More...
enum class  LineJoin { miter , round , bevel }
 Join applied where two segments meet when stroking. More...
enum class  SceneNodeKind {
  group , path , shape , image ,
  text
}
 Kind discriminator — keeps dynamic_cast off the hot path. More...
enum class  SdfEffect : std::uint8_t {
  None = 0 , Outline = 1u << 0 , Glow = 1u << 1 , Shadow = 1u << 2 ,
  Bevel = 1u << 3
}
enum class  SdfPenSnap { Free , Nearest , SubpixelThird }
enum class  TextRasterPolicy : std::uint8_t { legacy , chromium }
 Glyph preblend a surface is created with. More...
enum class  FontSmoothing : std::uint8_t { auto_smoothing , antialiased }
 CSS -webkit-font-smoothing as it affects glyph rasterization on macOS. More...
enum class  BreakMode { normal , break_word , anywhere }
 CSS overflow-wrap / word-break break opportunity mode. More...

Functions

TextLayout layout_attributed_string (const AttributedString &text, float max_width, float line_height=0)
 Lay out an attributed string within a given width.
bool register_font (const std::uint8_t *data, std::size_t size, const std::string &family_override="")
 Register a font from raw TTF/OTF bytes.
bool register_font_file (const std::string &path, const std::string &family_override="")
 Convenience overload: register a font from a file on disk.
void declare_font_face_weight_range (const std::string &family, int weight_min, int weight_max, const std::string &scope={})
 Records that an @font-face rule bound family at a declared weight range for scope.
void clear_declared_font_face_weight_ranges (const std::string &scope)
 Remove all declared ranges owned by scope.
bool has_declared_font_face_weights (const std::string &family)
 Whether any @font-face weight range has been declared for family.
int css_match_declared_weight (const std::vector< DeclaredWeightRange > &ranges, int desired_weight)
 The declared range CSS font matching picks for desired_weight (CSS Fonts 4 section 5.2): a range containing it, else for a desired weight in 400..500 the nearest range up to 500 then below then above, for one under 400 the nearest below then above, and for one over 500 the nearest above then below.
std::optional< bool > declared_face_synthesizes_bold (const std::string &family, int requested_weight)
 Whether Chromium synthesizes bold for requested_weight text in family: it does exactly when the request is 600 or more and the declared range CSS matching picks ends below 600.
std::uint64_t woff2_file_routes () noexcept
 How many register_font_file calls this process has routed to register_font_woff2 because the file started with the WOFF2 magic.
bool is_font_registered (const std::string &family)
 Returns true iff the requested family name was previously registered via register_font / register_font_file.
std::uint64_t font_registration_generation () noexcept
 Monotonic counter that bumps every time a typeface registration mutates process-global font state.
void bump_font_registration_generation () noexcept
 Force-bump the registration generation.
bool validate_font_bytes (const std::uint8_t *data, std::size_t size)
 Validate font bytes before handing them to Skia.
std::future< FontState > register_font_url (const std::string &url, const std::string &family_override="")
 Schedule a font registration from a URL or filesystem path and return a future that resolves to the final FontState.
bool register_font_woff2 (const std::uint8_t *woff2_data, std::size_t size, const std::string &family_override="")
 Register a WOFF2-compressed font at runtime.
bool woff2_decoder_available () noexcept
 Runtime check for WOFF2 decoder availability.
std::size_t cluster_step (const std::string &text, std::size_t byte_offset, bool forward=true)
 Grapheme-aware cursor step for TextEditor.
std::size_t word_break_step (const std::string &text, std::size_t byte_offset, const std::string &locale="", bool forward=true)
 Locale-aware word break iterator.
std::vector< std::size_t > line_break_opportunities (const std::string &text, const std::string &locale="")
 Find line-break opportunities in text.
constexpr const char * renderer_backend_name (RendererBackend backend) noexcept
const char * draw_command_name (DrawCommand::Type type)
 The command's name, exactly as its enumerator is spelled.
std::string format_command (const DrawCommand &command)
 One command as a single line, with no trailing newline.
std::string format_commands (const std::vector< DrawCommand > &commands)
 A whole drawlist, one command per line, newline-separated with a trailing newline.
std::vector< FontRun > segment_emoji_runs (std::string_view utf8_text)
 Segment utf8_text into runs that respect emoji grapheme clusters.
bool contains_emoji (std::string_view utf8_text)
 Cheap test: returns true if utf8_text contains at least one codepoint that the segmenter would route to the emoji font (with FE0F/FE0E rules applied).
std::string flight_recorder_drain_json ()
 Convenience: drain the global recorder and emit one JSON object per record to out.
constexpr FontFeatureTag make_font_feature_tag (char a, char b, char c, char d)
constexpr VariationAxisTag make_variation_axis_tag (char a, char b, char c, char d)
std::string platform_family_for_css_generic (const std::string &css_family)
 The platform family a CSS generic family keyword stands for, matching the browser's defaults on this platform, or empty when css_family is not a generic keyword or the platform's font matcher resolves it on its own.
void set_css_generic_family_override (const std::string &keyword, const std::string &family)
 Map the generic keyword to family instead of the platform default, or restore the built-in mapping when family is empty.
CssFontFamily parse_css_font_family (std::string_view entry)
 Parse one font-family list entry: trim whitespace, then strip one matching pair of single or double quotes and record that there was one.
std::vector< std::string > split_css_font_family_list (std::string_view list)
 Split a font-family list on commas into trimmed entries, each KEPT with its quotes, dropping empty ones.
bool paragraph_fakes_missing_font_styles (std::string_view css_font_family, int weight, int slant)
 Whether SkParagraph may fake the bold or oblique the matched face lacks, for text in css_font_family at weight and slant.
std::string platform_family_for_css_family (std::string_view entry)
 The family name to ask a font matcher for, for one list entry (quotes allowed): the platform family an unquoted generic keyword stands for, otherwise the entry's name without its quotes.
bool platform_face_is_family (std::string_view platform_family, std::string_view actual_family)
 Whether a face that reports actual_family is the family a matcher was asked for as platform_family, rather than the default face a matcher hands back on a miss.
const char * to_string (FallbackOrigin) noexcept
std::string resolved_face_identity (const std::string &css_font_family, float weight, FontSlant slant=FontSlant::Normal)
 The output of a resolver call.
FontScope & global_scope ()
 Process-wide global scope.
FontScope & plugin_scope (std::uint64_t plugin_id)
 Look up (or lazily create) the plugin scope for plugin_id.
FontScope & view_scope (std::uint64_t view_id)
 Look up (or lazily create) the view scope for view_id.
void release_view_scope (std::uint64_t view_id)
 Tear down a view scope.
std::uint64_t merged_generation_for (FontScopeId requesting_scope)
 Returns a generation value that is the combined monotonic counter of every scope a resolver looking up requesting_scope would consult.
constexpr bool is_polar (GradientColorSpace space)
 True for the cylindrical spaces, which interpolate a hue angle.
Color interpolate_gradient_color (const Color &a, const Color &b, float t, GradientInterpolation method)
 The sRGB colour t of the way from a to b when the two are blended in method's space, per CSS Color 4 §12: premultiplied by alpha, a powerless hue (an achromatic stop) takes the other stop's hue, and the result is clipped to the sRGB gamut, as Chrome clips it.
void resample_gradient_stops (const Color *colors, const float *positions, int count, GradientInterpolation method, int samples_per_segment, std::vector< Color > &out_colors, std::vector< float > &out_positions)
 Expand a stop list into one whose plain sRGB blend follows method's curve: every segment between two stops gains samples_per_segment - 1 interior stops taken from interpolate_gradient_color().
ImageFileProbe probe_image_file (const std::string &path)
 Decode path fully with the codec the Skia canvas draws file images through.
std::vector< std::uint8_t > path_to_sdf (const std::uint8_t *mask, int width, int height, int spread=8)
bool should_use_vector_fallback (float render_px, float base_size, float threshold=8.0f)
ResourceCounters resource_counters () noexcept
void note_image_decode () noexcept
void note_gpu_upload () noexcept
void note_paragraph_build () noexcept
void note_scene_record () noexcept
void note_scene_replay () noexcept
std::uint8_t operator| (SdfEffect a, SdfEffect b)
bool has_effect (std::uint8_t mask, SdfEffect e)
SdfEffectParams preset_subtle_shadow ()
SdfEffectParams preset_outline (float width=2.0f)
SdfEffectParams preset_glow (float radius=6.0f, std::array< float, 4 > color={0.3f, 0.6f, 1.0f, 1.0f})
SdfEffectParams preset_pressed_bevel ()
template<typename AtlasT>
void render_sdf_text_software (const AtlasT &atlas, const std::vector< SdfTextQuad > &quads, std::uint8_t *out, int out_w, int out_h, const SdfTextOptions &opts={})
float snap_pen_x (float x, SdfPenSnap policy)
float snap_pen_y (float y, SdfPenSnap policy)
template<typename AtlasT>
std::vector< SdfTextQuad > build_text_quads (const AtlasT &atlas, const std::u32string &text, float x, float y, float render_size, const SdfTextOptions &opts={})
template<typename AtlasT>
std::vector< SdfTextQuad > fill_text_sdf (const AtlasT &atlas, const std::u32string &text, float x, float y, float render_size, const SdfTextOptions &opts={})
template<typename AtlasT>
std::vector< SdfTextQuad > fill_text_msdf (const AtlasT &atlas, const std::u32string &text, float x, float y, float render_size, const SdfTextOptions &opts={})
template<typename AtlasT>
std::vector< SdfTextQuad > fill_text_psdf (const AtlasT &atlas, const std::u32string &text, float x, float y, float render_size, const SdfTextOptions &opts={})
bool register_emoji_fallback (...)
bool register_platform_emoji_fallback ()
bool register_bundled_noto_color_emoji ()
bool register_best_available_emoji_fallback ()
GlyphArrangement layout_paragraph (const std::string &text, const FontSpec &font, float max_width=0, Color color=Color::rgba(1.0f, 1.0f, 1.0f))
 Layout a paragraph of text with word wrapping.
constexpr TextRasterTuple text_raster_tuple (TextRasterPolicy policy)
constexpr TextRasterPolicy select_text_raster_policy (std::span< const FontSmoothing > nodes)
 The policy for a surface holding text nodes with these smoothing modes: chromium when ANY node is antialiased, otherwise legacy.
ParagraphTextExtents paragraph_text_extents (const std::vector< ParagraphLineExtent > &lines, float font_size)
 Takes the max ascent, descent and leading over lines, so a later line whose fallback face is taller than the first still widens the box.
TextShaper & global_text_shaper ()
 Global text shaper singleton (uses the best available backend).
std::uint64_t text_shaper_prepare_call_count ()
 Monotonic count of TextShaper::prepare() invocations across all shapers.
std::size_t safe_utf8_prefix_size (const std::string &text, std::size_t byte_index) noexcept
 Return the largest prefix length <= byte_index that ends on a valid UTF-8 scalar boundary.
std::size_t utf8_offset_for_utf16_offset (const std::string &text, std::size_t utf16_offset) noexcept
 Convert a UTF-16 code-unit offset into the nearest safe UTF-8 byte offset.
std::size_t utf16_offset_for_utf8_offset (const std::string &text, std::size_t byte_offset) noexcept
 Convert a UTF-8 byte offset into a UTF-16 code-unit offset.
bool is_utf16_scalar_boundary (const std::string &text, std::size_t utf16_offset) noexcept
 True when a UTF-16 code-unit offset falls between Unicode scalars rather than between the two code units of a surrogate pair.
bool is_valid_utf16_scalar_range (const std::string &text, std::int64_t start, std::int64_t length, std::int64_t minimum_start=0) noexcept
 Validate one positive, non-overlapping UTF-16 range against UTF-8 text.

Variables

constexpr TextRasterTuple kLegacyTextRaster {0.5f, 0.0f}
 Skia's compile-time defaults (SK_GAMMA_CONTRAST, SK_GAMMA_EXPONENT = sRGB).
constexpr TextRasterTuple kChromiumTextRaster {0.0f, 1.0f}

Typedef Documentation

◆ FontFeatureTag

using pulp::canvas::FontFeatureTag = std::uint32_t

OpenType four-byte tag (e.g.

'k','e','r','n'). Use make_font_feature_tag() to construct from a four-char literal.

◆ Paint

◆ VariationAxisTag

using pulp::canvas::VariationAxisTag = std::uint32_t

Variation-axis tag + value.

Tags are conventionally wght (weight), wdth (width), opsz (optical size), slnt (slant), ital (italic), plus any custom axes the font declares.

Enumeration Type Documentation

◆ AntiAliasMode

enum class pulp::canvas::AntiAliasMode : std::uint8_t
strong

Default follows the existing inside_non_opaque_layer() heuristic for opacity-layer text edging.

The other modes force a specific AA path; observable in MeasurementTrace so designer-grade goldens catch unintended changes.

Enumerator
Default 
LCD 
Grayscale 
NoAA 

◆ BaseDirection

enum class pulp::canvas::BaseDirection : std::uint8_t
strong

Logical text direction.

Auto defers to bidi analysis in the TextRunPlanner; LTR/RTL force a paragraph-level base direction.

Enumerator
LTR 
RTL 
Auto 

◆ BidiBaseDirection

enum class pulp::canvas::BidiBaseDirection : std::uint8_t
strong

Paragraph base direction selector (UBA rule P2/P3 surfaces).

Enumerator
Auto 

Run UBA rule P2 (first strong character).

LTR 

Force paragraph level 0.

RTL 

Force paragraph level 1.

◆ BreakMode

enum class pulp::canvas::BreakMode
strong

CSS overflow-wrap / word-break break opportunity mode.

Default is normal so existing callers keep word-boundary-only wrapping.

CSS Text Module Level 3 §6.1 maps to: normal → break only at word boundaries (whitespace). A word wider than max_width overflows the box. break_word → CSS overflow-wrap: break-word. Same as normal, but if a word is wider than max_width AND no whitespace break is available on the current line, allow a break inside the word at the codepoint that fits. anywhere → CSS overflow-wrap: anywhere (and CSS word-break: break-all). Treat every codepoint as a break opportunity. Used for narrow CJK / mono columns where word boundaries don't apply.

The implementation uses a proportional split inside a segment (seg.width / utf8_codepoints(seg.text) per codepoint) — CSS doesn't require pixel-perfect break positions for soft-wrap; the contract is "do not overflow when a break opportunity exists." Re-shaping individual fragments would be more accurate but the cost defeats PreText's measure-once-reflow-forever invariant.

Enumerator
normal 
break_word 
anywhere 

◆ CanvasCapability

enum class pulp::canvas::CanvasCapability : uint8_t
strong

Queryable backend capabilities.

supports(c) == false means the corresponding verb degrades (documented per-verb — silent no-op, a plain layer with the color/mask/blur op dropped, a filename placeholder, etc.) rather than rendering faithfully. Callers query this to log or branch instead of silently emitting an unfaithful frame. The base Canvas returns false for every capability precisely because its default verb implementations ARE those degradations.

Lives in its own header (included by canvas.hpp for back-compat) so the enum can be pulled in by capability-query call sites without dragging the whole Canvas interface. Keep count LAST — it is the enumerator total, used to statically bound any bitmask keyed by capability ordinal.

Enumerator
images 

draw_image_from_* really decode + draw

svg 

draw_svg renders via SkSVGDOM

clip_path_svg 

clip_path_svg parses the path and clips

filter_chain 

save_layer_with_filters honors color ops

mask_layer 

save_layer_with_mask applies the mask

backdrop_filter 

save_backdrop_filter really blurs the backdrop

backdrop_filter_chain 

save_backdrop_filter_chain honors the colour ops too.

Separate from backdrop_filter because the degradation is different in kind: a backend without it keeps the blur and drops the rest, so a saturate(0) backdrop comes back fully saturated rather than absent.

bloom_layer 

save_layer_with_bloom is a real bloom

sksl_draw 

draw_with_sksl executes the shader

sksl_post_effect 

save_layer_with_sksl_post_effect executes

box_shadow_gaussian 

draw_box_shadow is a true Gaussian, not stacked rects

scene_cache 

record_scene / draw_scene are functional (FU-3)

retained_layer_cache 

cacheable begin_layer handles survive across frames

count 

sentinel: number of real capabilities (keep LAST)

◆ ColorFontMode

enum class pulp::canvas::ColorFontMode : std::uint8_t
strong

Color-font policy.

Auto picks the best available format per glyph; the explicit modes force a single format (or monochrome) — useful when a designer needs deterministic output across backends with uneven COLR/CPAL support.

Enumerator
Auto 
Bitmap 
COLR 
SVG 
ForceMonochrome 

◆ FallbackMode

enum class pulp::canvas::FallbackMode : std::uint8_t
strong

Three fallback policies for the resolver cascade.

Plugins pick at registration time:

  • Deterministic — registered → bundled → platform-nullptr-fallback. Strictly identical across machines; what an audio plugin wants when shipping a fixed visual. Ignores Core Text / DirectWrite / fontconfig heuristic ranking.
  • Native — defers to the platform font manager for cascade ranking after the explicit family stack misses. Matches what a user would see in their browser, but means two machines may render differently.
  • Hybrid (default) — registered → bundled → platform, then platform-heuristic-ranked fallback for character-fallback only. Best for app-style UIs that want native feel for emoji / CJK while keeping plugin-bundled families deterministic.
Enumerator
Deterministic 
Native 
Hybrid 

◆ FallbackOrigin

enum class pulp::canvas::FallbackOrigin : std::uint8_t
strong

Which step of the cascade produced the resolved typeface.

Mirrored into FallbackTrace records on the FontFlightRecorder.

Enumerator
ScopeView 

Resolved inside a View-scoped registration.

ScopePlugin 

Resolved inside a Plugin-scoped registration.

ScopeGlobal 

Resolved inside the Global scope.

Bundled 

Resolved by match_bundled_typeface (external/fonts).

Platform 

Resolved by SkFontMgr::matchFamilyStyle.

PlatformChar 

Resolved by SkFontMgr::matchFamilyStyleCharacter (character-fallback path; only emitted by resolve_character_fallback).

Synthetic 

No matching face; resolver applied faux-synthesis.

NotFound 

Nothing matched and synthesis was disabled.

◆ FillRule

enum class pulp::canvas::FillRule
strong

Winding rule used to decide what counts as "inside" a path.

Declared here (rather than pulled from canvas.hpp) so path.hpp stays independent of the 1500-line Canvas header. canvas.hpp includes this file, so the two names are the same type everywhere.

Enumerator
nonzero 
evenodd 

◆ FontRunRole

enum class pulp::canvas::FontRunRole : unsigned char
strong

Which font role a run should resolve against.

  • Default: walks the existing typeface cascade (registered → bundled → SkFontMgr) for the current font-family.
  • Emoji: resolves to the color-emoji typeface registered via register_emoji_fallback(...). If no emoji typeface is registered, the caller falls back to the primary face (which typically tofus — that's the diagnostic).
Enumerator
Default 
Emoji 

◆ FontSlant

enum class pulp::canvas::FontSlant : std::uint8_t
strong

CSS-style slant.

Oblique carries a non-zero oblique_angle in FontOptions; Normal/Italic use oblique_angle = 0.

Enumerator
Normal 
Italic 
Oblique 

◆ FontSmoothing

enum class pulp::canvas::FontSmoothing : std::uint8_t
strong

CSS -webkit-font-smoothing as it affects glyph rasterization on macOS.

subpixel-antialiased and auto both resolve to auto there.

Enumerator
auto_smoothing 
antialiased 

◆ FontState

enum class pulp::canvas::FontState : std::uint8_t
strong

Async font lifecycle state.

Enumerator
Pending 
Loaded 
Failed 
Substituted 

◆ GradientColorSpace

enum class pulp::canvas::GradientColorSpace : std::uint8_t
strong

Interpolation colour spaces a gradient can be painted in.

xyz, xyz-d50, xyz-d65 and display-p3-linear have no member of their own: each is a fixed linear transform of linear-light sRGB, and linear interpolation commutes with a linear transform, so blending in any of them gives exactly the colours srgb_linear gives. Chrome renders all four identically to in srgb-linear.

Enumerator
srgb 

gamma-encoded sRGB; the CSS default for legacy colours

srgb_linear 

linear-light sRGB (and every space listed above)

display_p3 
a98_rgb 
prophoto_rgb 
rec2020 
lab 

CIE Lab, D50.

oklab 

the CSS default when a stop is a non-legacy colour

hsl 
hwb 
lch 

CIE LCh, D50.

oklch 

◆ GradientHueMethod

enum class pulp::canvas::GradientHueMethod : std::uint8_t
strong

Which way round the colour wheel a polar space travels between two hues.

Ignored for the rectangular spaces, where CSS forbids naming one.

Enumerator
shorter 
longer 
increasing 
decreasing 

◆ GradientTileMode

enum class pulp::canvas::GradientTileMode
strong

Gradient repeat mode.

Enumerator
clamp 
repeat 
mirror 

◆ HintingMode

enum class pulp::canvas::HintingMode : std::uint8_t
strong

CSS font-smoothing analogue.

PlatformDefault lets the platform pick; the others are explicit overrides.

Enumerator
None 
Slight 
Normal 
Full 
PlatformDefault 

◆ ImageFileProbe

enum class pulp::canvas::ImageFileProbe
strong

Whether the renderer can decode an encoded raster image file.

Enumerator
decodes 

Every pixel decoded.

undecodable 

Unreadable, not an image the renderer knows, or truncated.

unavailable 

No raster decoder in this build (no Skia); nothing was checked.

◆ LineCap

enum class pulp::canvas::LineCap
strong

Line cap applied to the ends of open subpaths when stroking.

Enumerator
butt 
round 
square 

◆ LineJoin

enum class pulp::canvas::LineJoin
strong

Join applied where two segments meet when stroking.

Enumerator
miter 
round 
bevel 

◆ RendererBackend

enum class pulp::canvas::RendererBackend
strong

Runtime identity of the concrete renderer receiving draw calls.

This is intentionally reported by Canvas itself, rather than supplied by a widget or application. A native editor that requires Graphite-on-Dawn can therefore fail closed instead of accepting a caller-provided string which may not describe the renderer that is actually painting the frame.

Enumerator
unknown 
recording 
core_graphics 
skia_raster 
skia_ganesh 
skia_dawn 

◆ SceneNodeKind

enum class pulp::canvas::SceneNodeKind
strong

Kind discriminator — keeps dynamic_cast off the hot path.

New concrete nodes append below; switch statements use a default arm.

Enumerator
group 
path 
shape 
image 
text 

◆ SdfEffect

enum class pulp::canvas::SdfEffect : std::uint8_t
strong
Enumerator
None 
Outline 
Glow 
Shadow 
Bevel 

◆ SdfPenSnap

enum class pulp::canvas::SdfPenSnap
strong
Enumerator
Free 
Nearest 
SubpixelThird 

◆ TextAlign

enum class pulp::canvas::TextAlign
strong
Enumerator
left 
center 
right 
justify 

◆ TextBaseline

enum class pulp::canvas::TextBaseline
strong
Enumerator
top 
middle 
bottom 
alphabetic 
hanging 
ideographic 

◆ TextDecoration

enum class pulp::canvas::TextDecoration
strong

Text decoration style.

Enumerator
none 
underline 
strikethrough 
overline 

◆ TextDirection

enum class pulp::canvas::TextDirection
strong
Enumerator
left_to_right 
right_to_left 
top_to_bottom 
bottom_to_top 

◆ TextRasterPolicy

enum class pulp::canvas::TextRasterPolicy : std::uint8_t
strong

Glyph preblend a surface is created with.

legacy is Skia's default and what every surface uses unless its creator asks otherwise.

Enumerator
legacy 
chromium 

◆ TextVerticalAlign

Enumerator
top 
center 
bottom 
baseline 

Function Documentation

◆ build_text_quads()

template<typename AtlasT>
std::vector< SdfTextQuad > pulp::canvas::build_text_quads ( const AtlasT & atlas,
const std::u32string & text,
float x,
float y,
float render_size,
const SdfTextOptions & opts = {} )
inline

◆ bump_font_registration_generation()

void pulp::canvas::bump_font_registration_generation ( )
noexcept

Force-bump the registration generation.

Called from register_emoji_fallback(...) and other entry points that mutate process-global font state outside register_font(...).

◆ clear_declared_font_face_weight_ranges()

void pulp::canvas::clear_declared_font_face_weight_ranges ( const std::string & scope)

Remove all declared ranges owned by scope.

The empty scope is the legacy process-wide bucket and is intentionally not cleared by bridge teardown.

◆ cluster_step()

std::size_t pulp::canvas::cluster_step ( const std::string & text,
std::size_t byte_offset,
bool forward = true )

Grapheme-aware cursor step for TextEditor.

Return the UTF-8 byte offset of the grapheme-cluster boundary one step forward or backward from byte_offset.

Returns the UTF-8 byte offset of the cluster boundary one step forward (or backward, when forward=false) from byte_offset. Always available and implemented as a UAX #29-lite UTF-8 walker, so common emoji ZWJ sequences, regional indicator pairs, combining marks, variation selectors, virama chains, skin-tone modifiers, and Hangul trailing jamo move as one cluster.

◆ contains_emoji()

bool pulp::canvas::contains_emoji ( std::string_view utf8_text)

Cheap test: returns true if utf8_text contains at least one codepoint that the segmenter would route to the emoji font (with FE0F/FE0E rules applied).

Faster than segment_emoji_runs() because it short-circuits on the first hit; use this to skip fallback set-up for ASCII-only labels.

◆ css_match_declared_weight()

int pulp::canvas::css_match_declared_weight ( const std::vector< DeclaredWeightRange > & ranges,
int desired_weight )

The declared range CSS font matching picks for desired_weight (CSS Fonts 4 section 5.2): a range containing it, else for a desired weight in 400..500 the nearest range up to 500 then below then above, for one under 400 the nearest below then above, and for one over 500 the nearest above then below.

Returns the index into ranges, or -1 when it is empty.

◆ declare_font_face_weight_range()

void pulp::canvas::declare_font_face_weight_range ( const std::string & family,
int weight_min,
int weight_max,
const std::string & scope = {} )

Records that an @font-face rule bound family at a declared weight range for scope.

Repeating a range already recorded by that owner is a no-op.

◆ declared_face_synthesizes_bold()

std::optional< bool > pulp::canvas::declared_face_synthesizes_bold ( const std::string & family,
int requested_weight )

Whether Chromium synthesizes bold for requested_weight text in family: it does exactly when the request is 600 or more and the declared range CSS matching picks ends below 600.

nullopt when no @font-face range was declared for the family, so the caller keeps its own rule.

◆ draw_command_name()

const char * pulp::canvas::draw_command_name ( DrawCommand::Type type)

The command's name, exactly as its enumerator is spelled.

The switch behind this has no default, so adding a DrawCommand::Type without naming it here fails to compile rather than formatting as something unhelpful at run time.

◆ fill_text_msdf()

template<typename AtlasT>
std::vector< SdfTextQuad > pulp::canvas::fill_text_msdf ( const AtlasT & atlas,
const std::u32string & text,
float x,
float y,
float render_size,
const SdfTextOptions & opts = {} )
inline

◆ fill_text_psdf()

template<typename AtlasT>
std::vector< SdfTextQuad > pulp::canvas::fill_text_psdf ( const AtlasT & atlas,
const std::u32string & text,
float x,
float y,
float render_size,
const SdfTextOptions & opts = {} )
inline

◆ fill_text_sdf()

template<typename AtlasT>
std::vector< SdfTextQuad > pulp::canvas::fill_text_sdf ( const AtlasT & atlas,
const std::u32string & text,
float x,
float y,
float render_size,
const SdfTextOptions & opts = {} )
inline

◆ flight_recorder_drain_json()

std::string pulp::canvas::flight_recorder_drain_json ( )

Convenience: drain the global recorder and emit one JSON object per record to out.

Intended drain path for a future pulp-ui-preview --font-trace --format=json flag and the import-missing-font-advisor.

◆ font_registration_generation()

std::uint64_t pulp::canvas::font_registration_generation ( )
noexcept

Monotonic counter that bumps every time a typeface registration mutates process-global font state.

Downstream caches sample this and flush.

◆ format_command()

std::string pulp::canvas::format_command ( const DrawCommand & command)

One command as a single line, with no trailing newline.

Shape: name f0 f1 f2 f3 f4 f5 followed by #RRGGBBAA when the colour is not the default, "text" when the text field is set, and +N floats when the variable-length payload is non-empty.

◆ format_commands()

std::string pulp::canvas::format_commands ( const std::vector< DrawCommand > & commands)

A whole drawlist, one command per line, newline-separated with a trailing newline.

An empty drawlist formats as an empty string.

◆ global_scope()

FontScope & pulp::canvas::global_scope ( )

Process-wide global scope.

register_font(...) (the free function in bundled_fonts.hpp) writes here.

◆ global_text_shaper()

TextShaper & pulp::canvas::global_text_shaper ( )

Global text shaper singleton (uses the best available backend).

◆ has_declared_font_face_weights()

bool pulp::canvas::has_declared_font_face_weights ( const std::string & family)

Whether any @font-face weight range has been declared for family.

◆ has_effect()

bool pulp::canvas::has_effect ( std::uint8_t mask,
SdfEffect e )
inline

◆ interpolate_gradient_color()

Color pulp::canvas::interpolate_gradient_color ( const Color & a,
const Color & b,
float t,
GradientInterpolation method )

The sRGB colour t of the way from a to b when the two are blended in method's space, per CSS Color 4 §12: premultiplied by alpha, a powerless hue (an achromatic stop) takes the other stop's hue, and the result is clipped to the sRGB gamut, as Chrome clips it.

This is the reference the backends are held to. Skia interpolates natively; a backend that blends only in sRGB approximates a curve by sampling this.

◆ is_font_registered()

bool pulp::canvas::is_font_registered ( const std::string & family)

Returns true iff the requested family name was previously registered via register_font / register_font_file.

Bundled families (Inter, JetBrains Mono) and platform-installed families are NOT covered by this query — use is_font_family_available for the cascading check.

Comparison is exact-string (case-sensitive) against the registered name (override-or-table-derived).

◆ is_polar()

bool pulp::canvas::is_polar ( GradientColorSpace space)
constexpr

True for the cylindrical spaces, which interpolate a hue angle.

◆ is_utf16_scalar_boundary()

bool pulp::canvas::is_utf16_scalar_boundary ( const std::string & text,
std::size_t utf16_offset )
inlinenoexcept

True when a UTF-16 code-unit offset falls between Unicode scalars rather than between the two code units of a surrogate pair.

◆ is_valid_utf16_scalar_range()

bool pulp::canvas::is_valid_utf16_scalar_range ( const std::string & text,
std::int64_t start,
std::int64_t length,
std::int64_t minimum_start = 0 )
inlinenoexcept

Validate one positive, non-overlapping UTF-16 range against UTF-8 text.

minimum_start is the end of the preceding range (zero for the first), so producers and consumers share the same bounds, ordering, overlap, and surrogate-pair contract.

◆ layout_attributed_string()

TextLayout pulp::canvas::layout_attributed_string ( const AttributedString & text,
float max_width,
float line_height = 0 )

Lay out an attributed string within a given width.

Performs word-wrapping and line breaking.

◆ layout_paragraph()

GlyphArrangement pulp::canvas::layout_paragraph ( const std::string & text,
const FontSpec & font,
float max_width = 0,
Color color = Color::rgba(1.0f, 1.0f, 1.0f) )

Layout a paragraph of text with word wrapping.

Uses Skia's SkShaper/SkParagraph internally for proper text shaping.

Parameters: text — the full paragraph text (UTF-8) font — font specification max_width — maximum line width for wrapping (0 = no wrapping) color — text color

Returns a GlyphArrangement with positioned glyphs for each line.

◆ line_break_opportunities()

std::vector< std::size_t > pulp::canvas::line_break_opportunities ( const std::string & text,
const std::string & locale = "" )

Find line-break opportunities in text.

Returns UTF-8 byte offsets where the renderer may wrap and always includes the trailing offset == text.size(). With ICU BreakIterator support this follows ICU's line-break iterator; otherwise it returns ASCII space/tab boundaries plus the trailing offset so the API still functions degraded.

◆ make_font_feature_tag()

FontFeatureTag pulp::canvas::make_font_feature_tag ( char a,
char b,
char c,
char d )
constexpr

◆ make_variation_axis_tag()

VariationAxisTag pulp::canvas::make_variation_axis_tag ( char a,
char b,
char c,
char d )
constexpr

◆ merged_generation_for()

std::uint64_t pulp::canvas::merged_generation_for ( FontScopeId requesting_scope)

Returns a generation value that is the combined monotonic counter of every scope a resolver looking up requesting_scope would consult.

Used by downstream caches as part of their cache key.

For requesting_scope.kind == Global: returns global_scope().generation(). For Plugin(id): returns a value combining plugin_scope(id).generation() and global_scope().generation(). For View(id): combines view_scope(id), the active plugin scope (if any), and global.

The returned value is monotonic — once it increases, it never goes down. Two consecutive calls with the same input may return different values if any consulted scope was bumped between them; that is the signal downstream caches use to evict stale entries.

◆ note_gpu_upload()

void pulp::canvas::note_gpu_upload ( )
inlinenoexcept

◆ note_image_decode()

void pulp::canvas::note_image_decode ( )
inlinenoexcept

◆ note_paragraph_build()

void pulp::canvas::note_paragraph_build ( )
inlinenoexcept

◆ note_scene_record()

void pulp::canvas::note_scene_record ( )
inlinenoexcept

◆ note_scene_replay()

void pulp::canvas::note_scene_replay ( )
inlinenoexcept

◆ operator|()

std::uint8_t pulp::canvas::operator| ( SdfEffect a,
SdfEffect b )
inline

◆ paragraph_fakes_missing_font_styles()

bool pulp::canvas::paragraph_fakes_missing_font_styles ( std::string_view css_font_family,
int weight,
int slant )

Whether SkParagraph may fake the bold or oblique the matched face lacks, for text in css_font_family at weight and slant.

SkParagraph judges on the face file's own weight; Chromium judges a page font on its @font-face's declared weight range, so a face declared 400 700 is never emboldened at 700 even when only a Regular file backs it. The first family with declared ranges decides; italic keeps the default, which the same switch covers. Every paragraph built for the same text must ask this: SkParagraph's shaping cache does not key on the switch, so a measurement paragraph left at the default hands its emboldened runs to the painter.

◆ paragraph_text_extents()

ParagraphTextExtents pulp::canvas::paragraph_text_extents ( const std::vector< ParagraphLineExtent > & lines,
float font_size )

Takes the max ascent, descent and leading over lines, so a later line whose fallback face is taller than the first still widens the box.

A line with non-finite, negative, zero-height or implausible (over ten font sizes) metrics is ignored.

◆ parse_css_font_family()

CssFontFamily pulp::canvas::parse_css_font_family ( std::string_view entry)

Parse one font-family list entry: trim whitespace, then strip one matching pair of single or double quotes and record that there was one.

◆ path_to_sdf()

std::vector< std::uint8_t > pulp::canvas::path_to_sdf ( const std::uint8_t * mask,
int width,
int height,
int spread = 8 )

◆ platform_face_is_family()

bool pulp::canvas::platform_face_is_family ( std::string_view platform_family,
std::string_view actual_family )

Whether a face that reports actual_family is the family a matcher was asked for as platform_family, rather than the default face a matcher hands back on a miss.

Names match case-insensitively when either contains the other ("Helvetica" / "Helvetica Neue"). A hidden system family (a leading '.') answers with another hidden name (".AppleSystemUIFont" reports ".SF NS"), so it matches any hidden family.

◆ platform_family_for_css_family()

std::string pulp::canvas::platform_family_for_css_family ( std::string_view entry)

The family name to ask a font matcher for, for one list entry (quotes allowed): the platform family an unquoted generic keyword stands for, otherwise the entry's name without its quotes.

◆ platform_family_for_css_generic()

std::string pulp::canvas::platform_family_for_css_generic ( const std::string & css_family)

The platform family a CSS generic family keyword stands for, matching the browser's defaults on this platform, or empty when css_family is not a generic keyword or the platform's font matcher resolves it on its own.

A generic keyword (system-ui, sans-serif, monospace, ...) is not a family name, and the macOS font manager matches none of them: asked for system-ui it returns nothing, so text falls through to whatever default the caller has, which is a different face from the one the browser drew. Pass the trimmed list entry WITH any quotes still on it: a quoted name is a family literally called that, never the keyword.

◆ plugin_scope()

FontScope & pulp::canvas::plugin_scope ( std::uint64_t plugin_id)

Look up (or lazily create) the plugin scope for plugin_id.

Plugin IDs are opaque integers; the host assigns them at load time.

◆ preset_glow()

SdfEffectParams pulp::canvas::preset_glow ( float radius = 6.0f,
std::array< float, 4 > color = {0.3f, 0.6f, 1.0f, 1.0f} )
inline

◆ preset_outline()

SdfEffectParams pulp::canvas::preset_outline ( float width = 2.0f)
inline

◆ preset_pressed_bevel()

SdfEffectParams pulp::canvas::preset_pressed_bevel ( )
inline

◆ preset_subtle_shadow()

SdfEffectParams pulp::canvas::preset_subtle_shadow ( )
inline

◆ probe_image_file()

ImageFileProbe pulp::canvas::probe_image_file ( const std::string & path)

Decode path fully with the codec the Skia canvas draws file images through.

A decode that reports success is not enough on its own: Skia fills the rows of a truncated PNG with transparent pixels and still succeeds, so a PNG must also have every chunk whole, every CRC correct, and an IEND. Raster formats only; an SVG is not an encoded raster and reports undecodable. File I/O — never call it on the audio or render thread.

◆ register_best_available_emoji_fallback()

bool pulp::canvas::register_best_available_emoji_fallback ( )
inline

◆ register_bundled_noto_color_emoji()

bool pulp::canvas::register_bundled_noto_color_emoji ( )
inline

◆ register_emoji_fallback()

bool pulp::canvas::register_emoji_fallback ( ...)
inline

◆ register_font()

bool pulp::canvas::register_font ( const std::uint8_t * data,
std::size_t size,
const std::string & family_override = "" )

Register a font from raw TTF/OTF bytes.

The supplied buffer is copied into a long-lived SkData so the caller may free data immediately.

If family_override is empty, the family name reported by the font's own name table (via Skia's SkTypeface::getFamilyName) is used. Pass a non-empty override when you want subsequent setFontFamily("Foo") calls to match a name that doesn't appear in the font file itself.

Returns true if Skia parsed the bytes into a usable SkTypeface and the registration was stored; false if Skia rejected the bytes, no platform font manager was available, the family name was empty (and no override was supplied), or PULP_HAS_SKIA is not defined (on Apple without Skia: whether CoreText could read the bytes).

Calling register_font repeatedly for one family is safe: each distinct Skia typeface is retained so Regular/Bold/Italic faces can share the same family key, while duplicate Skia identities are ignored. Successful registrations bump the font-generation counter so downstream caches flush on the next lookup. There is no unregister_font today; the expected lifetime is "process".

◆ register_font_file()

bool pulp::canvas::register_font_file ( const std::string & path,
const std::string & family_override = "" )

Convenience overload: register a font from a file on disk.

Reads the entire file into memory, then forwards to the bytes-based overload, or to register_font_woff2 when the file starts with the WOFF2 magic. Returns false if the file cannot be opened, is empty, or the bytes are rejected.

◆ register_font_url()

std::future< FontState > pulp::canvas::register_font_url ( const std::string & url,
const std::string & family_override = "" )

Schedule a font registration from a URL or filesystem path and return a future that resolves to the final FontState.

Supported URL forms:

  • file:///abs/path/to/font.ttf — decoded to an absolute path and dispatched to register_font_file on a background worker.
  • /abs/path/to/font.ttf — treated as a local path, same background dispatch.
  • http://… / https://… — resolved immediately to Failed because this API does not fetch network resources. Callers that need network fetches today should pre-download and call this entry point with a file:// URL.

The returned future never blocks the caller. Resolves to Loaded on success, Failed on any error (unreadable file, Skia rejection, or unsupported scheme). Dropping the future is safe; the worker reports its result through a detached promise.

◆ register_font_woff2()

bool pulp::canvas::register_font_woff2 ( const std::uint8_t * woff2_data,
std::size_t size,
const std::string & family_override = "" )

Register a WOFF2-compressed font at runtime.

Rejects malformed payloads cleanly and validates the decompressed sfnt bytes before handing them to Skia.

Behavior:

  • Null / empty input → false.
  • Bytes whose first 4 bytes are not the WOFF2 magic (wOF2, 0x774F4632 big-endian) → false. This is the structural reject path and works on every build.
  • Bytes WITH valid WOFF2 magic, when no Brotli/woff2 decoder is linked into the build → false. Callers can probe this case ahead of time via woff2_decoder_available() and route through register_font(...) with a pre-decoded TTF/OTF payload instead.
  • Bytes WITH valid WOFF2 magic when a decoder IS linked → the payload is decompressed, validated via validate_font_bytes, and forwarded to register_font(...).

Pulp's pinned Brotli/woff2 sources are compiled directly into pulp-canvas, so an installed static SDK has no hidden private decoder target that a downstream plugin must rediscover or link separately.

◆ register_platform_emoji_fallback()

bool pulp::canvas::register_platform_emoji_fallback ( )
inline

◆ release_view_scope()

void pulp::canvas::release_view_scope ( std::uint64_t view_id)

Tear down a view scope.

After this call, future view_scope(view_id) returns a fresh scope (generation reset to 0). The caller must guarantee no resolver caches hold ResolvedFont values keyed on the torn-down scope.

◆ render_sdf_text_software()

template<typename AtlasT>
void pulp::canvas::render_sdf_text_software ( const AtlasT & atlas,
const std::vector< SdfTextQuad > & quads,
std::uint8_t * out,
int out_w,
int out_h,
const SdfTextOptions & opts = {} )
inline

◆ renderer_backend_name()

const char * pulp::canvas::renderer_backend_name ( RendererBackend backend)
constexprnoexcept

◆ resample_gradient_stops()

void pulp::canvas::resample_gradient_stops ( const Color * colors,
const float * positions,
int count,
GradientInterpolation method,
int samples_per_segment,
std::vector< Color > & out_colors,
std::vector< float > & out_positions )

Expand a stop list into one whose plain sRGB blend follows method's curve: every segment between two stops gains samples_per_segment - 1 interior stops taken from interpolate_gradient_color().

The default method returns the stops unchanged. Positions must be non-decreasing, as a gradient's are.

◆ resolved_face_identity()

std::string pulp::canvas::resolved_face_identity ( const std::string & css_font_family,
float weight,
FontSlant slant = FontSlant::Normal )

The output of a resolver call.

Carries the resolved typeface (or nullptr if origin == NotFound), the trace, and the generation value baked into the cache key so consumers can verify their copy hasn't gone stale. The PostScript name of the face a CSS family stack actually resolves to.

actual_family above answers "which family", which is not enough to validate a captured layout: "Jost" covers Regular, Medium and SemiBold, and those break text differently. The PostScript name identifies the instance.

Takes the raw CSS font-family value — the comma list is walked here so a caller does not need its own copy of that parsing. Without Skia (and in the lite editor stack) on Apple platforms it answers with the face CoreText resolves, which is the face the CoreGraphics canvas paints. Returns empty when nothing resolves or the platform has neither, and an empty answer must be read as "unknown", never as "matches".

◆ resource_counters()

ResourceCounters pulp::canvas::resource_counters ( )
inlinenoexcept

◆ safe_utf8_prefix_size()

std::size_t pulp::canvas::safe_utf8_prefix_size ( const std::string & text,
std::size_t byte_index )
inlinenoexcept

Return the largest prefix length <= byte_index that ends on a valid UTF-8 scalar boundary.

Malformed or truncated input stops at the last known-good boundary so platform text APIs never receive an invalid substring while computing caret offsets.

◆ segment_emoji_runs()

std::vector< FontRun > pulp::canvas::segment_emoji_runs ( std::string_view utf8_text)

Segment utf8_text into runs that respect emoji grapheme clusters.

Postconditions:

  • Runs are non-overlapping and contiguous; the first run starts at 0 and the last run ends at utf8_text.size().
  • No emoji grapheme cluster is ever split across two runs.
  • Adjacent runs of the same role are merged into one.
  • Lone or malformed UTF-8 continuation bytes are tagged Default.

◆ select_text_raster_policy()

TextRasterPolicy pulp::canvas::select_text_raster_policy ( std::span< const FontSmoothing > nodes)
constexpr

The policy for a surface holding text nodes with these smoothing modes: chromium when ANY node is antialiased, otherwise legacy.

The rule is asymmetric on purpose. An antialiased node on a legacy surface paints about 21% too much ink, which is visible; an auto node on a chromium surface paints about 2% too much, which is not. A surface with no text stays legacy.

◆ set_css_generic_family_override()

void pulp::canvas::set_css_generic_family_override ( const std::string & keyword,
const std::string & family )

Map the generic keyword to family instead of the platform default, or restore the built-in mapping when family is empty.

Process-wide. It exists so a test can name a generic whose platform family the host lacks, which a stock install never does; call FontResolver::clear_cache() after it.

◆ should_use_vector_fallback()

bool pulp::canvas::should_use_vector_fallback ( float render_px,
float base_size,
float threshold = 8.0f )
inline

◆ snap_pen_x()

float pulp::canvas::snap_pen_x ( float x,
SdfPenSnap policy )
inline

◆ snap_pen_y()

float pulp::canvas::snap_pen_y ( float y,
SdfPenSnap policy )
inline

◆ split_css_font_family_list()

std::vector< std::string > pulp::canvas::split_css_font_family_list ( std::string_view list)

Split a font-family list on commas into trimmed entries, each KEPT with its quotes, dropping empty ones.

Quotes stay on so every consumer applies the same rule: an unquoted generic keyword names a platform family, a quoted one is a family of that name. Hand the entries to FontOptions::family_stack or to platform_family_for_css_family.

◆ text_raster_tuple()

TextRasterTuple pulp::canvas::text_raster_tuple ( TextRasterPolicy policy)
constexpr

◆ text_shaper_prepare_call_count()

std::uint64_t pulp::canvas::text_shaper_prepare_call_count ( )

Monotonic count of TextShaper::prepare() invocations across all shapers.

Always compiled (a single relaxed atomic increment per prepare() — cheap enough for release). Exposed so widget-level layout caches (e.g. Label's shaped-layout cache) can be proven in headless tests: paint a cached widget twice and assert the counter advanced by exactly one. Not part of the rendering contract — purely an observability hook for tests/diagnostics.

◆ to_string()

const char * pulp::canvas::to_string ( FallbackOrigin )
noexcept

◆ utf16_offset_for_utf8_offset()

std::size_t pulp::canvas::utf16_offset_for_utf8_offset ( const std::string & text,
std::size_t byte_offset )
inlinenoexcept

Convert a UTF-8 byte offset into a UTF-16 code-unit offset.

Offsets inside a UTF-8 scalar snap back to the scalar boundary, matching safe prefix handling.

◆ utf8_offset_for_utf16_offset()

std::size_t pulp::canvas::utf8_offset_for_utf16_offset ( const std::string & text,
std::size_t utf16_offset )
inlinenoexcept

Convert a UTF-16 code-unit offset into the nearest safe UTF-8 byte offset.

Native text APIs such as Cocoa NSTextInputClient express marked-text ranges in UTF-16, while Pulp stores editor positions as UTF-8 byte offsets.

◆ validate_font_bytes()

bool pulp::canvas::validate_font_bytes ( const std::uint8_t * data,
std::size_t size )

Validate font bytes before handing them to Skia.

Skia builds perform structural sfnt validation of the header, table directory, required tables, and critical table lengths; non-Skia builds accept any non-empty buffer because there is no parser available on that lane.

◆ view_scope()

FontScope & pulp::canvas::view_scope ( std::uint64_t view_id)

Look up (or lazily create) the view scope for view_id.

View IDs are opaque integers; the view layer assigns them. View scopes are short- lived; call release_view_scope(view_id) when the view is destroyed to avoid unbounded growth.

◆ woff2_decoder_available()

bool pulp::canvas::woff2_decoder_available ( )
noexcept

Runtime check for WOFF2 decoder availability.

Returns false on builds where no Brotli/woff2 implementation is linked, meaning register_font_woff2(...) cannot succeed regardless of input. Callers can use this to fall back to a pre-decoded TTF/OTF payload registered via register_font(...) instead.

Available on every build (Skia or no Skia), so plugin startup can branch on it without #ifdefs leaking into user code.

◆ woff2_file_routes()

std::uint64_t pulp::canvas::woff2_file_routes ( )
noexcept

How many register_font_file calls this process has routed to register_font_woff2 because the file started with the WOFF2 magic.

A platform font manager may decode WOFF2 on its own (CoreText does), so the registration result alone cannot show which path a file took; this can.

◆ word_break_step()

std::size_t pulp::canvas::word_break_step ( const std::string & text,
std::size_t byte_offset,
const std::string & locale = "",
bool forward = true )

Locale-aware word break iterator.

Returns the UTF-8 byte offset of the next word boundary forward from byte_offset (or backward when forward=false). locale is a BCP-47 tag ("en-US", "ja-JP", ...). Empty locale falls back to ICU's root locale. When ICU's public BreakIterator headers are not available, the implementation returns the fallback cluster_step() result so callers can rely on the surface universally.

Variable Documentation

◆ kChromiumTextRaster

TextRasterTuple pulp::canvas::kChromiumTextRaster {0.0f, 1.0f}
inlineconstexpr

◆ kLegacyTextRaster

TextRasterTuple pulp::canvas::kLegacyTextRaster {0.5f, 0.0f}
inlineconstexpr

Skia's compile-time defaults (SK_GAMMA_CONTRAST, SK_GAMMA_EXPONENT = sRGB).