0

Using the RAD Studio XE7 compiler, I'm trying to draw a text using DirectWrite and the provided VCL TDirect2DCanvas.

The text drawing works well as long as I use the fonts belonging to the Segoe family. However, DirectWrite seems unable to use several fonts like the Script font, and fallback to another font instead when I try to use them.

When I try to use the GDI to draw the exact same text, the Script font is well used. I cannot figure out what I'm doing wrong. Can someone explain to me how to use fonts such the Script font with DirectWrite?

Here is the code I currently use to draw a text with DirectWrite:

void __fastcall TMainForm::btDirectWriteClick(TObject *Sender)
{
    const std::wstring text = L"Test        ";

    HDC hDC = ::GetDC(Handle);

    std::auto_ptr<TCanvas> pGDICanvas(new TCanvas());
    pGDICanvas->Handle = hDC;

    pGDICanvas->Brush->Color = clWhite;
    pGDICanvas->Brush->Style = bsSolid;
    pGDICanvas->FillRect(TRect(0, 0, ClientWidth, ClientHeight));

    ::D2D1_RECT_F textRect;
    textRect.left   = 10;
    textRect.top    = 10;
    textRect.right  = ClientWidth  - 10;
    textRect.bottom = ClientHeight - 10;

    std::unique_ptr<TDirect2DCanvas> pCanvas(new TDirect2DCanvas(hDC, TRect(0, 0, ClientWidth, ClientHeight)));

    // configure Direct2D font
    pCanvas->Font->Size        = 40;
    //pCanvas->Font->Name        = L"Segoe Script"; // this works...
    pCanvas->Font->Name        = L"Script";         // ... but this not!
    pCanvas->Font->Orientation = 0;
    pCanvas->Font->Pitch       = System::Uitypes::TFontPitch::fpVariable;
    pCanvas->Font->Style       = TFontStyles();

    // get DirectWrite text format object
    _di_IDWriteTextFormat pFormat = pCanvas->Font->Handle;

    // found it?
    if (!pFormat)
        return;

    pCanvas->RenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);

    ::D2D1_COLOR_F color;
    color.r = 0.0f;
    color.g = 0.0f;
    color.b = 0.0f;
    color.a = 1.0f;

    ::ID2D1SolidColorBrush* pBrush = NULL;

    // create solid color brush, use pen color if rect is completely filled with outline
    pCanvas->RenderTarget->CreateSolidColorBrush(color, &pBrush);

    // found it?
    if (!pBrush)
        return;

    // set horiz alignment
    pFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);

    // set vert alignment
    pFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);

    // set reading direction
    pFormat->SetReadingDirection(DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);

    // set word wrapping mode
    pFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);

    IDWriteInlineObject* pInlineObject = NULL;

    ::DWRITE_TRIMMING trimming;
    trimming.delimiter      = 0;
    trimming.delimiterCount = 0;
    trimming.granularity    = DWRITE_TRIMMING_GRANULARITY_NONE;

    // set text trimming
    pFormat->SetTrimming(&trimming, pInlineObject);

    pCanvas->BeginDraw();

    pCanvas->RenderTarget->DrawText(text.c_str(), text.length(), pFormat, textRect, pBrush);

    pCanvas->EndDraw();
}

As an extra question, I'm also highly interested to use custom fonts like Font-Awesome 5 (https://fontawesome.com/) in my apps. How can I use them to draw a text with DirectWrite?

Jean-Milost Reymond
  • 1,833
  • 1
  • 15
  • 36

1 Answers1

1

If you mean font called "Script Standard" in Windows 10, as far as I can tell its file is script.fon. Bitmap fonts of that kind are not support in DirectWrite, you can tell by enumerating system font collection, this font won't be there.

Regarding custom fonts, there is a how-to on msdn https://learn.microsoft.com/en-us/windows/desktop/directwrite/custom-font-collections.

bunglehead
  • 1,104
  • 1
  • 14
  • 22