Ejemplo n.º 1
0
 public static SKTextBlob Create(ReadOnlySpan <char> text, SKFont font, SKPoint origin = default)
 {
     fixed(void *t = text)
     {
         return(Create(t, text.Length * 2, SKTextEncoding.Utf16, font, origin));
     }
 }
Ejemplo n.º 2
0
 public static SKTextBlob CreateRotationScale(ReadOnlySpan <char> text, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions)
 {
     fixed(void *t = text)
     {
         return(CreateRotationScale(t, text.Length * 2, SKTextEncoding.Utf16, font, positions));
     }
 }
Ejemplo n.º 3
0
        public void DrawText(string text, float x, float y, SKFont font, SKPaint paint)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }
            if (paint == null)
            {
                throw new ArgumentNullException(nameof(paint));
            }

            if (paint.TextAlign != SKTextAlign.Left)
            {
                var width = font.MeasureText(text);
                if (paint.TextAlign == SKTextAlign.Center)
                {
                    width *= 0.5f;
                }
                x -= width;
            }

            using var blob = SKTextBlob.Create(text, font);
            if (blob == null)
            {
                return;
            }

            DrawText(blob, x, y, paint);
        }
Ejemplo n.º 4
0
 public static SKTextBlob CreatePositioned(ReadOnlySpan <char> text, SKFont font, ReadOnlySpan <SKPoint> positions)
 {
     fixed(void *t = text)
     {
         return(CreatePositioned(t, text.Length * 2, SKTextEncoding.Utf16, font, positions));
     }
 }
Ejemplo n.º 5
0
 public static SKTextBlob CreateHorizontal(ReadOnlySpan <char> text, SKFont font, ReadOnlySpan <float> positions, float y)
 {
     fixed(void *t = text)
     {
         return(CreateHorizontal(t, text.Length * 2, SKTextEncoding.Utf16, font, positions, y));
     }
 }
Ejemplo n.º 6
0
 public static SKTextBlob CreatePathPositioned(ReadOnlySpan <char> 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));
     }
 }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        // AddHorizontalRun

        public void AddHorizontalRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <float> 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());
        }
Ejemplo n.º 9
0
        // AddPositionedRun

        public void AddPositionedRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <SKPoint> positions)
        {
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            var buffer = AllocatePositionedRun(font, glyphs.Length);

            glyphs.CopyTo(buffer.GetGlyphSpan());
            positions.CopyTo(buffer.GetPositionSpan());
        }
Ejemplo n.º 10
0
        // AddRotationScaleRun

        public void AddRotationScaleRun(ReadOnlySpan <ushort> glyphs, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions)
        {
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            var buffer = AllocateRotationScaleRun(font, glyphs.Length);

            glyphs.CopyTo(buffer.GetGlyphSpan());
            positions.CopyTo(buffer.GetRotationScaleSpan());
        }
Ejemplo n.º 11
0
        // AddRun

        public void AddRun(ReadOnlySpan <ushort> 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);
        }
Ejemplo n.º 12
0
        // AllocateRotationScaleRun

        public SKRotationScaleRunBuffer AllocateRotationScaleRun(SKFont font, int count)
        {
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            SKRunBufferInternal runbuffer;

            SkiaApi.sk_textblob_builder_alloc_run_rsxform(Handle, font.Handle, count, &runbuffer);

            return(new SKRotationScaleRunBuffer(runbuffer, count));
        }
Ejemplo n.º 13
0
        public SKPaint(SKFont font)
            : this(IntPtr.Zero, true)
        {
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            Handle = SkiaApi.sk_compatpaint_new_with_font(font.Handle);

            if (Handle == IntPtr.Zero)
            {
                throw new InvalidOperationException("Unable to create a new SKPaint instance.");
            }
        }
Ejemplo n.º 14
0
        // AllocatePositionedRun

        public SKPositionedRunBuffer AllocatePositionedRun(SKFont font, int count, SKRect?bounds = null)
        {
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            SKRunBufferInternal runbuffer;

            if (bounds is SKRect b)
            {
                SkiaApi.sk_textblob_builder_alloc_run_pos(Handle, font.Handle, count, &b, &runbuffer);
            }
            else
            {
                SkiaApi.sk_textblob_builder_alloc_run_pos(Handle, font.Handle, count, null, &runbuffer);
            }

            return(new SKPositionedRunBuffer(runbuffer, count));
        }
Ejemplo n.º 15
0
        // CreateHorizontal

        public static SKTextBlob CreateHorizontal(string text, SKFont font, ReadOnlySpan <float> positions, float y) =>
        CreateHorizontal(text.AsSpan(), font, positions, y);
Ejemplo n.º 16
0
        internal static SKTextBlob Create(void *text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin)
        {
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            var count = font.CountGlyphs(text, length, encoding);

            if (count <= 0)
            {
                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);
            return(builder.Build());
        }
Ejemplo n.º 17
0
 public static SKTextBlob Create(ReadOnlySpan <byte> text, SKTextEncoding encoding, SKFont font, SKPoint origin = default)
 {
     fixed(void *t = text)
     {
         return(Create(t, text.Length, encoding, font, origin));
     }
 }
Ejemplo n.º 18
0
        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));
            }

            var count = font.CountGlyphs(text, length, encoding);

            if (count <= 0)
            {
                return(null);
            }

            // we use temporary arrays because we might only use part of the text
            using var glyphs       = Utils.RentArray <ushort> (count);
            using var glyphWidths  = Utils.RentArray <float> (glyphs.Length);
            using var glyphOffsets = Utils.RentArray <SKPoint> (glyphs.Length);

            font.GetGlyphs(text, length, encoding, glyphs);
            font.GetGlyphWidths(glyphs, glyphWidths, Span <SKRect> .Empty);
            font.GetGlyphPositions(glyphs, glyphOffsets, origin);

            using var builder = new SKTextBlobBuilder();
            builder.AddPathPositionedRun(glyphs, font, glyphWidths, glyphOffsets, path, textAlign);
            return(builder.Build());
        }
Ejemplo n.º 19
0
        internal static SKTextBlob CreateHorizontal(void *text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <float> positions, float y)
        {
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            var count = font.CountGlyphs(text, length, encoding);

            if (count <= 0)
            {
                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());
            return(builder.Build());
        }
Ejemplo n.º 20
0
        // CreateRotationScale

        public static SKTextBlob CreateRotationScale(string text, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions) =>
        CreateRotationScale(text.AsSpan(), font, positions);
Ejemplo n.º 21
0
 public static SKTextBlob CreateRotationScale(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <SKRotationScaleMatrix> positions) =>
 CreateRotationScale(text.AsReadOnlySpan(length), encoding, font, positions);
Ejemplo n.º 22
0
        // CreatePathPositioned

        public static SKTextBlob CreatePathPositioned(string text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) =>
        CreatePathPositioned(text.AsSpan(), font, path, textAlign, origin);
Ejemplo n.º 23
0
        // Create

        public static SKTextBlob Create(string text, SKFont font, SKPoint origin = default) =>
        Create(text.AsSpan(), font, origin);
Ejemplo n.º 24
0
 public static SKTextBlob CreatePositioned(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <SKPoint> positions) =>
 CreatePositioned(text.AsReadOnlySpan(length), encoding, font, positions);
Ejemplo n.º 25
0
 public static SKTextBlob CreateHorizontal(IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan <float> positions, float y) =>
 CreateHorizontal(text.AsReadOnlySpan(length), encoding, font, positions, y);
Ejemplo n.º 26
0
 public static SKTextBlob CreatePositioned(ReadOnlySpan <byte> text, SKTextEncoding encoding, SKFont font, ReadOnlySpan <SKPoint> positions)
 {
     fixed(void *t = text)
     {
         return(CreatePositioned(t, text.Length, encoding, font, positions));
     }
 }
Ejemplo n.º 27
0
 public static SKTextBlob Create(IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin = default) =>
 Create(text.AsReadOnlySpan(length), encoding, font, origin);
Ejemplo n.º 28
0
 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);
Ejemplo n.º 29
0
        public void DrawTextOnPath(string text, SKPath path, SKPoint offset, bool warpGlyphs, SKFont font, SKPaint paint)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }
            if (paint == null)
            {
                throw new ArgumentNullException(nameof(paint));
            }

            if (warpGlyphs)
            {
                using var textPath = font.GetTextPathOnPath(text, path, paint.TextAlign, offset);
                DrawPath(textPath, paint);
            }
            else
            {
                using var blob = SKTextBlob.CreatePathPositioned(text, font, path, paint.TextAlign, offset);
                if (blob != null)
                {
                    DrawText(blob, 0, 0, paint);
                }
            }
        }
Ejemplo n.º 30
0
        // CreatePositioned

        public static SKTextBlob CreatePositioned(string text, SKFont font, ReadOnlySpan <SKPoint> positions) =>
        CreatePositioned(text.AsSpan(), font, positions);