Lazarus

Programming => Graphics and Multimedia => Graphics => Topic started by: SaraT on April 03, 2020, 04:24:06 am

Title: [SOLVED] Movable text on canvas
Post by: SaraT on April 03, 2020, 04:24:06 am
Coders :)
Is it possible to draw transparent and movable text on canvas like MS Paint and how?

Please, see attached gif to understand what I need. Many thx.
Title: Re: Movable text on canvas
Post by: eljo on April 03, 2020, 05:02:49 am
you can emulate the process by using a Timage to draw an image and give you a canvas and a Tlabel on top of it. You will need to write code in the tlabel mouse events to handle moving it.

Other than that you need to extend the canvas drawing in to two stages.
1) draw the canvas in to an image or form.
2) draw the latest object placed on the image.

With out more content on what you try to do its impossible to offer code.
Title: Re: Movable text on canvas
Post by: furious programming on April 05, 2020, 05:03:20 am
@SaraT: of course it is possible. 8)

Some time ago I created a small test application in which I programmed a tool for selecting a fragment of the image. The image is displayed in a TPaintBox component. It looks similar to the one from Paint — it can be moved and extended with nine anchors (or six/four, if they all don't fit). Each anchor and area itself has cursor change support. In addition, the anchor size can be changed with the + and (non-numeric) keys.

I add sources for this program to attachments. You can go ahead and use this code — all you have to do is add the rendering of the text in the frame (Canvas.TextRect method can be used) and that's it.

If I were to program such a selection tool today, I would probably do it differently. But the attached one is Ok.
Title: Re: Movable text on canvas
Post by: SaraT on April 07, 2020, 07:08:44 am
@SaraT: of course it is possible. 8)

Some time ago I created a small test application in which I programmed a tool for selecting a fragment of the image. The image is displayed in a TPaintBox component. It looks similar to the one from Paint — it can be moved and extended with nine anchors (or six/four, if they all don't fit). Each anchor and area itself has cursor change support. In addition, the anchor size can be changed with the + and (non-numeric) keys.

I add sources for this program to attachments. You can go ahead and use this code — all you have to do is add the rendering of the text in the frame (Canvas.TextRect method can be used) and that's it.

If I were to program such a selection tool today, I would probably do it differently. But the attached one is Ok.

Thanks, thanks furious. It works like a charm.

Is there a way to attach a TLabel to the Selection?
So the Selection will move with the text.
Thnx again :)
Title: Re: Movable text on canvas
Post by: furious programming on April 08, 2020, 12:33:27 am
Is there a way to attach a TLabel to the Selection?

No, since the background and the selection frame are virtual — they are rendered on the TPaintBox canvas. Attaching could be possible, if the frame would be a standalone component, but in my test application, it's not. That's why I recommend to make a text virtual too and just render it inside frame, on the canvas of the same TPaintBox. All elements will be virtual, so you will be able to render what you want at the given moment.
Title: Re: Movable text on canvas
Post by: furious programming on April 08, 2020, 01:46:03 am
I prepared a second test application — the text is rendered inside the selection frame. So that the PaintBox.OnPant event is not too long, I divided them into several smaller methods. The text is painted as white with a black outline — as a nice addition. Check the attachment.

For the purposes of this demo, I used the text centering in the selection frame and text wrapping functionality. If you do not need it (or need a different type of alignment), remove or change the TextStyle setup code (below the highlighted lines):

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.DrawPaintBoxSelectionText(ACanvas: TCanvas; ASelection: TSelectionTool; const AText: String);
  2. var
  3.   TextArea: TRect;
  4.   Style: TTextStyle;
  5. begin
  6.   ACanvas.Font.Size := 20;
  7.   ACanvas.Font.Color := clBlack;
  8.   ACanvas.Font.Style := [fsBold];
  9.  
  10.   Style := ACanvas.TextStyle;
  11.   Style.SingleLine := False;
  12.   Style.Alignment := taCenter;
  13.   Style.Layout := tlCenter;
  14.  
  15.   {..}
Title: Re: Movable text on canvas
Post by: Handoko on April 08, 2020, 04:25:37 am
I was wondering how TCanvas can draw outline text.

Nice trick furious programming!
Title: Re: Movable text on canvas
Post by: furious programming on April 08, 2020, 05:22:37 am
@Handoko: thanks. 8)

This trick is particularly good because it requires no additional libraries and supports anti-aliasing, where the outline has pretty good quality. And if anti-aliasing is turned off, it draws a sharp outline, still looking very cool.

Code: Pascal  [Select][+][-]
  1. type
  2.   TCanvasHelper = class helper for Graphics.TCanvas
  3.   public
  4.     procedure TextOutlined(AX, AY, AOutlineWidth: Integer; AOutlineColor: TColor; const AText: String);
  5.   end;
  6.  
  7. procedure TCanvasHelper.TextOutlined(AX, AY, AOutlineWidth: Integer; AOutlineColor: TColor; const AText: String);
  8. var
  9.   OldFontColor: TColor;
  10.   OldBrushStyle: TBrushStyle;
  11. begin
  12.   OldFontColor := Font.Color;
  13.   OldBrushStyle := Brush.Style;
  14.  
  15.   Font.Color := AOutlineColor;
  16.   Brush.Style := bsClear;
  17.  
  18.   TextOut(AX - AOutlineWidth, AY - AOutlineWidth, AText);
  19.   TextOut(AX + AOutlineWidth, AY - AOutlineWidth, AText);
  20.   TextOut(AX + AOutlineWidth, AY + AOutlineWidth, AText);
  21.   TextOut(AX - AOutlineWidth, AY + AOutlineWidth, AText);
  22.  
  23.   Font.Color := OldFontColor;
  24.   TextOut(AX, AY, AText);
  25.  
  26.   Brush.Style := OldBrushStyle;
  27. end;

However, this solution has many limitations. It is suitable only for thin outline, 1px wide for small text, for large and thick characters up to 2px. With anti-aliasing turned on, you cannot render more than 4 texts, because the outline quality will be very poor. And you have to change the Brush to bsClear — if not, the outline will be covered by the main text (or will be messy).
TinyPortal © 2005-2018