【问题标题】:DirectWrite - Unable to use several system fonts like "Script"DirectWrite - 无法使用多种系统字体,如“脚本”
【发布时间】:2019-05-17 22:20:48
【问题描述】:

使用 RAD Studio XE7 编译器,我尝试使用 DirectWrite 和提供的 VCL TDirect2DCanvas 绘制文本。

只要我使用属于 Segoe 家族的字体,文本绘制效果就很好。但是,DirectWrite 似乎无法使用像 Script 字体这样的几种字体,并且当我尝试使用它们时会回退到另一种字体。

当我尝试使用 GDI 绘制完全相同的文本时,Script 字体得到了很好的使用。我无法弄清楚我做错了什么。有人可以向我解释一下如何在 DirectWrite 中使用 Script 字体等字体吗?

这是我目前使用 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();
}

作为一个额外的问题,我也非常有兴趣在我的应用程序中使用自定义字体,例如 Font-Awesome 5 (https://fontawesome.com/)。如何使用它们通过 DirectWrite 绘制文本?

【问题讨论】:

  • 怎么不工作?

标签: fonts font-awesome-5 directwrite


【解决方案1】:

如果您指的是 Windows 10 中名为“Script Standard”的字体,据我所知,它的文件是 script.fon。 DirectWrite不支持那种位图字体,你可以通过枚举系统字体集合来判断,这种字体是不会存在的。

关于自定义字体,msdn https://docs.microsoft.com/en-us/windows/desktop/directwrite/custom-font-collections 上有一个操作方法。

【讨论】:

    猜你喜欢
    • 2014-06-10
    • 2017-05-21
    • 2018-07-30
    • 2014-10-06
    • 1970-01-01
    • 2012-05-22
    • 2018-04-07
    • 2012-12-16
    • 1970-01-01
    相关资源
    最近更新 更多