(Delphi FMX) 如何使用 Canvas.FillText 显示在椭圆的中间?
(Delphi FMX) How do I use Canvas.FillText to show up in the middle of an Ellipse?
我想将椭圆中间的数字显示为 canvas 上绘制的文本。坐标将存储(对于椭圆)在数据库内部,文本值将存储在数据库的另一部分。
到目前为止我所做的是我一直在使用来自 FMXExpress (Github) 的演示项目 (DrawApp),其中我将一些程序从私有更改为 Public。这些程序包括 StartDrawing(startP:TPointF)、EndDrawing(startP:TPointF)、DoDraw() 这样我就可以从外部使用这些函数 Unit/Object。 object 与 MouseUp/MouseDown 配合使用这些函数,以及包括 fDrawing 在内的一些属性来区分绘图是否正在进行,以及正在使用什么工具 (fdEllipse)。
我的主窗体在 FormCreate 中使用以下代码来初始创建 fdrawbox := TMyPaintBox.Create(Rectangle1); Rectangle1 位于图像的顶部,它代表一个网格以显示 body 部分,并且能够在图像的顶部绘制圆圈。我发现创建文本或椭圆并不难,但是为了创建多个带有标识符的圆圈以区分圆圈,正如我所提到的,我想要一个数字来显示哪个圆圈是哪个。甚至在未来,我可能想要更改颜色以显示要专注于哪个圆圈。
demonstration for mypaintbox http://www.abatepain.com/abate/OHlbF.jpg
因此以下代码 (Delphi FMX) 显示了通过使用 TRectangle 作为其 parent.
创建一个 drawapp
with fdrawbox do begin
Parent := Rectangle1;
Visible := True;
ForegroundColor := TAlphaColor($FF000000); //
BackgroundColor := TAlphaColor([=12=]000000); //
FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True;
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));
FuncDraw := TFunctionDraw.fdNone;
OnPaint := PaintBox1Paint;
end;
圆是使用最后几行创建的,但是为了使用 FillText,我需要使用我创建的 OnPaint 函数,代码看起来像这样。我相信 DrawApp 在内部处理 OnPaint 函数,但它如何处理它仍然是未知的。但打印 "Hello Text!!"
的必要性永远不会降低
procedure TMainForm.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
with Canvas do begin
BeginScene();
//Clear(cbbg.Color);
Font.Style := [];
Font.Size := 12;
Fill.Color := TAlphaColors.Red;
FillText(TRectF.Create(0, 0, 300, 295), 'Hello Text!!', false, 100, [], TTextAlign.Center, TTextAlign.Center); //TFillTextFlag.RightToLeft
EndScene;
end;
Application.ProcessMessages;
end;
有人可以举例说明如何处理这个问题(可能在单个函数内),我可以在其中打印多个圆圈并在其后添加相关文本吗?我相信对于前面的示例,我可以自己完成,但是我必须手动输入 PointF(用于圆)和 TRectF 用于文本,并且它们都使用不同的值作为坐标。
如您所知,TMyPaintBox
class 不支持文本呈现,也不支持文本输出中常用的属性,如字体或颜色等。但您可以通过定义字段自行添加这些属性在私有部分和 get/set public 部分中的值的属性。
在下文中,我假设添加的字段 ftextout
、ffontsize
和 ffontcolor
具有相应的属性 TextOut
FontSize
和 FontColor
。
要添加以与绘制其他元素类型类似的方式呈现文本的功能,请将 fdText
作为新枚举添加到 TFunctionDraw
。
TFunctionDraw=(fdNone,fdPen,fdLine,fdRectangle,fdEllipse,fdFillBgr,fdBitmapStamp,fdPolyLine, fdText);
然后在 TMyPaintBox.DoDraw
中向 case ffdraw of
添加一个新的大小写选项,例如:
with vCanvas do
begin
BeginScene();
case ffdraw of
//
// other TFunctionDraw enums
//
TFunctionDraw.fdText: begin
{Canvas.}Font.Size := ffonsize; // new field
{Canvas.}Fill.Color := ffontcolor; // new field
{Canvas.}FillText(r, TextOut, False, 1, [],
TTextAlign.Center, TTextAlign.Center);
end;
end;
编辑:
TFunctionDraw.fdText
中对 Canvas
的引用是多余的。删除注释掉的引用。要使用的 canvas 已在 with
语句中定义(添加到要显示的代码中)。哦,我讨厌那些 with
s!
同样值得注意的是,如果你只想显示带有文本的圆圈,而不是让用户在 canvas 上绘制,你可以使用自己制作的组件来实现它更简单.
另外,不要直接调用DoDraw
。它由 Paint
调用,只要 fdrawbox
无效就会被触发。因此,当您想要强制更新时,请改为调用 invalidate
。
编辑结束
然后您就可以像任何其他元素绘制一样实现文本渲染(使用您的代码模板):
with fdrawbox do begin
Parent := Rectangle1;
Visible := True;
ForegroundColor := TAlphaColor($FF000000); //
BackgroundColor := TAlphaColor([=12=]000000); //
FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True;
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));
FuncDraw := TFunctionDraw.fdText;
FontSize := 12; // set new property
FontColor := TAlphaColorRec.Red; // set new property
TextOut := 'Hello text!';
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));
FuncDraw := TFunctionDraw.fdNone;
invalidate;
// OnPaint := PaintBox1Paint; // no need for this
end;
我想将椭圆中间的数字显示为 canvas 上绘制的文本。坐标将存储(对于椭圆)在数据库内部,文本值将存储在数据库的另一部分。
到目前为止我所做的是我一直在使用来自 FMXExpress (Github) 的演示项目 (DrawApp),其中我将一些程序从私有更改为 Public。这些程序包括 StartDrawing(startP:TPointF)、EndDrawing(startP:TPointF)、DoDraw() 这样我就可以从外部使用这些函数 Unit/Object。 object 与 MouseUp/MouseDown 配合使用这些函数,以及包括 fDrawing 在内的一些属性来区分绘图是否正在进行,以及正在使用什么工具 (fdEllipse)。
我的主窗体在 FormCreate 中使用以下代码来初始创建 fdrawbox := TMyPaintBox.Create(Rectangle1); Rectangle1 位于图像的顶部,它代表一个网格以显示 body 部分,并且能够在图像的顶部绘制圆圈。我发现创建文本或椭圆并不难,但是为了创建多个带有标识符的圆圈以区分圆圈,正如我所提到的,我想要一个数字来显示哪个圆圈是哪个。甚至在未来,我可能想要更改颜色以显示要专注于哪个圆圈。
demonstration for mypaintbox http://www.abatepain.com/abate/OHlbF.jpg
因此以下代码 (Delphi FMX) 显示了通过使用 TRectangle 作为其 parent.
创建一个 drawappwith fdrawbox do begin
Parent := Rectangle1;
Visible := True;
ForegroundColor := TAlphaColor($FF000000); //
BackgroundColor := TAlphaColor([=12=]000000); //
FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True;
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));
FuncDraw := TFunctionDraw.fdNone;
OnPaint := PaintBox1Paint;
end;
圆是使用最后几行创建的,但是为了使用 FillText,我需要使用我创建的 OnPaint 函数,代码看起来像这样。我相信 DrawApp 在内部处理 OnPaint 函数,但它如何处理它仍然是未知的。但打印 "Hello Text!!"
的必要性永远不会降低procedure TMainForm.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
with Canvas do begin
BeginScene();
//Clear(cbbg.Color);
Font.Style := [];
Font.Size := 12;
Fill.Color := TAlphaColors.Red;
FillText(TRectF.Create(0, 0, 300, 295), 'Hello Text!!', false, 100, [], TTextAlign.Center, TTextAlign.Center); //TFillTextFlag.RightToLeft
EndScene;
end;
Application.ProcessMessages;
end;
有人可以举例说明如何处理这个问题(可能在单个函数内),我可以在其中打印多个圆圈并在其后添加相关文本吗?我相信对于前面的示例,我可以自己完成,但是我必须手动输入 PointF(用于圆)和 TRectF 用于文本,并且它们都使用不同的值作为坐标。
如您所知,TMyPaintBox
class 不支持文本呈现,也不支持文本输出中常用的属性,如字体或颜色等。但您可以通过定义字段自行添加这些属性在私有部分和 get/set public 部分中的值的属性。
在下文中,我假设添加的字段 ftextout
、ffontsize
和 ffontcolor
具有相应的属性 TextOut
FontSize
和 FontColor
。
要添加以与绘制其他元素类型类似的方式呈现文本的功能,请将 fdText
作为新枚举添加到 TFunctionDraw
。
TFunctionDraw=(fdNone,fdPen,fdLine,fdRectangle,fdEllipse,fdFillBgr,fdBitmapStamp,fdPolyLine, fdText);
然后在 TMyPaintBox.DoDraw
中向 case ffdraw of
添加一个新的大小写选项,例如:
with vCanvas do
begin
BeginScene();
case ffdraw of
//
// other TFunctionDraw enums
//
TFunctionDraw.fdText: begin
{Canvas.}Font.Size := ffonsize; // new field
{Canvas.}Fill.Color := ffontcolor; // new field
{Canvas.}FillText(r, TextOut, False, 1, [],
TTextAlign.Center, TTextAlign.Center);
end;
end;
编辑:
TFunctionDraw.fdText
中对 Canvas
的引用是多余的。删除注释掉的引用。要使用的 canvas 已在 with
语句中定义(添加到要显示的代码中)。哦,我讨厌那些 with
s!
同样值得注意的是,如果你只想显示带有文本的圆圈,而不是让用户在 canvas 上绘制,你可以使用自己制作的组件来实现它更简单.
另外,不要直接调用DoDraw
。它由 Paint
调用,只要 fdrawbox
无效就会被触发。因此,当您想要强制更新时,请改为调用 invalidate
。
编辑结束
然后您就可以像任何其他元素绘制一样实现文本渲染(使用您的代码模板):
with fdrawbox do begin
Parent := Rectangle1;
Visible := True;
ForegroundColor := TAlphaColor($FF000000); //
BackgroundColor := TAlphaColor([=12=]000000); //
FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True;
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));
FuncDraw := TFunctionDraw.fdText;
FontSize := 12; // set new property
FontColor := TAlphaColorRec.Red; // set new property
TextOut := 'Hello text!';
StartDrawing(PointF(100, 100));
EndDrawing(PointF(200, 200));
FuncDraw := TFunctionDraw.fdNone;
invalidate;
// OnPaint := PaintBox1Paint; // no need for this
end;