How to Ensure Text is Displayed with the Correct Reading Direction

Some languages, such as Arabic and Hebrew, require a right-to-left reading direction. The for a DirectWrite text format object, the default reading direction is left-to-right. DirectWrite does not automatically infer the reading direction from the locale, so you must do this yourself.

First, get the extended style flags for the window that the text will be rendered to by using the GetWindowStyleEx macro defined in windowsx.h.

// Get the window extended style flagsfor the current window.
DWORD dwStyle = GetWindowExStyle(hwnd_);

The macro returns a DWORD value made up of several flags combined with bitwise OR operations. You must determine if the specific flags affecting reading direction are there.

There are 2 different flags that are related to the reading direction: WS_EX_LAYOUTRTL and WS_EX_RTLREADING.

Use the bitwise AND operator (&) with the dwStyle variable and the WS_EX_LAYOUTRTL macro to store a BOOL value that indicates if the layout is mirrored.

// Is the WS_EX_LAYOUTRTL flag present?
BOOL bWSLayout = dwStyle & WS_EX_LAYOUTRTL;

Do the same thing for the WS_EX_RTLREADING flag.

// Is the WS_EX_RLTREADING flag present?
BOOL bWSReading = dwStyle & WS_EX_RTLREADING;

Set the reading direction by using the IDWriteTextFormat::SetReadingDirection method. The default is left-to-right, so you only need to set the reading direction if it is right-to-left.

Note  WS_EX_LAYOUTRTL mirrors the whole layout and implies right-to-left reading direction, so set the reading direction only if one of these flags is present. If both are present, they cancel one another out and the reading direction for the text format should be left-to-right.

// If either the WS_EX_LAYOUTRTL flag or the WS_EX_RLTREADING flag is present,
// but NOT BOTH, set the reading direction to right to left.
if ((bWSLayout && !bWSReading)
||  (!bWSLayout && bWSReading))