Ejemplo n.º 1
0
        /// <summary>
        /// Renders the text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="style">The style.</param>
        /// <param name="dpi">The dpi.</param>
        public void RenderText(string text, FontSpan style, Vector2 dpi)
        {
            var glyphsToRender = this.layoutEngine.GenerateLayout(text, style);

            foreach (var g in glyphsToRender)
            {
                g.Glyph.RenderTo(this.renderer, g.Location, dpi);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Measures the text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="style">The style.</param>
        /// <param name="dpi">The dpi.</param>
        /// <returns>The size of the text if it was to be rendered.</returns>
        public Size MeasureText(string text, FontSpan style, Vector2 dpi)
        {
            var glyphsToRender = this.layoutEngine.GenerateLayout(text, style);

            var left  = glyphsToRender.Min(x => x.Location.X);
            var right = glyphsToRender.Max(x => x.Location.X + x.Width);

            var top    = glyphsToRender.Min(x => x.Location.Y);
            var bottom = glyphsToRender.Max(x => x.Location.Y + x.Height);

            var topLeft     = new Vector2(left, top) * dpi;
            var bottomRight = new Vector2(right, bottom) * dpi;

            return(new Size(bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y));
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Measures the text.
 /// </summary>
 /// <param name="text">The text.</param>
 /// <param name="style">The style.</param>
 /// <param name="dpi">The dpi.</param>
 /// <returns>The size of the text if it was to be rendered.</returns>
 public Size MeasureText(string text, FontSpan style, float dpi)
 {
     return(this.MeasureText(text, style, new Vector2(dpi)));
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Generates the layout.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="style">The style.</param>
        /// <returns>A collection of layout that describe all thats needed to measure or render a series of glyphs.</returns>
        public ImmutableArray <GlyphLayout> GenerateLayout(string text, FontSpan style)
        {
            AppliedFontStyle   spanStyle = style.GetStyle(0, text.Length);
            List <GlyphLayout> layout    = new List <GlyphLayout>(text.Length);

            float         lineHeight            = 0f;
            Vector2       location              = Vector2.Zero;
            float         lineHeightOfFirstLine = 0;
            bool          firstLine             = true;
            GlyphInstance previousGlyph         = null;
            float         scale = 0;

            for (var i = 0; i < text.Length; i++)
            {
                if (spanStyle.End < i)
                {
                    spanStyle     = style.GetStyle(i, text.Length);
                    previousGlyph = null;
                }

                if (spanStyle.Font.LineHeight > lineHeight)
                {
                    // get the larget lineheight thus far
                    scale      = spanStyle.Font.EmSize * 72;
                    lineHeight = (spanStyle.Font.LineHeight * spanStyle.PointSize) / scale;
                }

                if (firstLine && lineHeight > lineHeightOfFirstLine)
                {
                    lineHeightOfFirstLine = lineHeight;
                }

                var c = text[i];
                switch (c)
                {
                case '\r':
                    // carrage return resets the XX coordinate to 0
                    location.X    = 0;
                    previousGlyph = null;

                    break;

                case '\n':
                    // carrage return resets the XX coordinate to 0
                    location.X    = 0;
                    location.Y   += lineHeight;
                    lineHeight    = 0;  // reset line height tracking for next line
                    previousGlyph = null;
                    firstLine     = false;
                    break;

                case '\t':
                {
                    var glyph   = spanStyle.Font.GetGlyph(c);
                    var width   = (glyph.AdvanceWidth * spanStyle.PointSize) / scale;
                    var tabStop = width * spanStyle.TabWidth;

                    // advance to a position > width away that
                    var dist = tabStop - ((location.X + width) % tabStop);
                    location.X   += dist;
                    previousGlyph = null;
                }

                break;

                case ' ':
                {
                    var glyph = spanStyle.Font.GetGlyph(c);
                    var width = (glyph.AdvanceWidth * spanStyle.PointSize) / scale;
                    location.X   += width;
                    previousGlyph = null;
                }

                break;

                default:
                {
                    var glyph  = spanStyle.Font.GetGlyph(c);
                    var width  = (glyph.AdvanceWidth * spanStyle.PointSize) / scale;
                    var height = (glyph.Height * spanStyle.PointSize) / scale;

                    var glyphLocation = location;
                    if (spanStyle.ApplyKerning && previousGlyph != null)
                    {
                        // if there is special instructions for this glyph pair use that width
                        var scaledOffset = (spanStyle.Font.GetOffset(glyph, previousGlyph) * spanStyle.PointSize) / scale;

                        glyphLocation += scaledOffset;

                        // only fix the 'X' of the current tracked location but use the actual 'X'/'Y' of the offset
                        location.X = glyphLocation.X;
                    }

                    layout.Add(new GlyphLayout(new Glyph(glyph, spanStyle.PointSize), glyphLocation, width, height));

                    // move foraward the actual with of the glyph, we are retaining the baseline
                    location.X   += width;
                    previousGlyph = glyph;
                }

                break;
                }
            }

            var offset = new Vector2(0, lineHeightOfFirstLine);

            for (var i = 0; i < layout.Count; i++)
            {
                var glyphLayout = layout[i];
                layout[i] = new GlyphLayout(glyphLayout.Glyph, glyphLayout.Location + offset, glyphLayout.Width, glyphLayout.Height);
            }
            return(layout.ToImmutableArray());
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Renders the text.
 /// </summary>
 /// <param name="text">The text.</param>
 /// <param name="style">The style.</param>
 /// <param name="dpi">The dpi.</param>
 public void RenderText(string text, FontSpan style, float dpi)
 {
     this.RenderText(text, style, new Vector2(dpi));
 }