Tag Archives: DirectWrite

MFC Static Control Using Direct2D and DirectWrite

While doing some refactoring on sample source code presented in MFC Support for DirectWrite series, I had the idea to make a control easy to be used for rendering text. It could be a custom MFC control derived from generic CWnd class or an ActiveX but finally I chose to derive from CStatic, just for simplicity.
By short, it consist in two main classes:

  • CDirect2DStatic extends MFC class CStatic, doing the following:
    • enables Direct2D MFC support;
    • handles AFX_WM_DRAW2D and AFX_WM_RECREATED2DRESOURCES registered messages, which are sent by the MFC framework to a window with Direct2D MFC support enabled.
  • CDirectWriteStaticCtrl, derived from CDirect2DStatic, effectively implements text formatting and rendering; it has the following groups of public methods:
    • operations: setting text and background brush;
    • text block format: set the format for the entire text;
    • text range format: set the format in a given range;
    • data access.

Notes

  • Implementation details can be found in the demo application, attached here for download.
  • So far, it doesn’t yet implement inline images, typography and effects but these will be done in a future version along with other Direct2D/DirectWrite features.
  • See the updated version.

Demo application

Download: DirectWrite Static Control.zip (310)

DirectWrite Static Control

DirectWrite Static Control

 

Resources

See also

Codexpert – 2015 Articles Summary

Microsoft Libraries and C++ Programming Language

What’s next?

We planned to continue the Direct2D/DirectWrite series but also other articles about programming with C++ using Microsoft Windows libraries like MFC, ATL, Windows API and so on.

See also

MFC Support for DirectWrite – Part 6: Effects

We can change the color of a text range by passing a brush object to IDWriteTextLayout::SetDrawingEffect. Here is a simple example.

An example of using IDWriteTextLayout::SetDrawingEffect

So far, there’s no much “special effects” in the above example. Although a little bit more difficult, it is possible to make more customized rendering like text highlighting, double/triple underline/strikethrough and so on. This will be the subject of a future article.

Demo application

Download: MFC Support for DirectWrite Demo - Part 6.zip (410)

MFC Support for DirectWrite (Part 6) – Effects

MFC Support for DirectWrite (Part 6) – Effects

Resources and related articles

MFC Support for DirectWrite – Part 5: Typography

Some fonts like Microsoft’s Gabriola support a number of typographic features which allow users to control how they look, e.g by enabling some fancy stylistic text rendering. With DirectWrite we can do that by passing a IDWriteTypography object to IDWriteTextLayout::SetTypography method.

Set text layout typography with DirectWrite in an MFC application

We have not an MFC class which wraps IDWriteTypography but that’s not a problem. First, we can get a pointer to IDWriteFactory from a global AFX_GLOBAL_DATA structure.  Further create an IDWriteTypography instance, add desired font feature(s) and finally, set the typography in a range of the text layout. Here is an example:

Later update

In Visual Studio 2012, IDWriteFactory instance has been moved in a D2D-specific structure of type _AFX_D2D_STATE that can be accessed by calling AfxGetD2DState.
So, if using Visual Studio 2012 or newer you have to replace

with

See also: Getting Direct2D, DirectWrite and WIC Factories in MFC.

Demo application

Download: MFC Support for DirectWrite Demo (Part 5).zip (562)

MFC Support for DirectWrite (Part 5) – Typography

MFC Support for DirectWrite (Part 5) – Typography

Resources and related articles

MFC Support for DirectWrite – Part 4: Inline Images

DirectWrite allows inserting objects in a block of text, e.g. images, as shown in the picture.

MFC Support for DirectWrite – Inline Images

MFC Support for DirectWrite (Part 4) – Inline Images

Let’s see how can be done!

Implement IDWriteInlineObject interface methods to insert inline images

Once we have created a CD2DTextLayout object, remains the following to do:

  1. Define a class for implementing IDWriteInlineObject interface, e.g. CInlineImage. We can derive it from IDWriteInlineObject then override and implement IDWriteInlineObject and IUnknown methods. However, if we already are using MFC, it’s a little bit handier to derive from CCmdTarget, then use MFC’s interface maps DECLARE_INTERFACE_MAP, BEGIN_INTERFACE_PART and so on.

    Detailed implementation can be found in the demo application attached to this article. Here is listed just an implementation example of overridden IDWriteInlineObject::Draw.
  2. Create and initialize a CInlineImage object.

  3. Pass the CInlineImage object to IDWriteTextLayout::SetInlineObject before drawing the text layout.

Demo application

Download: MFC Support for DirectWrite Demo (Part 4).zip (483)

Notes

  • CInlineImage class implementation is intentionally left as simple as possible, for learning purpose. Of course, it can be improved, for example, by scaling images to fit the text height.
  • Pictures used in the demo application are taken from http://www.icondrawer.com/gift-icons.php

Resources and related articles

MFC Support for DirectWrite – Part 3: Text Range Format

Once having a CD2DTextLayout object containing a formatted block of text and before drawing in the render target, we can change the formatting for particular ranges of text. For that purpose, call CD2DTextLayout::Get then directly use IDWriteTextLayout interface methods like SetFontWeight, SetUnderline, SetStrikethrough and whatever else we need and is available.

An example of using IDWriteTextLayout to format ranges of text

Notes

  • This example is just for demo purpose and contains hard-coded ranges. In a practical application you would probably need to get the ranges by parsing a text containing tags for text formatting (HTML, BBCode etc).
  • More details can be found in attached demo application

Demo application

Download: MFC Support for DirectWrite Demo (Part 3).zip (400)

MFC Support for DirectWrite (Part 3) – Demo Application

MFC Support for DirectWrite (Part 3) – Demo Application

Resources and related articles

MFC Support for DirectWrite – Part 2: Text Block Formatting

Beside the font attributes which can be set in the CD2DTextFormat MFC class constructor, DirectWrite supports more formatting for a block of text, e.g. text alignment, word wrapping, line spacing and so on. However, if taking a look at CD2DTextFormat documentation, we cannot find functions for doing that. Don’t worry, that’s not a problem at all: just call CD2DTextFormat::Get to obtain a pointer to contained IDWriteTextFormat interface, then directly call its methods like SetTextAlignment, SetWordWrapping, SetLineSpacing etc.

Formatting a block of text with DirectDraw in MFC applications

Here is a simple example, completing the one from the previous article:

More details can be found in the attached demo application.

Demo application

Download: MFC Support for DirectWrite Demo (Part 2).zip (847)

MFC Support for DirectWrite (Part 2) – Demo Application

MFC Support for DirectWrite (Part 2) – Demo Application

Notes

  • This example shows only how to set text alignment and word wrapping. Of course, you can use any other format supported by IDWriteTextFormat interface.
  • Some of Direct2D & DirectWrite features are supported in Windows 8.1 and later and/or may be missing in Windows SDK prior to v8.1, e.g DWRITE_WORD_WRAPPING_CHARACTER value for DWRITE_WORD_WRAPPING enum, which used as argument for IDWriteTextFormat::SetWordWrapping. See the DirectWrite documentation in MSDN.

Resources and related articles