Beispiel #1
0
        // AddPathPositionedRun

        public void AddPathPositionedRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <float> glyphWidths, ReadOnlySpan <SKPoint> glyphOffsets, SKPath path, SKTextAlign textAlign = SKTextAlign.Left)
        {
            using var pathMeasure = new SKPathMeasure(path);

            var contourLength = pathMeasure.Length;

            var textLength  = glyphOffsets[glyphs.Length - 1].X + glyphWidths[glyphs.Length - 1];
            var alignment   = (int)textAlign * 0.5f;
            var startOffset = glyphOffsets[0].X + (contourLength - textLength) * alignment;

            var firstGlyphIndex = 0;
            var pathGlyphCount  = 0;

            using var glyphTransforms = Utils.RentArray <SKRotationScaleMatrix> (glyphs.Length);

            // TODO: deal with multiple contours?
            for (var index = 0; index < glyphOffsets.Length; index++)
            {
                var glyphOffset = glyphOffsets[index];
                var halfWidth   = glyphWidths[index] * 0.5f;
                var pathOffset  = startOffset + glyphOffset.X + halfWidth;

                // TODO: clip glyphs on both ends of paths
                if (pathOffset >= 0 && pathOffset < contourLength && pathMeasure.GetPositionAndTangent(pathOffset, out var position, out var tangent))
                {
                    if (pathGlyphCount == 0)
                    {
                        firstGlyphIndex = index;
                    }

                    var tx = tangent.X;
                    var ty = tangent.Y;

                    var px = position.X;
                    var py = position.Y;

                    // horizontally offset the position using the tangent vector
                    px -= tx * halfWidth;
                    py -= ty * halfWidth;

                    // vertically offset the position using the normal vector  (-ty, tx)
                    var dy = glyphOffset.Y;
                    px -= dy * ty;
                    py += dy * tx;

                    glyphTransforms.Span[pathGlyphCount++] = new SKRotationScaleMatrix(tx, ty, px, py);
                }
            }

            var glyphSubset = glyphs.Slice(firstGlyphIndex, pathGlyphCount);
            var positions   = glyphTransforms.Span.Slice(0, pathGlyphCount);

            AddRotationScaleRun(glyphSubset, font, positions);
        }
Beispiel #2
0
		public extern static bool sk_pathmeasure_get_matrix(sk_pathmeasure_t pathMeasure, float distance, out SKMatrix matrix, SKPathMeasure.MatrixFlags flags);