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; } } }
/// <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); } } }
public static SKSize GetTextBound(string text, SKFont font) { var paint = PaintFromFont(font); var textSize = GetTextBound(text, paint); return(textSize); }
public void GetGlyphWidthsReturnsTheCorrectAmount() { var font = new SKFont(); var widths = font.GetGlyphWidths("Hello World!", out var bounds); Assert.Equal(widths.Length, bounds.Length); }
public void MeasureTextMeasuresTheText() { var font = new SKFont(); var width = font.MeasureText("Hello World!"); Assert.True(width > 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];
public void GetTextPathSucceedsForEmtptyString() { var font = new SKFont(); var path = font.GetTextPath(""); Assert.NotNull(path); Assert.Equal(0, path.PointCount); }
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); }
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); }
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); }
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(); }
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); }
public void ContainsTextIsCorrect() { const string text = "A"; var font = new SKFont(); font.Typeface = SKTypeface.Default; Assert.True(font.ContainsGlyphs(text)); }
void Reset() { RunKind = FontRunKind.Normal; CodePointBuffer = null; Style = null; Typeface = null; Line = null; _textBlob = null; _font = null; }
/// <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); }
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); }
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, }); }
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; }
/// <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)); }
/// <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)); }
/// <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; } }
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); }
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); } }
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]); }
/// <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); }
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; }
/// <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); }
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); }