예제 #1
0
        public static Point PivotPoint(Align align, Rectangle rect)   // computes the pivot of a given rectangle
        {
            int pivotPosX = align.HasFlag(Align.Left) ? 0 : align.HasFlag(Align.Right) ? rect.Width : rect.Width / 2;
            int pivotPosY = align.HasFlag(Align.Top) ? 0 : align.HasFlag(Align.Bottom) ? rect.Height : rect.Height / 2;

            return(new Point(pivotPosX, pivotPosY));
        }
예제 #2
0
 public static Align Flip(Align al)   // switches left/right flag if present
 {
     if (al.HasFlag(Align.Left))
     {
         al += Align.Right - Align.Left;
     }
     else if (al.HasFlag(Align.Right))
     {
         al -= Align.Right - Align.Left;
     }
     return(al);
 }
예제 #3
0
        /// <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;
        }
예제 #4
0
        public static Vector2 Offset(this Align align, Vector2 size, Rectangle bounds, Vector2 origin, Vector2 scale)
        {
            var offset = new Vector2(bounds.Width / 2 - size.X / 2 + origin.X * scale.X, bounds.Height / 2 - size.Y / 2 + origin.Y * scale.Y);

            if (align.HasFlag(Align.Left))
            {
                offset.X -= offset.X;
            }
            if (align.HasFlag(Align.Right))
            {
                offset.X += offset.X;
            }
            if (align.HasFlag(Align.Top))
            {
                offset.Y -= offset.Y;
            }
            if (align.HasFlag(Align.Bottom))
            {
                offset.Y += offset.Y;
            }
            return(new Vector2(bounds.X + offset.X, bounds.Y + offset.Y));
        }
예제 #5
0
        /// <summary>
        /// Measures the specified multi-text string.<br/>
        /// Measured values are returned in local space.
        /// </summary>
        /// <param name="bounds">Contains the bounds box of the multi-text when returned.</param>
        public static void TextBoxBounds(this Nvg nvg, Vector2D <float> pos, float breakRowWidth, string @string, string end, out Rectangle <float> bounds)
        {
            Fontstash fons     = nvg.fontManager.Fontstash;
            State     state    = nvg.stateStack.CurrentState;
            float     scale    = nvg.fontManager.GetFontScale() * nvg.pixelRatio.DevicePxRatio;
            float     invscale = 1.0f / scale;
            int       nrows;
            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)
            {
                bounds = default;
                return;
            }

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

            state.TextAlign = Align.Left | vAlign;

            float minX = pos.X, maxX = pos.X;
            float minY = pos.Y, maxY = pos.Y;

            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.LineBounds(0, out float rMinY, out float rMaxY);
            rMinY *= invscale;
            rMaxY *= invscale;

            while ((nrows = TextBreakLines(nvg, @string, end, breakRowWidth, out TextRow[] rows, 2)) != 0)
            {
                for (uint i = 0; i < nrows; i++)
                {
                    float rMinX, rMaxX;
                    float dx = 0.0f;
                    if (hAlign.HasFlag(Align.Left))
                    {
                        dx = 0.0f;
                    }
                    else if (hAlign.HasFlag(Align.Centre))
                    {
                        dx = breakRowWidth * 0.5f - rows[i].Width * 0.5f;
                    }
                    else if (hAlign.HasFlag(Align.Right))
                    {
                        dx = breakRowWidth - rows[i].Width;
                    }
                    rMinX = pos.X + rows[i].MinX + dx;
                    rMaxX = pos.X + rows[i].MaxX + dx;
                    minX  = MathF.Min(minX, rMinX);
                    maxX  = MathF.Max(maxX, rMaxX);

                    minY = MathF.Min(minY, pos.Y + rMinY);
                    maxY = MathF.Max(maxY, pos.Y + rMaxY);

                    pos.Y += lineh * state.LineHeight;
                }
                @string = rows[nrows - 1].Next;
            }

            state.TextAlign = oldAlign;

            bounds = new Rectangle <float>(new Vector2D <float>(minX, minY), new Vector2D <float>(maxX, maxY) - new Vector2D <float>(minX, minY));
        }