Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,17 @@ public static void DrawShapedText(this SKCanvas canvas, SKShaper shaper, string
// build
using var textBlob = builder.Build();

// adjust alignment
var xOffset = 0f;
if (paint.TextAlign != SKTextAlign.Left) {
var width = result.Width;
if (paint.TextAlign == SKTextAlign.Center)
width *= 0.5f;
xOffset -= width;
}

// draw the text
canvas.DrawText(textBlob, 0, 0, paint);
canvas.DrawText(textBlob, xOffset, 0, paint);
}
}
}
11 changes: 9 additions & 2 deletions source/SkiaSharp.HarfBuzz/SkiaSharp.HarfBuzz.Shared/SKShaper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public Result Shape(Buffer buffer, float xOffset, float yOffset, SKPaint paint)
var points = new SKPoint[len];
var clusters = new uint[len];
var codepoints = new uint[len];
var xOffsetStart = xOffset;

for (var i = 0; i < len; i++)
{
Expand All @@ -86,7 +87,9 @@ public Result Shape(Buffer buffer, float xOffset, float yOffset, SKPaint paint)
yOffset += pos[i].YAdvance * textSizeY;
}

return new Result(codepoints, clusters, points);
var width = xOffset - xOffsetStart;

return new Result(codepoints, clusters, points, width);
}

public Result Shape(string text, SKPaint paint) =>
Expand Down Expand Up @@ -129,20 +132,24 @@ public Result()
Codepoints = new uint[0];
Clusters = new uint[0];
Points = new SKPoint[0];
Width = 0f;
}

public Result(uint[] codepoints, uint[] clusters, SKPoint[] points)
public Result(uint[] codepoints, uint[] clusters, SKPoint[] points, float width)
Comment thread
mattleibow marked this conversation as resolved.
{
Codepoints = codepoints;
Clusters = clusters;
Points = points;
Width = width;
}

public uint[] Codepoints { get; private set; }

public uint[] Clusters { get; private set; }

public SKPoint[] Points { get; private set; }

public float Width { get; private set; }
}
}
}
47 changes: 47 additions & 0 deletions tests/Tests/SKShaperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,52 @@ Blob GetFaceBlob(Face face, Tag tag)
return new Blob(data, size, MemoryMode.Writeable, () => Marshal.FreeCoTaskMem(data));
}
}

[SkippableTheory]
[InlineData(SKTextAlign.Left, 300)]
[InlineData(SKTextAlign.Center, 162)]
[InlineData(SKTextAlign.Right, 23)]
public void TextAlignMovesTextPosition(SKTextAlign align, int offset)
{
var font = Path.Combine(PathToFonts, "segoeui.ttf");
using var tf = SKTypeface.FromFile(font);

using var bitmap = new SKBitmap(600, 200);
using var canvas = new SKCanvas(bitmap);

canvas.Clear(SKColors.White);

using var paint = new SKPaint();
paint.Typeface = tf;
paint.IsAntialias = true;
paint.TextSize = 64;
paint.Color = SKColors.Black;
paint.TextAlign = align;

canvas.DrawShapedText("SkiaSharp", 300, 100, paint);

AssertTextAlign(bitmap, offset, 0);
}

private static void AssertTextAlign(SKBitmap bitmap, int x, int y)
{
// [S]kia[S]har[p]

Assert.Equal(SKColors.Black, bitmap.GetPixel(x + 6, y + 66));
Assert.Equal(SKColors.Black, bitmap.GetPixel(x + 28, y + 87));
Assert.Equal(SKColors.White, bitmap.GetPixel(x + 28, y + 66));
Assert.Equal(SKColors.White, bitmap.GetPixel(x + 6, y + 87));

Assert.Equal(SKColors.Black, bitmap.GetPixel(x + 120, y + 66));
Assert.Equal(SKColors.Black, bitmap.GetPixel(x + 142, y + 87));
Assert.Equal(SKColors.White, bitmap.GetPixel(x + 142, y + 66));
Assert.Equal(SKColors.White, bitmap.GetPixel(x + 120, y + 87));

Assert.Equal(SKColors.Black, bitmap.GetPixel(x + 246, y + 70));
Assert.Equal(SKColors.Black, bitmap.GetPixel(x + 246, y + 113));
Assert.Equal(SKColors.Black, bitmap.GetPixel(x + 271, y + 83));
Assert.Equal(SKColors.White, bitmap.GetPixel(x + 258, y + 83));
Assert.Equal(SKColors.White, bitmap.GetPixel(x + 258, y + 113));
}
}
}