From d71e530751ccd6d80d5ef7c746c6f10bf10dc569 Mon Sep 17 00:00:00 2001 From: Phill Djonov Date: Mon, 3 Jun 2024 09:36:40 -0600 Subject: [PATCH] Fix the GetKerningPairAdjustments API. (#2858) Co-authored-by: Matthew Leibowitz (cherry picked from commit 7c5b9efe5fbbfb72eed2a4f4e4f0df1c299fc46e) --- binding/Binding/SKTypeface.cs | 55 +++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/binding/Binding/SKTypeface.cs b/binding/Binding/SKTypeface.cs index 71c37c63ee..bce85bae59 100644 --- a/binding/Binding/SKTypeface.cs +++ b/binding/Binding/SKTypeface.cs @@ -442,14 +442,65 @@ public SKStreamAsset OpenStream (out int ttcIndex) // GetKerningPairAdjustments + /// + /// If false, then will never return nonzero + /// adjustments for any possible pair of glyphs. + /// + public bool HasGetKerningPairAdjustments => + SkiaApi.sk_typeface_get_kerning_pair_adjustments (Handle, null, 0, null); + + /// + /// Gets a kerning adjustment for each sequential pair of glyph indices in . + /// + /// The sequence of glyph indices to get kerning adjustments for. + /// + /// Adjustments are returned in design units, relative to . + /// + /// + /// For backwards-compatibility reasons, an additional zero entry is present at the end of the array. + /// public int[] GetKerningPairAdjustments (ReadOnlySpan glyphs) { var adjustments = new int[glyphs.Length]; + GetKerningPairAdjustments (glyphs, adjustments); + return adjustments; + } + + /// + /// Gets a kerning adjustment for each sequential pair of glyph indices in . + /// + /// The sequence of glyph indices to get kerning adjustments for. + /// + /// The span that will hold the output adjustments, one per adjacent pari of . + /// Adjustments are returned in design units, relative to . + /// This must contain a minimum of glyphs.Length - 1 elements. + /// + /// + /// True if any kerning pair adjustments were written to . + /// False if the typeface does not contain adjustments for any of the given pairs of glyphs. + /// + /// + /// If this function returns false, then the first .Length - 1 elements of will be zero. + /// Elements of beyond .Length - 1 will not be modified. + /// + public bool GetKerningPairAdjustments (ReadOnlySpan glyphs, Span adjustments) + { + if (adjustments.Length < glyphs.Length - 1) + throw new ArgumentException ("Length of adjustments must be large enough to hold one adjustment per pair of glyphs (or, glyphs.Length - 1)."); + + bool res; fixed (ushort* gp = glyphs) fixed (int* ap = adjustments) { - SkiaApi.sk_typeface_get_kerning_pair_adjustments (Handle, gp, glyphs.Length, ap); + res = SkiaApi.sk_typeface_get_kerning_pair_adjustments (Handle, gp, glyphs.Length, ap); } - return adjustments; + + if (!res && glyphs.Length > 1) + //Per SkTypeface::GetKerningPairAdjustments documentation, the method may have written + //nonsense into the array before bailing. Don't return it to the caller, the doc says + //such values must be ignored. + adjustments.Slice(0, glyphs.Length - 1).Clear (); + + return res; } //