Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2008-04

DrawText function problems

21 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Lee Jenkins

Hi all,

I'm having a problem with drawing text on an image using the DrawText function where the area around the text masked out. Please see the attached image.

This same routine works perfectly in Delphi.  Maybe the Canvas.Brush.Style :=
bsClear is not working?
procedure TMyImage.DrawCaption;
var
   lRect: TRect;
begin
   // setup rect
   lRect.Left := 10;
   lRect.Top := 10;
   lRect.Right := Width -10;
   lRect.Bottom := Height -10;
   //Canvas.Pen.Style := psClear; // <-- tried this as well
   Canvas.Font.Assign(FButtonFont);
   Canvas.Brush.Style := bsClear;
   DrawText(Canvas.Handle, PChar(FCaption), -1, lRect,
     DT_WORDBREAK or DT_VCENTER or DT_CENTER or DT_END_ELLIPSIS);
end;
Warm Regards, Lee -------------- next part -------------- A non-text attachment was scrubbed... Name: lazarus_rendering.png Type: image/png Size: 10408 bytes Desc: not available Url : http://www.lazarus.freepascal.org/pipermail/lazarus/attachments/20080412/ff7c9cd5/attachment.png

Reply by email

Lee Jenkins
to Lee Jenkins
Lee Jenkins wrote 26 lines
Hi all, I'm having a problem with drawing text on an image using the DrawText function where the area around the text masked out. Please see the attached image. This same routine works perfectly in Delphi. Maybe the Canvas.Brush.Style := bsClear is not working? procedure TMyImage.DrawCaption; var lRect: TRect; begin // setup rect lRect.Left := 10; lRect.Top := 10; lRect.Right := Width -10; lRect.Bottom := Height -10; //Canvas.Pen.Style := psClear; // <-- tried this as well Canvas.Font.Assign(FButtonFont); Canvas.Brush.Style := bsClear; DrawText(Canvas.Handle, PChar(FCaption), -1, lRect, DT_WORDBREAK or DT_VCENTER or DT_CENTER or DT_END_ELLIPSIS); end;

As a follow up, Canvas.TextRect() works, but the output is terrible. See attached image.

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small." -------------- next part -------------- A non-text attachment was scrubbed... Name: lazarus_rendering.png Type: image/png Size: 10853 bytes Desc: not available Url : http://www.lazarus.freepascal.org/pipermail/lazarus/attachments/20080412/9c0c3966/attachment-0001.png

Reply by email

Lee Jenkins
to Lee Jenkins
Lee Jenkins wrote 31 lines
Lee Jenkins wrote: > > Hi all, > > I'm having a problem with drawing text on an image using the DrawText > function where the area around the text masked out. Please see the > attached image. > > This same routine works perfectly in Delphi. Maybe the > Canvas.Brush.Style := bsClear is not working? > > procedure TMyImage.DrawCaption; > var > lRect: TRect; > begin > // setup rect > lRect.Left := 10; > lRect.Top := 10; > lRect.Right := Width -10; > lRect.Bottom := Height -10; > //Canvas.Pen.Style := psClear; // <-- tried this as well > Canvas.Font.Assign(FButtonFont); > Canvas.Brush.Style := bsClear; > DrawText(Canvas.Handle, PChar(FCaption), -1, lRect, > DT_WORDBREAK or DT_VCENTER or DT_CENTER or DT_END_ELLIPSIS); > end; > As a follow up, Canvas.TextRect() works, but the output is terrible. See attached image.

After some thought, maybe it would be better to just ask:

Is there a workable way to draw centered text onto a TImage that has an image already assigned to it?

I thought about drawing to the bitmap first, but wanted avoid having to create/destroy bitmap image so many times.

Thanks,

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Luiz Americo Pereira Camara
to Lee Jenkins: I'm having a problem with drawing text on an image using the DrawText function where the…
Lee Jenkins wrote 9 lines
Hi all, I'm having a problem with drawing text on an image using the DrawText function where the area around the text masked out. Please see the attached image. This same routine works perfectly in Delphi. Maybe the Canvas.Brush.Style := bsClear is not working?

There's a bug in Delphi regarding bsClear (
http://www.efg2.com/Lab/OtherProjects/PrinterDemo2.htm <http://www.lockproxy.info/unblock-sites/index.php?q=uggc%3A%2F%2Fjjj.rst2.pbz%2FYno%2FBgureCebwrpgf%2FCevagreQrzb2.ugz>). See issues 8455 and 8340 in bug tracker for more info.

Maybe this can help you.

Luiz

Reply by email

Lee Jenkins
to Luiz Americo Pereira Camara
Luiz Americo Pereira Camara wrote 19 lines
Lee Jenkins wrote: > Hi all, > > I'm having a problem with drawing text on an image using the DrawText > function where the area around the text masked out. Please see the > attached image. > > This same routine works perfectly in Delphi. Maybe the > Canvas.Brush.Style := bsClear is not working? There's a bug in Delphi regarding bsClear ( http://www.efg2.com/Lab/OtherProjects/PrinterDemo2.htm <http://www.lockproxy.info/unblock-sites/index.php?q=uggc%3A%2F%2Fjjj.rst2.pbz%2FYno%2FBgureCebwrpgf%2FCevagreQrzb2.ugz>). See issues 8455 and 8340 in bug tracker for more info. Maybe this can help you. Luiz

Thanks for responding, Luiz. I'm not sure what Lazarus is doing here because I swear sometimes it works and sometimes it doesn't. There doesn't seem to be any consistency with these kinds of routines.

When it works, the output looks like crap, fat text with jagged edges, ignoring the Canvas.Font settings completely and when it doesn't work, well it doesn't work, lol.

I get this kind of off/on functionality with lazarus many times, inexplicable things that work sometimes and sometimes do not work.

I think the writing is on the wall. I just cannot do this particular application that I'm trying to do with lazarus because it strays strays too far from basic components like TEdit, TListBox, TComboBox to be a workable solution for me with lazarus.

Maybe fpGUI will be workable, I've been playing around with it for the last couple of days.

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Felipe Monteiro de Carvalho
to Lee Jenkins: After some thought, maybe it would be better to just ask: Is there a workable way to draw…
Lee Jenkins wrote
Is there a workable way to draw centered text onto a TImage that has an image already assigned to it?

You could just put a label on top of it.

I would usually go for either having a fully custom drawn component, where I manage all paint, like here:

http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Create_a_custom_control_which_draws_itself

Or, if using a TImage, try to put a label on top of it. I've never needed to draw to the canvas of a TImage, because I usually use TCustomControl descendents for complex drawing, but there are instructions here:

http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Draw_to_a_TImage

I thought about drawing to the bitmap first, but wanted avoid having to create/destroy bitmap image so many times.

Then cache the TBitmap in the creation of your form and free on it's destruction.

Felipe Monteiro de Carvalho

Reply by email

Lee Jenkins
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 10 lines
On Sat, Apr 12, 2008 at 8:18 PM, Lee Jenkins wrote: > Is there a workable way to draw centered text onto a TImage that has an image > already assigned to it? You could just put a label on top of it. I would usually go for either having a fully custom drawn component, where I manage all paint, like here: http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Create_a_custom_control_which_draws_itself

Won't I still run into the DrawText problem whether I am having whether I am trying to draw on a TImage or the canvas of a descendant of TCustomControl?

Show quoted text 7 lines
Or, if using a TImage, try to put a label on top of it. I've never needed to draw to the canvas of a TImage, because I usually use TCustomControl descendents for complex drawing, but there are instructions here: http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Draw_to_a_TImage

I had tried this almost 5 days ago I think. The problem is that there is a bug in TLabel where it does not fire the MouseUp event if you MouseDown and then move the cursor away from the TLabel before letting go of the mouse.

I'll have a look at the links though. That you very much.

Warm Regards, Lee

Reply by email

Funky Beast
to Lee Jenkins
Lee Jenkins wrote 10 lines
Felipe Monteiro de Carvalho wrote: > On Sat, Apr 12, 2008 at 8:18 PM, Lee Jenkins wrote: > I would usually go for either having a fully custom drawn component, > where I manage all paint, like here: > > http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Create_a_custom_control_which_draws_itself Won't I still run into the DrawText problem whether I am having whether I am trying to draw on a TImage or the canvas of a descendant of TCustomControl?

Nope, TCustomControl provides a canvas for you to draw everything your way and your style. TImage is a widgetset specific GTKImage or QtImage or Carbon Image or Win32 Image control (contained in comctrls.dll) component that renders itself according to the rules of the widgetset it belongs to. So some widgetset's TImage doesn't have some capabilities that some other widgetset's TImage have. In these cases its better to draw it yourself with a TCustomControl.

I do many exotic and non-conventional controls by descending from TCustomControl since Delphi2 days. It obeys you 100% and not the widgetset it binds with. Its the same concept of fpGUI widgets.

HTH,
Funky Beast

Reply by email

Martin Schreiber
to Lee Jenkins: Thanks for responding, Luiz. I'm not sure what Lazarus is doing here because I swear…
Lee Jenkins wrote
Maybe fpGUI will be workable, I've been playing around with it for the last couple of days.

Another alternative is MSEide+MSEgui:
http://sourceforge.net/projects/mseide-msegui

In MSEgui you could use for example a tbutton and assign the image to the face.image property. To render your custom frame you could use the frame property where it is possible to define four imagelist items for the corners and four imagelist items which will be stretched to form the edges of the button. Every button state has its own group of frame imagelist items. For even more funky buttons there is trichbutton with additional faces for the different button states.
Every MSEgui widget has the frame and the face property. There are tfacetemplate, tframetemplate and tskincontroller in order to centralize skin settings.

Julio developed a POS system with MSEide+MSEgui with success BTW. Questions and Bug reports please to NNTP:
news://news.grid-sky.com/public.mseide-msegui.talk

I'd like to repeat the message to the Lazarus devels: Feel free to use any piece of code out of MSEgui for Lazarus if you find it useful.

Martin

Reply by email

Felipe Monteiro de Carvalho
to Lee Jenkins: Won't I still run into the DrawText problem whether I am having whether I am trying to…
Lee Jenkins wrote
I had tried this almost 5 days ago I think. The problem is that there is a bug in TLabel where it does not fire the MouseUp event if you MouseDown and then move the cursor away from the TLabel before letting go of the mouse.

Where is the link for the bug report?

Also, this doesn't look like a bug to me, but rather a standard behavior. Just try any software out there. Clicking, moving the mouse out and releasing indicates that the user gave up clicking in the object, so a button, for example, wouldn't be activated by that. The same for clicking a label.

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho

On Sun, Apr 13, 2008 at 6:51 AM, Felipe Monteiro de Carvalho > Also, this doesn't look like a bug to me, but rather a standard

behavior. Just try any software out there. Clicking, moving the mouse out and releasing indicates that the user gave up clicking in the object, so a button, for example, wouldn't be activated by that. The same for clicking a label.

Clicking and moving away is also a sign for drag and drop, which doesn't activate the item, but rather places it somewhere else.

Felipe Monteiro de Carvalho

Reply by email

Lee Jenkins
to Felipe Monteiro de Carvalho: Where is the link for the bug report? Also, this doesn't look like a bug to me, but…
Felipe Monteiro de Carvalho wrote 13 lines
On Sat, Apr 12, 2008 at 11:31 PM, Lee Jenkins wrote: > I had tried this almost 5 days ago I think. The problem is that there is a bug > in TLabel where it does not fire the MouseUp event if you MouseDown and then > move the cursor away from the TLabel before letting go of the mouse. Where is the link for the bug report? Also, this doesn't look like a bug to me, but rather a standard behavior. Just try any software out there. Clicking, moving the mouse out and releasing indicates that the user gave up clicking in the object, so a button, for example, wouldn't be activated by that. The same for clicking a label.

My computer went up a few days ago and had to reinstall everything and lost about 3 weeks worth of emails. If you look back over the last week or so, you'll see a post that I made about this problem. I think someone (sorry I can remember exactly who) may have pointed me to a bug report concerning the SetCapture method in LCL.

As a side note, can anyone tell me where the recent archives are hosted? I tried googling, but only came up with older messages.

BTW, in Delphi the behavior that I mentioned above is present. Which made it a simple task to create custom buttons. With the current behavior of Lazarus, it leave custom buttons made like this in a "visually down" state.

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Lee Jenkins
to Felipe Monteiro de Carvalho: On Sun, Apr 13, 2008 at 6:51 AM, Felipe Monteiro de Carvalho > Also, this doesn't look…
Felipe Monteiro de Carvalho wrote 10 lines
On Sun, Apr 13, 2008 at 6:51 AM, Felipe Monteiro de Carvalho > Also, this doesn't look like a bug to me, but rather a standard > behavior. Just try any software out there. Clicking, moving the mouse > out and releasing indicates that the user gave up clicking in the > object, so a button, for example, wouldn't be activated by that. The > same for clicking a label. Clicking and moving away is also a sign for drag and drop, which doesn't activate the item, but rather places it somewhere else.

Even when Auto drag is not set or BeginDrag is not called?

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Lee Jenkins
to Lee Jenkins: As a follow up, Canvas.TextRect() works, but the output is terrible. See attached image.…
Lee Jenkins wrote 11 lines
Lee Jenkins wrote: > > Hi all, > > I'm having a problem with drawing text on an image using the DrawText > function where the area around the text masked out. Please see the > attached image. > > This same routine works perfectly in Delphi. Maybe the > Canvas.Brush.Style := bsClear is not working? >

I have attached a small sample application that shows that even though the text is printed onto the TImage descendant, it is not drawn correctly where the font is jagged and squeezed together and almost readable.

At first, I couldn't get the Brush.Style to be clear, but after I was able to do that, the font just will not render correctly. I have attached a screen shot also that shows what the phone looks like.

I'm on Lazarus 9.24 Vista Business (same behavior on XP Pro though).

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small." -------------- next part -------------- A non-text attachment was scrubbed... Name: lazarus_rendering.png Type: image/png Size: 10853 bytes Desc: not available Url : http://www.lazarus.freepascal.org/pipermail/lazarus/attachments/20080413/f0f5b94f/attachment-0001.png -------------- next part -------------- A non-text attachment was scrubbed... Name: imageproblem.zip Type: application/x-zip-compressed Size: 13392 bytes Desc: not available Url : http://www.lazarus.freepascal.org/pipermail/lazarus/attachments/20080413/f0f5b94f/attachment-0001.bin

Reply by email

Lee Jenkins
to Lee Jenkins
Lee Jenkins wrote 22 lines
Lee Jenkins wrote: > Lee Jenkins wrote: >> >> Hi all, >> >> I'm having a problem with drawing text on an image using the DrawText >> function where the area around the text masked out. Please see the >> attached image. >> >> This same routine works perfectly in Delphi. Maybe the >> Canvas.Brush.Style := bsClear is not working? >> I have attached a small sample application that shows that even though the text is printed onto the TImage descendant, it is not drawn correctly where the font is jagged and squeezed together and almost readable. At first, I couldn't get the Brush.Style to be clear, but after I was able to do that, the font just will not render correctly. I have attached a screen shot also that shows what the phone looks like.

Sorry, that should have been "what the image looks like", someone was ringing me when I was typing. ;)

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Felipe Monteiro de Carvalho
to Lee Jenkins: My computer went up a few days ago and had to reinstall everything and lost about 3 weeks…
Lee Jenkins wrote
BTW, in Delphi the behavior that I mentioned above is present. Which made it a simple task to create custom buttons. With the current behavior of Lazarus, it leave custom buttons made like this in a "visually down" state.

Ahhh ... so this is what this is about?

I would have used a TCustomControl descendent to do that.

Your code works fine in gtk2, the caption is drawn as expected. The button doesn't go back when the mouse leaves it. Pay attention to how real system buttons work. It doesn't go back on MouseUp. It goes back when the mouse leaves the button, so I added a handler for OnMouseLeave:

procedure TDTImageButton.HandleMouseLeave(Sender: TObject);
begin
  HandleMouseUp(Sender, mbLeft, [], 0, 0); // Just a hack, you should
actually have the code from you MouseUp here, and correct your MouseUp
end;

You would also need a handler for OnMouseEnter and some logic to see again when the mouse goes back to the button to put it down again.

Other hints. You don't need those ifdefs for fpc, so use mode delphi.

In Lazarus you can use LCLIntf and LCLType instead of the WIndows unit.

Even when Auto drag is not set or BeginDrag is not called?

I was just pointing which events may occur with that mouse gesture.

Felipe Monteiro de Carvalho

Reply by email

Lee Jenkins
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 8 lines
On Sun, Apr 13, 2008 at 10:16 AM, Lee Jenkins wrote: > BTW, in Delphi the behavior that I mentioned above is present. Which made it a > simple task to create custom buttons. With the current behavior of Lazarus, it > leave custom buttons made like this in a "visually down" state. Ahhh ... so this is what this is about? I would have used a TCustomControl descendent to do that.

Probably a better choice, but I have problems using with it with my limited experience of custom controls so a TImage descendant worked for me, except that it doesn't paint correctly.

Show quoted text 6 lines
Your code works fine in gtk2, the caption is drawn as expected. The button doesn't go back when the mouse leaves it. Pay attention to how real system buttons work. It doesn't go back on MouseUp. It goes back when the mouse leaves the button, so I added a handler for OnMouseLeave:

Hmm. Are you saying that OnMouseLeave is called as well when the user releases the mouse button after clicking down? I didn't know this, I'll give it a try.

Show quoted text 13 lines
procedure TDTImageButton.HandleMouseLeave(Sender: TObject); begin HandleMouseUp(Sender, mbLeft, [], 0, 0); // Just a hack, you should actually have the code from you MouseUp here, and correct your MouseUp end; You would also need a handler for OnMouseEnter and some logic to see again when the mouse goes back to the button to put it down again. Other hints. You don't need those ifdefs for fpc, so use mode delphi. In Lazarus you can use LCLIntf and LCLType instead of the WIndows unit.

Thanks for these tips.

> Even when Auto drag is not set or BeginDrag is not called? I was just pointing which events may occur with that mouse gesture.

I have managed to use a TImage descendant which doesn't have the problem of not firing OnMouseUp when the cursor leaves, but the output of DrawText is not acceptable for some reason. See me post with sample project attachment and screenshot of the image.

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Lee Jenkins
to Lee Jenkins: I have attached a small sample application that shows that even though the text is…
Lee Jenkins wrote 23 lines
Lee Jenkins wrote: > Lee Jenkins wrote: >> >> Hi all, >> >> I'm having a problem with drawing text on an image using the DrawText >> function where the area around the text masked out. Please see the >> attached image. >> >> This same routine works perfectly in Delphi. Maybe the >> Canvas.Brush.Style := bsClear is not working? >> I have attached a small sample application that shows that even though the text is printed onto the TImage descendant, it is not drawn correctly where the font is jagged and squeezed together and almost readable. At first, I couldn't get the Brush.Style to be clear, but after I was able to do that, the font just will not render correctly. I have attached a screen shot also that shows what the phone looks like. I'm on Lazarus 9.24 Vista Business (same behavior on XP Pro though).

On closer inspection, it looks like the text is being drawn more than once, but offset a little. Not sure how that could happen as my code is only being called once.

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Lee Jenkins
to Lee Jenkins: I'm having a problem with drawing text on an image using the DrawText function where the…
Lee Jenkins wrote 26 lines
Hi all, I'm having a problem with drawing text on an image using the DrawText function where the area around the text masked out. Please see the attached image. This same routine works perfectly in Delphi. Maybe the Canvas.Brush.Style := bsClear is not working? procedure TMyImage.DrawCaption; var lRect: TRect; begin // setup rect lRect.Left := 10; lRect.Top := 10; lRect.Right := Width -10; lRect.Bottom := Height -10; //Canvas.Pen.Style := psClear; // <-- tried this as well Canvas.Font.Assign(FButtonFont); Canvas.Brush.Style := bsClear; DrawText(Canvas.Handle, PChar(FCaption), -1, lRect, DT_WORDBREAK or DT_VCENTER or DT_CENTER or DT_END_ELLIPSIS); end;

Here is the problem that I was having with:

procedure TDTImageButton.HandleMouseUp(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
var
   lBmp: TBitmap;
begin
   if Button = mbLeft then
     begin
       lBmp := FImageManager.ImageByName(FUpImageName);
       Picture.Bitmap.Assign(lBmp);
       DrawCaption;
     end;
end;
Notice the line:
  Picture.Bitmap.Assign(lBmp);
Changing it to
  Canvas.Draw(0,0,lBmp);

Fixed the problem. Odd because it works in Delphi, but the .Canvas.Draw methods doesn't seem to work well in delphi so I ended with this:

procedure TDTImageButton.HandleMouseUp(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
var
   lBmp: TBitmap;
begin
   if Button = mbLeft then
     begin
       lBmp := FImageManager.ImageByName(FUpImageName);
       {$IFDEF fpc}
         Canvas.Draw(0,0,lBmp);
       {$ELSE}
         picture.Bitmap.Assign(lBmp);
       {$endif}
       DrawCaption;
     end;
end;
procedure TDTImageButton.DrawCaption;
var
   lRect: TRect;
   lBmp: TBitmap;
begin
   // setup rect
   lRect.Left := 10;
   lRect.Top := 10;
   lRect.Right := Width -10;
   lRect.Bottom := Height -10;
   Canvas.Brush.Style := bsClear;
   Canvas.Font.Assign(FButtonFont);
   DrawText(Picture.Bitmap.Canvas.Handle, PChar(FCaption), -1, lRect,
     DT_WORDBREAK or DT_CENTER);
end;

This works well and both methods are fast!

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Lee Jenkins
to Martin Schreiber: Another alternative is MSEide+MSEgui: http://sourceforge.net/projects/mseide-msegui In…
Martin Schreiber wrote 9 lines
Julio developed a POS system with MSEide+MSEgui with success BTW. Questions and Bug reports please to NNTP: news://news.grid-sky.com/public.mseide-msegui.talk I'd like to repeat the message to the Lazarus devels: Feel free to use any piece of code out of MSEgui for Lazarus if you find it useful.

Neat, is that the application used for screenshots on the MSEide & MSEgui/FPC wiki page?

Warm Regards, Lee "When my company started out, we were really, really, really, really small. Now...we're just really small."

Reply by email

Martin Schreiber
to Lee Jenkins
Lee Jenkins wrote 11 lines
Martin Schreiber wrote: > Julio developed a POS system with MSEide+MSEgui with success BTW. > Questions and Bug reports please to NNTP: > news://news.grid-sky.com/public.mseide-msegui.talk > > I'd like to repeat the message to the Lazarus devels: > Feel free to use any piece of code out of MSEgui for Lazarus if you find > it useful. Neat, is that the application used for screenshots on the MSEide & MSEgui/FPC wiki page?

No, there is a screenshot in the thread "PNGImageException" from 2008-02-15: news://news.grid-sky.com/public.mseide-msegui.talk

Martin

Reply by email