There are a few choices when it comes to native processing and rendering of Unicode text in Windows applications. Namely, GDI, GDI+, UniScribe and DirectWrite. I have been doing some research in the process of updating/fixing the Unicode handling in SynEdit. It appears that the future lies with DirectWrite. Here are some reasons:
WPF is based on DirectWrite
Recent Microsoft applications, such as the Windows Terminal, use DirectWrite
The Windows App SDK (new name of Project Reunion) is using a new cross-platform version of DirectWrite called DWriteCore, which is mostly compatible with DirectWrite. So presumably, switching to DWriteCore, if needed, would be easy.
DirectWrite has many advantages including:
Can play with GDI well, so you can mix the two.
Supports color fonts
Handles Unicode such as emojis reasonably well.
Supports bi-directional text (e.g. mixing Arabic with English)
Provides GPU acceleration.
The downside is that it is fairly complex and there is not much Delphi Code that is using DirectWrite. Also the Delphi header translations have bugs and have not been updated for years (see [RSP-36642] CreateGdiCompatibleTextLayout is declared wrongly in Winapi.D2D1 - Embarcadero Technologies for instance).
Further to the discussion in Unicode string - how element iterating? - RTL and Delphi Object Pascal - Delphi-PRAXiS [en] (delphipraxis.net), I have created a little demo which showcases rendering complex Unicode text with DirectWrite and also provides a Grapheme enumerator for Delphi strings also based on DirectWrite. Here is a screenshot.
The ListBox shows the graphemes of the text. It is custom painted with DirectWrite. The Emoji consists of 7 unicode codepoints.
See also fdwr/TextLayoutSampler: Utility to display text via multiple Windows API's simultaneously (D2D, DWrite, GDI, GDI+). (github.com)
The source code of the project is attached.
DirectWriteTest.zip