Recent

Author Topic: FPC and DCC Difference in 'Types' Unit missing functions in FPC  (Read 2325 times)

Schmitty2005

  • New Member
  • *
  • Posts: 49
I have recently been making programs that I would like to compile with DCC and FPC.  I ran across three functions that were helpful when working with Trect in the LCL/VCL  canvas and BGRABitmap. These functions were available in Delphi, but not in FPC.  I think that they are useful and simple enough to be added to FPC.

Here are links to two of the functions :

https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Types.CenteredRect

https://docwiki.embarcadero.com/Libraries/Athens/en/System.Types.RectCenter



They are simple enough that I wrote my own for the project, but I think others may find them useful if added to FPC.  I do not see how this could break anything.




Another function I could not find in FPC was 'NormalizeRect', and it relied on CenteredRect

https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.Types.TRect.NormalizeRect


EDIT:

Another function I could not find in FPC was Normalized :

https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Types.TRect.Normalize


This is the code that I used based off of NormalizeRect from the Delphi manual, that I can no longer find the link with the code :

It should work fine,  I remember it working fine. It uses some optimized calculations,  but I do not have time to verify at the moment:

Code: Pascal  [Select][+][-]
  1. procedure Normalize(var aRect: Trect); //NormalizedRect in Delphi
  2. var
  3.   replRect: Trect;
  4. begin
  5.   if aRect.top > aRect.bottom then
  6.   begin
  7.     with aRect do
  8.     begin
  9.       top := top xor bottom;
  10.       bottom := top xor bottom;
  11.       top := top xor bottom;
  12.     end;
  13.   end;
  14.  
  15.   if aRect.left > aRect.right then
  16.   begin
  17.     with aRect do
  18.     begin
  19.       left := left xor right;
  20.       right := left xor right;
  21.       left := left xor right;
  22.     end;
  23.   end;
  24.   replRect := aRect;
  25.   aRect := centeredRect(replRect, aRect);
  26. end;
  27.  

« Last Edit: July 27, 2025, 06:58:26 pm by Schmitty2005 »

gues1

  • Guest

Thaddy

  • Hero Member
  • *****
  • Posts: 18502
  • Here stood a man who saw the Elbe and jumped it.
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #2 on: July 27, 2025, 04:58:10 pm »
Unless it is trivial it is forbidden to use embarcadero code. Work always from the interface.
[edit read my later response]
Proof:
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode delphi}{$endif}
  2. {$APPTYPE CONSOLE}
  3. uses types;
  4. procedure NormalizeRect(var aRect: Trect); //NormalizedRect in Delphi
  5. var
  6.   replRect: Trect;
  7. begin
  8.   if aRect.top > aRect.bottom then
  9.   begin
  10.     with aRect do
  11.     begin
  12.       top := top xor bottom;
  13.       bottom := top xor bottom;
  14.       top := top xor bottom;
  15.     end;
  16.   end;
  17.  
  18.   if aRect.left > aRect.right then
  19.   begin
  20.     with aRect do
  21.     begin
  22.       left := left xor right;
  23.       right := left xor right;
  24.       left := left xor right;
  25.     end;
  26.   end;
  27.   replRect := aRect;
  28.   aRect := centeredRect(replRect, aRect);
  29. end;
  30. var
  31.   // intentionally screwed
  32.   Myrect:Trect = (left:200;top:50;right:100;bottom:25);
  33. begin
  34.   write(myrect.left:5);;
  35.   write(myrect.top:5);
  36.   write(myrect.right:5);
  37.   writeln(myrect.bottom:5);
  38.   normalizeRect(MyRect);
  39.   write(myrect.left:5);;
  40.   write(myrect.top:5);
  41.   write(myrect.right:5);
  42.   writeln(myrect.bottom:5);
  43.   readln;
  44. end.
I think it is trivial.
« Last Edit: July 27, 2025, 05:32:48 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Schmitty2005

  • New Member
  • *
  • Posts: 49
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #3 on: July 27, 2025, 05:08:26 pm »
Unless it is trivial it is forbidden to use embarcadero code. Work always from the interface.

I understand not using Embarcadero's code, but it is also trival and a person with experience could come up with the same solution without looking at Embarcadero code.

Are all of these suggestion too trivial to be added to FPC ?  With {$MODE DELPHI}  available in FPC, it would seem beneficial and maybe even expected.  I know I expected it to work without writing my own in FPC.

In this case I suggest to use the generic swap, which may be even faster than the usually expensive modulo on some platforms.
In this case I suggest to use the generic swap, which may be even faster than the usually expensive modulo on some platforms.

Could you please elaborate ?   I am guessing the 'NormalizedRect' will be quicker that the 'Normalize'  procedure I posted above

Code: C  [Select][+][-]
  1. void NormalizeRect() _ALWAYS_INLINE {
  2.     int i;
  3.     if (left > right)
  4.     {
  5.       i = left;
  6.       left = right;
  7.       right = i;
  8.     }
  9.     if (top > bottom)
  10.     {
  11.       i = top;
  12.       top = bottom;
  13.       bottom = i;
  14.     }
  15.   }
  16.  


CenteredRect Procedure :

Code: Pascal  [Select][+][-]
  1. function centeredRect(const ARect: TRect; const bRect: TRect): TRect;
  2.   //@TODO check if this even works correctly
  3. var
  4.   outerSize, innerSize: TSize;
  5.   xNew, yNew: longint;
  6. begin
  7.   xNew := 0;
  8.   yNew := 0;
  9.  
  10.   outerSize := ARect.Size;
  11.   innerSize := bRect.Size;
  12.  
  13.   if innerSize.cx > outerSize.cx then
  14.     innerSize.cx := outerSize.cx;
  15.  
  16.   if innerSize.cy > outerSize.cy then
  17.     innerSize.cy := outerSize.cy;
  18.  
  19.   Result := bounds(xNew, yNew, innerSize.cx, innerSize.cy);
  20. end;
  21.  
  22.  

You were posting as I was replying...  I added the CenteredRect procedure to your code so it would compile .The output of your example , so others can see :

Code: Pascal  [Select][+][-]
  1.   200   50  100   25
  2.     0    0  100   25
  3.  
  4.  
« Last Edit: July 27, 2025, 05:32:10 pm by Schmitty2005 »

Thaddy

  • Hero Member
  • *****
  • Posts: 18502
  • Here stood a man who saw the Elbe and jumped it.
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #4 on: July 27, 2025, 05:16:52 pm »
Posts crossed, see above, I edited my post. It is OK to call it NormalizeRect too.
It is trivial because the branchless swap trick stems from "bit twiddling hacks".
https://graphics.stanford.edu/~seander/bithacks.html ( everybody should know these )
Entry: swapping with xor.

So your code is fine.

Note this trick is not always faster on all platforms, but there is some logic in implementing it like that if you compile for multiple platforms.

« Last Edit: July 27, 2025, 05:36:29 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

simone

  • Hero Member
  • *****
  • Posts: 681
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #5 on: July 27, 2025, 05:35:09 pm »
Another function I could not find in FPC was 'NormalizeRect', and it relied on CenteredRect

In the Types unit (part of RTL in fpc), the TRect record has the NormalizeRect method. See https://www.freepascal.org/docs-html/rtl/types/trect.html
Microsoft Windows 10/11 64 bit - Lazarus 3.8/4.0 FPC 3.2.2 x86_64-win64-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 18502
  • Here stood a man who saw the Elbe and jumped it.
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #6 on: July 27, 2025, 05:37:56 pm »
That's even better. Forgot about that. Should have a class function too, now I looked at it.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12563
  • FPC developer.
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #7 on: July 27, 2025, 06:13:04 pm »
Posts crossed, see above, I edited my post. It is OK to call it NormalizeRect too.
It is trivial because the branchless swap trick stems from "bit twiddling hacks".
https://graphics.stanford.edu/~seander/bithacks.html ( everybody should know these )
Entry: swapping with xor.

The XOR is swapping, but not any more branchless. Afaik it might reduce register pressure in some rare cases though. (but possibly have more load/stores from memory?)

I think it is a bit weird that there is both a normalize and normalizerect that are basically the same except for the xor trick. But it might have being to do with unification of the windows unit (with winapi macro's converted into functions vs some C++ derived system independent implementation into the types unit in Kylix times, or during the XE2 era resurrection of it).

It seems the easiest solution is to use normalizerect for now and file a bugreport for the normalize addition.


Schmitty2005

  • New Member
  • *
  • Posts: 49
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #8 on: July 27, 2025, 06:59:51 pm »
Another function I could not find in FPC was 'NormalizeRect', and it relied on CenteredRect

In the Types unit (part of RTL in fpc), the TRect record has the NormalizeRect method. See https://www.freepascal.org/docs-html/rtl/types/trect.html

I mistyped in my original post.  I have edited it.  It has been months since I have noticed this, and did not remember correctly what the issues were.  The issue is that there is no Normalize function in FPC.

https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Types.TRect.Normalize
« Last Edit: July 27, 2025, 07:13:00 pm by Schmitty2005 »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12563
  • FPC developer.
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #9 on: July 27, 2025, 09:59:07 pm »
Yeah, I got that. I was merely musing about the reasons for duplicate situation. I copy and pasted a copy of normalizerect as normalize for now.

https://gitlab.com/freepascal.org/fpc/source/-/commit/f7aa2f60dce649ccd37a638858d19c278ebf8391
« Last Edit: July 27, 2025, 10:05:50 pm by marcov »

gues1

  • Guest
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #10 on: July 28, 2025, 09:45:39 am »
Yeah, I got that. I was merely musing about the reasons for duplicate situation. I copy and pasted a copy of normalizerect as normalize for now.
https://gitlab.com/freepascal.org/fpc/source/-/commit/f7aa2f60dce649ccd37a638858d19c278ebf8391
Does not exist any "Normalize" function / procedure / methods in TRect record in actual (last) Delphi Athens 12.3 (and may be neither in the previous version).

It exist in C++ (may be for compatibility with something old).

Schmitty2005

  • New Member
  • *
  • Posts: 49
Re: FPC and DCC Difference in 'Types' Unit missing functions in FPC
« Reply #11 on: July 29, 2025, 04:19:56 am »
I have recently been making programs that I would like to compile with DCC and FPC.  I ran across three functions that were helpful when working with Trect in the LCL/VCL  canvas and BGRABitmap. These functions were available in Delphi, but not in FPC.  I think that they are useful and simple enough to be added to FPC.

Here are links to two of the functions :

https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Types.CenteredRect

https://docwiki.embarcadero.com/Libraries/Athens/en/System.Types.RectCenter



They are simple enough that I wrote my own for the project, but I think others may find them useful if added to FPC.  I do not see how this could break anything.


They were useful when using Trect's with canvas objects.

Any thoughts on CenteredRect and RectCentered being added to FPC Types unit ?   Any reason they shouldn't be added ?   

 

TinyPortal © 2005-2018