Recent

Author Topic: Why a compile optimization greater than one messes with TLogFont?  (Read 1852 times)

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Why a compile optimization greater than one messes with TLogFont?
« on: September 19, 2021, 08:30:59 am »
Hey Y'all,

Still asking for the lazCAPTCHA thingamaboob I made :)

I noticed that there's a HUGE difference on how TLogFont behaves depending on what compile optimization I set it.
I noticed this cuz I had the IDE generate the Debug and Release build modes and then when building for Release the result was WAYYYY off the Debug result as you can attest from the attached images.

The build modes generated by the IDE have Debug at -O1 and Release at -O3, just FYI.

As you can see from the attached images, the Debug version works as expected and the font size and rotation are as expected.
BUT in the Release version both the font size and the rotation is not obeyed, which is rather strange!!

Is this a bug that needs reporting to the GitLab issue tracker?

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

ccrause

  • Sr. Member
  • ****
  • Posts: 446
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #1 on: September 19, 2021, 06:14:23 pm »
From your description this does sound suspiciously like a bug. Can you reproduce this behaviour in a minimal test that isolates the misbehaving code? For example, do you see any similar problem when simply drawing a character on a bitmap?

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #2 on: September 19, 2021, 06:39:48 pm »
Hey ccrause,

From your description this does sound suspiciously like a bug. Can you reproduce this behaviour in a minimal test that isolates the misbehaving code? For example, do you see any similar problem when simply drawing a character on a bitmap?

Thanks for the suggestion!! I really appreciate it!!

First of all I didn't create the code, I adapted it from a previous coder as I mention on the repo. So I wouldn't know how to do the Rotation just by using the default font used on Canvas.TextOut.

The fact that the author is using TLogFont to create the custom style of a font, suggest that it's not possible with the font used by default on a Canvas.TextOut.

The code itself is rather simple so I think that a more simplified version wouldn't be possible.

But then again, I have to re-iterate that I'm rather lacking in anything graphical related in terms of Lazarus and that is a hindrance when trying to debug this particular issue.

I was able to reproduce the issue in both Lazarus trunk(still need to update to Laz-main, I'm still on the last SVN before the SVN was shutdown) and Lazarus 2.0.12, so it's not a compiler issue, I think...

Nonetheless it is a good suggestion and I think if I had any chops in the graphical department of Lazarus I could suss it out myself :(

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

wp

  • Hero Member
  • *****
  • Posts: 8880
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #3 on: September 19, 2021, 07:33:08 pm »
The fact that the author is using TLogFont to create the custom style of a font, suggest that it's not possible with the font used by default on a Canvas.TextOut.
No, you can use TFont and the standard text routines of the canvas. Just use TFont.Orientation to rotate it. The original author probably uses the TLogFont because it's the Windows way to do it.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 7434
  • Debugger - SynEdit - and more
    • wiki
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #4 on: September 19, 2021, 07:46:53 pm »
Have you tried to compare the resulting assembler? You can stop in the debugger, and copy it from the disassembler window.

Maybe there is something?

DomingoGP

  • New Member
  • *
  • Posts: 16
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #5 on: September 19, 2021, 08:25:52 pm »
I can't reproduce with lazarus 2.0.10 nor 2.2 rc1 on windows 7 64 bits.

But you can try to set all fields of logFont to 0 and fill the logFont.lfOrientation field in drawletter function.


Code: Pascal  [Select][+][-]
  1. procedure TCAPTCHA.DrawLetter(ch: Char; angle, nextPos: Integer);
  2. var
  3.   logFont: TLogFont;
  4.   fontHandle: THandle;
  5. begin
  6.   Fillchar(logFont,Sizeof(logFont),0);    //<-------
  7.   logFont.lfheight:= 40;
  8.   logFont.lfwidth:= 20;
  9.   logFont.lfweight:= 900;
  10.  
  11.   logFont.lfEscapement:= angle;
  12.   logFont.lfOrientation:= angle;         //<------
  13.   logFont.lfcharset:= 1;
  14.   logFont.lfoutprecision:= OUT_TT_ONLY_PRECIS;
  15.   logFont.lfquality:= DEFAULT_QUALITY;
  16.   logFont.lfpitchandfamily:= FF_SWISS;
  17.   logFont.lfUnderline:= 0;
  18.   logFont.lfStrikeOut:= 0;
  19.  
  20.   fontHandle:= CreateFontIndirect(logFont);
  21.   SelectObject(FCAPTCHABitmap.Canvas.Handle, fontHandle);
  22.  
  23.   SetTextColor(FCAPTCHABitmap.Canvas.Handle, rgb(0, 180, 0));
  24.   SetBKmode(FCAPTCHABitmap.Canvas.Handle, TRANSPARENT);
  25.  
  26.   SetTextColor(FCAPTCHABitmap.Canvas.Handle, Random(MAXWORD));
  27.   FCAPTCHABitmap.Canvas.TextOut(nextPos, FCAPTCHABitmap.Height div 3, ch);
  28.   DeleteObject(fontHandle);
  29. end;
  30.  

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #6 on: September 19, 2021, 09:02:26 pm »
Hey Martin,

Have you tried to compare the resulting assembler? You can stop in the debugger, and copy it from the disassembler window.

Maybe there is something?

Great suggestion to look at.

It's gonna be quite an endeavour for me since I'm not used at this type of low level scrutiny. But I'll try and give it a go.

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #7 on: September 19, 2021, 09:07:55 pm »
Hey Domingo,

I can't reproduce with lazarus 2.0.10 nor 2.2 rc1 on windows 7 64 bits.

Hummm, so looks like it's a problem with my Ubuntu 21.04 64b then.
That's one less thing to question about :)

But you can try to set all fields of logFont to 0 and fill the logFont.lfOrientation field in drawletter function.

AHAH!! Yes, the old issue with the fact that optimization could introduce garbage from the area of memory allocated to the TLogFont record.

Completely forgot about that, and for your suggestion I'm quite grateful!!!

I'll have a go with the FillChar and then report if it changes anything!!

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #8 on: September 19, 2021, 09:17:05 pm »
Hey Domingo,

Had a go with the FillChar and adding the lfOrientation:= angle but it didn't change the result :(

Many thanks for the try thou!!

Will probably need to take Martin's advice and look at the assembler!

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #9 on: September 19, 2021, 09:24:44 pm »
Hey WP,

No, you can use TFont and the standard text routines of the canvas. Just use TFont.Orientation to rotate it.

Ahhhh, Ok, I wasn't aware of that, many thanks!!!

But looking at your screenshot of your implementation, the font look different than the one I get with TLogFont.

I still have a question: What's the difference between Orientation and Escapement?
Is there an Escapement property on TFont?

I really have to look at your code since it will provide me with more inside knowledge on how this works.

The original author probably uses the TLogFont because it's the Windows way to do it.

I have to agree with you. My problem is that being so ignorant on these graphical/font matters I din't have enough knowledge to make it less Windowsee and more Lazarusee :(

Like I said, need to have a good look at your code :)

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

wp

  • Hero Member
  • *****
  • Posts: 8880
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #10 on: September 19, 2021, 11:14:15 pm »
What's the difference between Orientation and Escapement?
Is there an Escapement property on TFont?
Look at this: http://fixxion.de/software/fontinfo/fontinfode.htm#lfescapement - it is in German but you'll see the difference immediately..

AFAIK, there is not Escapement on TFont, but I don't see why it is needed here. With single characters Escapement and Orientation are the same (in my opinion, which may be wrong, of course).
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #11 on: September 19, 2021, 11:44:43 pm »
Hey WP,

Look at this: http://fixxion.de/software/fontinfo/fontinfode.htm#lfescapement - it is in German but you'll see the difference immediately..

Quite clear indeed, thanks for the explanation!!

AFAIK, there is not Escapement on TFont, but I don't see why it is needed here. With single characters Escapement and Orientation are the same (in my opinion, which may be wrong, of course).

I checked after I asked, and you're correct, there is no escapement in TFont. I think I agree with you on the single char argument.

I think I got a bit confused because in your screenshot the letters are very apart, are smaller and differ in angle, I think, with my version. So I attributed it to escapement cuz I really didn't know what it is, LOL!!

I like the way it's done in my version because it has a bit more difficulty added. But I guess that if I mess with font size and/or weight and spaces between chars I can get yours to be more like mine, don't you think?

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

wp

  • Hero Member
  • *****
  • Posts: 8880
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #12 on: September 20, 2021, 12:54:32 am »
I think I got a bit confused because in your screenshot the letters are very apart, are smaller and differ in angle, I think, with my version. So I attributed it to escapement cuz I really didn't know what it is, LOL!!

I like the way it's done in my version because it has a bit more difficulty added. But I guess that if I mess with font size and/or weight and spaces between chars I can get yours to be more like mine, don't you think?
The difference between your version and mine is:
- Your code rotates the characters abour a random angle between 0 and 60 degrees, i.e. always in the same direction. My code rotates in both directions, about an angle between -60 and +60 degrees (by default).
- Your code has hard-coded spacings (25 * i - 15, in RefreshBitmap), i.e. works only with that specific font size. My code calculates the boundary rectangle of the rotated character (which is a bit wider than the unrotated character), and puts the characters at a variable spacing defined by the width of the boundary rectangle so that the characters do not overlap.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

Fred vS

  • Hero Member
  • *****
  • Posts: 2411
    • StrumPract is the musicians best friend
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #13 on: September 20, 2021, 01:30:52 am »
Hello Gus.

Nice project.!

I like both your version vs the one of wp.

But, I prefer the one of winni, that uses BGRABitmap.
This because it is more universal and can be used for all widgetset compatible with BGRABitmap.

And it is the case for LCL, fpGUI and MSEgui.

Your and wp versions are very good but LCL only.

Fre;D



I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 757
  • Professional amateur ;-P
Re: Why a compile optimization greater than one messes with TLogFont?
« Reply #14 on: September 20, 2021, 01:38:51 am »
Hey WP,

- Your code rotates the characters abour a random angle between 0 and 60 degrees, i.e. always in the same direction. My code rotates in both directions, about an angle between -60 and +60 degrees (by default).

Yeap, that makes a lot more sense and I'll maybe adopt your method.

- Your code has hard-coded spacings (25 * i - 15, in RefreshBitmap), i.e. works only with that specific font size. My code calculates the boundary rectangle of the rotated character (which is a bit wider than the unrotated character), and puts the characters at a variable spacing defined by the width of the boundary rectangle so that the characters do not overlap.

Hummm, so that's what the pi over 180 thing is all about :) Gotcha!!

While I admire the fact that you made the extra effort to keep them apart, I still think that a bit of overlap isn't that bad, but to be honest it's just a matter of taste and is irrelevant.
I think that the lines will produce enough noise that both my version and yours would be very computationally intensive to suss out by a computer, so it doesn't matter what the chars look like.

Next thing I'll do is, for sure, adopt using TFont instead of TLogFont. But I'm still gonna try and mimic the overlapping and the general appearance of my version.

Again, and I can't say this enough, your code will be invaluable for me to up my ante and make my version a component!!

Another thing that I really liked about your solution is that you don't care about the component size, you just draw the CAPTCHA in the middle, Vertically and Horizontally, of the available space.
This eliminates the aspect ratio question I had and makes it easier to always have the necessary size without going into complicated calculations of aspect ratio!!

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.04 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.04 64b Dark Theme
http://github.com/gcarreno

 

TinyPortal © 2005-2018