Exemple #1
0
                    /// <summary>
                    /// Sets the formatting for the given range of characters in the line
                    /// </summary>
                    public void SetFormatting(int start, int end, GlyphFormat format, bool onlyChangeColor)
                    {
                        Vector4 bbColor = QuadBoard.GetQuadBoardColor(format.Data.Item4);

                        for (int n = start; n <= end; n++)
                        {
                            if (onlyChangeColor)
                            {
                                var quadBoard = glyphBoards[n];
                                quadBoard.bbColor = bbColor;

                                glyphBoards[n]     = quadBoard;
                                formattedGlyphs[n] = new FormattedGlyph(formattedGlyphs[n].glyph, format);
                            }
                            else if (!formattedGlyphs[n].format.Equals(format))
                            {
                                IFontStyle fontStyle = FontManager.GetFontStyle(format.Data.Item3);
                                float      scale     = format.Data.Item2 * fontStyle.FontScale;
                                Glyph      glyph     = fontStyle[chars[n]];
                                Vector2    glyphSize = new Vector2(glyph.advanceWidth, fontStyle.Height) * scale;

                                formattedGlyphs[n] = new FormattedGlyph(glyph, format);
                                locData[n]         = new GlyphLocData(glyph.MatFrame.Material.size * scale, glyphSize);
                                glyphBoards[n]     = glyph.GetQuadBoard(format, bbColor);
                            }
                        }
                    }
                /// <summary>
                /// Updates the position of the right character.
                /// </summary>
                private float UpdateCharOffset(Line line, int right, int left, Vector2 pos, float xAlign)
                {
                    char           ch             = line.Chars[right];
                    FormattedGlyph formattedGlyph = line.FormattedGlyphs[right];
                    IFontStyle     fontStyle      = FontManager.GetFontStyle(formattedGlyph.format.StyleIndex);

                    float textSize    = formattedGlyph.format.TextSize,
                          formatScale = textSize * fontStyle.FontScale,
                    // Quick fix for CJK characters in Space Engineers font data
                          cjkOffset = (formattedGlyph.format.StyleIndex.X == 0 && ch >= 0x4E00) ? (-4f * textSize) : 0f;

                    // Kerning adjustment
                    if (left >= 0)
                    {
                        GlyphFormat leftFmt = line.FormattedGlyphs[left].format, rightFmt = formattedGlyph.format;

                        if (leftFmt.StyleIndex == rightFmt.StyleIndex && leftFmt.TextSize == rightFmt.TextSize)
                        {
                            pos.X += fontStyle.GetKerningAdjustment(line.Chars[left], ch) * formatScale;
                        }
                    }

                    GlyphLocData locData = line.LocData[right];

                    line.SetOffsetAt(right, new Vector2()
                    {
                        X = pos.X + locData.bbSize.X * .5f + (formattedGlyph.glyph.leftSideBearing * formatScale) + xAlign,
                        Y = pos.Y - (locData.bbSize.Y * .5f) + (fontStyle.BaseLine * formatScale) + cjkOffset
                    });

                    return(pos.X + locData.chSize.X);
                }
Exemple #3
0
                    /// <summary>
                    /// Recalculates the width and height of the line.
                    /// </summary>
                    public void UpdateSize()
                    {
                        _size = Vector2.Zero;

                        if (chars.Count > 0)
                        {
                            for (int n = 0; n < locData.Count; n++)
                            {
                                GlyphLocData sizeData = locData[n];

                                if (sizeData.chSize.Y > _size.Y)
                                {
                                    _size.Y = sizeData.chSize.Y;
                                }

                                float chWidth = sizeData.chSize.X;

                                if (chars[n] == '\t')
                                {
                                    FormattedGlyph formattedGlyph = formattedGlyphs[n];
                                    IFontStyle     fontStyle      = FontManager.GetFontStyle(formattedGlyph.format.StyleIndex);
                                    float          scale          = formattedGlyph.format.TextSize * fontStyle.FontScale;

                                    chWidth = formattedGlyphs[n].glyph.advanceWidth * scale;
                                    float rem = _size.X % chWidth;

                                    if (rem < chWidth * .8f)
                                    {
                                        chWidth -= rem;
                                    }
                                    else // if it's really close, just skip to the next stop
                                    {
                                        chWidth += (chWidth - rem);
                                    }

                                    sizeData.chSize.X = chWidth;
                                    sizeData.bbSize.X = chWidth;

                                    locData[n] = sizeData;
                                }

                                _size.X += chWidth;
                            }
                        }
                    }
        public IFormattedText FormatText(string text, FormatOptions formatOptions)
        {
            var colorStack = new Stack<Color>();
            colorStack.Push(Color.White);
            var fontMetrics = m_registeredFonts[GetFontId(formatOptions.Font)];
            var ansiFontMetrics = m_registeredFonts[GetFontId(formatOptions.AnsiFont)];
            var ascentOffset = Math.Max(fontMetrics.m_ascentInPixels, ansiFontMetrics.m_ascentInPixels) - fontMetrics.m_ascentInPixels;
            var ansiAscentOffset = Math.Max(fontMetrics.m_ascentInPixels, ansiFontMetrics.m_ascentInPixels) - ansiFontMetrics.m_ascentInPixels;

            float currentX = 0;
            float currentY = 0;

            // ensures the last line
            string textCopy = text.EndsWith("\n") ? text : text + "\n";

            var charArray = textCopy.ToArray();
            var glyphs = new List<FormattedGlyph>();
            var lines = new List<FormattedText.FormattedLine>();
            var maxLineWidth = 0.0f;
            var lineHeight = Math.Max(fontMetrics.m_fontObject.Height, ansiFontMetrics.m_fontObject.Height);
            var lineSpacing = formatOptions.LineSpacing + lineHeight;

            for (int i = 0; i < charArray.Length; ++i)
            {
                var ch = charArray[i];
                if (ch == ' ')
                {
                    var fg = new FormattedGlyph
                    {
                        m_pos = new Vector2(currentX, IsAnsiChar(ch) ? ansiAscentOffset : ascentOffset),
                        m_width = ansiFontMetrics.m_spaceWidth,
                        m_color = colorStack.Peek(),
                        m_glyph = ch,
                    };
                    glyphs.Add(fg);
                    currentX += fg.m_width;
                }
                else if (ch == '\x3000')
                {
                    var fg = new FormattedGlyph
                    {
                        m_pos = new Vector2(currentX, IsAnsiChar(ch) ? ansiAscentOffset : ascentOffset),
                        m_width = ansiFontMetrics.m_fullWidthSpaceWidth,
                        m_color = colorStack.Peek(),
                        m_glyph = ch,
                    };
                    glyphs.Add(fg);
                    currentX += fg.m_width;
                }
                else if (ch == '\t')
                {
                    var fg = new FormattedGlyph
                    {
                        m_pos = new Vector2(currentX, IsAnsiChar(ch) ? ansiAscentOffset : ascentOffset),
                        m_width = ansiFontMetrics.m_spaceWidth * formatOptions.TabSpaces,
                        m_color = colorStack.Peek(),
                        m_glyph = ch,
                    };
                    glyphs.Add(fg);
                    currentX += fg.m_width;;
                }
                else if (ch == '\n')
                {
                    var line = new FormattedText.FormattedLine();
                    line.m_glyphs = glyphs.ToArray();
                    line.m_offset = new Vector2(0, currentY);

                    var lineWidth = Math.Max(currentX - formatOptions.CharSpacing, 0);
                    maxLineWidth = Math.Max(maxLineWidth, lineWidth);

                    if (formatOptions.Alignment == Alignment.CenterTop
                        || formatOptions.Alignment == Alignment.CenterMiddle
                        || formatOptions.Alignment == Alignment.CenterBottom)
                    {
                        line.m_offset.X = -lineWidth * 0.5f;
                    }
                    else if (formatOptions.Alignment == Alignment.RightTop
                             || formatOptions.Alignment == Alignment.RightMiddle
                             || formatOptions.Alignment == Alignment.RightBottom)
                    {
                        line.m_offset.X = -lineWidth;
                    }

                    currentY += lineSpacing;
                    currentX = 0;
                    glyphs.Clear();
                    lines.Add(line);
                }
                else
                {
                    if (!formatOptions.DisableRTF && ch == '[' && i + 1 < charArray.Length)
                    {
                        if (charArray[i + 1] != '[')
                        {
                            int j = i + 1;
                            for (; j < charArray.Length; ++j)
                            {
                                if (charArray[j] == ']')
                                {
                                    break;
                                }
                            }
                            string token = new string(charArray, i + 1, j - i - 1);
                            if (token.StartsWith("color:", StringComparison.InvariantCultureIgnoreCase))
                            {
                                string colorCode = token.Substring(6);
                                // use Style library color syntax
                                var color = Style.Values.Color.Parse(colorCode);
                                colorStack.Push(new Color(color.Red, color.Green, color.Blue, color.Alpha));
                            }
                            else if (token == "/color" && colorStack.Count > 1)
                            {
                                colorStack.Pop();
                            }

                            i = j;
                            continue;
                        }
                        else
                        {
                            ++i;
                        }
                    }

                    var glyphData = Load(ch, formatOptions);
                    var fg = new FormattedGlyph
                    {
                        m_pos = new Vector2(currentX, IsAnsiChar(ch) ? ansiAscentOffset : ascentOffset),
                        m_width = glyphData.m_glyphSize.Width,
                        m_color = colorStack.Peek(),
                        m_glyph = ch,
                    };
                    glyphs.Add(fg);
                    currentX += fg.m_width + formatOptions.CharSpacing;
                }
            }

            var offsetY = 0.0f;
            var textHeight = lines.Count > 0
                             ? lineSpacing * (lines.Count - 1) + lineHeight
                             : 0;
            if (formatOptions.Alignment == Alignment.LeftMiddle
                || formatOptions.Alignment == Alignment.CenterMiddle
                || formatOptions.Alignment == Alignment.RightMiddle)
            {
                offsetY = -textHeight * 0.5f;
            }
            else if (formatOptions.Alignment == Alignment.LeftBottom
                     || formatOptions.Alignment == Alignment.CenterBottom
                     || formatOptions.Alignment == Alignment.RightBottom)
            {
                offsetY = -textHeight;
            }

            return new FormattedText
            {
                Text = text,
                FormatOptions = formatOptions,
                Offset = new Point(0, offsetY),
                Size = new Size(maxLineWidth, textHeight),
                RichTextFormat = !formatOptions.DisableRTF,
                m_lines = lines.ToArray()
            };
        }