Class FontExtensions
Glyphs and text as Paths in canvas units, y down, for clipping, stroking or measuring them as shapes.
public static class FontExtensions
- Inheritance
-
FontExtensions
- Inherited Members
Examples
// Text as a shape: outline it, or clip a picture to it.
Path title = font.GetTextPath("EGAMI", new Vector2(10, 80));
using Raster<Rgba8> image = Raster.Create(300, 100, Rgba8.White);
using (RasterCanvas<Rgba8> canvas = image.CreateCanvas())
{
canvas.StrokePath(title, new Stroke(2), Rgba8.Black);
canvas.ClipPath(title);
canvas.FillRect(new RectF(0, 50, 300, 50), Rgba8.Red);
}
Methods
GetGlyphPath(Font, ushort)
Gets a glyph's outline at the font's size, with the glyph's origin at (0, 0) on the baseline, y down: slanted 14 degrees for synthetic italic and outset for synthetic bold when Synthesis asks and AllowSynthesis allows.
public static Path GetGlyphPath(this Font font, ushort glyph)
Parameters
Returns
- Path
The outline; empty for a glyph without ink.
GetTextPath(Font, string, Vector2)
Gets the outline of a line of text as DrawText(string, Vector2, Font, Paint, ShapingOptions?) lays it out.
public static Path GetTextPath(this Font font, string text, Vector2 origin)
Parameters
Returns
- Path
The outline of every glyph, in one path.
ShapeOnPath(Font, string, Path, TextOnPathOptions?)
Lays text along a path by SVG's textPath rules: the text is shaped as one line, each glyph's advance midpoint is placed on the path at the start point plus its distance along the line, and the glyph is turned to the path's direction there and moved by the baseline shift along the normal. Glyphs whose midpoint falls before the path's start or past its end are left out, with their clusters. Contours are walked one after another as one path.
public static GlyphRun ShapeOnPath(this Font font, string text, Path path, TextOnPathOptions? options = null)
Parameters
fontFontThe font.
textstringThe text; newlines draw nothing.
pathPathThe path, in the same coordinates the run is drawn in.
optionsTextOnPathOptions
Returns
- GlyphRun
A run with a GlyphTransform per glyph, relative to (0, 0).
Examples
// A label along a curve: each glyph's midpoint on the path, turned to its direction, as SVG's textPath. The result is
// still a glyph run, so a PDF backend writes it as searchable text.
Path curve = new PathBuilder().MoveTo(20, 150).CubicTo(80, 20, 240, 20, 300, 150).ToPath();
var font = new Font(face, 18);
using (RasterCanvas<Rgba8> canvas = image.CreateCanvas())
{
canvas.DrawTextOnPath("Text that follows the curve", curve, font, Rgba8.Black,
new TextOnPathOptions { StartFraction = 0.5f, Anchor = TextAnchor.Center, BaselineShift = 4 });
}
// Or place glyphs yourself, each with its own turn and scale.
GlyphRun dial = GlyphRun.CreateTransformed(font, [face.GetGlyph('N'), face.GetGlyph('E')],
[GlyphTransform.FromRotationScale(1, 0, new Vector2(150, 30)), GlyphTransform.FromRotationScale(1, 90, new Vector2(290, 90))]);
Exceptions
- ArgumentException
fonthas no typeface.
ToPath(GlyphRun, Vector2)
Gets the outline of every glyph of a run, placed at its position relative to origin, with the font's
synthetic bold and italic.
public static Path ToPath(this GlyphRun run, Vector2 origin)
Parameters
Returns
- Path
The outline, in one path.
ToPath(DecorationShape, Vector2)
Gets a decoration line's outline, the layout's top-left corner at origin.
public static Path ToPath(this DecorationShape shape, Vector2 origin)
Parameters
shapeDecorationShapeThe decoration.
originVector2Where the layout's top-left corner goes.
Returns
- Path
The outline.
ToPath(TextLayout, Vector2)
Gets a laid-out paragraph as one path: every glyph run's outline with its font's synthetic bold and italic, then every
decoration, the layout's top-left corner at origin.
public static Path ToPath(this TextLayout layout, Vector2 origin)
Parameters
layoutTextLayoutThe layout.
originVector2Where the layout's top-left corner goes.
Returns
- Path
The outline, in one path.
Examples
ParagraphStyle style = new()
{
DefaultStyle = new TextStyle
{
FontFamilies = [family],
Size = 18,
Color = new Rgba8(30, 30, 60, 255),
Shadows = [new TextShadow(new System.Numerics.Vector2(1, 1), 2, new Rgba8(0, 0, 0, 80))],
},
Align = TextAlign.Justify,
};
// One call: wrap into a box, centred across the lines.
TextLayout boxed = canvas.DrawText("Paragraphs wrap, justify and drop shadows.", new RectF(10, 10, 300, 80), style, VerticalAlign.Center);
// Or lay out once and draw where needed, skipping lines outside the visible part.
TextLayout layout = Paragraph.Create("Laid out once, drawn many times.", style).Layout(300);
canvas.DrawTextLayout(layout, new System.Numerics.Vector2(10, 110), visibleRect: new RectF(0, 0, 320, 200));
// Inline placeholders (an icon, a badge) are drawn by a painter called with each one's box.
canvas.DrawTextLayout(layout, new System.Numerics.Vector2(10, 130), placeholderPainter: (c, index, box) => c.FillRoundRect(new RoundRect(box, 3), new Rgba8(200, 60, 40, 255)));
// The same text as one path: glyphs and decorations.
Egami.Drawing.Path outline = layout.ToPath(new System.Numerics.Vector2(10, 150));
ToRectF(TextBounds)
Converts text bounds to a rectangle.
public static RectF ToRectF(this TextBounds bounds)
Parameters
boundsTextBoundsThe bounds.
Returns
- RectF
The rectangle.