From 05954022d9788fccd06d852658e43294aa71d333 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sat, 2 Mar 2024 02:03:43 +0200 Subject: [PATCH 1/4] Clean up SKTextBlobBuilder and SKRunBuffer APIs --- binding/SkiaSharp/SKRunBuffer.cs | 113 ++++++----- binding/SkiaSharp/SKTextBlob.cs | 190 +++++++++++------- .../SkiaSharp.HarfBuzz/CanvasExtensions.cs | 6 +- tests/Tests/SkiaSharp/SKTextBlobTest.cs | 51 ++++- 4 files changed, 231 insertions(+), 129 deletions(-) diff --git a/binding/SkiaSharp/SKRunBuffer.cs b/binding/SkiaSharp/SKRunBuffer.cs index 8f4916104e..44bb79c9bd 100644 --- a/binding/SkiaSharp/SKRunBuffer.cs +++ b/binding/SkiaSharp/SKRunBuffer.cs @@ -1,10 +1,11 @@ #nullable disable using System; -using System.ComponentModel; namespace SkiaSharp { + // Base + public unsafe class SKRunBuffer { internal readonly SKRunBufferInternal internalBuffer; @@ -17,103 +18,125 @@ internal SKRunBuffer (SKRunBufferInternal buffer, int size) public int Size { get; } - public Span GetGlyphSpan () => - new Span (internalBuffer.glyphs, internalBuffer.glyphs == null ? 0 : Size); + public Span Glyphs => new (internalBuffer.glyphs, Size); - public void SetGlyphs (ReadOnlySpan glyphs) => - glyphs.CopyTo (GetGlyphSpan ()); + public void SetGlyphs (ReadOnlySpan glyphs) => glyphs.CopyTo (Glyphs); } public sealed unsafe class SKHorizontalRunBuffer : SKRunBuffer { - internal SKHorizontalRunBuffer (SKRunBufferInternal buffer, int count) - : base (buffer, count) + internal SKHorizontalRunBuffer (SKRunBufferInternal buffer, int size) + : base (buffer, size) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); } public sealed unsafe class SKPositionedRunBuffer : SKRunBuffer { - internal SKPositionedRunBuffer (SKRunBufferInternal buffer, int count) - : base (buffer, count) + internal SKPositionedRunBuffer (SKRunBufferInternal buffer, int size) + : base (buffer, size) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); } public sealed unsafe class SKRotationScaleRunBuffer : SKRunBuffer { - internal SKRotationScaleRunBuffer (SKRunBufferInternal buffer, int count) - : base (buffer, count) + internal SKRotationScaleRunBuffer (SKRunBufferInternal buffer, int size) + : base (buffer, size) { } - public Span GetRotationScaleSpan () => - new Span (internalBuffer.pos, Size); + public Span Positions => new (internalBuffer.pos, Size); - public void SetRotationScale (ReadOnlySpan positions) => - positions.CopyTo (GetRotationScaleSpan ()); + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); } + // Text + public unsafe class SKTextRunBuffer : SKRunBuffer { - internal SKTextRunBuffer (SKRunBufferInternal buffer, int count, int textSize) - : base (buffer, count) + internal SKTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size) { TextSize = textSize; } public int TextSize { get; } - public Span GetTextSpan () => - new Span (internalBuffer.utf8text, internalBuffer.utf8text == null ? 0 : TextSize); + public Span Text => new (internalBuffer.utf8text, TextSize); - public Span GetClusterSpan () => - new Span (internalBuffer.clusters, internalBuffer.clusters == null ? 0 : Size); + public Span Clusters => new (internalBuffer.clusters, Size); - public void SetText (ReadOnlySpan text) => - text.CopyTo (GetTextSpan ()); + public void SetText (ReadOnlySpan text) => text.CopyTo (Text); - public void SetClusters (ReadOnlySpan clusters) => - clusters.CopyTo (GetClusterSpan ()); + public void SetClusters (ReadOnlySpan clusters) => clusters.CopyTo (Clusters); } public sealed unsafe class SKHorizontalTextRunBuffer : SKTextRunBuffer { - internal SKHorizontalTextRunBuffer (SKRunBufferInternal buffer, int count, int textSize) - : base (buffer, count, textSize) + internal SKHorizontalTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size, textSize) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); } public sealed unsafe class SKPositionedTextRunBuffer : SKTextRunBuffer { - internal SKPositionedTextRunBuffer (SKRunBufferInternal buffer, int count, int textSize) - : base (buffer, count, textSize) + internal SKPositionedTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size, textSize) + { + } + + public Span Positions => new (internalBuffer.pos, Size); + + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + } + + public sealed unsafe class SKRotationScaleTextRunBuffer : SKTextRunBuffer + { + internal SKRotationScaleTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size, textSize) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); + + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + } + + public unsafe readonly struct SKRunBuffer + { + internal readonly SKRunBufferInternal buffer; + private readonly int size; + private readonly int posSize; + private readonly int textSize; + + internal SKRunBuffer (SKRunBufferInternal buffer, int size, int posSize, int textSize) + { + this.buffer = buffer; + this.size = size; + this.posSize = posSize; + this.textSize = textSize; + } + + public Span Glyphs => new (buffer.glyphs, size); + + public Span Positions => new (buffer.pos, posSize); + + public Span Text => new (buffer.utf8text, textSize); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + public Span Clusters => new (buffer.clusters, size); } } diff --git a/binding/SkiaSharp/SKTextBlob.cs b/binding/SkiaSharp/SKTextBlob.cs index 704b3e95b8..7ae972ba54 100644 --- a/binding/SkiaSharp/SKTextBlob.cs +++ b/binding/SkiaSharp/SKTextBlob.cs @@ -1,7 +1,4 @@ -#nullable disable - -using System; -using System.ComponentModel; +using System; namespace SkiaSharp { @@ -31,27 +28,27 @@ public SKRect Bounds { // Create - public static SKTextBlob Create (string text, SKFont font, SKPoint origin = default) => + public static SKTextBlob? Create (string text, SKFont font, SKPoint origin = default) => Create (text.AsSpan (), font, origin); - public static SKTextBlob Create (ReadOnlySpan text, SKFont font, SKPoint origin = default) + public static SKTextBlob? Create (ReadOnlySpan text, SKFont font, SKPoint origin = default) { fixed (void* t = text) { return Create (t, text.Length * 2, SKTextEncoding.Utf16, font, origin); } } - public static SKTextBlob Create (IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin = default) => + 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 Create (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPoint origin = default) + public static SKTextBlob? Create (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPoint origin = default) { fixed (void* t = text) { return Create (t, text.Length, encoding, font, origin); } } - internal static SKTextBlob Create (void* text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin) + internal static SKTextBlob? Create (void* text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -61,35 +58,35 @@ 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, null, out var buffer); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + font.GetGlyphPositions (buffer.Glyphs, buffer.Positions, origin); return builder.Build (); } // CreateHorizontal - public static SKTextBlob CreateHorizontal (string text, SKFont font, ReadOnlySpan positions, float y) => + public static SKTextBlob? CreateHorizontal (string text, SKFont font, ReadOnlySpan positions, float y) => CreateHorizontal (text.AsSpan (), font, positions, y); - public static SKTextBlob CreateHorizontal (ReadOnlySpan text, SKFont font, ReadOnlySpan positions, float y) + public static SKTextBlob? CreateHorizontal (ReadOnlySpan text, SKFont font, ReadOnlySpan positions, float y) { fixed (void* t = text) { return CreateHorizontal (t, text.Length * 2, SKTextEncoding.Utf16, font, positions, y); } } - public static SKTextBlob CreateHorizontal (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) => + public static SKTextBlob? CreateHorizontal (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) => CreateHorizontal (text.AsReadOnlySpan (length), encoding, font, positions, y); - public static SKTextBlob CreateHorizontal (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) + public static SKTextBlob? CreateHorizontal (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) { fixed (void* t = text) { return CreateHorizontal (t, text.Length, encoding, font, positions, y); } } - internal static SKTextBlob CreateHorizontal (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) + internal static SKTextBlob? CreateHorizontal (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -99,35 +96,35 @@ 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, null, out var buffer); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + positions.CopyTo (buffer.Positions); return builder.Build (); } // CreatePositioned - public static SKTextBlob CreatePositioned (string text, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreatePositioned (string text, SKFont font, ReadOnlySpan positions) => CreatePositioned (text.AsSpan (), font, positions); - public static SKTextBlob CreatePositioned (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreatePositioned (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreatePositioned (t, text.Length * 2, SKTextEncoding.Utf16, font, positions); } } - public static SKTextBlob CreatePositioned (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreatePositioned (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => CreatePositioned (text.AsReadOnlySpan (length), encoding, font, positions); - public static SKTextBlob CreatePositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreatePositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreatePositioned (t, text.Length, encoding, font, positions); } } - internal static SKTextBlob CreatePositioned (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + internal static SKTextBlob? CreatePositioned (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -137,35 +134,35 @@ 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, null, out var buffer); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + positions.CopyTo (buffer.Positions); return builder.Build (); } // CreateRotationScale - public static SKTextBlob CreateRotationScale (string text, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreateRotationScale (string text, SKFont font, ReadOnlySpan positions) => CreateRotationScale (text.AsSpan (), font, positions); - public static SKTextBlob CreateRotationScale (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreateRotationScale (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreateRotationScale (t, text.Length * 2, SKTextEncoding.Utf16, font, positions); } } - public static SKTextBlob CreateRotationScale (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreateRotationScale (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => CreateRotationScale (text.AsReadOnlySpan (length), encoding, font, positions); - public static SKTextBlob CreateRotationScale (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreateRotationScale (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreateRotationScale (t, text.Length, encoding, font, positions); } } - internal static SKTextBlob CreateRotationScale (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + internal static SKTextBlob? CreateRotationScale (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -176,34 +173,34 @@ internal static SKTextBlob CreateRotationScale (void* text, int length, SKTextEn using var builder = new SKTextBlobBuilder (); var buffer = builder.AllocateRotationScaleRun (font, count); - font.GetGlyphs (text, length, encoding, buffer.GetGlyphSpan ()); - positions.CopyTo (buffer.GetRotationScaleSpan ()); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + positions.CopyTo (buffer.Positions); return builder.Build (); } // CreatePathPositioned - public static SKTextBlob CreatePathPositioned (string text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => + public static SKTextBlob? CreatePathPositioned (string text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => CreatePathPositioned (text.AsSpan (), font, path, textAlign, origin); - public static SKTextBlob CreatePathPositioned (ReadOnlySpan text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) + public static SKTextBlob? CreatePathPositioned (ReadOnlySpan 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); } } - public static SKTextBlob CreatePathPositioned (IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => + 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 static SKTextBlob CreatePathPositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) + public static SKTextBlob? CreatePathPositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) { fixed (void* t = text) { return CreatePathPositioned (t, text.Length, encoding, font, path, textAlign, origin); } } - internal static SKTextBlob CreatePathPositioned (void* text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) + 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)); @@ -228,7 +225,7 @@ internal static SKTextBlob CreatePathPositioned (void* text, int length, SKTextE // GetIntercepts - public float[] GetIntercepts (float upperBounds, float lowerBounds, SKPaint paint = null) + public float[] GetIntercepts (float upperBounds, float lowerBounds, SKPaint? paint = null) { var n = CountIntercepts (upperBounds, lowerBounds, paint); var intervals = new float[n]; @@ -236,7 +233,7 @@ public float[] GetIntercepts (float upperBounds, float lowerBounds, SKPaint pain return intervals; } - public void GetIntercepts (float upperBounds, float lowerBounds, Span intervals, SKPaint paint = null) + public void GetIntercepts (float upperBounds, float lowerBounds, Span intervals, SKPaint? paint = null) { var bounds = stackalloc float[2]; bounds[0] = upperBounds; @@ -248,7 +245,7 @@ public void GetIntercepts (float upperBounds, float lowerBounds, Span int // CountIntercepts - public int CountIntercepts (float upperBounds, float lowerBounds, SKPaint paint = null) + public int CountIntercepts (float upperBounds, float lowerBounds, SKPaint? paint = null) { var bounds = stackalloc float[2]; bounds[0] = upperBounds; @@ -258,7 +255,7 @@ public int CountIntercepts (float upperBounds, float lowerBounds, SKPaint paint // - internal static SKTextBlob GetObject (IntPtr handle) => + internal static SKTextBlob? GetObject (IntPtr handle) => handle == IntPtr.Zero ? null : new SKTextBlob (handle, true); } @@ -282,7 +279,7 @@ protected override void DisposeNative () => // Build - public SKTextBlob Build () + public SKTextBlob? Build () { var blob = SKTextBlob.GetObject (SkiaApi.sk_textblob_builder_make (Handle)); GC.KeepAlive (this); @@ -293,48 +290,36 @@ public SKTextBlob Build () public void AddRun (ReadOnlySpan 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); + AllocatePositionedRun (font, glyphs.Length, null, out var buffer); + glyphs.CopyTo (buffer.Glyphs); + font.GetGlyphPositions (buffer.Glyphs, buffer.Positions, origin); } // AddHorizontalRun public void AddHorizontalRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan 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 ()); + AllocateHorizontalRun (font, glyphs.Length, y, null, out var buffer); + glyphs.CopyTo (buffer.Glyphs); + positions.CopyTo (buffer.Positions); } // AddPositionedRun public void AddPositionedRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { - 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, null, out var buffer); + glyphs.CopyTo (buffer.Glyphs); + positions.CopyTo (buffer.Positions); } // AddRotationScaleRun public void AddRotationScaleRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { - 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, null, out var buffer); + glyphs.CopyTo (buffer.Glyphs); + positions.CopyTo (buffer.Positions); } // AddPathPositionedRun @@ -393,6 +378,12 @@ public void AddPathPositionedRun (ReadOnlySpan glyphs, SKFont font, Read // AllocateRun public SKRunBuffer AllocateRun (SKFont font, int count, float x, float y, SKRect? bounds = null) + { + AllocateRun (font, count, x, y, bounds, out var buffer); + return new SKRunBuffer (buffer.buffer, count); + } + + public void AllocateRun (SKFont font, int count, float x, float y, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -403,10 +394,16 @@ public SKRunBuffer AllocateRun (SKFont font, int count, float x, float y, SKRect else SkiaApi.sk_textblob_builder_alloc_run (Handle, font.Handle, count, x, y, null, &runbuffer); - return new SKRunBuffer (runbuffer, count); + buffer = new SKRunBuffer (runbuffer, count, 0, 0); } public SKTextRunBuffer AllocateTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds = null) + { + AllocateTextRun (font, count, x, y, textByteCount, bounds, out var buffer); + return new SKTextRunBuffer (buffer.buffer, count, textByteCount); + } + + public void AllocateTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -417,12 +414,18 @@ public SKTextRunBuffer AllocateTextRun (SKFont font, int count, float x, float y else SkiaApi.sk_textblob_builder_alloc_run_text (Handle, font.Handle, count, x, y, textByteCount, null, &runbuffer); - return new SKTextRunBuffer (runbuffer, count, textByteCount); + buffer = new SKRunBuffer (runbuffer, count, 0, textByteCount); } // AllocateHorizontalRun public SKHorizontalRunBuffer AllocateHorizontalRun (SKFont font, int count, float y, SKRect? bounds = null) + { + AllocateHorizontalRun (font, count, y, bounds, out var buffer); + return new SKHorizontalRunBuffer (buffer.buffer, count); + } + + public void AllocateHorizontalRun (SKFont font, int count, float y, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -433,10 +436,16 @@ public SKHorizontalRunBuffer AllocateHorizontalRun (SKFont font, int count, floa else SkiaApi.sk_textblob_builder_alloc_run_pos_h (Handle, font.Handle, count, y, null, &runbuffer); - return new SKHorizontalRunBuffer (runbuffer, count); + buffer = new SKRunBuffer (runbuffer, count, count, 0); } public SKHorizontalTextRunBuffer AllocateHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds = null) + { + AllocateHorizontalTextRun (font, count, y, textByteCount, bounds, out var buffer); + return new SKHorizontalTextRunBuffer (buffer.buffer, count, textByteCount); + } + + public void AllocateHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -447,12 +456,19 @@ public SKHorizontalTextRunBuffer AllocateHorizontalTextRun (SKFont font, int cou else SkiaApi.sk_textblob_builder_alloc_run_text_pos_h (Handle, font.Handle, count, y, textByteCount, null, &runbuffer); - return new SKHorizontalTextRunBuffer (runbuffer, count, textByteCount); + buffer = new SKRunBuffer (runbuffer, count, count, textByteCount); + } // AllocatePositionedRun public SKPositionedRunBuffer AllocatePositionedRun (SKFont font, int count, SKRect? bounds = null) + { + AllocatePositionedRun (font, count, bounds, out var buffer); + return new SKPositionedRunBuffer (buffer.buffer, count); + } + + public void AllocatePositionedRun (SKFont font, int count, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -463,10 +479,16 @@ public SKPositionedRunBuffer AllocatePositionedRun (SKFont font, int count, SKRe else SkiaApi.sk_textblob_builder_alloc_run_pos (Handle, font.Handle, count, null, &runbuffer); - return new SKPositionedRunBuffer (runbuffer, count); + buffer = new SKRunBuffer (runbuffer, count, count, 0); } public SKPositionedTextRunBuffer AllocatePositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) + { + AllocatePositionedTextRun (font, count, textByteCount, bounds, out var buffer); + return new SKPositionedTextRunBuffer (buffer.buffer, count, textByteCount); + } + + public void AllocatePositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -477,12 +499,18 @@ public SKPositionedTextRunBuffer AllocatePositionedTextRun (SKFont font, int cou else SkiaApi.sk_textblob_builder_alloc_run_text_pos (Handle, font.Handle, count, textByteCount, null, &runbuffer); - return new SKPositionedTextRunBuffer (runbuffer, count, textByteCount); + buffer = new SKRunBuffer (runbuffer, count, count, textByteCount); } // AllocateRotationScaleRun public SKRotationScaleRunBuffer AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds = null) + { + AllocateRotationScaleRun (font, count, bounds, out var buffer); + return new SKRotationScaleRunBuffer (buffer.buffer, count); + } + + public void AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -493,10 +521,16 @@ public SKRotationScaleRunBuffer AllocateRotationScaleRun (SKFont font, int count else SkiaApi.sk_textblob_builder_alloc_run_rsxform (Handle, font.Handle, count, null, &runbuffer); - return new SKRotationScaleRunBuffer (runbuffer, count); + buffer = new SKRunBuffer (runbuffer, count, count, 0); + } + + public SKRotationScaleTextRunBuffer AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) + { + AllocateRotationScaleTextRun (font, count, textByteCount, bounds, out var buffer); + return new SKRotationScaleTextRunBuffer (buffer.buffer, count, textByteCount); } - public SKRotationScaleRunBuffer AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) + public void AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -507,7 +541,7 @@ public SKRotationScaleRunBuffer AllocateRotationScaleTextRun (SKFont font, int c else SkiaApi.sk_textblob_builder_alloc_run_text_rsxform (Handle, font.Handle, count, textByteCount, null, &runbuffer); - return new SKRotationScaleRunBuffer (runbuffer, count); + buffer = new SKRunBuffer (runbuffer, count, count, textByteCount); } } } diff --git a/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs b/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs index d03462caf8..9b355ce313 100644 --- a/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs +++ b/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs @@ -74,11 +74,11 @@ 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, null, out var run); // copy the glyphs - var g = run.GetGlyphSpan(); - var p = run.GetPositionSpan(); + var g = run.Glyphs; + var p = run.Positions; for (var i = 0; i < result.Codepoints.Length; i++) { g[i] = (ushort)result.Codepoints[i]; diff --git a/tests/Tests/SkiaSharp/SKTextBlobTest.cs b/tests/Tests/SkiaSharp/SKTextBlobTest.cs index 32cb3e35cd..c834d3dc55 100644 --- a/tests/Tests/SkiaSharp/SKTextBlobTest.cs +++ b/tests/Tests/SkiaSharp/SKTextBlobTest.cs @@ -16,6 +16,36 @@ public void TestEmptyBuilderReturnsNull() Assert.Null(blob); } + [SkippableFact] + public void RunsAllocateNoPositions() + { + var font = new SKFont(); + + using var builder = new SKTextBlobBuilder(); + + var run = builder.AllocateRun(font, 100, 0, 0); + Assert.Equal(100, run.Glyphs.Length); + + using var blob = builder.Build(); + Assert.NotNull(blob); + } + + [SkippableFact] + public void RawRunsAllocateNoPositions() + { + var font = new SKFont(); + + using var builder = new SKTextBlobBuilder(); + + builder.AllocateRun(font, 100, 0, 0, null, out var run); + Assert.Equal(100, run.Glyphs.Length); + Assert.Equal(0, run.Positions.Length); + Assert.Equal(0, run.Text.Length); + + using var blob = builder.Build(); + Assert.NotNull(blob); + } + [SkippableFact] public void TextRunsAllocateTextSpan() { @@ -24,8 +54,23 @@ public void TextRunsAllocateTextSpan() using var builder = new SKTextBlobBuilder(); var run = builder.AllocateTextRun(font, 100, 0, 0, 50); - Assert.Equal(100, run.GetGlyphSpan().Length); - Assert.Equal(50, run.GetTextSpan().Length); + Assert.Equal(100, run.Glyphs.Length); + Assert.Equal(50, run.Text.Length); + + using var blob = builder.Build(); + Assert.NotNull(blob); + } + + [SkippableFact] + public void RawTextRunsAllocateTextSpan() + { + var font = new SKFont(); + + using var builder = new SKTextBlobBuilder(); + + builder.AllocateTextRun(font, 100, 0, 0, 50, null, out var run); + Assert.Equal(100, run.Glyphs.Length); + Assert.Equal(50, run.Text.Length); using var blob = builder.Build(); Assert.NotNull(blob); @@ -112,7 +157,7 @@ public unsafe void TestPositionedRunIsBothPointsAndFloats() run.SetPositions(positions); - var span = run.GetPositionSpan(); + var span = run.Positions; Assert.Equal(positions, span.ToArray()); var floats = new float[6]; From 81ac45beb04a850e4e906625ca18af0b6eb2318e Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sat, 2 Mar 2024 02:18:01 +0200 Subject: [PATCH 2/4] No need to break everyone. --- binding/SkiaSharp/SKRunBuffer.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/binding/SkiaSharp/SKRunBuffer.cs b/binding/SkiaSharp/SKRunBuffer.cs index 44bb79c9bd..03459c5f93 100644 --- a/binding/SkiaSharp/SKRunBuffer.cs +++ b/binding/SkiaSharp/SKRunBuffer.cs @@ -21,6 +21,9 @@ internal SKRunBuffer (SKRunBufferInternal buffer, int size) public Span Glyphs => new (internalBuffer.glyphs, Size); public void SetGlyphs (ReadOnlySpan glyphs) => glyphs.CopyTo (Glyphs); + + [Obsolete ("Use Glyphs instead.")] + public Span GetGlyphSpan () => Glyphs; } public sealed unsafe class SKHorizontalRunBuffer : SKRunBuffer @@ -33,6 +36,9 @@ internal SKHorizontalRunBuffer (SKRunBufferInternal buffer, int size) public Span Positions => new (internalBuffer.pos, Size); public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + + [Obsolete ("Use Positions instead.")] + public Span GetPositionSpan () => Positions; } public sealed unsafe class SKPositionedRunBuffer : SKRunBuffer @@ -45,6 +51,9 @@ internal SKPositionedRunBuffer (SKRunBufferInternal buffer, int size) public Span Positions => new (internalBuffer.pos, Size); public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + + [Obsolete ("Use Positions instead.")] + public Span GetPositionSpan () => Positions; } public sealed unsafe class SKRotationScaleRunBuffer : SKRunBuffer @@ -57,6 +66,12 @@ internal SKRotationScaleRunBuffer (SKRunBufferInternal buffer, int size) public Span Positions => new (internalBuffer.pos, Size); public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + + [Obsolete ("Use Positions instead.")] + public Span GetRotationScaleSpan () => Positions; + + [Obsolete ("Use SetPositions instead.")] + public void SetRotationScale (ReadOnlySpan positions) => SetPositions (positions); } // Text From d338509859685111253963e112967f2a30e681ba Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sat, 2 Mar 2024 02:22:15 +0200 Subject: [PATCH 3/4] comment --- binding/SkiaSharp/SKRunBuffer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/binding/SkiaSharp/SKRunBuffer.cs b/binding/SkiaSharp/SKRunBuffer.cs index 03459c5f93..5980f75182 100644 --- a/binding/SkiaSharp/SKRunBuffer.cs +++ b/binding/SkiaSharp/SKRunBuffer.cs @@ -131,6 +131,8 @@ internal SKRotationScaleTextRunBuffer (SKRunBufferInternal buffer, int size, int public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); } + // Raw / Struct + public unsafe readonly struct SKRunBuffer { internal readonly SKRunBufferInternal buffer; From fc8ad1cdf6eae81b06075a7e01004fa60158ee9e Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sat, 2 Mar 2024 02:55:38 +0200 Subject: [PATCH 4/4] Not sure if this is better --- binding/SkiaSharp/SKRunBuffer.cs | 4 +- binding/SkiaSharp/SKTextBlob.cs | 68 ++++++++++--------- .../SkiaSharp.HarfBuzz/CanvasExtensions.cs | 2 +- tests/Tests/SkiaSharp/SKTextBlobTest.cs | 4 +- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/binding/SkiaSharp/SKRunBuffer.cs b/binding/SkiaSharp/SKRunBuffer.cs index 5980f75182..65831136ef 100644 --- a/binding/SkiaSharp/SKRunBuffer.cs +++ b/binding/SkiaSharp/SKRunBuffer.cs @@ -133,14 +133,14 @@ internal SKRotationScaleTextRunBuffer (SKRunBufferInternal buffer, int size, int // Raw / Struct - public unsafe readonly struct SKRunBuffer + public unsafe readonly struct SKRawRunBuffer { internal readonly SKRunBufferInternal buffer; private readonly int size; private readonly int posSize; private readonly int textSize; - internal SKRunBuffer (SKRunBufferInternal buffer, int size, int posSize, int textSize) + internal SKRawRunBuffer (SKRunBufferInternal buffer, int size, int posSize, int textSize) { this.buffer = buffer; this.size = size; diff --git a/binding/SkiaSharp/SKTextBlob.cs b/binding/SkiaSharp/SKTextBlob.cs index 7ae972ba54..10193d25a0 100644 --- a/binding/SkiaSharp/SKTextBlob.cs +++ b/binding/SkiaSharp/SKTextBlob.cs @@ -58,7 +58,7 @@ public SKRect Bounds { return null; using var builder = new SKTextBlobBuilder (); - builder.AllocatePositionedRun (font, count, null, out var buffer); + var buffer = builder.AllocateRawPositionedRun (font, count); font.GetGlyphs (text, length, encoding, buffer.Glyphs); font.GetGlyphPositions (buffer.Glyphs, buffer.Positions, origin); return builder.Build (); @@ -96,7 +96,7 @@ public SKRect Bounds { return null; using var builder = new SKTextBlobBuilder (); - builder.AllocateHorizontalRun (font, count, y, null, out var buffer); + var buffer = builder.AllocateRawHorizontalRun (font, count, y); font.GetGlyphs (text, length, encoding, buffer.Glyphs); positions.CopyTo (buffer.Positions); return builder.Build (); @@ -134,7 +134,7 @@ public SKRect Bounds { return null; using var builder = new SKTextBlobBuilder (); - builder.AllocatePositionedRun (font, count, null, out var buffer); + var buffer = builder.AllocateRawPositionedRun (font, count); font.GetGlyphs (text, length, encoding, buffer.Glyphs); positions.CopyTo (buffer.Positions); return builder.Build (); @@ -290,7 +290,7 @@ protected override void DisposeNative () => public void AddRun (ReadOnlySpan glyphs, SKFont font, SKPoint origin = default) { - AllocatePositionedRun (font, glyphs.Length, null, out var buffer); + var buffer = AllocateRawPositionedRun (font, glyphs.Length); glyphs.CopyTo (buffer.Glyphs); font.GetGlyphPositions (buffer.Glyphs, buffer.Positions, origin); } @@ -299,7 +299,7 @@ public void AddRun (ReadOnlySpan glyphs, SKFont font, SKPoint origin = d public void AddHorizontalRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions, float y) { - AllocateHorizontalRun (font, glyphs.Length, y, null, out var buffer); + var buffer = AllocateRawHorizontalRun (font, glyphs.Length, y); glyphs.CopyTo (buffer.Glyphs); positions.CopyTo (buffer.Positions); } @@ -308,7 +308,7 @@ public void AddHorizontalRun (ReadOnlySpan glyphs, SKFont font, ReadOnly public void AddPositionedRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { - AllocatePositionedRun (font, glyphs.Length, null, out var buffer); + var buffer = AllocateRawPositionedRun (font, glyphs.Length); glyphs.CopyTo (buffer.Glyphs); positions.CopyTo (buffer.Positions); } @@ -317,7 +317,7 @@ public void AddPositionedRun (ReadOnlySpan glyphs, SKFont font, ReadOnly public void AddRotationScaleRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { - AllocateRotationScaleRun (font, glyphs.Length, null, out var buffer); + var buffer = AllocateRawRotationScaleRun (font, glyphs.Length); glyphs.CopyTo (buffer.Glyphs); positions.CopyTo (buffer.Positions); } @@ -375,15 +375,17 @@ public void AddPathPositionedRun (ReadOnlySpan glyphs, SKFont font, Read AddRotationScaleRun (glyphSubset, font, positions); } - // AllocateRun + // Allocate* + + // Allocate*Run public SKRunBuffer AllocateRun (SKFont font, int count, float x, float y, SKRect? bounds = null) { - AllocateRun (font, count, x, y, bounds, out var buffer); + var buffer = AllocateRawRun (font, count, x, y, bounds); return new SKRunBuffer (buffer.buffer, count); } - public void AllocateRun (SKFont font, int count, float x, float y, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawRun (SKFont font, int count, float x, float y, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -394,16 +396,16 @@ public void AllocateRun (SKFont font, int count, float x, float y, SKRect? bound else SkiaApi.sk_textblob_builder_alloc_run (Handle, font.Handle, count, x, y, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, 0, 0); + return new SKRawRunBuffer (runbuffer, count, 0, 0); } public SKTextRunBuffer AllocateTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds = null) { - AllocateTextRun (font, count, x, y, textByteCount, bounds, out var buffer); + var buffer = AllocateRawTextRun (font, count, x, y, textByteCount, bounds); return new SKTextRunBuffer (buffer.buffer, count, textByteCount); } - public void AllocateTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -414,18 +416,18 @@ public void AllocateTextRun (SKFont font, int count, float x, float y, int textB else SkiaApi.sk_textblob_builder_alloc_run_text (Handle, font.Handle, count, x, y, textByteCount, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, 0, textByteCount); + return new SKRawRunBuffer (runbuffer, count, 0, textByteCount); } - // AllocateHorizontalRun + // Allocate*HorizontalRun public SKHorizontalRunBuffer AllocateHorizontalRun (SKFont font, int count, float y, SKRect? bounds = null) { - AllocateHorizontalRun (font, count, y, bounds, out var buffer); + var buffer = AllocateRawHorizontalRun (font, count, y, bounds); return new SKHorizontalRunBuffer (buffer.buffer, count); } - public void AllocateHorizontalRun (SKFont font, int count, float y, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawHorizontalRun (SKFont font, int count, float y, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -436,16 +438,16 @@ public void AllocateHorizontalRun (SKFont font, int count, float y, SKRect? boun else SkiaApi.sk_textblob_builder_alloc_run_pos_h (Handle, font.Handle, count, y, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, count, 0); + return new SKRawRunBuffer (runbuffer, count, count, 0); } public SKHorizontalTextRunBuffer AllocateHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds = null) { - AllocateHorizontalTextRun (font, count, y, textByteCount, bounds, out var buffer); + var buffer = AllocateRawHorizontalTextRun (font, count, y, textByteCount, bounds); return new SKHorizontalTextRunBuffer (buffer.buffer, count, textByteCount); } - public void AllocateHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -456,7 +458,7 @@ public void AllocateHorizontalTextRun (SKFont font, int count, float y, int text else SkiaApi.sk_textblob_builder_alloc_run_text_pos_h (Handle, font.Handle, count, y, textByteCount, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, count, textByteCount); + return new SKRawRunBuffer (runbuffer, count, count, textByteCount); } @@ -464,11 +466,11 @@ public void AllocateHorizontalTextRun (SKFont font, int count, float y, int text public SKPositionedRunBuffer AllocatePositionedRun (SKFont font, int count, SKRect? bounds = null) { - AllocatePositionedRun (font, count, bounds, out var buffer); + var buffer = AllocateRawPositionedRun (font, count, bounds); return new SKPositionedRunBuffer (buffer.buffer, count); } - public void AllocatePositionedRun (SKFont font, int count, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawPositionedRun (SKFont font, int count, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -479,16 +481,16 @@ public void AllocatePositionedRun (SKFont font, int count, SKRect? bounds, out S else SkiaApi.sk_textblob_builder_alloc_run_pos (Handle, font.Handle, count, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, count, 0); + return new SKRawRunBuffer (runbuffer, count, count, 0); } public SKPositionedTextRunBuffer AllocatePositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) { - AllocatePositionedTextRun (font, count, textByteCount, bounds, out var buffer); + var buffer = AllocateRawPositionedTextRun (font, count, textByteCount, bounds); return new SKPositionedTextRunBuffer (buffer.buffer, count, textByteCount); } - public void AllocatePositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawPositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -499,18 +501,18 @@ public void AllocatePositionedTextRun (SKFont font, int count, int textByteCount else SkiaApi.sk_textblob_builder_alloc_run_text_pos (Handle, font.Handle, count, textByteCount, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, count, textByteCount); + return new SKRawRunBuffer (runbuffer, count, count, textByteCount); } // AllocateRotationScaleRun public SKRotationScaleRunBuffer AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds = null) { - AllocateRotationScaleRun (font, count, bounds, out var buffer); + var buffer = AllocateRawRotationScaleRun (font, count, bounds); return new SKRotationScaleRunBuffer (buffer.buffer, count); } - public void AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawRotationScaleRun (SKFont font, int count, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -521,16 +523,16 @@ public void AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds, ou else SkiaApi.sk_textblob_builder_alloc_run_rsxform (Handle, font.Handle, count, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, count, 0); + return new SKRawRunBuffer (runbuffer, count, count, 0); } public SKRotationScaleTextRunBuffer AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) { - AllocateRotationScaleTextRun (font, count, textByteCount, bounds, out var buffer); + var buffer = AllocateRawRotationScaleTextRun (font, count, textByteCount, bounds); return new SKRotationScaleTextRunBuffer (buffer.buffer, count, textByteCount); } - public void AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds, out SKRunBuffer buffer) + public SKRawRunBuffer AllocateRawRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -541,7 +543,7 @@ public void AllocateRotationScaleTextRun (SKFont font, int count, int textByteCo else SkiaApi.sk_textblob_builder_alloc_run_text_rsxform (Handle, font.Handle, count, textByteCount, null, &runbuffer); - buffer = new SKRunBuffer (runbuffer, count, count, textByteCount); + return new SKRawRunBuffer (runbuffer, count, count, textByteCount); } } } diff --git a/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs b/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs index 9b355ce313..8b39ae75d9 100644 --- a/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs +++ b/source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz/CanvasExtensions.cs @@ -74,7 +74,7 @@ public static void DrawShapedText(this SKCanvas canvas, SKShaper shaper, string // create the text blob using var builder = new SKTextBlobBuilder(); - builder.AllocatePositionedRun(font, result.Codepoints.Length, null, out var run); + var run = builder.AllocateRawPositionedRun(font, result.Codepoints.Length, null); // copy the glyphs var g = run.Glyphs; diff --git a/tests/Tests/SkiaSharp/SKTextBlobTest.cs b/tests/Tests/SkiaSharp/SKTextBlobTest.cs index c834d3dc55..58785b35c7 100644 --- a/tests/Tests/SkiaSharp/SKTextBlobTest.cs +++ b/tests/Tests/SkiaSharp/SKTextBlobTest.cs @@ -37,7 +37,7 @@ public void RawRunsAllocateNoPositions() using var builder = new SKTextBlobBuilder(); - builder.AllocateRun(font, 100, 0, 0, null, out var run); + var run = builder.AllocateRawRun(font, 100, 0, 0); Assert.Equal(100, run.Glyphs.Length); Assert.Equal(0, run.Positions.Length); Assert.Equal(0, run.Text.Length); @@ -68,7 +68,7 @@ public void RawTextRunsAllocateTextSpan() using var builder = new SKTextBlobBuilder(); - builder.AllocateTextRun(font, 100, 0, 0, 50, null, out var run); + var run = builder.AllocateRawTextRun(font, 100, 0, 0, 50); Assert.Equal(100, run.Glyphs.Length); Assert.Equal(50, run.Text.Length);