Why a compile optimization greater than one messes with TLogFont? lazarus / 39-Graphics ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 06:30 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 ---------------------------------------------------------------------- ccrause · 2021-09-19 16:14 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 · 2021-09-19 16:39 Hey ccrause, Quote from: ccrause on September 19, 2021, 06:14:23 pmFrom 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 ---------------------------------------------------------------------- wp · 2021-09-19 17:33 Quote from: Gustavo 'Gus' Carreno on September 19, 2021, 06:39:48 pmThe 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. ---------------------------------------------------------------------- Martin_fr · 2021-09-19 17:46 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 · 2021-09-19 18:25 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TCAPTCHA.DrawLetter(ch: Char; angle, nextPos: Integer);var  logFont: TLogFont;  fontHandle: THandle;begin  Fillchar(logFont,Sizeof(logFont),0);    //<-------  logFont.lfheight:= 40;  logFont.lfwidth:= 20;  logFont.lfweight:= 900;   logFont.lfEscapement:= angle;  logFont.lfOrientation:= angle;         //<------  logFont.lfcharset:= 1;  logFont.lfoutprecision:= OUT_TT_ONLY_PRECIS;  logFont.lfquality:= DEFAULT_QUALITY;  logFont.lfpitchandfamily:= FF_SWISS;  logFont.lfUnderline:= 0;  logFont.lfStrikeOut:= 0;   fontHandle:= CreateFontIndirect(logFont);  SelectObject(FCAPTCHABitmap.Canvas.Handle, fontHandle);   SetTextColor(FCAPTCHABitmap.Canvas.Handle, rgb(0, 180, 0));  SetBKmode(FCAPTCHABitmap.Canvas.Handle, TRANSPARENT);   SetTextColor(FCAPTCHABitmap.Canvas.Handle, Random(MAXWORD));  FCAPTCHABitmap.Canvas.TextOut(nextPos, FCAPTCHABitmap.Height div 3, ch);  DeleteObject(fontHandle);end; ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 19:02 Hey Martin, Quote from: Martin_fr on September 19, 2021, 07:46:53 pmHave 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 ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 19:07 Hey Domingo, Quote from: DomingoGP on September 19, 2021, 08:25:52 pmI 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 Quote from: DomingoGP on September 19, 2021, 08:25:52 pmBut 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 ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 19:17 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 ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 19:24 Hey WP, Quote from: wp on September 19, 2021, 07:33:08 pmNo, 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. Quote from: wp on September 19, 2021, 07:33:08 pmThe 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 ---------------------------------------------------------------------- wp · 2021-09-19 21:14 Quote from: Gustavo 'Gus' Carreno on September 19, 2021, 09:24:44 pmWhat'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). ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 21:44 Hey WP, Quote from: wp on September 19, 2021, 11:14:15 pmLook 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!! Quote from: wp on September 19, 2021, 11:14:15 pmAFAIK, 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 ---------------------------------------------------------------------- wp · 2021-09-19 22:54 Quote from: Gustavo 'Gus' Carreno on September 19, 2021, 11:44:43 pmI 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. ---------------------------------------------------------------------- Fred vS · 2021-09-19 23:30 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 ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 23:38 Hey WP, Quote from: wp on September 20, 2021, 12:54:32 am- 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. Quote from: wp on September 20, 2021, 12:54:32 am- 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 ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-09-19 23:44 Hey Fred, Quote from: Fred vS on September 20, 2021, 01:30:52 amNice project.! I like both your version vs the one of wp. From my part, thank you so very much, even if I can't take all the credit cuz I just adapted someone else's code Quote from: Fred vS on September 20, 2021, 01:30:52 amYour and wp versions are very good but LCL only. This was my intention from the beginning: Just use the bare minimum that Lazarus ships with. One of the things that I would love winni to do is to have it on a GitHub repo like me and WP. This would be great and we could all link to it instead of having to dig through the infinite posts on this site I'll probably bug winni on a PM Cheers, Gus