コード例 #1
0
ファイル: NvgText.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Measures the specified text string. Parameter bounds contains the bounds of the text.<br/>
        /// Measured values are returned in local coordinate space.
        /// </summary>
        /// <param name="bounds">Contains the bounds of the text when returned.</param>
        /// <returns>The horizontal advance of the measured text (i.e. where the next character should be drawn).</returns>
        public static float TextBounds(this Nvg nvg, Vector2D <float> pos, string @string, string end, out Rectangle <float> bounds)
        {
            bounds = default;

            Fontstash fons     = nvg.fontManager.Fontstash;
            State     state    = nvg.stateStack.CurrentState;
            float     scale    = nvg.fontManager.GetFontScale() * nvg.pixelRatio.DevicePxRatio;
            float     invscale = 1.0f / scale;

            if (state.FontId == Fontstash.INVALID)
            {
                return(0);
            }

            fons.SetSize(state.FontSize * scale);
            fons.SetSpacing(state.LetterSpacing * scale);
            fons.SetBlur(state.FontBlur * scale);
            fons.SetAlign((int)state.TextAlign);
            fons.SetFont(state.FontId);

            float width = fons.TextBounds(pos.X * scale, pos.Y * scale, @string, end, out float[] bs);

            if (bs != null)
            {
                fons.LineBounds(pos.Y * scale, out bs[1], out bs[3]);
                bounds = new Rectangle <float>()
                {
                    Origin = new Vector2D <float>(bs[0] * invscale, bs[1] * invscale),
                    Size   = new Vector2D <float>((bs[2] - bs[0]) * invscale, (bs[3] - bs[1]) * invscale)
                };
            }

            return(width * invscale);
        }
コード例 #2
0
        public FontManager(Nvg nvg)
        {
            _nvg = nvg;

            for (uint i = 0; i < MAX_FONTIMAGES; i++)
            {
                _fontImages[i] = 0;
            }

            FonsParams fontParams = new()
            {
                width        = (int)INIT_FONTIMAGE_SIZE,
                height       = (int)INIT_FONTIMAGE_SIZE,
                flags        = (byte)FonsFlags.ZeroTopleft,
                renderCreate = null,
                renderUpdate = null,
                renderDraw   = null,
                renderDelete = null
            };

            Fontstash = new Fontstash(fontParams);

            _fontImages[0] = _nvg.renderer.CreateTexture(Texture.Alpha, new Vector2D <uint>((uint)fontParams.width, (uint)fontParams.height), 0, null);
            if (_fontImages[0] == 0)
            {
                _nvg.Dispose();
                throw new Exception("Failed to create dummy font atlas!");
            }
            _fontImageIdx = 0;
        }
コード例 #3
0
        /// <summary>
        /// Fills the current path with current fill style.
        /// </summary>
        public static void Fill(this Nvg nvg)
        {
            State state     = nvg.stateStack.CurrentState;
            Paint fillPaint = state.Fill;

            nvg.instructionQueue.FlattenPaths();

            if (nvg.renderer.EdgeAntiAlias && nvg.stateStack.CurrentState.ShapeAntiAlias)
            {
                nvg.pathCache.ExpandFill(nvg.pixelRatio.FringeWidth, Graphics.LineCap.Miter, 2.4f, nvg.pixelRatio);
            }
            else
            {
                nvg.pathCache.ExpandFill(0.0f, Graphics.LineCap.Miter, 2.4f, nvg.pixelRatio);
            }

            fillPaint.PremultiplyAlpha(nvg.stateStack.CurrentState.Alpha);

            nvg.renderer.Fill(fillPaint, state.CompositeOperation, state.Scissor, nvg.pixelRatio.FringeWidth, nvg.pathCache.Bounds, nvg.pathCache.Paths);

            foreach (Path path in nvg.pathCache.Paths)
            {
                nvg.FrameMeta.Update(0, 0, (uint)path.Fill.Count - 2 + (uint)path.Stroke.Count - 2, 2);
            }
        }
コード例 #4
0
        /// <summary>
        /// Fills the current path with current stroke style.
        /// </summary>
        public static void Stroke(this Nvg nvg)
        {
            State state       = nvg.stateStack.CurrentState;
            float scale       = Maths.GetAverageScale(state.Transform);
            float strokeWidth = Maths.Clamp(state.StrokeWidth * scale, 0.0f, 200.0f);
            Paint strokePaint = state.Stroke;

            if (strokeWidth < nvg.pixelRatio.FringeWidth)
            {
                float alpha = Maths.Clamp(strokeWidth / nvg.pixelRatio.FringeWidth, 0.0f, 1.0f);
                strokePaint.PremultiplyAlpha(alpha * alpha);
                strokeWidth = nvg.pixelRatio.FringeWidth;
            }

            strokePaint.PremultiplyAlpha(state.Alpha);

            nvg.instructionQueue.FlattenPaths();

            if (nvg.renderer.EdgeAntiAlias && state.ShapeAntiAlias)
            {
                nvg.pathCache.ExpandStroke(strokeWidth * 0.5f, nvg.pixelRatio.FringeWidth, state.LineCap, state.LineJoin, state.MiterLimit, nvg.pixelRatio);
            }
            else
            {
                nvg.pathCache.ExpandStroke(strokeWidth * 0.5f, 0.0f, state.LineCap, state.LineJoin, state.MiterLimit, nvg.pixelRatio);
            }

            nvg.renderer.Stroke(strokePaint, state.CompositeOperation, state.Scissor, nvg.pixelRatio.FringeWidth, strokeWidth, nvg.pathCache.Paths);

            foreach (Path path in nvg.pathCache.Paths)
            {
                nvg.FrameMeta.Update(0, (uint)path.Stroke.Count - 2, 0, 1);
            }
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: MatijaBrown/SilkyNvg
        private static void Load()
        {
            IInputContext input = window.CreateInput();

            foreach (IKeyboard keyboard in input.Keyboards)
            {
                keyboard.KeyDown += KeyDown;
            }
            foreach (IMouse mouse in input.Mice)
            {
                mouse.MouseMove += MouseMove;
            }

            gl = window.CreateOpenGL();

            OpenGLRenderer nvgRenderer = new(CreateFlags.Antialias | CreateFlags.StencilStrokes | CreateFlags.Debug, gl);

            nvg = Nvg.Create(nvgRenderer);

            demo = new Demo(nvg);

            timer = Stopwatch.StartNew();

            timer.Restart();

            prevTime = timer.Elapsed.TotalMilliseconds;
        }
コード例 #6
0
        /// <summary>
        /// Adds an arc segment at the corner defined by the last path point and two specified points.
        /// </summary>
        public static void ArcTo(this Nvg nvg, Vector2D <float> p1, Vector2D <float> p2, float radius)
        {
            Vector2D <float> p0 = nvg.instructionQueue.EndPosition;

            if (nvg.instructionQueue.Count == 0)
            {
                return;
            }

            float distToll = nvg.pixelRatio.DistTol;

            if (Maths.PtEquals(p0, p1, distToll) ||
                Maths.PtEquals(p1, p2, distToll) ||
                Maths.DistPtSeg(p1, p0, p2) < distToll ||
                radius < distToll)
            {
                LineTo(nvg, p1);
                return;
            }

            Vector2D <float> d0 = p0 - p1;
            Vector2D <float> d1 = p2 - p1;

            d0 = Vector2D.Normalize(d0);
            d1 = Vector2D.Normalize(d1);
            float a = MathF.Acos(d0.X * d1.X + d0.Y * d1.Y);
            float d = radius / MathF.Tan(a / 2.0f);

            if (d > 10000.0f)
            {
                LineTo(nvg, p1);
                return;
            }

            Winding          dir;
            Vector2D <float> valuesC;
            float            a0, a1;

            if (Maths.Cross(d0, d1) > 0.0f)
            {
                float cx = p1.X + d0.X * d + d0.Y * radius;
                float cy = p1.Y + d0.Y * d + -d0.X * radius;
                a0      = MathF.Atan2(d0.X, -d0.Y);
                a1      = MathF.Atan2(-d1.X, d1.Y);
                dir     = Winding.Cw;
                valuesC = new Vector2D <float>(cx, cy);
            }
            else
            {
                float cx = p1.X + d0.X * d + -d0.Y * radius;
                float cy = p1.Y + d0.Y * d + d0.X * radius;
                a0      = MathF.Atan2(-d0.X, d0.Y);
                a1      = MathF.Atan2(d1.X, -d1.Y);
                dir     = Winding.Ccw;
                valuesC = new Vector2D <float>(cx, cy);
            }

            Arc(nvg, valuesC, radius, a0, a1, dir);
        }
コード例 #7
0
        /// <summary>
        /// Adds quadratic bezier segment from last point in the path via a control point to the specified point.
        /// </summary>
        public static void QuadTo(this Nvg nvg, Vector2D <float> cp, Vector2D <float> p)
        {
            Vector2D <float> lastPos = nvg.instructionQueue.EndPosition;

            nvg.instructionQueue.AddBezierTo(
                lastPos + 2.0f / 3.0f * (cp - lastPos),
                p + 2.0f / 3.0f * (cp - p),
                p
                );
        }
コード例 #8
0
        /// <summary>
        /// Creates a new rectangle shaped sub-path.
        /// </summary>
        public static void Rect(this Nvg nvg, Rectangle <float> rect)
        {
            InstructionQueue queue = nvg.instructionQueue;

            queue.AddMoveTo(rect.Origin);
            queue.AddLineTo(new(rect.Origin.X, rect.Max.Y));
            queue.AddLineTo(rect.Max);
            queue.AddLineTo(new(rect.Max.X, rect.Origin.Y));
            queue.AddClose();
        }
コード例 #9
0
ファイル: NvgText.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Adds a fallback font by handle.
        /// </summary>
        public static bool AddFallbackFontId(this Nvg nvg, int baseFont, int fallbackFont)
        {
            if (baseFont == -1 || fallbackFont == -1)
            {
                return(false);
            }

            Fontstash fons = nvg.fontManager.Fontstash;

            return(fons.AddFallbackFont(baseFont, fallbackFont));
        }
コード例 #10
0
ファイル: NvgText.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Finds a loaded font from specified name.
        /// </summary>
        /// <returns>Handle to it, or -1 if the font is not found.</returns>
        public static int FindFont(this Nvg nvg, string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return(-1);
            }

            Fontstash fons = nvg.fontManager.Fontstash;

            return(fons.GetFontByName(name));
        }
コード例 #11
0
ファイル: NvgImages.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Creates image by loading it from the specified chunk of memory.
        /// </summary>
        /// <returns>Handle to the image.</returns>
        public static int CreateImageMem(this Nvg nvg, ImageFlags imageFlags, byte[] data)
        {
            ImageResult result = ImageResult.FromMemory(data, ColorComponents.RedGreenBlueAlpha);

            if (result == null)
            {
                return(0);
            }
            int image = CreateImageRgba(nvg, (uint)result.Width, (uint)result.Height, imageFlags, data);

            return(image);
        }
コード例 #12
0
ファイル: NvgText.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Calculates the glyph x positions of the specified text. Only the sub-string will be used.<br/>
        /// Measures values are returned in local coordinate space.
        /// </summary>
        public static int TextGlyphPositions(this Nvg nvg, Vector2D <float> pos, string @string, string end, out GlyphPosition[] positions, int maxRows)
        {
            positions = new GlyphPosition[maxRows];

            Fontstash fons     = nvg.fontManager.Fontstash;
            State     state    = nvg.stateStack.CurrentState;
            float     scale    = nvg.fontManager.GetFontScale() * nvg.pixelRatio.DevicePxRatio;
            float     invscale = 1.0f / scale;
            FonsQuad  q        = new();
            int       npos     = 0;

            if (state.FontId == Fontstash.INVALID)
            {
                return(0);
            }

            if (@string == end)
            {
                return(0);
            }

            fons.SetSize(state.FontSize * scale);
            fons.SetSpacing(state.LetterSpacing * scale);
            fons.SetBlur(state.FontBlur * scale);
            fons.SetAlign((int)state.TextAlign);
            fons.SetFont(state.FontId);

            fons.TextIterInit(out FonsTextIter iter, pos.X * scale, pos.Y * scale, @string, end, FonsGlyphBitmap.Optional);
            FonsTextIter prevIter = iter;

            while (fons.TextIterNext(ref iter, ref q))
            {
                if (iter.prevGlyphIndex < 0 && nvg.fontManager.AllocTextAtlas())
                {
                    iter = prevIter;
                    fons.TextIterNext(ref iter, ref q);
                }
                prevIter          = iter;
                positions[npos++] = new GlyphPosition(iter.str, iter.x * invscale, MathF.Min(iter.x, q.x0) * invscale, MathF.Max(iter.nextx, q.x1) * invscale);
                if (npos >= maxRows)
                {
                    return(npos);
                }
            }

            return(npos);
        }
コード例 #13
0
ファイル: Program.cs プロジェクト: MatijaBrown/SilkyNvg
        private static void Load()
        {
            IInputContext input = window.CreateInput();

            foreach (IKeyboard keyboard in input.Keyboards)
            {
                keyboard.KeyDown += KeyDown;
            }

            gl = window.CreateOpenGL();

            OpenGLRenderer nvgRenderer = new(CreateFlags.Antialias | CreateFlags.StencilStrokes | CreateFlags.Debug, gl);

            nvg = Nvg.Create(nvgRenderer);

            fontSize = 20.0f;
            _        = nvg.CreateFont("Roboto", "Roboto-Regular.ttf");
        }
コード例 #14
0
        /// <summary>
        /// Creates a new rounded rectangle shaped sub-path with varying radii for each corner.
        /// </summary>
        public static void RoundedRectVarying(this Nvg nvg, Rectangle <float> rect, float radTopLeft, float radTopRight, float radBottomRight, float radBottomLeft)
        {
            if (radTopLeft < 0.1f && radTopRight < 0.1f && radBottomRight < 0.1f && radBottomLeft < 0.1f)
            {
                Rect(nvg, rect);
            }
            else
            {
                InstructionQueue queue = nvg.instructionQueue;

                float            factor = 1 - KAPPA90;
                Vector2D <float> half   = Vector2D.Abs(rect.Size) * 0.5f;
                Vector2D <float> rBL    = new(MathF.Min(radBottomLeft, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radBottomLeft, half.Y) * Maths.Sign(rect.Size.Y));
                Vector2D <float> rBR    = new(MathF.Min(radBottomRight, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radBottomRight, half.Y) * Maths.Sign(rect.Size.Y));
                Vector2D <float> rTR    = new(MathF.Min(radTopRight, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radTopRight, half.Y) * Maths.Sign(rect.Size.Y));
                Vector2D <float> rTL    = new(MathF.Min(radTopLeft, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radTopLeft, half.Y) * Maths.Sign(rect.Size.Y));
                queue.AddMoveTo(new(rect.Origin.X, rect.Origin.Y + rTL.Y));
                queue.AddLineTo(new(rect.Origin.X, rect.Origin.Y + rect.Size.Y - rBL.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X, rect.Origin.Y + rect.Size.Y - rBL.Y * factor),
                    new(rect.Origin.X + rBL.X * factor, rect.Origin.Y + rect.Size.Y),
                    new(rect.Origin.X + rBL.X, rect.Origin.Y + rect.Size.Y)
                    );
                queue.AddLineTo(new(rect.Origin.X + rect.Size.X - rBR.X, rect.Origin.Y + rect.Size.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X + rect.Size.X - rBR.X * factor, rect.Origin.Y + rect.Size.Y),
                    new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rect.Size.Y - rBR.Y * factor),
                    new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rect.Size.Y - rBR.Y)
                    );
                queue.AddLineTo(new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rTR.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rTR.Y * factor),
                    new(rect.Origin.X + rect.Size.X - rTR.X * factor, rect.Origin.Y),
                    new(rect.Origin.X + rect.Size.X - rTR.X, rect.Origin.Y)
                    );
                queue.AddLineTo(new(rect.Origin.X + rTL.X, rect.Origin.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X + rTL.X * factor, rect.Origin.Y),
                    new(rect.Origin.X, rect.Origin.Y + rTL.Y * factor),
                    new(rect.Origin.X, rect.Origin.Y + rTL.Y)
                    );
                queue.AddClose();
            }
        }
コード例 #15
0
ファイル: Demo.cs プロジェクト: MatijaBrown/SilkyNvg
        public Demo(Nvg nvg)
        {
            _nvg = nvg;

            for (uint i = 0; i < 12; i++)
            {
                string file = "./images/image" + i + ".jpg";
                _images[i] = _nvg.CreateImage(file, 0);
                if (_images[i] == 0)
                {
                    Console.Error.WriteLine("Could not load " + file);
                    Environment.Exit(-1);
                }
            }

            _fontIcons = _nvg.CreateFont("icons", "./fonts/entypo.ttf");
            if (_fontIcons == -1)
            {
                Console.Error.WriteLine("Could not add font icons.");
                Environment.Exit(-1);
            }
            _fontNormal = _nvg.CreateFont("sans", "./fonts/Roboto-Regular.ttf");
            if (_fontIcons == -1)
            {
                Console.Error.WriteLine("Could not add font regular.");
                Environment.Exit(-1);
            }
            _fontBold = _nvg.CreateFont("sans-bold", "./fonts/Roboto-Bold.ttf");
            if (_fontIcons == -1)
            {
                Console.Error.WriteLine("Could not add font bold.");
                Environment.Exit(-1);
            }
            _fontEmoji = _nvg.CreateFont("emoji", "./fonts/NotoEmoji-Regular.ttf");
            if (_fontIcons == -1)
            {
                Console.Error.WriteLine("Could not add font emoji.");
                Environment.Exit(-1);
            }

            _ = _nvg.AddFallbackFontId(_fontNormal, _fontEmoji);
            _ = _nvg.AddFallbackFontId(_fontBold, _fontEmoji);
        }
コード例 #16
0
ファイル: NvgScissoring.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Sets the current scissor rectangle.
        /// The scissor rectangle is transformed by the current transform.
        /// </summary>
        public static void Scissor(this Nvg nvg, Rectangle <float> rect)
        {
            Vector2D <float> pos  = rect.Origin;
            Vector2D <float> size = rect.Size;

            size.X = MathF.Max(0.0f, size.X);
            size.Y = MathF.Max(0.0f, size.Y);

            Vector2D <float>  lastRow   = pos + size * 0.5f;
            Matrix3X2 <float> transform = Matrix3X2 <float> .Identity;

            transform.M31 = lastRow.X;
            transform.M32 = lastRow.Y;

            nvg.stateStack.CurrentState.Scissor = new(
                Transforms.NvgTransforms.Multiply(transform, nvg.stateStack.CurrentState.Transform),
                size * 0.5f
                );
        }
コード例 #17
0
ファイル: NvgText.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Draws multi-line text string at specified location wrapped at the specified width. Only the sub-string up to the end is drawn.
        /// White space is stripped at the beginning of the rows, the text is split at word boundries or when new-line characters are encountered.
        /// Words longer than the max width are slit at nearest character (i.e. no hyphenation).
        /// </summary>
        public static void TextBox(this Nvg nvg, Vector2D <float> pos, float breakRowWidth, string @string, string end)
        {
            State state = nvg.stateStack.CurrentState;
            int   rowCount;
            Align oldAlign = state.TextAlign;
            Align hAlign   = state.TextAlign & (Align.Left | Align.Centre | Align.Right);
            Align vAlign   = state.TextAlign & (Align.Top | Align.Middle | Align.Bottom | Align.Baseline);

            if (state.FontId == Fontstash.INVALID)
            {
                return;
            }

            TextMetrics(nvg, out _, out _, out float lineh);

            state.TextAlign = Align.Left | vAlign;

            while ((rowCount = TextBreakLines(nvg, @string, end, breakRowWidth, out TextRow[] rows, 2)) != 0)
            {
                for (int i = 0; i < rowCount; i++)
                {
                    if (hAlign.HasFlag(Align.Left))
                    {
                        _ = Text(nvg, pos, rows[i].Start, rows[i].End.Length > 0 ? rows[i].End : null);
                    }
                    else if (hAlign.HasFlag(Align.Centre))
                    {
                        _ = Text(nvg, pos.X + breakRowWidth * 0.5f, pos.Y - rows[i].Width * 0.5f, rows[i].Start, rows[i].End.Length > 0 ? rows[i].End : null);
                    }
                    else if (hAlign.HasFlag(Align.Right))
                    {
                        _ = Text(nvg, pos.X + breakRowWidth - rows[i].Width, pos.Y, rows[i].Start, rows[i].End.Length > 0 ? rows[i].End : null);
                    }
                    pos.Y += lineh * state.LineHeight;
                }
                @string = rows[rowCount - 1].Next;
            }

            state.TextAlign = oldAlign;
        }
コード例 #18
0
        /// <summary>
        /// Creates a new ellipse shaped sub-path.
        /// </summary>
        public static void Ellipse(this Nvg nvg, Vector2D <float> c, float rx, float ry)
        {
            InstructionQueue queue = nvg.instructionQueue;

            queue.AddMoveTo(new(c.X - rx, c.Y));
            queue.AddBezierTo(
                new(c.X - rx, c.Y + ry * KAPPA90),
                new(c.X - rx * KAPPA90, c.Y + ry),
                new(c.X, c.Y + ry));
            queue.AddBezierTo(
                new(c.X + rx * KAPPA90, c.Y + ry),
                new(c.X + rx, c.Y + ry * KAPPA90),
                new(c.X + rx, c.Y));
            queue.AddBezierTo(
                new(c.X + rx, c.Y - ry * KAPPA90),
                new(c.X + rx * KAPPA90, c.Y - ry),
                new(c.X, c.Y - ry));
            queue.AddBezierTo(
                new(c.X - rx * KAPPA90, c.Y - ry),
                new(c.X - rx, c.Y - ry * KAPPA90),
                new(c.X - rx, c.Y));
            queue.AddClose();
        }
コード例 #19
0
ファイル: NvgImages.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Creates image by loading it from the disk from specified file name.
        /// </summary>
        /// <returns>Handle to the image.</returns>
        public static int CreateImage(this Nvg nvg, string fileName, ImageFlags imageFlags)
        {
            Stream stream;

            try
            {
                stream = File.OpenRead(fileName);
            }
            catch
            {
                return(0);
            }
            ImageResult result = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha);

            if (result == null)
            {
                return(0);
            }
            int image = CreateImageRgba(nvg, (uint)result.Width, (uint)result.Height, imageFlags, result.Data);

            stream.Close();
            stream.Dispose();
            return(image);
        }
コード例 #20
0
ファイル: NvgText.cs プロジェクト: MatijaBrown/SilkyNvg
        /// <summary>
        /// Returns the vertical metrics based on the current text style.<br/>
        /// Measured values are returned in local coordinate space.
        /// </summary>
        public static void TextMetrics(this Nvg nvg, out float ascender, out float descender, out float lineh)
        {
            Fontstash fons     = nvg.fontManager.Fontstash;
            State     state    = nvg.stateStack.CurrentState;
            float     scale    = nvg.fontManager.GetFontScale() * nvg.pixelRatio.DevicePxRatio;
            float     invscale = 1.0f / scale;

            if (state.FontId == Fontstash.INVALID)
            {
                ascender = descender = lineh = -1.0f;
                return;
            }

            fons.SetSize(state.FontSize * scale);
            fons.SetSpacing(state.LetterSpacing * scale);
            fons.SetBlur(state.FontBlur * scale);
            fons.SetAlign((int)state.TextAlign);
            fons.SetFont(state.FontId);

            fons.VertMetrics(out ascender, out descender, out lineh);
            ascender  *= invscale;
            descender *= invscale;
            lineh     *= invscale;
        }
コード例 #21
0
 /// <inheritdoc cref="Paint.ImagePattern(Rectangle{float}, float, int, float)"/>
 public static Paint ImagePattern(this Nvg _, Rectangle <float> bounds, float angle, int image, float alpha)
 => Paint.ImagePattern(bounds, angle, image, alpha);
コード例 #22
0
 /// <inheritdoc cref="Paint.ImagePattern(float, float, float, float, float, int, float)"/>
 public static Paint ImagePattern(this Nvg _, float ox, float oy, float width, float height, float angle, int image, float alpha)
 => Paint.ImagePattern(ox, oy, width, height, angle, image, alpha);
コード例 #23
0
 /// <inheritdoc cref="Paint.ImagePattern(Vector2D{float}, Vector2D{float}, float, int, float)"/>
 public static Paint ImagePattern(this Nvg _, Vector2D <float> pos, Vector2D <float> size, float angle, int image, float alpha)
 => Paint.ImagePattern(pos, size, angle, image, alpha);
コード例 #24
0
 /// <inheritdoc cref="Rotate(float)"/>
 public static Matrix3X2 <float> TransformRotate(this Nvg _, float a)
 => Rotate(a);
コード例 #25
0
 /// <inheritdoc cref="Scale(Vector2D{float})"/>
 public static Matrix3X2 <float> TransformScale(this Nvg _, float x, float y)
 => Scale(new Vector2D <float>(x, y));
コード例 #26
0
 /// <inheritdoc cref="Scale(Vector2D{float})"/>
 public static Matrix3X2 <float> TransformScale(this Nvg _, Vector2D <float> s)
 => Scale(s);
コード例 #27
0
 /// <inheritdoc cref="Translate(Vector2D{float})"/>
 public static Matrix3X2 <float> TransformTranslate(this Nvg _, Vector2D <float> t)
 => Translate(t);
コード例 #28
0
 /// <inheritdoc cref="RadToDeg(float)"/>
 public static float RadToDeg(this Nvg _, float rad)
 => RadToDeg(rad);
コード例 #29
0
 /// <inheritdoc cref="DegToRad(float)"/>
 public static float DegToRad(this Nvg _, float deg)
 => DegToRad(deg);
コード例 #30
0
 /// <inheritdoc cref="Identity"/>
 public static Matrix3X2 <float> TransformIdentity(this Nvg _)
 => Identity;