SvgCanvas
Mojo struct 🡭
SvgCanvas
@memory_only
struct SvgCanvasAccumulates SVG body markup for a width x height document. width/height are public fields, as on Canvas.
Fields
- width (
Int) - height (
Int)
Implemented traits
AnyType, Deinitable, DrawTarget, Movable
Methods
__init__
fn def __init__(out self, width: Int, height: Int)An empty width x height SVG document.
Args:
- width (
Int): Document width in pixels. - height (
Int): Document height in pixels. - self (
Self)
Returns:
Self
save
fn def save(mut self)Push the current transform, blend mode and clip depth for restore to put back, as Canvas.save does.
Args:
- self (
Self)
restore
fn def restore(mut self)Pop the state save pushed. A no-op with nothing saved, matching Canvas.restore.
Args:
- self (
Self)
translate
fn def translate(mut self, tx: Float64, ty: Float64)Shift subsequent elements by (tx, ty) in the current user space – see Canvas.translate.
Args:
- self (
Self) - tx (
Float64): Horizontal shift. - ty (
Float64): Vertical shift.
rotate
fn def rotate(mut self, angle: Float64)Turn subsequent elements by angle radians about the current origin – see Canvas.rotate.
Args:
- self (
Self) - angle (
Float64): Radians.
scale
fn def scale(mut self, sx: Float64, sy: Float64)Scale subsequent elements about the current origin – see Canvas.scale.
Args:
- self (
Self) - sx (
Float64): Horizontal factor. - sy (
Float64): Vertical factor.
transform
fn def transform(mut self, matrix: Matrix2D)Compose matrix into the current transform, applied first – the order Canvas.transform composes in.
Args:
- self (
Self) - matrix (
Matrix2D): The map to apply first.
set_transform
fn def set_transform(mut self, matrix: Matrix2D)Replace the current transform outright.
Args:
- self (
Self) - matrix (
Matrix2D): The new map from user space to document pixels.
reset_transform
fn def reset_transform(mut self)Back to the identity: elements carry no transform.
Args:
- self (
Self)
current_transform
fn def current_transform(self) -> Matrix2DThe map every element drawn now carries.
Args:
- self (
Self)
Returns:
Matrix2D: The current transform; the identity if none is set.
has_transform
fn def has_transform(self) -> BoolWhether elements drawn now carry a transform attribute.
Args:
- self (
Self)
Returns:
Bool: True if the current transform is not the identity.
set_blend_mode
fn def set_blend_mode(mut self, mode: BlendMode)Set how elements drawn from here on combine with what is already painted, the counterpart of Canvas.set_blend_mode.
A blend mode (MULTIPLY through LUMINOSITY) becomes a
style="mix-blend-mode:..." attribute on each element. CSS
has no keyword for the Porter-Duff operators – SOURCE,
DESTINATION_IN, XOR, ADD and the rest – so those emit no
attribute at all and render as ordinary source-over. A caller
needing them has to use the raster backend.
save/restore carry the mode, as they do the transform.
Args:
- self (
Self) - mode (
BlendMode): The blend mode later elements carry.
blend_mode
fn def blend_mode(self) -> BlendModeThe blend mode elements drawn now carry.
Args:
- self (
Self)
Returns:
BlendMode: The current mode, BlendMode.SOURCE_OVER until
set_blend_mode says otherwise.
set_color_space
fn def set_color_space(mut self, space: ColorSpace)Set the space elements drawn from here on composite in, the counterpart of Canvas.set_color_space: under LINEAR each element carries color-interpolation="linearRGB", which asks the viewer to composite it in linear light. Viewer support varies; a caller needing the result guaranteed has the raster backend. save/restore carry the space.
Args:
- self (
Self) - space (
ColorSpace): The color space later elements carry.
color_space
fn def color_space(self) -> ColorSpaceThe color space elements drawn now carry.
Args:
- self (
Self)
Returns:
ColorSpace: The current space, ColorSpace.SRGB until
set_color_space says otherwise.
fill_rect
fn def fill_rect(mut self, x: Int, y: Int, width: Int, height: Int, color: Color)Emit a <rect> element.
Args:
- self (
Self) - x (
Int): Rectangle’s left edge. - y (
Int): Rectangle’s top edge. - width (
Int): Rectangle’s width. - height (
Int): Rectangle’s height. - color (
Color): Fill color.
fn def fill_rect(mut self, x: Float64, y: Float64, width: Float64, height: Float64, color: Color)fill_rect for a geometric box, snapped to whole pixels in user space – the same snap the raster backend applies, so both emit the same rectangle – and written as the Int form.
Args:
- self (
Self) - x (
Float64): Left edge. - y (
Float64): Top edge. - width (
Float64): Width. - height (
Float64): Height. - color (
Color): Fill color.
fill_rect_gradient
fn def fill_rect_gradient(mut self, x: Float64, y: Float64, width: Float64, height: Float64, gradient: LinearGradient)fill_rect_gradient for a geometric box, snapped to whole pixels as the Float64 fill_rect is.
Args:
- self (
Self) - x (
Float64): Left edge. - y (
Float64): Top edge. - width (
Float64): Width. - height (
Float64): Height. - gradient (
LinearGradient): Fill source, projected across the rectangle.
fn def fill_rect_gradient(mut self, x: Int, y: Int, width: Int, height: Int, gradient: LinearGradient)An SVG <linearGradient> with gradientUnits="userSpaceOnUse". LinearGradient’s (x0, y0)-(x1, y1) axis is already in the same absolute pixel space as this document’s <rect>, so userSpaceOnUse carries it over untranslated instead of SVG’s default shape-relative objectBoundingBox units.
Emits a fresh <defs><linearGradient id="gradN"> per call;
<stop> elements come out in ascending-offset order.
Args:
- self (
Self) - x (
Int): Rectangle’s left edge. - y (
Int): Rectangle’s top edge. - width (
Int): Rectangle’s width. - height (
Int): Rectangle’s height. - gradient (
LinearGradient): Fill source, projected across the rectangle.
fill_rect_radial_gradient
fn def fill_rect_radial_gradient(mut self, x: Int, y: Int, width: Int, height: Int, gradient: RadialGradient)fill_rect_gradient for a RadialGradient: a fresh <defs><radialGradient id="gradN"> in the document’s pixel space, with the focal circle when the gradient has one, and a <rect> filled from it.
Args:
- self (
Self) - x (
Int): Rectangle’s left edge. - y (
Int): Rectangle’s top edge. - width (
Int): Rectangle’s width. - height (
Int): Rectangle’s height. - gradient (
RadialGradient): Fill source, in the document’s pixel space.
fill_path_gradient_aa
fn def fill_path_gradient_aa(mut self, path: Path, gradient: LinearGradient, fill_rule: FillRule = FillRule.EVEN_ODD)fill_path_aa filled from a LinearGradient: a fresh <defs><linearGradient> in the document’s pixel space and a <path> referencing it, with the fill rule written out as fill_path_aa writes it.
Args:
- self (
Self) - path (
Path): Path to fill. - gradient (
LinearGradient): Fill source, in the document’s pixel space. - fill_rule (
FillRule): EVEN_ODD (default) or NONZERO – see FillRule.
fill_path_radial_gradient_aa
fn def fill_path_radial_gradient_aa(mut self, path: Path, gradient: RadialGradient, fill_rule: FillRule = FillRule.EVEN_ODD)fill_path_gradient_aa for a RadialGradient.
Args:
- self (
Self) - path (
Path): Path to fill. - gradient (
RadialGradient): Fill source, in the document’s pixel space. - fill_rule (
FillRule): EVEN_ODD (default) or NONZERO – see FillRule.
draw_line_aa
fn def draw_line_aa(mut self, x0: Int, y0: Int, x1: Int, y1: Int, color: Color, width: Float64 = 1, dashes: List[Float64] = List(), dash_offset: Float64 = 0, cap: LineCap = LineCap.ROUND, join: LineJoin = LineJoin.ROUND, miter_limit: Float64 = 4)Emit a <line> element, round-capped by default.
Args:
- self (
Self) - x0 (
Int): Start point x. - y0 (
Int): Start point y. - x1 (
Int): End point x. - y1 (
Int): End point y. - color (
Color): Line color. - width (
Float64): Stroke width in pixels. - dashes (
List[Float64]): On/off segment lengths in user-space pixels, cycled along the line. Empty (default) draws a solid line. - dash_offset (
Float64): Distance into the dash pattern the line starts at. - cap (
LineCap): How the two ends are finished – see LineCap. - join (
LineJoin): Unused for a single segment, which has no corners. - miter_limit (
Float64): Unused for a single segment.
fn def draw_line_aa(mut self, x0: Float64, y0: Float64, x1: Float64, y1: Float64, color: Color, width: Float64 = 1, dashes: List[Float64] = List(), dash_offset: Float64 = 0, cap: LineCap = LineCap.ROUND, join: LineJoin = LineJoin.ROUND, miter_limit: Float64 = 4)Emit a <line> element, round-capped by default.
Args:
- self (
Self) - x0 (
Float64): Start point x. - y0 (
Float64): Start point y. - x1 (
Float64): End point x. - y1 (
Float64): End point y. - color (
Color): Line color. - width (
Float64): Stroke width in pixels. - dashes (
List[Float64]): On/off segment lengths in user-space pixels, cycled along the line. Empty (default) draws a solid line. - dash_offset (
Float64): Distance into the dash pattern the line starts at. - cap (
LineCap): How the two ends are finished – see LineCap. - join (
LineJoin): Unused for a single segment, which has no corners. - miter_limit (
Float64): Unused for a single segment.
fill_circle_aa
fn def fill_circle_aa(mut self, cx: Float64, cy: Float64, radius: Float64, color: Color)A <circle> at a sub-pixel center and radius.
Args:
- self (
Self) - cx (
Float64): Center x. - cy (
Float64): Center y. - radius (
Float64): Circle radius in pixels. - color (
Color): Fill color.
fn def fill_circle_aa(mut self, cx: Int, cy: Int, radius: Int, color: Color)Emit a <circle> element.
Args:
- self (
Self) - cx (
Int): Center x. - cy (
Int): Center y. - radius (
Int): Circle radius in pixels. - color (
Color): Fill color.
fill_circles_aa
fn def fill_circles_aa(mut self, centers: List[FPoint], radius: Float64, color: Color)DrawTarget’s batched disks. This backend emits per marker whichever entry point is used, so the batch is the loop and the output is unchanged by construction.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - radius (
Float64): Radius shared by every marker, in pixels. - color (
Color): Fill color shared by every marker.
Raises:
fn def fill_circles_aa(mut self, centers: List[FPoint], radius: Float64, colors: List[Color])fill_circles_aa with a color per marker.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - radius (
Float64): Radius shared by every marker, in pixels. - colors (
List[Color]): One color per centre, same length ascenters.
Raises:
Error: If colors is not the same length as centers.
fill_mesh
fn def fill_mesh(mut self, points: List[FPoint], faces: List[Int], colors: List[Color])DrawTarget’s mesh: one <path> per face. Browsers seam adjacent anti-aliased fills the way the raster backend did, so an opaque face also carries stroke in its own color at half a pixel, which covers the seam without changing the face’s extent by more than that. A translucent face is not stroked: the stroke would double its alpha along every edge, which is a darker seam in place of a lighter one.
Args:
- self (
Self) - points (
List[FPoint]): The vertices, in user space. - faces (
List[Int]): Index triples intopoints, in draw order. - colors (
List[Color]): One color per triangle.
Raises:
Error: faces is not whole triples, an index is out of
range, or colors is not one per triangle.
fill_mesh_shaded
fn def fill_mesh_shaded(mut self, points: List[FPoint], faces: List[Int], vertex_colors: List[Color])DrawTarget’s smooth-shaded mesh, flat here: each face at the mean of its three corner colors. SVG has no shipping way to interpolate color across a triangle – mesh gradients are SVG 2 and unimplemented in browsers – so this is the same faceted approximation every SVG exporter makes, and the one place this backend’s picture differs from the raster one by design. The faces are seam-treated as fill_mesh’s are.
Args:
- self (
Self) - points (
List[FPoint]): The vertices, in user space. - faces (
List[Int]): Index triples intopoints, in draw order. - vertex_colors (
List[Color]): One color per vertex.
Raises:
Error: faces is not whole triples, an index is out of
range, or vertex_colors is not one per vertex.
fill_ellipses_aa
fn def fill_ellipses_aa(mut self, centers: List[FPoint], rx: Float64, ry: Float64, color: Color)DrawTarget’s batched ellipses. This backend emits per marker whichever entry point is used, so the batch is the loop and the output is unchanged by construction.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - rx (
Float64): Horizontal radius shared by every marker, in pixels. - ry (
Float64): Vertical radius shared by every marker, in pixels. - color (
Color): Fill color shared by every marker.
Raises:
fn def fill_ellipses_aa(mut self, centers: List[FPoint], rx: Float64, ry: Float64, colors: List[Color])fill_ellipses_aa with a color per marker.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - rx (
Float64): Horizontal radius shared by every marker, in pixels. - ry (
Float64): Vertical radius shared by every marker, in pixels. - colors (
List[Color]): One color per centre, same length ascenters.
Raises:
Error: If colors is not the same length as centers.
draw_circle_aa
fn def draw_circle_aa(mut self, cx: Float64, cy: Float64, radius: Float64, color: Color, width: Float64 = 1)Emit an unfilled <circle> element, at a sub-pixel center and radius.
Args:
- self (
Self) - cx (
Float64): Center x, sub-pixel. - cy (
Float64): Center y, sub-pixel. - radius (
Float64): Circle radius in pixels, to the middle of the stroke. - color (
Color): Outline color. - width (
Float64): Stroke width in pixels.
fill_ellipse_aa
fn def fill_ellipse_aa(mut self, cx: Float64, cy: Float64, rx: Float64, ry: Float64, color: Color)An <ellipse> at a sub-pixel center and radii.
Args:
- self (
Self) - cx (
Float64): Center x. - cy (
Float64): Center y. - rx (
Float64): Horizontal radius in pixels. - ry (
Float64): Vertical radius in pixels. - color (
Color): Fill color.
fn def fill_ellipse_aa(mut self, cx: Int, cy: Int, rx: Int, ry: Int, color: Color)Emit an <ellipse> element.
Args:
- self (
Self) - cx (
Int): Center x. - cy (
Int): Center y. - rx (
Int): Horizontal radius in pixels. - ry (
Int): Vertical radius in pixels. - color (
Color): Fill color.
draw_ellipse_aa
fn def draw_ellipse_aa(mut self, cx: Int, cy: Int, rx: Int, ry: Int, color: Color)Emit an unfilled <ellipse> element, ~1px stroke.
Args:
- self (
Self) - cx (
Int): Center x. - cy (
Int): Center y. - rx (
Int): Horizontal radius in pixels. - ry (
Int): Vertical radius in pixels. - color (
Color): Outline color.
fn def draw_ellipse_aa(mut self, cx: Float64, cy: Float64, rx: Float64, ry: Float64, color: Color, width: Float64 = 1)Emit an unfilled <ellipse> element, at a sub-pixel center and radii.
Args:
- self (
Self) - cx (
Float64): Center x, sub-pixel. - cy (
Float64): Center y, sub-pixel. - rx (
Float64): Horizontal radius in pixels, to the middle of the stroke. - ry (
Float64): Vertical radius in pixels, to the middle of the stroke. - color (
Color): Outline color. - width (
Float64): Stroke width in pixels.
fill_arc_aa
fn def fill_arc_aa(mut self, cx: Float64, cy: Float64, radius: Float64, start_angle: Float64, end_angle: Float64, color: Color)A wedge, drawn as M center L start-point A ... end-point Z. sweep_flag=1 with no sign flip: SVG’s space is y-down like the raster canvas’s, so increasing angle sweeps clockwise in both.
Args:
- self (
Self) - cx (
Float64): Center x. - cy (
Float64): Center y. - radius (
Float64): Wedge radius in pixels. - start_angle (
Float64): Sweep start, radians, 0 pointing along +x. - end_angle (
Float64): Sweep end, radians. Must be >= start_angle. - color (
Color): Fill color.
fill_arcs_aa
fn def fill_arcs_aa(mut self, centers: List[FPoint], radius: Float64, start_angle: Float64, end_angle: Float64, color: Color)DrawTarget’s batched wedges. This backend emits one element per wedge whichever entry point is used, so the batch is the loop and the output is unchanged by construction.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each wedge, in draw order. - radius (
Float64): Radius shared by every wedge, in pixels. - start_angle (
Float64): Start of the sweep, radians, shared. - end_angle (
Float64): End of the sweep, radians, shared. - color (
Color): Fill color shared by every wedge.
Raises:
fn def fill_arcs_aa(mut self, centers: List[FPoint], radius: Float64, start_angle: Float64, end_angle: Float64, colors: List[Color])fill_arcs_aa with a color per wedge.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each wedge, in draw order. - radius (
Float64): Radius shared by every wedge, in pixels. - start_angle (
Float64): Start of the sweep, radians, shared. - end_angle (
Float64): End of the sweep, radians, shared. - colors (
List[Color]): One color per centre, same length ascenters.
Raises:
Error: If colors is not the same length as centers.
fill_ring_sector_aa
fn def fill_ring_sector_aa(mut self, cx: Float64, cy: Float64, inner_radius: Float64, outer_radius: Float64, start_angle: Float64, end_angle: Float64, color: Color)A donut wedge: M outer-start A ... outer-end L inner-end A ... inner-start Z. The outer arc sweeps forward (sweep_flag=1), a radial line runs inward, then the inner arc sweeps backward (sweep_flag=0), closing the ring in one loop.
Args:
- self (
Self) - cx (
Float64): Center x. - cy (
Float64): Center y. - inner_radius (
Float64): Ring’s inner edge, in pixels. - outer_radius (
Float64): Ring’s outer edge, in pixels. Must exceed inner_radius. - start_angle (
Float64): Sweep start, radians, 0 pointing along +x. - end_angle (
Float64): Sweep end, radians. Must be >= start_angle. - color (
Color): Fill color.
stroke_path_aa
fn def stroke_path_aa(mut self, path: Path, color: Color, width: Float64 = 1, dashes: List[Float64] = List(), dash_offset: Float64 = 0, cap: LineCap = LineCap.ROUND, join: LineJoin = LineJoin.ROUND, miter_limit: Float64 = 4)Emit a <path> element, stroked only.
Args:
- self (
Self) - path (
Path): Path to stroke. - color (
Color): Stroke color. - width (
Float64): Stroke width in pixels. - dashes (
List[Float64]): On/off segment lengths in user-space pixels, cycled along the stroke. Empty (default) draws a solid line. - dash_offset (
Float64): Distance into the dash pattern the stroke starts at. - cap (
LineCap): How an open sub-path’s two ends are finished – see LineCap. - join (
LineJoin): How corners are turned – see LineJoin. - miter_limit (
Float64): Ratio past which a MITER join falls back to BEVEL, as a multiple of half the stroke width.
fill_path_aa
fn def fill_path_aa(mut self, path: Path, color: Color, fill_rule: FillRule = FillRule.EVEN_ODD)Emit a <path> element, filled only. The default rule is written out as fill-rule="evenodd", since SVG’s own default is nonzero and the raster backend’s is even-odd; a path with a hole has to come out the same on both. NONZERO adds nothing, being what a renderer does when the attribute is absent.
Args:
- self (
Self) - path (
Path): Path to fill. - color (
Color): Fill color. - fill_rule (
FillRule): EVEN_ODD (default) or NONZERO – see FillRule.
push_clip
fn def push_clip(mut self, x: Int, y: Int, width: Int, height: Int)Restrict subsequent elements to a rectangle, the counterpart of Canvas.push_clip: a <clipPath id="clipN"> holding the <rect> (in the current user space, so it carries the transform attribute an element drawn now would) and a <g clip-path="url(#clipN)"> every element until the matching pop lands inside. Clips nest, and the viewer intersects them.
Clips and annotated groups do not interleave: pushing or popping a clip closes an open annotated group first, so the markup stays well-formed.
Known issue for anyone asserting on the markup: the
<clipPath>’s <rect> is an element of the document like any
other, so a test counting <rect> elements sees one more per
clip pushed. Count inside <defs> separately, or strip the
defs before counting; a consumer adopting the clip had eight
tests change their counts this way.
Args:
- self (
Self) - x (
Int): Clip rectangle’s left edge. - y (
Int): Clip rectangle’s top edge. - width (
Int): Clip rectangle’s width. - height (
Int): Clip rectangle’s height.
push_clip_path
fn def push_clip_path(mut self, path: Path, fill_rule: FillRule = FillRule.EVEN_ODD)Restrict subsequent elements to path’s interior, the counterpart of Canvas.push_clip_path: a <clipPath> holding the <path> with its fill rule as clip-rule, and a <g> referencing it. See push_clip for how clips nest and how they relate to annotated groups.
Args:
- self (
Self) - path (
Path): Shape to clip to. Its interior is what stays visible. - fill_rule (
FillRule): EVEN_ODD (default) or NONZERO – see FillRule.
pop_clip
fn def pop_clip(mut self)Remove the most recently pushed clip, rectangle or path: this backend keeps one stack of <g> wrappers, so the two pops are the same operation. A no-op with nothing pushed, matching Canvas.pop_clip.
Args:
- self (
Self)
pop_clip_path
fn def pop_clip_path(mut self)Remove the most recently pushed clip, rectangle or path – see pop_clip.
Args:
- self (
Self)
draw_image
fn def draw_image(mut self, image: Canvas, x: Float64, y: Float64, width: Float64 = 0, height: Float64 = 0)Emit an <image> element with image as a PNG in a base64 data: URI, its top-left at (x, y), scaled to width x height (its own pixel size when 0): DrawTarget’s image primitive. preserveAspectRatio="none" stretches the pixels to the box, and image-rendering:pixelated keeps the cells hard-edged when a viewer scales them, so a heatmap reads as it does on the raster backend. The transform and blend attributes are the ones every element carries. A 512x512 array is tens of kilobytes this way against megabytes as a <rect> per cell, which is the case the primitive exists for.
Args:
- self (
Self) - image (
Canvas): The pixels to draw. Unchanged. - x (
Float64): Left edge. - y (
Float64): Top edge. - width (
Float64): Drawn width, or 0 forimage.width. - height (
Float64): Drawn height, or 0 forimage.height.
Raises:
Error: Never in practice; the PNG encoder’s signature.
begin_batch
fn def begin_batch(mut self)Nothing to defer: every element goes into the markup in order as it is drawn. Here so a caller generic over DrawTarget can batch for the raster backend; see Canvas.begin_batch.
Args:
- self (
Self)
end_batch
fn def end_batch(mut self)The other half of begin_batch, also nothing.
Args:
- self (
Self)
begin_annotated_group
fn def begin_annotated_group(mut self, title: String)Open <g><title>title</title>, labeling every element emitted until end_annotated_group. Browsers show a <title> inside a <g> as a hover tooltip over anything in the group, which is what gives a chart per-datum tooltips without any scripting.
title is escaped as element content, so it may contain &,
< and > freely.
Groups do not nest: opening one while another is open closes
the first. See the DrawTarget docstring for why the operation
is scoped rather than a parameter on each primitive.
Args:
- self (
Self) - title (
String): Human-readable label, escaped here. Pass it raw.
end_annotated_group
fn def end_annotated_group(mut self)Close the group begin_annotated_group opened, a no-op when none is open. Emitting a stray </g> would make the document malformed, which is worse than ignoring an unbalanced call, and it matches Canvas.pop_clip treating an unbalanced close as nothing to undo.
Args:
- self (
Self)
draw_text
fn def draw_text(mut self, x: Int, y: Int, text: String, color: Color, size: Float64, align: TextAlign, family: String = "sans-serif", rotation: Float64 = 0, weight: FontWeight = FontWeight.NORMAL)Draw a <text> element at a whole-pixel anchor with a literal CSS font-family. The DrawTarget form below takes a sub-pixel anchor, a slant and the raster backend’s family names; this one predates it and stays for callers that write the CSS stack themselves.
family is always emitted, defaulting to "sans-serif", since
a viewer without one falls back to its own varying default. It
is a different kind of value from raster draw_text’s family
despite the shared name: raster’s resolves to one concrete font
file, while this is a literal CSS font-family – keyword,
face name, or comma-separated stack – interpreted by whatever
renders the SVG.
(x, y) is the baseline anchor, matching raster draw_text, since
SVG <text> anchors y to the alphabetic baseline already.
text-anchor (start/middle/end) is the equivalent of
align’s three values.
rotation is radians and rotates the whole <text> around its
(x, y) anchor via transform="rotate(<degrees> <x> <y>)",
omitted at 0.0. No sign flip: raster and SVG viewport space both
put y downward.
weight emits font-weight="bold" for FontWeight.BOLD and is
omitted at NORMAL.
Args:
- self (
Self) - x (
Int): Anchor x – baseline left end for TextAlign.LEFT. - y (
Int): Anchor y – baseline. - text (
String): Text to draw. No line-break handling for embedded “\n”. - color (
Color): Text color. - size (
Float64): Font size in pixels. - align (
TextAlign): Horizontal alignment relative to (x, y). - family (
String): A literal CSSfont-familyvalue (keyword, face name, or comma-separated stack), not a font-matching query. - rotation (
Float64): Radians, rotating the whole<text>element around (x, y). - weight (
FontWeight): Normal/bold weight.
fn def draw_text(mut self, x: Float64, y: Float64, text: String, color: Color, size: Float64, family: String = "Sans", slant: FontSlant = FontSlant.NORMAL, weight: FontWeight = FontWeight.NORMAL, rotation: Float64 = 0, align: TextAlign = TextAlign.LEFT, *, mut cache: FontCache)The DrawTarget form: a <text> element at a sub-pixel anchor, with family in the raster backend’s terms. The generic names ("Sans", "Serif", "Monospace", and their CSS spellings) become the CSS generic keywords; a face name or an explicit CSS stack passes through verbatim, so a caller can still write the stack itself. slant emits font-style (italic or oblique), omitted when upright.
cache is unused: a <text> element carries no glyphs, so
there is nothing to resolve. It is in the signature so one
generic call serves every backend.
Everything the whole-pixel overload says about the anchor,
text-anchor, rotation and weight holds here.
Args:
- self (
Self) - x (
Float64): Anchor x, sub-pixel – baseline left end for TextAlign.LEFT. - y (
Float64): Anchor y, sub-pixel – baseline. - text (
String): Text to draw. No line-break handling for embedded “\n”. - color (
Color): Text color. - size (
Float64): Font size in pixels. - family (
String): Font family name or generic alias, as the raster backend takes it. - slant (
FontSlant): Upright, italic or oblique. - weight (
FontWeight): Normal/bold weight. - rotation (
Float64): Radians, rotating the whole<text>element around (x, y). - align (
TextAlign): Horizontal alignment relative to (x, y). - cache (
FontCache): Unused here; see above.
Raises:
Error: Never; the signature is the trait’s.
draw_text_runs
fn def draw_text_runs(mut self, x: Float64, y: Float64, runs: List[TextRun], color: Color, family: String = "Sans", weight: FontWeight = FontWeight.NORMAL, rotation: Float64 = 0, align: TextAlign = TextAlign.LEFT, *, mut cache: FontCache)One <text> element with a <tspan> per run: SVG’s own form for a label whose pieces differ in size or slant, and what keeps the label one string in a viewer – one selection, one copy with its spaces in place, one announcement – where the same runs as separate draw_text calls are as many elements. The element carries the family, weight, fill, anchor and transform as draw_text’s does; each <tspan> carries its font-size, its font-style when slanted, its dx, and a dy that is the difference from the previous run’s baseline, since a <tspan>’s dy shifts the current position for everything after it where TextRun.dy names a baseline. Nothing is written between the tspans: whitespace there would be a space in the rendered text.
The viewer’s own font metrics advance the pen from run to run
and resolve align, as they do for a single draw_text; a
run’s kern and rise are what this backend carries, not the
anchor the other backends measure. A run with no text is left
out, and a label of nothing but those writes nothing.
cache is unused, as in draw_text.
Args:
- self (
Self) - x (
Float64): Anchor x, sub-pixel – the label’s left end forTextAlign.LEFT. - y (
Float64): Anchor y, sub-pixel – the label’s baseline. - runs (
List[TextRun]): The label’s runs, in reading order. - color (
Color): Fill color. - family (
String): Font family name or generic alias, as the raster backend takes it; mapped asdraw_textmaps it. - weight (
FontWeight): Normal/bold weight, on the element. - rotation (
Float64): Radians, rotating the whole<text>element around (x, y). - align (
TextAlign):text-anchorfor the whole label. - cache (
FontCache): Unused here; see above.
Raises:
Error: Never; the signature is the trait’s.
stroke_text
fn def stroke_text(mut self, x: Int, y: Int, text: String, color: Color, size: Float64, align: TextAlign, width: Float64 = 1, family: String = "sans-serif", rotation: Float64 = 0, weight: FontWeight = FontWeight.NORMAL, join: LineJoin = LineJoin.ROUND, miter_limit: Float64 = 4)Draw a <text> element outlined rather than filled: fill="none" plus the stroke attributes. The vector counterpart of raster stroke_text; not part of DrawTarget, which carries only the filled draw_text.
Everything draw_text says about (x, y), family, align,
rotation and weight holds here unchanged; only the paint
differs.
No stroke-linecap is emitted: a glyph outline is a set of
closed contours, so it has no ends to cap, and the raster side
takes no cap parameter for the same reason.
SVG applies stroke-width in the element’s user space, so an
outlined label under a scale thickens with it, as on Canvas.
Args:
- self (
Self) - x (
Int): Anchor x – baseline left end for TextAlign.LEFT. - y (
Int): Anchor y – baseline. - text (
String): Text to draw. No line-break handling for embedded “\n”. - color (
Color): Stroke color. - size (
Float64): Font size in pixels. - align (
TextAlign): Horizontal alignment relative to (x, y). - width (
Float64): Stroke width in user-space pixels. - family (
String): A literal CSSfont-familyvalue, not a font-matching query – see draw_text. - rotation (
Float64): Radians, rotating the whole<text>element around (x, y). - weight (
FontWeight): Normal/bold weight. - join (
LineJoin): How a corner of the outline is turned – see LineJoin. - miter_limit (
Float64): Ratio past which a MITER join falls back to BEVEL, as a multiple of half the stroke width.
draw_text_on_path
fn def draw_text_on_path(mut self, path: Path, text: String, color: Color, size: Float64, align: TextAlign, offset: Float64 = 0, family: String = "sans-serif", weight: FontWeight = FontWeight.NORMAL)Draw text along path, as a <textPath> referring to a <path> in a <defs> block emitted just before it. The vector counterpart of raster draw_text_on_path.
Each call mints a fresh id (tpN), so two calls never collide
and a path drawn as well as labeled is written twice rather
than shared – the visible path carries its own paint.
offset becomes startOffset, a distance along the path, for
all three alignments: SVG anchors a <textPath> at
startOffset and then applies text-anchor about it, which is
exactly what the raster side’s align does.
A renderer drops the glyphs that do not fit on the path, the rule the raster side applies to a glyph whose center falls past an end.
Args:
- self (
Self) - path (
Path): Curve the baseline follows. - text (
String): Text to draw, one line. - color (
Color): Text color. - size (
Float64): Font size in pixels. - align (
TextAlign): Whereoffsetsits in the string – its start, middle or end. - offset (
Float64): Distance along the path the string is placed at. - family (
String): A literal CSSfont-familyvalue, not a font-matching query – see draw_text. - weight (
FontWeight): Normal/bold weight.
set_title
fn def set_title(mut self, title: String, description: String = "")Give the document an accessible title: the root <svg> gains role="img" and aria-label, and <title> (and <desc> when description is non-empty) become its first children, which is what screen readers that walk an SVG’s accessible tree look for. The document-level counterpart of begin_annotated_group.
Both strings are escaped here; pass them raw. Calling again
replaces the previous title. An empty title removes it.
This helps where the SVG’s accessible tree is walked: inline
markup, a standalone file, or an <object>/<iframe> embed.
A plain <img src="chart.svg"> treats the SVG as an opaque
image and reads the <img>’s alt text instead.
Args:
- self (
Self) - title (
String): Short accessible name for the whole document. - description (
String): Longer description, optional.
to_string
fn def to_string(self) -> StringArgs:
- self (
Self)
Returns:
String