public ShapedBuffer ShapeText(ReadOnlySlice <char> text, TextShaperOptions options) { var typeface = options.Typeface; var fontRenderingEmSize = options.FontRenderingEmSize; var bidiLevel = options.BidLevel; var culture = options.Culture; using (var buffer = new Buffer()) { buffer.AddUtf16(text.Buffer.Span, text.Start, text.Length); MergeBreakPair(buffer); buffer.GuessSegmentProperties(); buffer.Direction = (bidiLevel & 1) == 0 ? Direction.LeftToRight : Direction.RightToLeft; buffer.Language = new Language(culture ?? CultureInfo.CurrentCulture); var font = ((HarfBuzzGlyphTypefaceImpl)typeface.PlatformImpl).Font; font.Shape(buffer); if (buffer.Direction == Direction.RightToLeft) { buffer.Reverse(); } font.GetScale(out var scaleX, out _); var textScale = fontRenderingEmSize / scaleX; var bufferLength = buffer.Length; var shapedBuffer = new ShapedBuffer(text, bufferLength, typeface, fontRenderingEmSize, bidiLevel); var glyphInfos = buffer.GetGlyphInfoSpan(); var glyphPositions = buffer.GetGlyphPositionSpan(); for (var i = 0; i < bufferLength; i++) { var sourceInfo = glyphInfos[i]; var glyphIndex = (ushort)sourceInfo.Codepoint; var glyphCluster = (int)sourceInfo.Cluster; var glyphAdvance = GetGlyphAdvance(glyphPositions, i, textScale); var glyphOffset = GetGlyphOffset(glyphPositions, i, textScale); var targetInfo = new Media.TextFormatting.GlyphInfo(glyphIndex, glyphCluster, glyphAdvance, glyphOffset); shapedBuffer[i] = targetInfo; } return(shapedBuffer); } }
public void ShouldReverse() { using (var buffer = new Buffer()) { buffer.AddUtf8("12"); buffer.Reverse(); Assert.Equal(50u, buffer.GlyphInfos[0].Codepoint); Assert.Equal(1u, buffer.GlyphInfos[0].Cluster); Assert.Equal(49u, buffer.GlyphInfos[1].Codepoint); Assert.Equal(0u, buffer.GlyphInfos[1].Cluster); } }