public static SKTextBlob Create(ReadOnlySpan <char> text, SKFont font, SKPoint origin = default) { fixed(void *t = text) { return(Create(t, text.Length * 2, SKTextEncoding.Utf16, font, origin)); } }
public static SKTextBlob CreateRotationScale(ReadOnlySpan <char> text, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions) { fixed(void *t = text) { return(CreateRotationScale(t, text.Length * 2, SKTextEncoding.Utf16, font, positions)); } }
public void DrawText(string text, float x, float y, SKFont font, SKPaint paint) { if (text == null) { throw new ArgumentNullException(nameof(text)); } if (font == null) { throw new ArgumentNullException(nameof(font)); } if (paint == null) { throw new ArgumentNullException(nameof(paint)); } if (paint.TextAlign != SKTextAlign.Left) { var width = font.MeasureText(text); if (paint.TextAlign == SKTextAlign.Center) { width *= 0.5f; } x -= width; } using var blob = SKTextBlob.Create(text, font); if (blob == null) { return; } DrawText(blob, x, y, paint); }
public static SKTextBlob CreatePositioned(ReadOnlySpan <char> text, SKFont font, ReadOnlySpan <SKPoint> positions) { fixed(void *t = text) { return(CreatePositioned(t, text.Length * 2, SKTextEncoding.Utf16, font, positions)); } }
public static SKTextBlob CreateHorizontal(ReadOnlySpan <char> text, SKFont font, ReadOnlySpan <float> positions, float y) { fixed(void *t = text) { return(CreateHorizontal(t, text.Length * 2, SKTextEncoding.Utf16, font, positions, y)); } }
public static SKTextBlob CreatePathPositioned(ReadOnlySpan <char> text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) { fixed(void *t = text) { return(CreatePathPositioned(t, text.Length * 2, SKTextEncoding.Utf16, font, path, textAlign, origin)); } }
// AddPathPositionedRun public void AddPathPositionedRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <float> glyphWidths, ReadOnlySpan <SKPoint> glyphOffsets, SKPath path, SKTextAlign textAlign = SKTextAlign.Left) { using var pathMeasure = new SKPathMeasure(path); var contourLength = pathMeasure.Length; var textLength = glyphOffsets[glyphs.Length - 1].X + glyphWidths[glyphs.Length - 1]; var alignment = (int)textAlign * 0.5f; var startOffset = glyphOffsets[0].X + (contourLength - textLength) * alignment; var firstGlyphIndex = 0; var pathGlyphCount = 0; using var glyphTransforms = Utils.RentArray <SKRotationScaleMatrix> (glyphs.Length); // TODO: deal with multiple contours? for (var index = 0; index < glyphOffsets.Length; index++) { var glyphOffset = glyphOffsets[index]; var halfWidth = glyphWidths[index] * 0.5f; var pathOffset = startOffset + glyphOffset.X + halfWidth; // TODO: clip glyphs on both ends of paths if (pathOffset >= 0 && pathOffset < contourLength && pathMeasure.GetPositionAndTangent(pathOffset, out var position, out var tangent)) { if (pathGlyphCount == 0) { firstGlyphIndex = index; } var tx = tangent.X; var ty = tangent.Y; var px = position.X; var py = position.Y; // horizontally offset the position using the tangent vector px -= tx * halfWidth; py -= ty * halfWidth; // vertically offset the position using the normal vector (-ty, tx) var dy = glyphOffset.Y; px -= dy * ty; py += dy * tx; glyphTransforms.Span[pathGlyphCount++] = new SKRotationScaleMatrix(tx, ty, px, py); } } var glyphSubset = glyphs.Slice(firstGlyphIndex, pathGlyphCount); var positions = glyphTransforms.Span.Slice(0, pathGlyphCount); AddRotationScaleRun(glyphSubset, font, positions); }
// AddHorizontalRun public void AddHorizontalRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <float> positions, float y) { if (font == null) { throw new ArgumentNullException(nameof(font)); } var buffer = AllocateHorizontalRun(font, glyphs.Length, y); glyphs.CopyTo(buffer.GetGlyphSpan()); positions.CopyTo(buffer.GetPositionSpan()); }
// AddPositionedRun public void AddPositionedRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <SKPoint> positions) { if (font == null) { throw new ArgumentNullException(nameof(font)); } var buffer = AllocatePositionedRun(font, glyphs.Length); glyphs.CopyTo(buffer.GetGlyphSpan()); positions.CopyTo(buffer.GetPositionSpan()); }
// AddRotationScaleRun public void AddRotationScaleRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions) { if (font == null) { throw new ArgumentNullException(nameof(font)); } var buffer = AllocateRotationScaleRun(font, glyphs.Length); glyphs.CopyTo(buffer.GetGlyphSpan()); positions.CopyTo(buffer.GetRotationScaleSpan()); }
// AddRun public void AddRun(ReadOnlySpan <ushort> glyphs, SKFont font, SKPoint origin = default) { if (font == null) { throw new ArgumentNullException(nameof(font)); } var buffer = AllocatePositionedRun(font, glyphs.Length); glyphs.CopyTo(buffer.GetGlyphSpan()); font.GetGlyphPositions(buffer.GetGlyphSpan(), buffer.GetPositionSpan(), origin); }
// AllocateRotationScaleRun public SKRotationScaleRunBuffer AllocateRotationScaleRun(SKFont font, int count) { if (font == null) { throw new ArgumentNullException(nameof(font)); } SKRunBufferInternal runbuffer; SkiaApi.sk_textblob_builder_alloc_run_rsxform(Handle, font.Handle, count, &runbuffer); return(new SKRotationScaleRunBuffer(runbuffer, count)); }
public SKPaint(SKFont font) : this(IntPtr.Zero, true) { if (font == null) { throw new ArgumentNullException(nameof(font)); } Handle = SkiaApi.sk_compatpaint_new_with_font(font.Handle); if (Handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create a new SKPaint instance."); } }
// AllocatePositionedRun public SKPositionedRunBuffer AllocatePositionedRun(SKFont font, int count, SKRect?bounds = null) { if (font == null) { throw new ArgumentNullException(nameof(font)); } SKRunBufferInternal runbuffer; if (bounds is SKRect b) { SkiaApi.sk_textblob_builder_alloc_run_pos(Handle, font.Handle, count, &b, &runbuffer); } else { SkiaApi.sk_textblob_builder_alloc_run_pos(Handle, font.Handle, count, null, &runbuffer); } return(new SKPositionedRunBuffer(runbuffer, count)); }
// CreateHorizontal public static SKTextBlob CreateHorizontal(string text, SKFont font, ReadOnlySpan <float> positions, float y) => CreateHorizontal(text.AsSpan(), font, positions, y);
internal static SKTextBlob Create(void *text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin) { if (font == null) { throw new ArgumentNullException(nameof(font)); } var count = font.CountGlyphs(text, length, encoding); if (count <= 0) { return(null); } using var builder = new SKTextBlobBuilder(); var buffer = builder.AllocatePositionedRun(font, count); font.GetGlyphs(text, length, encoding, buffer.GetGlyphSpan()); font.GetGlyphPositions(buffer.GetGlyphSpan(), buffer.GetPositionSpan(), origin); return(builder.Build()); }
public static SKTextBlob Create(ReadOnlySpan <byte> text, SKTextEncoding encoding, SKFont font, SKPoint origin = default) { fixed(void *t = text) { return(Create(t, text.Length, encoding, font, origin)); } }
internal static SKTextBlob CreatePathPositioned(void *text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) { if (font == null) { throw new ArgumentNullException(nameof(font)); } var count = font.CountGlyphs(text, length, encoding); if (count <= 0) { return(null); } // we use temporary arrays because we might only use part of the text using var glyphs = Utils.RentArray <ushort> (count); using var glyphWidths = Utils.RentArray <float> (glyphs.Length); using var glyphOffsets = Utils.RentArray <SKPoint> (glyphs.Length); font.GetGlyphs(text, length, encoding, glyphs); font.GetGlyphWidths(glyphs, glyphWidths, Span <SKRect> .Empty); font.GetGlyphPositions(glyphs, glyphOffsets, origin); using var builder = new SKTextBlobBuilder(); builder.AddPathPositionedRun(glyphs, font, glyphWidths, glyphOffsets, path, textAlign); return(builder.Build()); }
internal static SKTextBlob CreateHorizontal(void *text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <float> positions, float y) { if (font == null) { throw new ArgumentNullException(nameof(font)); } var count = font.CountGlyphs(text, length, encoding); if (count <= 0) { return(null); } using var builder = new SKTextBlobBuilder(); var buffer = builder.AllocateHorizontalRun(font, count, y); font.GetGlyphs(text, length, encoding, buffer.GetGlyphSpan()); positions.CopyTo(buffer.GetPositionSpan()); return(builder.Build()); }
// CreateRotationScale public static SKTextBlob CreateRotationScale(string text, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions) => CreateRotationScale(text.AsSpan(), font, positions);
public static SKTextBlob CreateRotationScale(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions) => CreateRotationScale(text.AsReadOnlySpan(length), encoding, font, positions);
// CreatePathPositioned public static SKTextBlob CreatePathPositioned(string text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => CreatePathPositioned(text.AsSpan(), font, path, textAlign, origin);
// Create public static SKTextBlob Create(string text, SKFont font, SKPoint origin = default) => Create(text.AsSpan(), font, origin);
public static SKTextBlob CreatePositioned(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <SKPoint> positions) => CreatePositioned(text.AsReadOnlySpan(length), encoding, font, positions);
public static SKTextBlob CreateHorizontal(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <float> positions, float y) => CreateHorizontal(text.AsReadOnlySpan(length), encoding, font, positions, y);
public static SKTextBlob CreatePositioned(ReadOnlySpan <byte> text, SKTextEncoding encoding, SKFont font, ReadOnlySpan <SKPoint> positions) { fixed(void *t = text) { return(CreatePositioned(t, text.Length, encoding, font, positions)); } }
public static SKTextBlob Create(IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin = default) => Create(text.AsReadOnlySpan(length), encoding, font, origin);
public static SKTextBlob CreatePathPositioned(IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => CreatePathPositioned(text.AsReadOnlySpan(length), encoding, font, path, textAlign, origin);
public void DrawTextOnPath(string text, SKPath path, SKPoint offset, bool warpGlyphs, SKFont font, SKPaint paint) { if (text == null) { throw new ArgumentNullException(nameof(text)); } if (path == null) { throw new ArgumentNullException(nameof(path)); } if (font == null) { throw new ArgumentNullException(nameof(font)); } if (paint == null) { throw new ArgumentNullException(nameof(paint)); } if (warpGlyphs) { using var textPath = font.GetTextPathOnPath(text, path, paint.TextAlign, offset); DrawPath(textPath, paint); } else { using var blob = SKTextBlob.CreatePathPositioned(text, font, path, paint.TextAlign, offset); if (blob != null) { DrawText(blob, 0, 0, paint); } } }
// CreatePositioned public static SKTextBlob CreatePositioned(string text, SKFont font, ReadOnlySpan <SKPoint> positions) => CreatePositioned(text.AsSpan(), font, positions);