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:

Demo application

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

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 (51)

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 (51)

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 (53)

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

MFC Support for DirectWrite – Part 1: The Basics

A previous article shows how easy is to make an image viewer with MFC by enabling Direct2D support and using MFC wrappers over Direct2D interfaces. Now let’s discover MFC wrapper classes for DirectWrite.

A simple example of drawing texts by using MFC DirectWrite wrapper classes

Basically, must follow these steps:

  1. Enable MFC support for Direct2D. A good place for doing it is in WM_CREATE message handler.
  2. If the view class is derived from CView, override CView::OnDraw pure virtual method. Do nothing inside it, because all drawing will be done in AFX_WM_DRAW2D message handler.
  3. Map a handler function for AFX_WM_DRAW2D MFC registered message.

  4. In AFX_WM_DRAW2D message handler implementation, get the CHwndRenderTarget pointer which comes in lParam then use CD2DTextFormat and CD2DTextLayout to format and draw the text.

Notes

  • More details can be found in the demo application attached to this article.
  • DirectWrite has more capabilities like for example formatting a particular range in text and applying special efects; I will present them in a future article.
  • Minimum required Visual Studio version is 2010 SP1.
  • Minimum required operating systems are:
    • Windows 7, Windows Vista with SP2 and Platform Update for Windows Vista;
    • Windows Server 2008 R2, Windows Server 2008 with SP2 and Platform Update for Windows Server 2008.

Demo application

Download: MFC Support for DirectWrite Demo.zip (69)

MFC Support for DirectWrite - Demo Application.jpg

MFC Support for DirectWrite – Demo Application.jpg

References and related articles

Easy Shadow Drawing with MFC

Years ago I had to draw shadows in a custom image thumbnails viewer and the code I used  was prety complicated and slow. Now can do that much easier by using CDrawingManager MFC class, defined in afxdrawmanager.h header file.

Draw shadows using CDrawingManager::DrawShadow

Here is a simple example:

You can even more speed up the drawing by passing two CBitmap objects, one for the bottom and one for the right shadow.

A little bit more practical example can be found in the demo project attached to this article.

A simple thumbnail viewer using CDrawingManager for drawing shadows

Download demo project: MFC Shadow Drawing Demo.zip (141)

Thumbnail Viewer

Thumbnail Viewer

Resources and related articles

Easy Browse for Folder with MFC

SHBrowseForFolder shell API function shows a dialog which allows users to select a folder. As can be seen in MSDN documentation or other examples, it requires pretty much additional code around, so you would prefer to write your own wrapper in order to reuse code along applications. But luckily, MFC library has that wrapper already done.

Browse for folder using MFC

All you have to do is the following:

  1. derive your application class from CWinAppEx;
  2. whenever you want to show a “browse for folder” dialog
    • call CWinAppEx::GetShellManager to get a pointer to a global CShellManager object then
    • call CShellManager::BrowseForFolder.

A simple example of using CShellManager::BrowseForFolder

Notes

  • CWinAppEx as well as CShellManager classes were introduced with MFC Feature Pack. That means you need Visual Studio 2008 or newer;
  • CShellManager::BrowseForFolder has additional default parameters which can be used for more customization;
  • a little bit more complete example can be found in the demo application.

MFC Browse For Folder demo application

Download: MFC BrowseForFolder Demo.zip (127)

MFC BrowseForFolder demo application

MFC Browse For Folder demo application

Resources and related stuff