示例#1
0
        public SkiaFont(string name, float size, FontStyle fontStyle, GraphicsUnit unit, char?typefaceCharakter = null)
        {
            var pixelSize = size;

            switch (unit)
            {
            case GraphicsUnit.Point:
                pixelSize = size.FontSizePointsToPixels();
                break;
            }

            var skFont = new SKFont(SKTypeface.FromFamilyName(name, fontStyle.ToSKFontStyle()), size: pixelSize);

            _skPaint = new SKPaint(skFont)
            {
                Style = SKPaintStyle.Fill
            };

            this.Name  = name;
            this.Size  = size;
            this.Style = fontStyle;
            this.Unit  = unit;

            if (typefaceCharakter.HasValue)
            {
                var fontManager = SKFontManager.Default;
                var typeFace    = fontManager.MatchCharacter(name, typefaceCharakter.Value);
                if (typeFace != null)
                {
                    _skPaint.Typeface = typeFace;
                }
            }
        }
示例#2
0
 /// <summary>
 /// Set the font from a Font object
 /// </summary>
 /// <param name="Font"></param>
 public void SetFromFont(SKFont Font)
 {
     Name   = Font.Typeface.FamilyName;
     Size   = (int)Font.Size;
     Bold   = Font.Typeface.IsBold;
     Italic = Font.Typeface.IsItalic;
 }
        private static void DrawGrid(SKCanvas canvas, float canvasWidth, float canvasHeight, SKPaint paint)
        {
            paint.PathEffect = SKPathEffect.CreateDash(new float[] { 20, 20 }, 0);
            for (int i = 0; i <= 8; i++)
            {
                var x = i * canvasWidth / 8;
                var y = i * canvasHeight / 8;

                int textOffset;
                if (i > 0 && i < 8)
                {
                    canvas.DrawLine(new SKPoint(x, 0), new SKPoint(x, canvasHeight), paint);
                    canvas.DrawLine(new SKPoint(0, y), new SKPoint(canvasWidth, y), paint);
                    textOffset = 0;
                }
                else if (i == 0)
                {
                    textOffset = 15;
                }
                else
                {
                    textOffset = -15;
                }

                var font            = new SKFont(SKTypeface.Default, 12.0f);
                var measurementText = SKTextBlob.Create($"{i * 10}", font);
                canvas.DrawText(measurementText, x + textOffset, 10, paint);
                canvas.DrawText(measurementText, 5, y + textOffset, paint);
            }
        }
        private void DrawHorizontalRuler(SKCanvas canvas, float canvasWidth, int RulerWidth, int LargeSteps, int SmallSteps)
        {
            using (var paint = new SKPaint
            {
                Color = SKColors.Black,
                StrokeWidth = 1 * _displayScale,
                TextAlign = SKTextAlign.Center,
            })
            {
                canvas.DrawLine(0, 0, canvasWidth, 0, paint);
                canvas.DrawLine(0, RulerWidth, canvasWidth, RulerWidth, paint);

                for (int x = 0; x < canvasWidth; x += LargeSteps)
                {
                    for (int x1 = x + SmallSteps; x1 < x + LargeSteps; x1 += SmallSteps)
                    {
                        canvas.DrawLine(x1, 0, x1, 10, paint);
                    }
                    canvas.DrawLine(x, 0, x, 20, paint);

                    var typeface        = SKTypeface.FromFamilyName(FontFamily.Source);
                    var font            = new SKFont(typeface, (float)FontSize * _displayScale);
                    var measurementText = SKTextBlob.Create($"{x}", font);
                    canvas.DrawText(measurementText, x, 30, paint);
                }
            }
        }
示例#5
0
        public static SKSize GetTextBound(string text, SKFont font)
        {
            var paint    = PaintFromFont(font);
            var textSize = GetTextBound(text, paint);

            return(textSize);
        }
示例#6
0
        public void GetGlyphWidthsReturnsTheCorrectAmount()
        {
            var font = new SKFont();

            var widths = font.GetGlyphWidths("Hello World!", out var bounds);

            Assert.Equal(widths.Length, bounds.Length);
        }
示例#7
0
        public void MeasureTextMeasuresTheText()
        {
            var font = new SKFont();

            var width = font.MeasureText("Hello World!");

            Assert.True(width > 0);
        }
示例#8
0
        public override string Encode(string barcode)
        {
            // Barcode checks
            Barcode = Validate(barcode, 13);
            CheckCharset(Barcode);

            // Bars encode
            var bars = EncodeBars(Barcode);

            // Calculate drawing data
            var scale           = Math.Max(Options.Scale, 0);
            var margin          = 2 * scale;
            var width           = scale * bars.Length + margin * 2;
            var height          = scale * Options.Height + margin * 2;
            var barsHeights     = new[] { (int)((height - margin * 2) * 0.76), height - margin * 2 };
            var leftExtraMargin = margin * 3;

            if (Options.DrawText)
            {
                width += leftExtraMargin;
            }

            // Generate barcode image
            var surface = SKSurface.Create(new SKImageInfo(width, height));

            using (var canvas = surface.Canvas)
            {
                // Draw bg color
                canvas.Clear(Options.BackgroundColor);

                var brush = new SKPaint
                {
                    Color    = Options.Color,
                    IsStroke = false,
                };

                var posX = margin;
                if (Options.DrawText)
                {
                    posX += leftExtraMargin;
                }
                for (var i = 0; i < bars.Length; i++)
                {
                    // Draw bars
                    if (bars[i] == '1')
                    {
                        canvas.DrawRect(posX, margin, scale, barsHeights[_barsHeight[i]], brush);
                    }

                    posX += scale;
                }

                if (Options.DrawText)
                {
                    // Draw texts
                    var font = new SKFont(SKTypeface.FromFamilyName(Options.Font, Options.FontStyle), 9 * scale);
#if NET6_0_OR_GREATER
                    var leftExtraText = barcode[..1];
示例#9
0
        public void GetTextPathSucceedsForEmtptyString()
        {
            var font = new SKFont();

            var path = font.GetTextPath("");

            Assert.NotNull(path);
            Assert.Equal(0, path.PointCount);
        }
示例#10
0
        public void CountGlyphsReturnsTheCorrectNumberOfGlyphsForUnicode(SKTextEncoding encoding)
        {
            using var font = new SKFont();

            var bytes = StringUtilities.GetEncodedText("ä", encoding);
            var count = font.CountGlyphs(bytes, encoding);

            Assert.Equal(1, count);
        }
示例#11
0
        public void PlainGlyphsReturnsTheCorrectNumberOfCharacters()
        {
            const string text = "Hello World!";

            var font = new SKFont();

            Assert.Equal(text.Length, font.CountGlyphs(text));
            Assert.Equal(text.Length, font.GetGlyphs(text).Length);
        }
示例#12
0
        public void MeasureTextReturnsTheBounds()
        {
            var font = new SKFont();

            var width = font.MeasureText("Hello World!", out var bounds);

            Assert.True(width > 0);
            Assert.NotEqual(SKRect.Empty, bounds);
        }
示例#13
0
 public void Draw(SKSurface surface, Pixel point, SKPaint paint)
 {
     using SKFont font = MakeFont();
     font.Embolden     = Bold;
     surface.Canvas.Save();
     surface.Canvas.Translate(point.X, point.Y);
     surface.Canvas.RotateDegrees(Rotation);
     surface.Canvas.DrawText(Text, 0, FontSize, font, paint);
     surface.Canvas.Restore();
 }
示例#14
0
        public void MeasureTextMeasuresTheTextForGlyphs()
        {
            var font          = new SKFont();
            var expectedWidth = font.MeasureText("Hello World!");

            var glyphs = font.GetGlyphs("Hello World!");
            var width  = font.MeasureText(glyphs);

            Assert.Equal(expectedWidth, width);
        }
示例#15
0
        public void ContainsTextIsCorrect()
        {
            const string text = "A";

            var font = new SKFont();

            font.Typeface = SKTypeface.Default;

            Assert.True(font.ContainsGlyphs(text));
        }
示例#16
0
 void Reset()
 {
     RunKind         = FontRunKind.Normal;
     CodePointBuffer = null;
     Style           = null;
     Typeface        = null;
     Line            = null;
     _textBlob       = null;
     _font           = null;
 }
示例#17
0
        /// <summary>
        /// Processes the source image by adding the boundary boxes and saves the file locally.
        /// </summary>
        /// <param name="camera">The camera the image came from.</param>
        /// <param name="imageBytes">The image data.</param>
        /// <param name="predictions">The list of predictions to add to the image.</param>
        private SKBitmap ProcessImage(Camera camera)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            _logger.LogInformation($"{camera.Name}: Processing image boundaries.");

            // Load the bitmap
            SKBitmap image = SKBitmap.Decode(new MemoryStream(_snapshot));

            // Don't process the drawing if the drawing mode is off
            if (Config.DrawMode == DrawMode.Off)
            {
                _logger.LogInformation($"{camera.Name}: Draw mode is Off. Skipping image boundaries.");
                return(image);
            }

            // Draw the predictions
            using (SKCanvas canvas = new SKCanvas(image))
            {
                foreach (AIPrediction prediction in Config.DrawMode == DrawMode.All ? _predictions : _validPredictions)
                {
                    // Write out anything detected that was above the minimum size
                    int minSizeX = camera.GetMinSizeX();
                    int minSizeY = camera.GetMinSizeY();
                    if (prediction.SizeX >= minSizeX && prediction.SizeY >= minSizeY)
                    {
                        decimal confidence = Math.Round(prediction.Confidence, 0, MidpointRounding.AwayFromZero);
                        string  label      = $"{prediction.Label} ({confidence}%)";

                        // Draw the box
                        SKRect rectangle = SKRect.Create(prediction.MinX, prediction.MinY, prediction.SizeX, prediction.SizeY);
                        canvas.DrawRect(rectangle, new SKPaint
                        {
                            Style = SKPaintStyle.Stroke,
                            Color = GetColour(Config.BoxColor)
                        });

                        int x = prediction.MinX + Config.TextOffsetX;
                        int y = prediction.MinY + Config.FontSize + Config.TextOffsetY;

                        // Draw the text
                        SKFont font = new SKFont(SKTypeface.FromFamilyName(Config.Font), Config.FontSize);
                        canvas.DrawText(label, x, y, font, new SKPaint
                        {
                            Color = GetColour(Config.FontColor)
                        });
                    }
                }
            }

            stopwatch.Stop();
            _logger.LogInformation($"{camera.Name}: Finished processing image boundaries ({stopwatch.ElapsedMilliseconds}ms).");

            return(image);
        }
示例#18
0
        public void MeasureTextReturnsTheBoundsForGlyphs()
        {
            var font          = new SKFont();
            var expectedWidth = font.MeasureText("Hello World!", out var expectedBounds);

            var glyphs = font.GetGlyphs("Hello World!");
            var width  = font.MeasureText(glyphs, out var bounds);

            Assert.Equal(expectedWidth, width);
            Assert.Equal(expectedBounds, bounds);
        }
示例#19
0
        public static SKPaint PaintFromFont(SKFont font)
        {
            // var fontStyle = font.Typeface.FontStyle;
            // var typeface = SKTypeface.FromFamilyName(font.Typeface.FamilyName, fontStyle); // f.FontFamily.Name

            return(new SKPaint
            {
                // TextAlign =
                TextSize = font.Size * 1.2f,
                Typeface = font.Typeface,
            });
        }
示例#20
0
        public SkiaFont(CreateFontOptions fontOptions)
        {
            var fontFace = fontOptions.FontFace as SkiaFontFace;
            var typeface = fontFace?.SKTypeface;

            if (fontFace == null)
            {
                fontFace = new SkiaFontFace(SKTypeface.Default);
            }

            Font     = new SKFont(fontFace.SKTypeface, fontOptions.FontSize);
            Paint    = new SKPaint(Font);
            FontFace = fontFace;
        }
示例#21
0
        /// <summary>
        /// Measures the specified string when drawn with the specified
        /// Font object and formatted with the specified StringFormat object.
        /// </summary>
        /// <param name="text">String to measure.</param>
        /// <param name="font">Font object defines the text format of the string.</param>
        /// <param name="layoutArea">SKSize structure that specifies the maximum layout area for the text.</param>
        /// <param name="stringFormat">StringFormat object that represents formatting information, such as line spacing, for the string.</param>
        /// <returns>This method returns a SKSize structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter.</returns>
        public SKSize MeasureString(
            string text,
            SKFont font,
            SKSize layoutArea)
        {
            var p = new SKPaint()
            {
                Typeface = font.Typeface, TextSize = font.Size
            };
            var width  = p.MeasureText(text);
            var height = p.TextSize;

            return(new SKSize(width > layoutArea.Width ? layoutArea.Width : width, height > layoutArea.Height ? layoutArea.Height : height));
        }
示例#22
0
        /// <summary>
        /// Measures the specified string when drawn with the specified
        /// Font object and formatted with the specified StringFormat object.
        /// </summary>
        /// <param name="text">String to measure.</param>
        /// <param name="font">Font object defines the text format of the string.</param>
        /// <returns>This method returns a SKSize structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter.</returns>
        public SKSize MeasureString(
            string text,
            SKFont font
            )
        {
            var p = new SKPaint()
            {
                Typeface = font.Typeface, TextSize = font.Size
            };
            var width  = p.MeasureText(text);
            var height = p.TextSize;

            return(new SKSize(width, height));
        }
示例#23
0
 /// <summary>
 /// Set the font style from a font object
 /// </summary>
 /// <param name="Font"></param>
 public void SetFromFont(SKFont Font)
 {
     LatinFont   = Font.Typeface.FamilyName;
     ComplexFont = Font.Typeface.FamilyName;
     Size        = Font.Size;
     if (Font.Typeface.IsBold)
     {
         Bold = Font.Typeface.IsBold;
     }
     if (Font.Typeface.IsItalic)
     {
         Italic = Font.Typeface.IsItalic;
     }
 }
示例#24
0
            internal override void Draw(SKCanvas c)
            {
                SKPoint pos = SKPoint(Pos);

                string[] parts = Text.Split('\n');
                if (CenterHeight)                                                     //!!! here should be real text measuring
                {
                    float fontHeight = 0.75f;                                         // real letter part for Arial
                    float fullHeight = (parts.Length - 1) * LineLeading + fontHeight; // text full height
                    pos.Y -= (fullHeight / 2 - fontHeight) * FontSize;                // vertical shift of first line level
                }
                //!!! create font outside
                using (var typeface = SKTypeface.FromFamilyName(Image.FontFamily))
                    using (var font = new SKFont(typeface, FontSize))
                        using (var paint = new SKPaint(font)
                        {
                            IsAntialias = Owner.IsAntialias
                        }) {
                            if (Align > 0)
                            {
                                paint.TextAlign = ToSKTextAlign(Align);
                            }
                            if (FillColor != Color.Empty)
                            {
                                paint.Style = SKPaintStyle.Fill;
                                paint.Color = SKColor(FillColor);
                                for (int i = 0; i < parts.Length; ++i)
                                {
                                    SKPoint p = pos;
                                    p.Y += FontSize * LineLeading * i;
                                    c.DrawText(parts[i], p, paint);
                                }
                            }
                            if (StrokeColor != Color.Empty)
                            {
                                paint.Style       = SKPaintStyle.Stroke;
                                paint.Color       = SKColor(StrokeColor);
                                paint.StrokeWidth = StrokeWidth;
                                for (int i = 0; i < parts.Length; ++i)
                                {
                                    SKPoint p = pos;
                                    p.Y += FontSize * LineLeading * i;
                                    c.DrawText(parts[i], p, paint);
                                }
                            }
                        }
                base.Draw(c);
            }
示例#25
0
        public unsafe void UnicharCountReturnsCorrectCount()
        {
            var text  = new uint[] { 79 };
            var count = text.Length * sizeof(uint);

            using var font = new SKFont();

            fixed(uint *t = text)
            {
                Assert.Equal(1, font.CountGlyphs((IntPtr)t, count, SKTextEncoding.Utf32));

                var glyphs = font.GetGlyphs((IntPtr)t, count, SKTextEncoding.Utf32);

                Assert.Single(glyphs);
            }
        }
示例#26
0
        public void UnicodeGlyphsReturnsTheCorrectNumberOfCharacters()
        {
            const string text      = "🚀";
            var          emojiChar = StringUtilities.GetUnicodeCharacterCode(text, SKTextEncoding.Utf32);

            var typeface = SKFontManager.Default.MatchCharacter(emojiChar);

            Assert.NotNull(typeface);

            using var font = new SKFont();
            font.Typeface  = typeface;

            Assert.Equal(1, font.CountGlyphs(text));
            Assert.Single(font.GetGlyphs(text));
            Assert.NotEqual(0, font.GetGlyphs(text)[0]);
        }
示例#27
0
 /// <summary>
 /// Draws the specified text string at the specified location with the specified Brush and Font objects using the formatting properties of the specified StringFormat object.
 /// </summary>
 /// <param name="s">String to draw.</param>
 /// <param name="font">Font object that defines the text format of the string.</param>
 /// <param name="brush">Brush object that determines the color and texture of the drawn text.</param>
 /// <param name="point">SKPoint structure that specifies the upper-left corner of the drawn text.</param>
 /// <param name="format">StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text.</param>
 public void DrawString(
     string s,
     SKFont font,
     SKPaint brush,
     SKPoint point)
 {
     point             = new SKPoint(1, 1);
     brush.IsAntialias = true;
     brush.Style       = SKPaintStyle.StrokeAndFill;
     font.Hinting      = SKFontHinting.Normal;
     Graphics.DrawRect(new SKRect(point.X, point.Y, point.X + 10, point.Y + 10), new SKPaint()
     {
         Style = SKPaintStyle.Stroke, Color = SKColors.Red, StrokeWidth = 1
     });
     Graphics.DrawText(s, point.X, point.Y, font, brush);
 }
示例#28
0
        public SkiaFont(SKFont font)
        {
            SKFont = font;

            SKPaint = new SKPaint(font)
            {
                IsStroke     = false,
                IsAntialias  = true,
                SubpixelText = true,
                HintingLevel = SKPaintHinting.Full,
                //IsAutohinted = true,
                //LcdRenderText = true,
                FilterQuality = SKFilterQuality.High
            };

            FamilyName = font.Typeface.FamilyName;
        }
示例#29
0
        /// <summary>
        /// Shape an array of utf-32 code points replacing each grapheme cluster with a replacement character
        /// </summary>
        /// <param name="bufferSet">A re-usable text shaping buffer set that results will be allocated from</param>
        /// <param name="codePoints">The utf-32 code points to be shaped</param>
        /// <param name="style">The user style for the text</param>
        /// <param name="clusterAdjustment">A value to add to all reported cluster numbers</param>
        /// <returns>A TextShaper.Result representing the shaped text</returns>
        public Result ShapeReplacement(ResultBufferSet bufferSet, Slice <int> codePoints, IStyle style, int clusterAdjustment)
        {
            var   clusters   = GraphemeClusterAlgorithm.GetBoundaries(codePoints).ToArray();
            var   glyph      = _typeface.GetGlyph(style.ReplacementCharacter);
            var   font       = new SKFont(_typeface, overScale);
            float glyphScale = style.FontSize / overScale;

            float[]  widths = new float[1];
            SKRect[] bounds = new SKRect[1];
            font.GetGlyphWidths((new ushort[] { glyph }).AsSpan(), widths.AsSpan(), bounds.AsSpan());

            var r = new Result();

            r.GlyphIndicies    = bufferSet.GlyphIndicies.Add((int)clusters.Length - 1, false);
            r.GlyphPositions   = bufferSet.GlyphPositions.Add((int)clusters.Length - 1, false);
            r.Clusters         = bufferSet.Clusters.Add((int)clusters.Length - 1, false);
            r.CodePointXCoords = bufferSet.CodePointXCoords.Add(codePoints.Length, false);
            r.CodePointXCoords.Fill(0);

            float xCoord = 0;

            for (int i = 0; i < clusters.Length - 1; i++)
            {
                r.GlyphPositions[i].X = xCoord * glyphScale;
                r.GlyphPositions[i].Y = 0;
                r.GlyphIndicies[i]    = codePoints[clusters[i]] == 0x2029 ? (ushort)0 : glyph;
                r.Clusters[i]         = clusters[i] + clusterAdjustment;

                for (int j = clusters[i]; j < clusters[i + 1]; j++)
                {
                    r.CodePointXCoords[j] = r.GlyphPositions[i].X;
                }

                xCoord += widths[0] + style.LetterSpacing / glyphScale;
            }

            // Also return the end cursor position
            r.EndXCoord = new SKPoint(xCoord * glyphScale, 0);

            // And some other useful metrics
            r.Ascent  = _fontMetrics.Ascent * style.FontSize / overScale;
            r.Descent = _fontMetrics.Descent * style.FontSize / overScale;
            r.XMin    = _fontMetrics.XMin * style.FontSize / overScale;

            return(r);
        }
示例#30
0
        public void PaintWithAliasEdgingIsPreserved()
        {
            var font = new SKFont();

            font.Edging = SKFontEdging.Alias;

            var paint = new SKPaint(font);

            Assert.False(paint.LcdRenderText);
            Assert.False(paint.IsAntialias);
            Assert.Equal(SKFontEdging.Alias, paint.GetFont().Edging);

            paint.IsAntialias = true;

            Assert.False(paint.LcdRenderText);
            Assert.True(paint.IsAntialias);
            Assert.Equal(SKFontEdging.Antialias, paint.GetFont().Edging);
        }