调用ID2D1RenderTarget::DrawTextLayout()不工作

Calls To ID2D1RenderTarget::DrawTextLayout() Not Working

本文关键字:工作 DrawTextLayout ID2D1RenderTarget 调用      更新时间:2023-10-16

基本上,给出以下测试代码:

CComPtr<IDWriteTextLayout> layout;
wstring text2 = L"Here is some text.";
this->currentLevelText->Formatting->TextFactory->CreateTextLayout(text2.c_str(), text2.length(), this->matrixHeaderTextInfo->TextFormat, FLT_MAX, FLT_MAX, &layout);
target->DrawTextLayout(D2D1::Point2F(30, 30), layout, this->textBrush);

target->DrawTextLayout方法没有绘制任何东西。然而,下面对DrawTextW的调用确实有效:

target->DrawTextW(this->currentLevelText->Text.c_str(), this->currentLevelText->Text.length(), 
    this->currentLevelText->Formatting->TextFormat, this->currentLevelText->ActualRectangle.DrawingRectangle,
    this->textBrush);

以下是我所知道的总结:

  • TextFactory是指向IDWriteFactory对象的指针,TextFormat是一个IDWriteTextFormat对象,target是一个有效的ID2D1HwndRenderTarget。
  • TextFormat是一个有效的IDWriteTextFormat对象,因为我可以通过DrawTextW方法正确地绘制文本。
  • 调用CreateTextLayout不返回错误代码,它返回S_OK成功代码。
  • TextFormat和文本布局对象都是使用相同的DirectWrite工厂创建的,这也是我的应用程序中唯一存在的DirectWrite工厂。ID2D1SolidColorBrush textBrush是一个有效的画笔,不透明度1.0,设置为黑色。我知道这不是问题,因为DrawTextW使用这个画笔成功地绘制到窗口。
  • 调用ID2D1TextLayout对象的GetMetrics方法返回有效的度量;换句话说,对象中存储的文本的宽度和高度不为0或负值。
  • 调用ID2D1RenderTarget::EndDraw()不返回错误代码,它返回S_OK成功代码。
  • 最令人困惑的是,在我的代码的另一部分(这恰好是在另一个dll文件),调用DrawTextLayout 工作。尽管这段代码是在dll文件中,但它使用了相同的DirectWrite Factory。我真的不认为在另一个dll文件应该有什么不同。

我提供的两个代码示例一个接一个地执行,并且都应该成功地绘制文本。然而,只有DrawTextW是绘制文本。我没有做任何复杂的绘画,比如使用直接2D效果。代码并不比我提供的示例更复杂。现在我可以只使用DrawTextW方法,但我宁愿不这样做,因为我读到的地方,只是创建一个IDWriteTextLayout对象,绘制它,然后销毁对象。这是很多不必要的工作,可以通过自己使用文本布局对象来减轻。

有人知道为什么会发生这种情况吗?我完全不知道为什么会发生这种情况,尽管我会继续努力在某处找到联系。

我相信我已经找到了解决办法。TextFormat对象创建的段落对齐方式为dwrite_paragraph h_alignment_center,文本对齐方式为DWRITE_TEXT_ALIGNMENT_CENTER,布局的边界框大小为FLT_MAX(模拟没有边界,因此文本将永远不会被强制换行)。

我没有意识到这一点,但是DWRITE_PARAGRAPH_ALIGNMENT指的是文本的垂直对齐方式。DWRITE_PARAGRAPH_ALIGNMENT_NEAR表示向上对齐,DWRITE_PARAGRAPH_ALIGNMENT_FAR表示向下对齐,DWRITE_PARAGRAPH_ALIGNMENT_CENTER表示垂直对齐中心。

由于布局容器是FLT_MAX * FLT_MAX,文本不会在屏幕上的任何地方可见,无论我指定的原点位置,因为它总是在x和y方向上大约FLT_MAX/2像素。

将文本格式的段落对齐方式从dwrite_paragraph h_alignment_center更改为dwrite_paragraph h_alignment_near是解决问题的第一步。然而,我注意到文本仍然没有显示出来。我意识到DWRITE_TEXT_ALIGNMENT_CENTER也不会与FLT_MAX宽度一起工作,因为同样的原因,段落对齐没有像我预期的那样工作。当有FLT_MAX宽度要绘制时,将文本居中会再次将文本置于屏幕右侧。

所以,即使使用FLT_MAX到目前为止还没有给我带来问题(我一定没有需要使用中心对齐到现在),为布局提供特定的大小限制,并使用"Near"段落对齐是什么解决了我的问题。