示例#1
0
        private Rectangle RenderHelper(SpriteList spriteList, ICaretPosition caret)
        {
            var lines = SplitText(DisplayText);

            if (TrimWhitespaces)
            {
                TrimLinesWhitespaces(lines);
            }
            var pos = new Vector2(0, Padding.Top + CalcVerticalTextPosition(lines));

            caret.StartSync();
            if (String.IsNullOrEmpty(DisplayText))
            {
                pos.X = CalcXByAlignment(lineWidth: 0);
                caret.EmptyText(pos);
                return(Rectangle.Empty);
            }
            caret.ClampTextPos(DisplayText.Length);
            caret.ClampLine(lines.Count);
            Rectangle rect = new Rectangle(Vector2.PositiveInfinity, Vector2.NegativeInfinity);
            int       i    = 0;

            foreach (var line in lines)
            {
                bool lastLine = ++i == lines.Count;
                caret.ClampCol(line.Length - (lastLine ? 0 : 1));
                float lineWidth = MeasureTextLine(line).X;
                pos.X = CalcXByAlignment(lineWidth);
                if (spriteList != null)
                {
                    Renderer.DrawTextLine(
                        Font, pos, line, Color4.White, FontHeight, 0, line.Length, letterSpacing, spriteList, caret.Sync, -1);
                }
                Rectangle lineRect = new Rectangle(pos.X, pos.Y, pos.X + lineWidth, pos.Y + FontHeight);
                if (lastLine)
                {
                    // There is no end-of-text character, so simulate it.
                    caret.Sync(line.Length, new Vector2(lineRect.Right, lineRect.Top), Vector2.Down * fontHeight);
                }
                pos.Y += Spacing + FontHeight;
                caret.NextLine();
                rect = Rectangle.Bounds(rect, lineRect);
            }
            caret.FinishSync();
            return(rect);
        }
示例#2
0
 private void EnsureSpriteLists()
 {
     if (spriteLists == null)
     {
         PrepareRenderer();
         spriteLists = new SpriteList[renderer.Styles.Count];
         for (int i = 0; i < spriteLists.Length; i++)
         {
             spriteLists[i] = new SpriteList();
         }
         renderer.Render(spriteLists, Size, HAlignment, VAlignment, maxDisplayCharacters);
         gradientMapIndices = new int[renderer.Styles.Count];
         for (var i = 0; i < gradientMapIndices.Length; i++)
         {
             gradientMapIndices[i] = renderer.Styles[i].GradientMapIndex;
         }
     }
 }
示例#3
0
 private void PrepareSpriteListAndExtent()
 {
     if (spriteList != null)
     {
         return;
     }
     if (OverflowMode == TextOverflowMode.Minify)
     {
         var savedSpacing = spacing;
         var savedHeight  = fontHeight;
         FitTextInsideWidgetArea();
         spriteList = new SpriteList();
         extent     = RenderHelper(spriteList, Caret);
         spacing    = savedSpacing;
         fontHeight = savedHeight;
     }
     else
     {
         spriteList = new SpriteList();
         extent     = RenderHelper(spriteList, Caret);
     }
 }
示例#4
0
 protected override void OnRelease()
 {
     SpriteList = null;
     base.OnRelease();
 }
示例#5
0
        public static void DrawTextLine(
            IFont font, Vector2 position, string text, Color4 color, float fontHeight, int start, int length, float letterSpacing,
            SpriteList list, Action <int, Vector2, Vector2> onDrawChar = null, int tag = -1)
        {
            int j = 0;

            if (list != null)
            {
                for (int i = 0; i < length; i++)
                {
                    char ch = text[i + start];
                    if (ch != '\n' && ch != '\r' && font.CharSource.Get(ch, fontHeight) != FontChar.Null)
                    {
                        ++j;
                    }
                }
            }
            // Use array instead of list to reduce memory consumption.
            var chars = new SpriteList.CharDef[j];

            j = 0;
            FontChar prevChar          = null;
            var      halfLetterSpacing = letterSpacing * .5f;
            float    savedX            = position.X;

            for (int i = 0; i < length; i++)
            {
                char ch = text[i + start];
                if (ch == '\n')
                {
                    onDrawChar?.Invoke(i, position, Vector2.Down * fontHeight);
                    position.X  = savedX;
                    position.Y += fontHeight;
                    prevChar    = null;
                    continue;
                }
                else if (ch == '\r')
                {
                    continue;
                }
                FontChar fontChar = font.CharSource.Get(ch, fontHeight);
                if (fontChar == FontChar.Null)
                {
                    onDrawChar?.Invoke(i, position, Vector2.Down * fontHeight);
                    continue;
                }
                var scale = fontChar.Height != 0.0f ? fontHeight / fontChar.Height : 0.0f;
                // Pen Position + Bearing + Kerning gives a proper letter position
                // but we have to subtract left padding in order to avoid extra spacing
                position.X += scale * (fontChar.ACWidths.X + fontChar.Kerning(prevChar) + halfLetterSpacing - fontChar.Padding);
                var size         = new Vector2(scale * fontChar.PaddedWidth, fontHeight + scale * (fontChar.PaddedHeight - fontChar.VerticalOffset));
                var charPosition = new Vector2(position.X, position.Y + scale * (fontChar.VerticalOffset - fontChar.Padding));
                if (font.RoundCoordinates)
                {
                    charPosition = new Vector2(charPosition.X.Round(), charPosition.Y.Round());
                }
                onDrawChar?.Invoke(i, charPosition, size);
                chars[j].FontChar = fontChar;
                chars[j].Position = charPosition;
                ++j;
                // We have to add left padding to get actual letter position
                // Width + (Horizontal Advance - Bearing) will give a proper pen position for next letter
                position.X += scale * (fontChar.Width + fontChar.ACWidths.Y + halfLetterSpacing + fontChar.Padding);
                prevChar    = fontChar;
            }
            list.Add(font, color, fontHeight, chars, tag);
        }
示例#6
0
        public static void DrawTextLine(
            IFont font, Vector2 position, string text, Color4 color, float fontHeight, int start, int length, float letterSpacing,
            SpriteList list, Action <int, Vector2, Vector2> onDrawChar = null, int tag = -1)
        {
            int j = 0;

            if (list != null)
            {
                for (int i = 0; i < length; i++)
                {
                    char ch = text[i + start];
                    if (ch != '\n' && ch != '\r' && font.Chars.Get(ch, fontHeight) != FontChar.Null)
                    {
                        ++j;
                    }
                }
            }
            // Use array instead of list to reduce memory consumption.
            var chars = new SpriteList.CharDef[j];

            j = 0;
            FontChar prevChar = null;
            float    savedX   = position.X;

            for (int i = 0; i < length; i++)
            {
                char ch = text[i + start];
                if (ch == '\n')
                {
                    onDrawChar?.Invoke(i, position, Vector2.Down * fontHeight);
                    position.X  = savedX;
                    position.Y += fontHeight;
                    prevChar    = null;
                    continue;
                }
                else if (ch == '\r')
                {
                    continue;
                }
                FontChar fontChar = font.Chars.Get(ch, fontHeight);
                if (fontChar == FontChar.Null)
                {
                    onDrawChar?.Invoke(i, position, Vector2.Down * fontHeight);
                    continue;
                }
                float scale  = fontChar.Height != 0.0f ? fontHeight / fontChar.Height : 0.0f;
                var   xDelta = scale * (fontChar.ACWidths.X + fontChar.Kerning(prevChar) + letterSpacing);
                position.X += xDelta;
                var     size = new Vector2(scale * fontChar.Width, fontHeight - fontChar.VerticalOffset);
                Vector2 roundPos;
                if (font.RoundCoordinates)
                {
                    roundPos = new Vector2(position.X.Round(), position.Y.Round() + fontChar.VerticalOffset);
                    onDrawChar?.Invoke(i, new Vector2((position.X - xDelta).Round(), position.Y.Round()), size);
                }
                else
                {
                    roundPos = new Vector2(position.X, position.Y + fontChar.VerticalOffset);
                    onDrawChar?.Invoke(i, new Vector2(position.X - xDelta, position.Y), size);
                }
                chars[j].FontChar = fontChar;
                chars[j].Position = roundPos;
                ++j;
                position.X += scale * (fontChar.Width + fontChar.ACWidths.Y);
                prevChar    = fontChar;
            }
            list.Add(font, color, fontHeight, chars, tag);
        }