Text Formatting and Layout

DirectWrite provides two interfaces for formatting text: IDWriteTextFormat and IDWriteTextLayout. IDWriteTextFormat describes only the format for text and is used in cases when an entire string is to be the same font size, style, weight and so on. On the other hand, IDWriteTextLayout encapsulates both a text string and the formatting for specified ranges of the string. This document describes each interface and their uses. For more information about the creation and methods of these interfaces, see the IDWriteTextFormat and IDWriteTextLayout reference pages.

This document contains the following parts:

IDWriteTextFormat

An IDWriteTextFormat object is used to:

  • Describe the format for an entire string when rendering. To render a string with multiple formats, use an IDWriteTextLayout object.
  • Specify the default text format when creating an IDWriteTextLayout object.

To create an IDWriteTextFormat object, you use the IDWriteFactory::CreateTextFormat method and specify the font family, font collection, font weight, font size (in DIPs), locale name.

Modifying an IDWriteTextFormat

Once an IDWriteTextFormat interface is created, some values cannot be changed: the font family, collection, weight, and size, as well the locale name. To change these values, a new IDWriteTextFormat object must be created.

IDWriteTextLayout enables you to change the properties above without recreating anything. IDWriteTextFormat enables you to make format changes that apply to the entire text, such as text alignment. If you want to apply formatting to specific character ranges, you should do so by using a IDWriteTextLayout.

IDWriteTextFormat provides methods to set the text alignment, flow direction, incremental tab stop, line spacing, paragraph alignment, trimming, and word wrapping. These properties can be changed at any time after the creation of the IDWriteTextFormat object.

IDWriteTextLayout

The IDWriteTextLayout interface, unlike IDWriteTextFormat, represents both a block of text and the associated formatting. IDWriteTextFormat represents initial formatting information. The following example shows how to create an IDWriteTextLayout object using IDWriteFactory::CreateTextLayout.

// Create a text layout using the text format.
if (SUCCEEDED(hr))
{
    RECT rect;
    GetClientRect(hwnd_, &rect); 
    float width  = rect.right  / dpiScaleX_;
    float height = rect.bottom / dpiScaleY_;

    hr = pDWriteFactory_->CreateTextLayout(
        wszText_,      // The string to be laid out and formatted.
        cTextLength_,  // The length of the string.
        pTextFormat_,  // The text format to apply to the string (contains font information, etc).
        width,         // The width of the layout box.
        height,        // The height of the layout box.
        &pTextLayout_  // The IDWriteTextLayout interface pointer.
        );
}

The text in an IDWriteTextLayout object cannot be changed once the object is created. To change the text you must delete the existing object and create a new IDWriteTextLayout object.

You can use an IDWriteTextLayout to format specified ranges of text. IDWriteTextLayout also provides methods for changing font style and weight, and adding OpenType font features and hit testing. For more information and a complete list of methods see the IDWriteTextLayout reference page.

Formatting a range of text

IDWriteTextLayout provides several methods to format ranges of text. Each of these methods takes a DWRITE_TEXT_RANGE structure as a parameter to specify the starting text position within the string and the length of the range to format. The following example shows how to set the font weight of a range of text to bold.

// Set the font weight to bold for the first 5 letters.
DWRITE_TEXT_RANGE textRange = {0, 5};

if (SUCCEEDED(hr))
{
    hr = pTextLayout_->SetFontWeight(DWRITE_FONT_WEIGHT_BOLD, textRange);
}

Rendering Options

Text with formatting described by only a IDWriteTextFormat object can be rendered with Direct2D, however, there are a few more options for rendering an IDWriteTextLayout object.

The string described by an IDWriteTextLayout object can be rendered using the methods below.

  1. Render using Direct2D.
  2. Render using a custom text renderer.
  3. Render to a GDI surface.