Delphi graphics32文本层

时间:2015-01-20 02:10:52

标签: delphi delphi-xe graphics32

我正在尝试为我的图像编辑应用程序创建一个textTool,所以我在主窗体上有一个按钮,说“文本工具”。单击它时,新表单(模态)显示允许我选择字体并在RichEdit中输入文本。

我的想法是让用户在RichEdit中格式化他的文本,当他满意时,他应该点击模态按钮,文本(格式化)将被插入到我的图像中的新图层中。 我的想法是将文本视为文本行,并在新的Bitmap32中单独渲染它们,然后将获得的位图分配给新的图层。

为此,我使用此功能

function GetTextWidth(const Text: string; const Font: TFont): Integer;
var
  Canvas: TCanvas;
begin
  Canvas := TCanvas.Create;
  try
    Canvas.Handle := GetDC(0);
    try
      Canvas.Font.Assign(Font);
      Result := Canvas.TextWidth(Text);
    finally
      ReleaseDC(0, Canvas.Handle);
    end;
  finally
    Canvas.Free;
  end;
end;

并解析richedit的行并获取每个文本的textWidth:

    for q := 0 to TextEditor.RichEdit1.Lines.Count-1 do
    begin
      latime:=GetTextWidth(TextEditor.RichEdit1.Lines[q], TextEditor.RichEdit1.Font);
      Memo1.Lines.Add('Text row '+IntToStr(q)+' width='+IntToStr(latime));
    end;

所以我很容易获得最大的宽度线(maxwidth),我打算用它来生成我的Bitmap32。

因此,对于我的Bitmap32,我使用以下代码(不会显示任何不幸的内容)

// generating the Bitmap32  to place text on it
    tmp := TBitmap32.Create;
    tmp.SetSize(maxwidth, textLineHeight*TextLineCount);
    for q := 0 to textLineCount-1 do
    begin
      tmp.RenderText(maxwidth,textLineHeight,TextEditor.RichEdit1.Lines[q],1,myFont.Color);
        Memo1.Lines.Add('rendering line of text:'+TextEditor.RichEdit1.Lines[q]);
    end;

// Generating the text layer
    B := TBitmapLayer.Create(ImgView.Layers);
// Assigning the 'written' bitmap to the new layer
    B.Bitmap.Assign(tmp);
    B.Bitmap.DrawMode:=dmBlend;

// Positioning 
    with ImgView.GetViewportRect do
        P := ImgView.ControlToBitmap(GR32.Point((Right + Left) div 2, (Top + Bottom) div 2));

// Sizing the layer
    B.Location:=GR32.FloatRect(P.X - maxwidth, P.Y - textLineHeight, P.X + maxwidth, P.Y + textLineHeight);

// displaying the new text layer
    imgView.Invalidate;

所以我没有错误,但新图层没有显示......就像没有任何事情发生。

我尝试使用宽度和高度的固定值(我使用了200 bor)但是我的ImageView上仍然没有显示任何内容,所以我认为位置可能有问题吗?

请协助我解决这个问题。

非常感谢

1 个答案:

答案 0 :(得分:1)

首先,RenderText函数不支持任何高级格式(以RichEdit提供的扩展功能的形式)。它只是将一个字符串(就是这样)与位图的字体属性的属性输出到某个位置(在你的情况下定位maxwidth / textLineHeight)。

为了解决问题,我将从一个更简单的代码开始。类似的东西:

B := TBitmapLayer.Create(ImgView.Layers);
B.Location := FloatRect(0, 0, 100, 100);
B.Bitmap.SetSize(100, 100);
B.Bitmap.RenderText(0, 0, 'Test', 1, clBlack32);
B.Bitmap.DrawMode := dmBlend;

请注意,clBlack32用作颜色而不是clBlack,因为后者不包含有关透明度的信息。可能是您使用的颜色(在myFont.Color中)是TColor类型(而不是TColor32类型)。如果它是一个TColor,如clBlack,它的alpha值为0,等于完全透明。

此代码应绘制文本'测试'到左上角的位置。如果您没有看到文字,可以添加类似

的内容
B.Bitmap.Clear(clRed32);
在SetSize调用之后

。这样,图层的位图背景颜色将设置为红色。因此,您应该能够更轻松地发现图层的边界。

一旦文本显示在屏幕上,您可以通过显示多行文本,通过调整x / y位置等进一步移动,直到您的代码看起来像您在上面发布的代码。

一些评论:

通过将图层调整为与位图尺寸不同的尺寸,文本将被拉伸。这可能看起来很奇怪,文本可能呈现不可读。最终,您可能希望在调整图层大小后刷新位图上的文本。

如果AALevel(过采样因子)较高,则函数RenderText(...)会产生更平滑的输出。但是,值越高,函数调用也会越慢。比例更多或是二次,这意味着如果您将值加倍,则呼叫将至少慢4倍。实际上,一旦超过处理器的缓存,它甚至会更慢。在这种情况下,您将面临重大的性能下降。

此外,文字宽度将准确。在最坏的情况下,它可以通过(2 ^ AALevel *长度(字符串))像素关闭!

最终在v2.0中使用新矢量引擎的文本渲染功能可能会更好。尽管这些步骤并不像使用相当简单的RenderText(...)调用那样简单,但输出看起来更令人愉悦,而且与高AALevel输出相比,它的速度要快得多。 TextWidth也可以完美准确地确定。