コード例 #1
0
        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);
                }
            }
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
 public void DrawText(SKTextBlob text, float x, float y, SKPaint paint)
 {
     canvas.DrawText(text, x, y, paint);
     if (calculateBounds)
     {
         displayObject.addBoundingRect(text.Bounds);
     }
 }
コード例 #4
0
 void Reset()
 {
     RunKind         = FontRunKind.Normal;
     CodePointBuffer = null;
     Style           = null;
     Typeface        = null;
     Line            = null;
     _textBlob       = null;
     _font           = null;
 }
コード例 #5
0
ファイル: SKFontTest.cs プロジェクト: tonymkenu/SkiaSharp
        public unsafe void TextInterceptsAreFoundCorrectly()
        {
            var text = "|";

            var font = new SKFont();

            font.Size = 100;

            var blob = SKTextBlob.Create(text, font, new SKPoint(50, 100));

            var widths = blob.GetIntercepts(0, 100);

            Assert.Equal(2, widths.Length);

            var diff = widths[1] - widths[0];

            var textPath  = font.GetTextPath(text, SKPoint.Empty);
            var pathWidth = textPath.TightBounds.Width;

            Assert.Equal(pathWidth, diff, 2);
        }
コード例 #6
0
ファイル: GlyphRunImpl.cs プロジェクト: yahiheb/Avalonia
 public GlyphRunImpl(SKTextBlob textBlob)
 {
     TextBlob = textBlob;
 }
コード例 #7
0
ファイル: GlyphRunImpl.cs プロジェクト: yzq1979/Avalonia
 public GlyphRunImpl(SKPaint paint, SKTextBlob textBlob)
 {
     Paint    = paint;
     TextBlob = textBlob;
 }
コード例 #8
0
        /// <summary>
        /// Paint this font run
        /// </summary>
        /// <param name="ctx"></param>
        internal void Paint(PaintTextContext ctx)
        {
            // Paint selection?
            if (ctx.PaintSelectionBackground != null && RunKind != FontRunKind.Ellipsis)
            {
                float selStartXCoord;
                if (ctx.SelectionStart < Start)
                {
                    selStartXCoord = Direction == TextDirection.LTR ? 0 : Width;
                }
                else if (ctx.SelectionStart >= End)
                {
                    selStartXCoord = Direction == TextDirection.LTR ? Width : 0;
                }
                else
                {
                    selStartXCoord = RelativeCodePointXCoords[ctx.SelectionStart - this.Start];
                }

                float selEndXCoord;
                if (ctx.SelectionEnd < Start)
                {
                    selEndXCoord = Direction == TextDirection.LTR ? 0 : Width;
                }
                else if (ctx.SelectionEnd >= End)
                {
                    selEndXCoord = Direction == TextDirection.LTR ? Width : 0;
                }
                else
                {
                    selEndXCoord = RelativeCodePointXCoords[ctx.SelectionEnd - this.Start];
                }

                if (selStartXCoord != selEndXCoord)
                {
                    var tl = new SKPoint(selStartXCoord + this.XCoord, Line.YCoord);
                    var br = new SKPoint(selEndXCoord + this.XCoord, Line.YCoord + Line.Height);

                    // Align coords to pixel boundaries
                    // Not needed - disabled antialias on SKPaint instead

                    /*
                     * if (ctx.Canvas.TotalMatrix.TryInvert(out var inverse))
                     * {
                     *  tl = ctx.Canvas.TotalMatrix.MapPoint(tl);
                     *  br = ctx.Canvas.TotalMatrix.MapPoint(br);
                     *  tl = new SKPoint((float)Math.Round(tl.X), (float)Math.Round(tl.Y));
                     *  br = new SKPoint((float)Math.Round(br.X), (float)Math.Round(br.Y));
                     *  tl = inverse.MapPoint(tl);
                     *  br = inverse.MapPoint(br);
                     * }
                     */

                    var rect = new SKRect(tl.X, tl.Y, br.X, br.Y);
                    ctx.Canvas.DrawRect(rect, ctx.PaintSelectionBackground);
                }
            }

            // Don't paint trailing whitespace runs
            if (RunKind == FontRunKind.TrailingWhitespace)
            {
                return;
            }

            // Text
            using (var paint = new SKPaint())
            {
                // Work out font variant adjustments
                float glyphScale   = 1;
                float glyphVOffset = 0;
                if (Style.FontVariant == FontVariant.SuperScript)
                {
                    glyphScale   = 0.65f;
                    glyphVOffset = -Style.FontSize * 0.35f;
                }
                if (Style.FontVariant == FontVariant.SubScript)
                {
                    glyphScale   = 0.65f;
                    glyphVOffset = Style.FontSize * 0.1f;
                }

                // Setup SKPaint
                paint.Color         = Style.TextColor;
                paint.IsAntialias   = ctx.Options.IsAntialias;
                paint.LcdRenderText = ctx.Options.LcdRenderText;

                unsafe
                {
                    fixed(ushort *pGlyphs = Glyphs.Underlying)
                    {
                        // Get glyph positions
                        var glyphPositions = GlyphPositions.ToArray();

                        // Create the font
                        if (_font == null)
                        {
                            _font          = new SKFont(this.Typeface, this.Style.FontSize * glyphScale);
                            _font.Subpixel = true;
                        }

                        // Create the SKTextBlob (if necessary)
                        if (_textBlob == null)
                        {
                            _textBlob = SKTextBlob.CreatePositioned(
                                (IntPtr)(pGlyphs + Glyphs.Start),
                                Glyphs.Length * sizeof(ushort),
                                SKTextEncoding.GlyphId,
                                _font,
                                GlyphPositions.AsSpan());
                        }

                        // Paint underline
                        if (Style.Underline != UnderlineStyle.None && RunKind == FontRunKind.Normal)
                        {
                            // Work out underline metrics
                            float underlineYPos = Line.YCoord + Line.BaseLine + (_font.Metrics.UnderlinePosition ?? 0);
                            paint.StrokeWidth = _font.Metrics.UnderlineThickness ?? 1;

                            if (Style.Underline == UnderlineStyle.Gapped)
                            {
                                // Get intercept positions
                                var interceptPositions = _textBlob.GetIntercepts(underlineYPos - paint.StrokeWidth / 2, underlineYPos + paint.StrokeWidth);

                                // Paint gapped underlinline
                                float x = XCoord;
                                for (int i = 0; i < interceptPositions.Length; i += 2)
                                {
                                    float b = interceptPositions[i] - paint.StrokeWidth;
                                    if (x < b)
                                    {
                                        ctx.Canvas.DrawLine(new SKPoint(x, underlineYPos), new SKPoint(b, underlineYPos), paint);
                                    }
                                    x = interceptPositions[i + 1] + paint.StrokeWidth;
                                }
                                if (x < XCoord + Width)
                                {
                                    ctx.Canvas.DrawLine(new SKPoint(x, underlineYPos), new SKPoint(XCoord + Width, underlineYPos), paint);
                                }
                            }
                            else
                            {
                                switch (Style.Underline)
                                {
                                case UnderlineStyle.ImeInput:
                                    paint.PathEffect = SKPathEffect.CreateDash(new float[] { paint.StrokeWidth, paint.StrokeWidth }, paint.StrokeWidth);
                                    break;

                                case UnderlineStyle.ImeConverted:
                                    paint.PathEffect = SKPathEffect.CreateDash(new float[] { paint.StrokeWidth, paint.StrokeWidth }, paint.StrokeWidth);
                                    break;

                                case UnderlineStyle.ImeTargetConverted:
                                    paint.StrokeWidth *= 2;
                                    break;

                                case UnderlineStyle.ImeTargetNonConverted:
                                    break;
                                }
                                // Paint solid underline
                                ctx.Canvas.DrawLine(new SKPoint(XCoord, underlineYPos), new SKPoint(XCoord + Width, underlineYPos), paint);
                                paint.PathEffect = null;
                            }
                        }


                        ctx.Canvas.DrawText(_textBlob, 0, 0, paint);
                    }
                }

                // Paint strikethrough
                if (Style.StrikeThrough != StrikeThroughStyle.None && RunKind == FontRunKind.Normal)
                {
                    paint.StrokeWidth = _font.Metrics.StrikeoutThickness ?? 0;
                    float strikeYPos = Line.YCoord + Line.BaseLine + (_font.Metrics.StrikeoutPosition ?? 0) + glyphVOffset;
                    ctx.Canvas.DrawLine(new SKPoint(XCoord, strikeYPos), new SKPoint(XCoord + Width, strikeYPos), paint);
                }
            }
        }
コード例 #9
0
 public GlyphRunImpl([NotNull] SKTextBlob textBlob)
 {
     TextBlob = textBlob ?? throw new ArgumentNullException(nameof(textBlob));
 }
コード例 #10
0
 public SKRenderable(SKTextBlob text)
 {
     skiaObject = text;
     renderImpl = RenderTextBlob;
 }
コード例 #11
0
        public void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IWidget widget, float layerOpacity)
        {
            canvas.RotateDegrees((float)viewport.Rotation, 0.0f, 0.0f);


            var TL = viewport.ScreenToWorld(canvas.LocalClipBounds.Left, canvas.LocalClipBounds.Top);
            var BR = viewport.ScreenToWorld(canvas.LocalClipBounds.Right, canvas.LocalClipBounds.Bottom);

            var width  = viewport.Extent.Width;
            var height = viewport.Extent.Height;

            var  usedLineOffset    = lineOffset;
            uint usedLineOffsetInt = (uint)usedLineOffset;

            IEnumerable <SKPaint> usedPaints = paints;

            if (viewport.Resolution > 0.25)
            {
                usedLineOffset    *= 10; // hide 10m layer
                usedLineOffsetInt *= 10; // hide 10m layer
                usedPaints         = paintsL2;
            }

            if (viewport.Resolution > 3)
            {
                usedLineOffset    *= 10; // hide 100m layer
                usedLineOffsetInt *= 10; // hide 100m layer
                usedPaints         = paintsL3;
            }

            int lineCount100M = (int)(100 / usedLineOffset);
            //How many lines are 1000m
            int lineCount1000M = (int)(1000 / usedLineOffset);

            if (lineCount100M == 0)
            {
                lineCount100M = 9000;                     //will never be reached, if we only render 1k's
            }
            double screenWidthPerLine  = canvas.LocalClipBounds.Width / (width / usedLineOffset);
            double screenHeightPerLine = canvas.LocalClipBounds.Height / (height / usedLineOffset);

            //World coordinates of first lineOffset line
            var first100mW = (TL.X + (usedLineOffset - TL.X % usedLineOffset));
            var first100mH = (TL.Y + (usedLineOffset - TL.Y % usedLineOffset));

            //Screen offset of first lineOffset line
            double offsetCW = ((first100mW - TL.X) / usedLineOffset) * screenWidthPerLine;
            double offsetCH = screenHeightPerLine + ((TL.Y - first100mH) / usedLineOffset) * screenHeightPerLine;

            //offset of next 1k
            int KOffsetW = (int)((first100mW % 1000) / usedLineOffset);

            if (KOffsetW < 0)
            {
                KOffsetW = 10 + KOffsetW;
            }
            int KOffsetH = (int)((first100mH % 1000) / usedLineOffset) - 1;

            if (lineCount1000M > 1)
            {
                KOffsetH = lineCount1000M - KOffsetH;
            }

            for (double curX = offsetCW; curX < canvas.LocalClipBounds.Right; curX += screenWidthPerLine)
            {
                var worldPos  = viewport.ScreenToWorld(curX, 0).X;
                var Xgrid10KM = (uint)(worldPos / 10000) % 10;
                var Xgrid1KM  = (uint)(worldPos / 1000) % 10;
                var Xgrid100m = (uint)(worldPos / 100) % 10;
                //var Xgrid10m = (uint)(worldPos / 10) % 10;


                string gridPosString;
                if (usedLineOffsetInt == 1000)
                {
                    gridPosString = $"{Xgrid10KM}{Xgrid1KM}";
                }
                else if (usedLineOffsetInt == 100)
                {
                    gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}";
                }
                else
                {
                    gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}{(uint)(worldPos / 10) % 10}";
                }


                SKPaint paint;
                if (KOffsetW >= 1000 && KOffsetW % 1000 == 0)
                {
                    paint = usedPaints.ElementAt(0);
                }
                if (KOffsetW >= 100 && KOffsetW % 100 == 0)
                {
                    paint = usedPaints.ElementAt(2);
                }
                else if (KOffsetW >= 10 && KOffsetW % 10 == 0)
                {
                    paint = usedPaints.ElementAt(1);
                }
                else
                {
                    paint = usedPaints.ElementAt(0);
                }

                if (KOffsetW == lineCount1000M)
                {
                    KOffsetW = 0;
                }

                canvas.DrawLine((float)curX, 0, (float)curX, canvas.LocalClipBounds.Height, paint);



                using (var gtext = SKTextBlob.Create(gridPosString, markerFont))
                    canvas.DrawText(gtext, (float)(curX + screenWidthPerLine / 2) - gtext.Bounds.MidX,
                                    20 + gtext.Bounds.MidY,
                                    paint100m);

                KOffsetW++;
            }

            for (double curH = offsetCH; curH < canvas.LocalClipBounds.Bottom; curH += screenHeightPerLine)
            {
                var worldPos  = viewport.ScreenToWorld(0, curH).Y;
                var Xgrid10KM = (uint)(worldPos / 10000) % 10;
                var Xgrid1KM  = (uint)(worldPos / 1000) % 10;
                var Xgrid100m = (uint)(worldPos / 100) % 10;
                //var Xgrid10m = (uint)(worldPos / 10) % 10;

                string gridPosString;
                if (usedLineOffsetInt == 1000)
                {
                    gridPosString = $"{Xgrid10KM}{Xgrid1KM}";
                }
                else if (usedLineOffsetInt == 100)
                {
                    gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}";
                }
                else
                {
                    gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}{(uint)(worldPos / 10) % 10}";
                }

                SKPaint paint;
                if (KOffsetH >= 100 && KOffsetH % 100 == 0)
                {
                    paint = usedPaints.ElementAt(2);
                }
                else if (KOffsetH >= 10 && KOffsetH % 10 == 0)
                {
                    paint = usedPaints.ElementAt(1);
                }
                else
                {
                    paint = usedPaints.ElementAt(0);
                }



                if (KOffsetH == lineCount1000M)
                {
                    KOffsetH = 0;
                }

                canvas.DrawLine(0, (float)curH, canvas.LocalClipBounds.Width, (float)curH, paint);

                using (var gtext = SKTextBlob.Create(gridPosString, markerFont))
                    canvas.DrawText(gtext, 0,
                                    (float)(curH + screenWidthPerLine / 2) - gtext.Bounds.MidY,
                                    paint100m);


                KOffsetH++;
            }
        }