Text Trimming

Posted by: s.mcchesney on 20 June 2018, 4:58 am EST

    • Post Options:
    • Link

    Posted 20 June 2018, 4:58 am EST

    I am working through your library (we are in the process of purchasing it), and while I believe I know the answer to this question, I thought I would ask just in case.

    Is there any way to have a ```

    TextLayout

    
    Thanks!
    
    - Scott McChesney
  • Posted 20 June 2018, 10:19 am EST

    We actually have this feature in our plans but did not have the time to add it, it will be in the next update. In the meantime though you can relatively easily do it in user code, attached is a complete sample that demonstrates how this can be done. The relevant code is as follows:

    
        // ...
        var doc = new GcPdfDocument();
        var g = doc.Pages.Insert(0).Graphics;
        const float maxContentWidth = 400f;
    
        var text = "some long text that won't fit in a single line";
        var fmt = new TextFormat
        {
            FontName = "Segoe UI",
            FontSize = 20
        };
        var tl = new TextLayout();
        tl.Append(text, fmt);
        tl.PerformLayout(true);
        // If the text does not fit, trim it:
        if (tl.ContentWidth > maxContentWidth)
            TrimToWidth(text, fmt, tl, maxContentWidth);
    
        g.DrawTextLayout(tl, new PointF(100, 100));
        // ...
    }
    
    static void TrimToWidth(string text, TextFormat fmt, TextLayout tl, float width)
    {
        var runs = tl.Lines[0].GlyphRuns;
        int len = 0;
        for (int i = runs.Length - 1; i >= 0; i--)
        {
            var run = runs[i];
            if (run.Offset < width)
            {
                float xStop = (width - run.Offset) / run.FontUnitsToSize;
                var gi = run.FirstGlyph;
                for (int j = 0; j < run.GlyphCount; j++)
                {
                    xStop -= gi.GlyphAdvance;
                    if (xStop < 0)
                    {
                        break;
                    }
                    gi = gi.NextGlyph;
                }
                len = gi.CodePointIndex;
                break;
            }
        }
        var sb = new StringBuilder(text.Substring(0, len));
        if (len == 0)
        {
            sb.Append(' ');
            len = 1;
        }
        do
        {
            while (len > 1 && Char.IsWhiteSpace(sb[len - 2]))
            {
                len -= 1;
            }
            sb.Length = len;
            sb[len - 1] = '\u2026'; // Unicode ellipsis symbol
    
            tl.Clear();
            tl.Append(sb.ToString(), fmt);
            tl.PerformLayout(true);
            if (tl.ContentWidth <= width)
            {
                break;
            }
            len -= 1;
        } while (len > 1);
    }
    
    

    Let me know whether this helps.

    Ellipsis.zip

  • Posted 21 June 2018, 2:30 am EST

    This works like a charm. I look forward to this being integrated into the library.

    Thank you very much!

    • Scott McChesney
  • Posted 21 June 2018, 3:38 am EST

    Great, thanks for the heads up!

  • Posted 6 October 2018, 8:35 am EST

    Note that in v2 we now have text trimming built into TextLayout:

    http://demos.componentone.com/gcdocs/gcpdf#TextTrimming

    Thanks.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels