Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide allocate-less overloads of methods in SKTextBlobBuilder #2664

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 148 additions & 24 deletions binding/SkiaSharp/SKTextBlob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ internal static SKTextBlob Create (void* text, int length, SKTextEncoding encodi
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);
builder.AllocatePositionedRun (font, count, bounds: null, out var positionSpan, out var glyphSpan);
font.GetGlyphs (text, length, encoding, glyphSpan);
font.GetGlyphPositions (glyphSpan, positionSpan, origin);
return builder.Build ();
}

Expand Down Expand Up @@ -99,9 +99,9 @@ internal static SKTextBlob CreateHorizontal (void* text, int length, SKTextEncod
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 ());
builder.AllocateHorizontalRun (font, count, y, bounds: null, out var positionSpan, out var glyphSpan);
font.GetGlyphs (text, length, encoding, glyphSpan);
positions.CopyTo (positionSpan);
return builder.Build ();
}

Expand Down Expand Up @@ -137,9 +137,9 @@ internal static SKTextBlob CreatePositioned (void* text, int length, SKTextEncod
return null;

using var builder = new SKTextBlobBuilder ();
var buffer = builder.AllocatePositionedRun (font, count);
font.GetGlyphs (text, length, encoding, buffer.GetGlyphSpan ());
positions.CopyTo (buffer.GetPositionSpan ());
builder.AllocatePositionedRun (font, count, bounds: null, out var positionSpan, out var glyphSpan);
font.GetGlyphs (text, length, encoding, glyphSpan);
positions.CopyTo (positionSpan);
return builder.Build ();
}

Expand Down Expand Up @@ -175,9 +175,9 @@ internal static SKTextBlob CreateRotationScale (void* text, int length, SKTextEn
return null;

using var builder = new SKTextBlobBuilder ();
var buffer = builder.AllocateRotationScaleRun (font, count);
font.GetGlyphs (text, length, encoding, buffer.GetGlyphSpan ());
positions.CopyTo (buffer.GetRotationScaleSpan ());
builder.AllocateRotationScaleRun (font, count, bounds: null, out var glyphSpan, out var rotationScaleSpan);
font.GetGlyphs (text, length, encoding, glyphSpan);
positions.CopyTo (rotationScaleSpan);
return builder.Build ();
}

Expand Down Expand Up @@ -296,9 +296,9 @@ public void AddRun (ReadOnlySpan<ushort> glyphs, SKFont font, SKPoint origin = d
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);
AllocatePositionedRun (font, glyphs.Length, bounds: null, out var positionSpan, out var glyphSpan);
glyphs.CopyTo (glyphSpan);
font.GetGlyphPositions (glyphSpan, positionSpan, origin);
}

// AddHorizontalRun
Expand All @@ -308,9 +308,9 @@ public void AddHorizontalRun (ReadOnlySpan<ushort> glyphs, SKFont font, ReadOnly
if (font == null)
throw new ArgumentNullException (nameof (font));

var buffer = AllocateHorizontalRun (font, glyphs.Length, y);
glyphs.CopyTo (buffer.GetGlyphSpan ());
positions.CopyTo (buffer.GetPositionSpan ());
AllocateHorizontalRun (font, glyphs.Length, y, bounds: null, out var positionSpan, out var glyphSpan);
glyphs.CopyTo (glyphSpan);
positions.CopyTo (positionSpan);
}

// AddPositionedRun
Expand All @@ -320,9 +320,9 @@ public void AddPositionedRun (ReadOnlySpan<ushort> glyphs, SKFont font, ReadOnly
if (font == null)
throw new ArgumentNullException (nameof (font));

var buffer = AllocatePositionedRun (font, glyphs.Length);
glyphs.CopyTo (buffer.GetGlyphSpan ());
positions.CopyTo (buffer.GetPositionSpan ());
AllocatePositionedRun (font, glyphs.Length, bounds: null, out var positionSpan, out var glyphSpan);
glyphs.CopyTo (glyphSpan);
positions.CopyTo (positionSpan);
}

// AddRotationScaleRun
Expand All @@ -332,9 +332,9 @@ public void AddRotationScaleRun (ReadOnlySpan<ushort> glyphs, SKFont font, ReadO
if (font == null)
throw new ArgumentNullException (nameof (font));

var buffer = AllocateRotationScaleRun (font, glyphs.Length);
glyphs.CopyTo (buffer.GetGlyphSpan ());
positions.CopyTo (buffer.GetRotationScaleSpan ());
AllocateRotationScaleRun (font, glyphs.Length, bounds: null, out var glyphSpan, out var rotationScaleSpan);
glyphs.CopyTo (glyphSpan);
positions.CopyTo (rotationScaleSpan);
}

// AddPathPositionedRun
Expand Down Expand Up @@ -406,6 +406,20 @@ public SKRunBuffer AllocateRun (SKFont font, int count, float x, float y, SKRect
return new SKRunBuffer (runbuffer, count);
}

public void AllocateRun (SKFont font, int count, float x, float y, SKRect? bounds, out Span<ushort> glyphSpan)
{
if (font == null)
throw new ArgumentNullException (nameof (font));

SKRunBufferInternal runbuffer;
if (bounds is SKRect b)
SkiaApi.sk_textblob_builder_alloc_run (Handle, font.Handle, count, x, y, &b, &runbuffer);
else
SkiaApi.sk_textblob_builder_alloc_run (Handle, font.Handle, count, x, y, null, &runbuffer);

glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
}

public SKTextRunBuffer AllocateTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds = null)
{
if (font == null)
Expand All @@ -420,6 +434,22 @@ public SKTextRunBuffer AllocateTextRun (SKFont font, int count, float x, float y
return new SKTextRunBuffer (runbuffer, count, textByteCount);
}

public void AllocateTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds, out Span<byte> textSpan, out Span<ushort> glyphSpan, out Span<uint> clusterSpan)
{
if (font == null)
throw new ArgumentNullException (nameof (font));

SKRunBufferInternal runbuffer;
if (bounds is SKRect b)
SkiaApi.sk_textblob_builder_alloc_run_text (Handle, font.Handle, count, x, y, textByteCount, &b, &runbuffer);
else
SkiaApi.sk_textblob_builder_alloc_run_text (Handle, font.Handle, count, x, y, textByteCount, null, &runbuffer);

textSpan = new Span<byte> (runbuffer.utf8text, runbuffer.utf8text == null ? 0 : textByteCount);
glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
clusterSpan = new Span<uint> (runbuffer.clusters, runbuffer.clusters == null ? 0 : count);
}

// AllocateHorizontalRun

public SKHorizontalRunBuffer AllocateHorizontalRun (SKFont font, int count, float y, SKRect? bounds = null)
Expand All @@ -436,6 +466,21 @@ public SKHorizontalRunBuffer AllocateHorizontalRun (SKFont font, int count, floa
return new SKHorizontalRunBuffer (runbuffer, count);
}

public void AllocateHorizontalRun (SKFont font, int count, float y, SKRect? bounds, out Span<float> positionSpan, out Span<ushort> glyphSpan)
{
if (font == null)
throw new ArgumentNullException (nameof (font));

SKRunBufferInternal runbuffer;
if (bounds is SKRect b)
SkiaApi.sk_textblob_builder_alloc_run_pos_h (Handle, font.Handle, count, y, &b, &runbuffer);
else
SkiaApi.sk_textblob_builder_alloc_run_pos_h (Handle, font.Handle, count, y, null, &runbuffer);

positionSpan = new Span<float> (runbuffer.pos, runbuffer.pos == null ? 0 : count);
glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
}

public SKHorizontalTextRunBuffer AllocateHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds = null)
{
if (font == null)
Expand All @@ -450,6 +495,23 @@ public SKHorizontalTextRunBuffer AllocateHorizontalTextRun (SKFont font, int cou
return new SKHorizontalTextRunBuffer (runbuffer, count, textByteCount);
}

public void AllocateHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds, out Span<byte> textSpan, out Span<float> positionSpan, out Span<ushort> glyphSpan, out Span<uint> clusterSpan)
{
if (font == null)
throw new ArgumentNullException (nameof (font));

SKRunBufferInternal runbuffer;
if (bounds is SKRect b)
SkiaApi.sk_textblob_builder_alloc_run_text_pos_h (Handle, font.Handle, count, y, textByteCount, &b, &runbuffer);
else
SkiaApi.sk_textblob_builder_alloc_run_text_pos_h (Handle, font.Handle, count, y, textByteCount, null, &runbuffer);

textSpan = new Span<byte> (runbuffer.utf8text, runbuffer.utf8text == null ? 0 : textByteCount);
positionSpan = new Span<float> (runbuffer.pos, runbuffer.pos == null ? 0 : count);
glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
clusterSpan = new Span<uint> (runbuffer.clusters, runbuffer.clusters == null ? 0 : count);
}

// AllocatePositionedRun

public SKPositionedRunBuffer AllocatePositionedRun (SKFont font, int count, SKRect? bounds = null)
Expand All @@ -466,6 +528,21 @@ public SKPositionedRunBuffer AllocatePositionedRun (SKFont font, int count, SKRe
return new SKPositionedRunBuffer (runbuffer, count);
}

public void AllocatePositionedRun (SKFont font, int count, SKRect? bounds, out Span<SKPoint> positionSpan, out Span<ushort> glyphSpan)
{
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);

positionSpan = new Span<SKPoint> (runbuffer.pos, runbuffer.pos == null ? 0 : count);
glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
}

public SKPositionedTextRunBuffer AllocatePositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null)
{
if (font == null)
Expand All @@ -480,6 +557,23 @@ public SKPositionedTextRunBuffer AllocatePositionedTextRun (SKFont font, int cou
return new SKPositionedTextRunBuffer (runbuffer, count, textByteCount);
}

public void AllocatePositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds, out Span<byte> textSpan, out Span<float> positionSpan, out Span<ushort> glyphSpan, out Span<uint> clusterSpan)
{
if (font == null)
throw new ArgumentNullException (nameof (font));

SKRunBufferInternal runbuffer;
if (bounds is SKRect b)
SkiaApi.sk_textblob_builder_alloc_run_text_pos (Handle, font.Handle, count, textByteCount, &b, &runbuffer);
else
SkiaApi.sk_textblob_builder_alloc_run_text_pos (Handle, font.Handle, count, textByteCount, null, &runbuffer);

textSpan = new Span<byte> (runbuffer.utf8text, runbuffer.utf8text == null ? 0 : textByteCount);
positionSpan = new Span<float> (runbuffer.pos, runbuffer.pos == null ? 0 : count);
glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
clusterSpan = new Span<uint> (runbuffer.clusters, runbuffer.clusters == null ? 0 : count);
}

// AllocateRotationScaleRun

public SKRotationScaleRunBuffer AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds = null)
Expand All @@ -496,6 +590,21 @@ public SKRotationScaleRunBuffer AllocateRotationScaleRun (SKFont font, int count
return new SKRotationScaleRunBuffer (runbuffer, count);
}

public void AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds, out Span<ushort> glyphSpan, out Span<SKRotationScaleMatrix> rotationScaleSpan)
{
if (font == null)
throw new ArgumentNullException (nameof (font));

SKRunBufferInternal runbuffer;
if (bounds is SKRect b)
SkiaApi.sk_textblob_builder_alloc_run_rsxform (Handle, font.Handle, count, &b, &runbuffer);
else
SkiaApi.sk_textblob_builder_alloc_run_rsxform (Handle, font.Handle, count, null, &runbuffer);

glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
rotationScaleSpan = new Span<SKRotationScaleMatrix> (runbuffer.pos, count);
}

public SKRotationScaleRunBuffer AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null)
{
if (font == null)
Expand All @@ -509,5 +618,20 @@ public SKRotationScaleRunBuffer AllocateRotationScaleTextRun (SKFont font, int c

return new SKRotationScaleRunBuffer (runbuffer, count);
}

public void AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds, out Span<ushort> glyphSpan, out Span<SKRotationScaleMatrix> rotationScaleSpan)
{
if (font == null)
throw new ArgumentNullException (nameof (font));

SKRunBufferInternal runbuffer;
if (bounds is SKRect b)
SkiaApi.sk_textblob_builder_alloc_run_text_rsxform (Handle, font.Handle, count, textByteCount, &b, &runbuffer);
else
SkiaApi.sk_textblob_builder_alloc_run_text_rsxform (Handle, font.Handle, count, textByteCount, null, &runbuffer);

glyphSpan = new Span<ushort> (runbuffer.glyphs, runbuffer.glyphs == null ? 0 : count);
rotationScaleSpan = new Span<SKRotationScaleMatrix> (runbuffer.pos, count);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,9 @@ public static void DrawShapedText(this SKCanvas canvas, SKShaper shaper, string

// create the text blob
using var builder = new SKTextBlobBuilder();
var run = builder.AllocatePositionedRun(font, result.Codepoints.Length);
builder.AllocatePositionedRun(font, result.Codepoints.Length, bounds: null, out var p, out var g);

// copy the glyphs
var g = run.GetGlyphSpan();
var p = run.GetPositionSpan();
for (var i = 0; i < result.Codepoints.Length; i++)
{
g[i] = (ushort)result.Codepoints[i];
Expand Down