BeginPath Textout EndPath 绘制反转文本

Posted

技术标签:

【中文标题】BeginPath Textout EndPath 绘制反转文本【英文标题】:BeginPath Textout EndPath draws inverted text 【发布时间】:2016-07-20 13:32:21 【问题描述】:

这是我在表单的OnPaint 事件中的代码:

int elementCount;
String tStr = L"15:00";

::BeginPath(Canvas->Handle);
::TextOut(Canvas->Handle, 5, 5, tStr.c_str(), tStr.Length());
::EndPath(Canvas->Handle);
elementCount = ::GetPath(Canvas->Handle, NULL, NULL, 0);
Canvas->Brush->Color = clBlue;
Canvas->Pen->Color = clYellow;
Canvas->Pen->Width = 4;
if(0 < elementCount)

    boost::scoped_array<TPoint> mPoints(new TPoint[elementCount]);
    boost::scoped_array<BYTE> mTypes(new BYTE[elementCount]);

    ::GetPath(Canvas->Handle, mPoints.get(), mTypes.get(), elementCount);
    ::FillPath(Canvas->Handle);
    ::PolyDraw(Canvas->Handle, mPoints.get(), mTypes.get(), elementCount);

else
    ::StrokeAndFillPath(Canvas->Handle);

但这是我在表格上得到的:

正如你所看到的那样,文本是倒置的(文本必须是蓝色的,背景是灰色的,但它是相反的,黄线在背景周围而不是文本周围)。有谁知道我该如何解决这个问题?

我正在使用 C++ Builder 10 Seattle,但如果有人知道 Delphi 或纯 C++ 技巧,我也可以使用它。

谢谢

【问题讨论】:

【参考方案1】:

这在TextOut的documentation中有解释:

TextOut 函数放在路径括号内时, 系统为 TrueType 文本生成一个路径,其中包括每个 字符加上它的字符框。生成的区域是 字符框减去文本,而不是文本本身。你可以 通过以下方式获得由 TrueType 文本的轮廓包围的区域 在放置之前将背景模式设置为透明 TextOut 函数在路径括号中。以下是演示此过程的示例代码。

下面是提到的示例代码和您的 sn-p 的 Delphi 改编,绘制黄色轮廓蓝色文本:

procedure TForm1.FormPaint(Sender: TObject);
var
  elementCount: Integer;
  mPoints: array of TPoint;
  mTypes: array of Byte;
const
  tStr = '15:00';
begin
  BeginPath(Canvas.Handle);
  Canvas.Brush.Style := bsClear;
  TextOut(Canvas.Handle, 5, 5, PChar(tStr), Length(tStr));
  EndPath(Canvas.Handle);

  Canvas.Brush.Color := clBlue;
  Canvas.Pen.Color := clYellow;
  Canvas.Pen.Width := 4;

  elementCount := GetPath(Canvas.Handle, Pointer(nil)^, Pointer(nil)^, 0);
  if elementCount > 0 then begin
    SetLength(mPoints, elementCount);
    SetLength(mTypes, elementCount);
    GetPath(Canvas.Handle, mPoints[0], mTypes[0], elementCount);

    Canvas.Brush.Style := bsSolid;
    SelectClipPath(Canvas.Handle, RGN_AND);
    Canvas.FillRect(ClientRect);

    SelectClipRgn(Canvas.Handle, 0);
    PolyDraw(Canvas.Handle, mPoints[0], mTypes[0], elementCount);
  end else
    StrokeAndFillPath(Canvas.Handle);
end;

【讨论】:

感谢 Akyuz。诀窍是在TextOut 之前添加Canvas-&gt;Brush-&gt;Style = bsClear;

以上是关于BeginPath Textout EndPath 绘制反转文本的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 TCanvas (delphi) 的 textOut 的颜色?

textout.getText() 导致“可能产生'java.lang.NullPointerException'”消息

delphi Canvas的TextOut如何自动换行?

自定义函数中的 WINAPI BeginPaint 和 TextOut 多次调用

HTML5 canvas beginPath() 方法

MFC 画字体DrawText()或TextOut(),CFont字体样式类