Formatted Text

In the Drawing Simple Text Objects topic, we explored how to draw various types of text and modify properties like font, outline, and fill. We also covered text effects and transformations, lists, and OpenType features. This topic addresses how to format portions of text within a single string, such as applying different font styles to specific parts of the text.

Additionally, this topic covers Measuring Formatted Text and Handling Exceptions.

In Graphics Mill, you can format any type of text. Specifically, any child class of Text supports formatting. For demonstration, we'll use the BoundedText class, but the same principles apply to other text types like PlainText, PathText, DoublePathText, and ArtText.

Paragraph and Text Formatting

Text formatting in Graphics Mill uses the <span> and <p> tags with CSS-like style attributes. Here's how it works:

  1. Mark the text you want to format with <span> and <p> tags.
  2. Set styles using the style attribute.
  3. Initialize a text class with the formatted string.
  4. Use the class's draw method to output the text.

Here's an example:

C#
using (var bitmap = new Bitmap(600, 400, PixelFormat.Format24bppRgb, new RgbColor(255, 255, 255, 255)))
using (var graphics = bitmap.GetGraphics())
{
    var brush = new SolidBrush(RgbColor.Black);

    var text = @"<p style='first-line-indent:20pt; space-before:30pt; space-after:20pt;'>Lorem ipsum dolor sit <span style='color:red;'>amet</span>," +
        @"consectetur adipiscing elit. <span style='bold:true;underline:true;color:rgb(0,0,255)'>Cras</span> elementum quam ac nisi varius gravida. " +
        @"Mauris ornare, <span style='font-name:Times New Roman;font-size:60pt;pen-color:green;pen-width:1px;color:yellow;'>dolor</span> et scelerisque " +
        @"volutpat, <span style='italic:true;color:gray;'>enim urna commodo odio, <span style='color:green;'>consequat</span> fermentum sem arcu</span>" +
        @" sit amet nisl.</p> <p style='first-line-indent:40pt; space-before:60pt; space-after:10pt;'>Aliquam tincidunt id neque in gravida. " +
        @"Mauris mollis est vulputate suscipit facilisis.</p>";

    var boundedText = new BoundedText(text, graphics.CreateFont("Verdana", 26f), brush)
    {
        Rectangle = new System.Drawing.RectangleF(20f, 20f, 560f, 360f)
    };

    graphics.DrawText(boundedText);

    bitmap.Save(@"Images\Output\DrawFormattedText.png");
}

This code produces the following image:

Formatted text

You can also use the <br/> tag to insert line breaks.

To display reserved symbols, use the following combinations:

  • &amp; for & (ampersand)
  • &lt; for < (less than)
  • &gt; for > (greater than)

Paragraph Style

Configure a paragraph's style to control text direction, indentation, and spacing.

Name Description Examples
direction Specifies text direction (RTL or LTR). style='direction:RTL'
first-line-indent Indents the first line of the paragraph. style='first-line-indent:20pt'
left-indent Indents the left side of the paragraph. style='left-indent:10pt'
right-indent Indents the right side of the paragraph. style='right-indent:10pt'
space-before Sets space before the paragraph. style='space-before:30pt'
space-after Sets space after the paragraph. style='space-after:20pt'
char-style Sets the paragraph's default character style. This is not a key inside style like the other rows here. It is a separate attribute on the paragraph tag, and its value is itself a style string using the same keys as the Char Style and Color Style tables below. <p char-style='bold:true;color:red'>
alignment Specifies the paragraph alignment (left, center, right, justification, justification-last-left, justification-last-center, justification-last-right). style='alignment:center'

Char Style

Customize character style to change the appearance of your text.

Name Description Examples
font-family Specifies the font family name. style='font-family:Arial'
font-name Specifies the PostScript font name. If the specified font is not found, the Text.CharStyle font is used. style='font-name:LucidaSans'
font-style Specifies the font style name. style='font-style:Narrow Italic'
font-size Specifies the font size. style='font-size:12pt'
bold Enables bold style. style='bold:true'
italic Enables italic style. style='italic:true'
underline Enables underlining. style='underline:true'
leading Specifies leading. style = 'leading:50pt'
tracking Specifies letter spacing, in thousandths of em. style = 'tracking:500'
word-spacing-scale Specifies word spacing. style = 'word-spacing-scale:3'
horz-scale Specifies horizontal scaling, as a decimal factor where 1 is normal width. Don't use a unit or a percent sign. style='horz-scale:1.2' (120% width)
vert-scale Specifies vertical scaling, as a decimal factor where 1 is normal height. Don't use a unit or a percent sign. style='vert-scale:1.2' (120% height)
strike-through Enables strike-through style. style='strike-through:true'
baseline-shift Adjusts the vertical position of individual characters relative to the baseline of the text. style='baseline-shift:0pt'
sup Enables superscript. style='sup:true'
sup-size Specifies the superscript size, as a decimal factor of the normal font size. Default is 0.583. style='sup-size:0.583'
sup-position Specifies how far the superscript is raised, as a decimal factor of the normal font size. Default is 0.333. style='sup-position:0.333'
sub Enables subscript. style='sub:true'
sub-size Specifies the subscript size, as a decimal factor of the normal font size. Default is 0.583. style='sub-size:0.583'
sub-position Specifies how far the subscript is lowered, as a decimal factor of the normal font size. Default is 0.333. style='sub-position:0.333'

Color Style

Adjust color styles to change the appearance of text and outlines. The color, pen-color, ink-color, and pen-ink-color keys below accept any of these formats: rgb(r,g,b) or rgb(r,g,b,a); cmyk(c,m,y,k) or cmyk(c,m,y,k,a); gray(g) or gray(g,a); lab(l,a,b) or lab(l,a,b,alpha); spot(tint) or spot(tint,a); a plain palette index number; or a named color such as red or crimson.

Name Description Examples
color Specifies the text fill color. style='color:rgb(0,255,0)'
pen-color Specifies the text outline color. style='pen-color:rgb(0,255,0)'
pen-width Specifies the text outline width. style='pen-width:1px'
ink-name Specifies the ink name for text fill. style='ink-name:black'
ink-solidity Specifies the ink solidity for text fill, as a decimal factor where 1 is full solidity. Don't use a unit or a percent sign. style='ink-solidity:1'
ink-color Specifies the ink color for text fill. style='ink-color:rgb(0,0,0)'
pen-ink-name Specifies the ink name for text outline. style='pen-ink-name:black'
pen-ink-solidity Specifies the ink solidity for text outline, as a decimal factor where 1 is full solidity. Don't use a unit or a percent sign. style='pen-ink-solidity:1'
pen-ink-color Specifies the ink color for text outline. style='pen-ink-color:rgb(0,0,0)'

List Style

These keys style a list item directly on its <p> or <li> tag. The Lists section below covers a separate, shorter way to write lists using <ol> and <ul> tags - those tags set some of the same underlying properties, but under different attribute names.

Name Description Examples
list-type Specifies the type of list (none, bullets, numbers). style='list-type:bullets'
level Specifies the level of the list item. style='level:1'
number-format Specifies the number format for ordered lists (none, number, lower-letter, upper-letter, lower-roman, upper-roman). style='number-format:lower-roman'
number-mode Specifies the numbering mode (continue-from-previous, start-at). style='number-mode:start-at'
number-start-at Specifies the starting number for ordered lists. style='number-start-at:3'
bullet-char Specifies the bullet character for unordered lists, as a # followed by the character's decimal Unicode code point. style='bullet-char:#42' (asterisk)
bullet-number-pos-alignment Specifies the alignment of bullet or number position (left, center, right). style='bullet-number-pos-alignment:center'
bullet-number-tab-position Specifies the tab position for bullets or numbers. style='bullet-number-tab-position:10pt'
text-indent Specifies the text indent of list elements. style='text-indent:30pt'
level-indent Specifies the level indent of list elements. style='level-indent:50pt'

Tab Style

To register a tab stop within a paragraph, add a <tab> element as a direct child of <p> or <li>, at the point in the markup where the stop should be declared. The element's content is a single value in points that sets the stop's horizontal offset from the paragraph's left edge, for example <tab>100pt</tab>; if the element is left empty, the offset defaults to 0. Use the style attribute to configure the stop's alignment, leader, and character-alignment target, as described in the table below.

Each tab stop within a paragraph must have a unique offset - declaring two stops at the same position (or omitting the content of more than one) throws an error when the text is parsed. A <tab> element can't be nested inside another <tab>, and isn't allowed anywhere except directly inside <p> or <li>.

Declaring a <tab> element only registers the stop - it doesn't by itself mark where in the text the layout should jump to it. Place an actual tab character in the text at that point, just as you would with plain text. Here's an example that lays out two right-aligned, dot-leadered columns:

A tab character can run out of stops to advance to. This happens when the paragraph has no <tab> elements, or when all the stops declared before that point are already used. In that case, the text falls back to a default tab stop.

Default tab stops sit on a fixed grid, spaced every 36pt (0.5 inch) from the paragraph's left edge. They are always left-aligned and have no leader.

C#
using (var bitmap = new Bitmap(600, 160, PixelFormat.Format24bppRgb, new RgbColor(255, 255, 255, 255)))
using (var graphics = bitmap.GetGraphics())
{
    var brush = new SolidBrush(RgbColor.Black);

    // The <tab> element only registers the stop; the "\t" character
    // in the span text is what makes the layout actually jump to it.
    // Labels of different lengths still line up at the same tab stop.
    var text = "<p style='space-after:6pt;'><tab style='alignment:right;leader:#46;'>500pt</tab><span>Opening Keynote\t9:00 AM</span></p>" +
               "<p style='space-after:6pt;'><tab style='alignment:right;leader:#46;'>500pt</tab><span>Color Management Deep Dive\t10:30 AM</span></p>" +
               "<p style='space-after:6pt;'><tab style='alignment:right;leader:#46;'>500pt</tab><span>Working with Vector PDFs\t1:00 PM</span></p>" +
               "<p><tab style='alignment:right;leader:#46;'>500pt</tab><span>Closing Panel\t3:30 PM</span></p>";

    var boundedText = new BoundedText(text, graphics.CreateFont("Verdana", 16f), brush)
    {
        Rectangle = new System.Drawing.RectangleF(20f, 20f, 560f, 120f)
    };

    graphics.DrawText(boundedText);

    bitmap.Save(@"Images\Output\DrawFormattedTab.png");
}

This code produces the following image:

Formatted tab
Name Description Examples
alignment Specifies the alignment of the tab stop (left, center, right, character). Default is left. style='alignment:center'
leader Specifies the character(s) used to fill the gap before the tab stop, as one or more #-prefixed decimal Unicode code points concatenated together. A single code repeats a single character; multiple codes form a repeating multi-character pattern. style='leader:#46' (dot leader); style='leader:#49#50#51' (repeats "123")
align-on Specifies the character to align on for character-aligned tabs (alignment:character), as a # followed by its decimal Unicode code point. style='align-on:#46' (period)

OpenType Features

The ot format option allows you to apply OpenType features if your font supports them. To disable features, add ,0 after the feature name. Here's an example of drawing formatted text with superscript, small caps, and fraction features enabled:

C#
using (var bitmap = new Bitmap(400, 130, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    var brush = new SolidBrush(RgbColor.Black);

    var text = @"<p>OpenType Regular Text 1234567890</p>" +
               @"<p><span style='ot:sups'>OpenType Superscript 1234567890</span></p>" +
               @"<p><span style='ot:smcp;ot:c2sc'>OpenType Small Caps 1234567890</span></p>" +
               @"<p><span style='ot:frac;ot:lnum'>OpenType Fractions 1 2/3</span></p>";

    var boundedText = new BoundedText(text, FontRegistry.Installed.CreateFont("Lyon Text", "Regular", 24, graphics.DpiX, graphics.DpiX), brush)
    {
        Rectangle = new System.Drawing.RectangleF(10f, 10f, 380f, 110f)
    };

    graphics.DrawText(boundedText);

    bitmap.Save(@"Images\Output\DrawOpenType.png");
}

This code produces the following text:

OpenType features

For the full list of supported OpenType features, refer to the OpenTypeFeatureTag topic.

OpenType Style

These keys enable advanced typographic features through OpenType.

Name Description Examples
ot Enables OpenType features. To disable a feature, add ,0 after the feature name (e.g., liga,0). To explicitly enable it, use ,1 (e.g., liga,1), or simply omit the value. style='ot:liga,0;ot:sups'
all-caps Enables all caps style. style='all-caps:true'
small-caps Enables small caps style. style='small-caps:true'
small-caps-size Specifies the small caps size, as a decimal factor of the normal font size. This is not a point size. Default is 0.7. style='small-caps-size:0.7'
digit-type Sets the digit type (hindi, arabic, farsi). style='digit-type:hindi'

Lists

Graphics Mill supports numbered and bulleted lists. Use the <ol> tag for numbered lists and the <ul> tag for bulleted lists. Each list item must be tagged with <li>.

The <ol> and <ul> tags are a shorthand: they set the same underlying List Style properties on each <li> they contain, but through their own type and start attributes instead of number-format, bullet-char, and number-start-at. Use <ol>/<ul> for a plain list. Style a <p> or <li> directly with the List Style keys when you need finer control, such as bullet-number-pos-alignment or level-indent.

C#
using (var bitmap = new Bitmap(600, 420, PixelFormat.Format24bppRgb, new RgbColor(255, 255, 255, 255)))
using (var graphics = bitmap.GetGraphics())
{
    var brush = new SolidBrush(RgbColor.Black);

    var text = @"<ol style='type:upperRoman;'>" +
                  @"<li>The first level element." +
                     @"<ul style='type:bullet; text-indent:30pt; level-indent:50pt;'>" +
                        @"<li>The second level element.</li>" +
                        @"<li>Lorem ipsum dolor sit amet consectetur adipiscing elit.</li>" +
                        @"<li>Cras elementum quam ac nisi varius gravida.</li>" +
                     @"</ul>" +
                  @"</li>" +
                  @"<li>The first level element." +
                     @"<ul style='type:minus;'>" +
                        @"<li>The second level element.</li>" +
                        @"<li>Lorem ipsum dolor sit amet consectetur adipiscing elit.</li>" +
                        @"<li>Cras elementum quam ac nisi varius gravida.</li>" +
                     @"</ul>" +
                  @"</li>" +
               @"</ol>";

    var boundedText = new BoundedText(text, graphics.CreateFont("Verdana", 26f), brush)
    {
        Rectangle = new System.Drawing.RectangleF(20f, 20f, 600f, 420f)
    };

    graphics.DrawText(boundedText);

    bitmap.Save(@"Images\Output\DrawFormattedList.png");
}

This code produces the following image:

Formatted list

Configure lists using the style attribute. The type parameter can be one of the following:

For numbered lists:

  • number - Default type with numbers (1, 2, 3, etc.).
  • lowerLetter - Lower-alpha (a, b, c, etc.).
  • upperLetter - Upper-alpha (A, B, C, etc.).
  • lowerRoman - Lower-roman (i, ii, iii, etc.).
  • upperRoman - Upper-roman (I, II, III, etc.).

For bulleted lists:

  • none - Default type without markers.
  • bullet - Circle marker.
  • minus - Minus marker.

Use any symbol by specifying its UTF-8 code, for example:

  • <ul style='type: #9675;'> for circle.
  • <ul style='type: #9632;'> for square.
  • <ul style='type: #9679;'> for disc.

To start a numbered list with a specific number, use the start argument of the style attribute. For example, <ol style='start: 3; type: upperRoman;'> starts the list from III.

Measuring Formatted Text

Measuring text involves determining the dimensions of a rectangle that tightly encloses the text. To measure formatted text, use the Text.GetBlackBox(FontRegistry, Single, Single) method:

C#
using (var bitmap = new Bitmap(160, 160, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    var text = @"<span style='font-size:36pt;color:red;'>Art</span> " +
               @"<span style='color:green;'>Round</span> <span style='font-size:36pt;color:blue;'>Text</span>";
    using (var roundText = new RoundText(text, graphics.CreateFont("Verdana", 26f), new System.Drawing.PointF(80, 80)))
    {
        roundText.Bend = 0.9f;
        graphics.DrawText(roundText);
        graphics.DrawRectangle(
            new Pen(RgbColor.Gray, 1f), 
            roundText.GetBlackBox(graphics.FontRegistry, graphics.DpiX, graphics.DpiY));
        bitmap.Save(@"Images\Output\MeasureFormattedText.png");
    }
}            

This code draws the text and its black box:

Measuring formatted text.

Handling Exceptions

The exception classes for formatted text are:

The following code catches the UnknownTagException error because the <article> tag is not supported:

C#
using (var bitmap = new Bitmap(600, 350, PixelFormat.Format24bppRgb, new RgbColor(255, 255, 255, 255)))
using (var graphics = bitmap.GetGraphics())
{
    var text = @"<article>Lorem ipsum dolor sit <span style='color:red;'>amet</span></article>";
    try
    {
        var plainText = new PlainText(text, graphics.CreateFont("Verdana", 26f));
        graphics.DrawText(plainText);
        bitmap.Save(@"Images\Output\DrawFormattedText.png");
    }
    catch (UnknownTagException e)
    {
        Debug.WriteLine("The {0} exception message is caught.", e.GetType());
        Debug.WriteLine("The unknown tag: " + e.Message + ".");
    }
}

The output is:

The Aurigma.GraphicsMill.Drawing.UnknownTagException exception message is caught.
The unknown tag: article.

See Also

Reference

Manual