Lazarus

Programming => LCL => Topic started by: ϻαϻɾΣɀО on May 23, 2019, 05:01:51 pm

Title: [SOLVED] EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 23, 2019, 05:01:51 pm
Hi,
Just for note, I`m actively working on fpGUI base on BGRABitma.
After some day of starting, Today just checked for memory usage and comparing it with fpGUI with native canvas!
WOW  :o on any invalidating of form, memory increase a lot(about 0.5 MB).
And also I have a problem already, That App hangs on close!
Today I  find out why! 8-)

On the EasyLazFreeType(Managing glyphs for drawing Text independently :-X) unit any glyph will add to the AVL_Tree every time! Because of the developer of this Component forgot to set OnCompare of the TAvlTree. This event enables AVLTree to compare and put the new Item on the right position on the tree, So after FindGlyph will work.
I did it, Memory loading gone, Hangs on close gone  8-)...

My Changes:
Code: Pascal  [Select]
  1.   // ~/lazarus/components/lazutils/easylazfreetype.pas line1441
  2. constructor TFreeTypeFont.Create;
  3. begin
  4.   EnsureFreeTypeInitialized;
  5.   FFaceLoaded := false;
  6.   FFaceItem := nil;
  7.   FInstanceCreated := false;
  8.   FCharmapOk := false;
  9.   FPointSize := 10;
  10.   FDPI := 96;
  11.   FGlyphTable := TAvlTree.Create;
  12.   FGlyphTable.OnCompare := @GlyphTableOnCompare;   //What need it is...
  13.  

And the GlyphTableOnCompare function:
Code: Pascal  [Select]
  1. function GlyphTableOnCompare(Item1, Item2: Pointer): Integer;
  2. begin
  3.   if TFreeTypeGlyph(Item1).Index = TFreeTypeGlyph(Item2).Index then
  4.     Result := 0
  5.   else if TFreeTypeGlyph(Item1).Index > TFreeTypeGlyph(Item2).Index then
  6.     Result := 1
  7.   else if TFreeTypeGlyph(Item1).Index < TFreeTypeGlyph(Item2).Index then
  8.     Result := -1;
  9. end;  
  10.  

I did it, But for my knowledge, How I can report these kinds of  [improvment/currections]?
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: valdir.marcos on May 23, 2019, 07:04:15 pm
Hi,
Just for note, I`m actively working on fpGUI base on BGRABitma.
After some day of starting, Today just checked for memory usage and comparing it with fpGUI with native canvas!
WOW  :o on any invalidating of form, memory increase a lot(about 0.5 MB).
And also I have a problem already, That App hangs on close!
Today I  find out why! 8-)

On the EasyLazFreeType(Managing glyphs for drawing Text independently :-X) unit any glyph will add to the AVL_Tree every time! Because of the developer of this Component forgot to set OnCompare of the TAvlTree. This event enables AVLTree to compare and put the new Item on the right position on the tree, So after FindGlyph will work.
I did it, Memory loading gone, Hangs on close gone  8-)...

My Changes:
Code: Pascal  [Select]
  1.   // ~/lazarus/components/lazutils/easylazfreetype.pas line1441
  2. constructor TFreeTypeFont.Create;
  3. begin
  4.   EnsureFreeTypeInitialized;
  5.   FFaceLoaded := false;
  6.   FFaceItem := nil;
  7.   FInstanceCreated := false;
  8.   FCharmapOk := false;
  9.   FPointSize := 10;
  10.   FDPI := 96;
  11.   FGlyphTable := TAvlTree.Create;
  12.   FGlyphTable.OnCompare := @GlyphTableOnCompare;   //What need it is...
  13.  

And the GlyphTableOnCompare function:
Code: Pascal  [Select]
  1. function GlyphTableOnCompare(Item1, Item2: Pointer): Integer;
  2. begin
  3.   if TFreeTypeGlyph(Item1).Index = TFreeTypeGlyph(Item2).Index then
  4.     Result := 0
  5.   else if TFreeTypeGlyph(Item1).Index > TFreeTypeGlyph(Item2).Index then
  6.     Result := 1
  7.   else if TFreeTypeGlyph(Item1).Index < TFreeTypeGlyph(Item2).Index then
  8.     Result := -1;
  9. end;  
  10.  

I did it, But for my knowledge, How I can report these kinds of  [improvment/currections]?
Try to contact Graeme directly:
https://forum.lazarus.freepascal.org/index.php?action=profile;u=40195
http://wiki.lazarus.freepascal.org/fpGUI#Support
https://github.com/graemeg/fpgui/
http://fpgui.sourceforge.net/
https://en.wikipedia.org/wiki/FpGUI
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: korba812 on May 23, 2019, 08:04:14 pm
How I can report these kinds of  [improvment/currections]?
You should report it in the bugtracker:
http://bugs.freepascal.org/ (http://bugs.freepascal.org/)

Try to contact Graeme directly:
This problem is in "lazutils" package, not fpGui.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: valdir.marcos on May 23, 2019, 09:54:57 pm
How I can report these kinds of  [improvment/currections]?
You should report it in the bugtracker:
http://bugs.freepascal.org/ (http://bugs.freepascal.org/)

Try to contact Graeme directly:
This problem is in "lazutils" package, not fpGui.
I am sorry, I missed that detail.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: jamie on May 24, 2019, 03:22:25 am
How quaint that just happen to be missing, considering there was already an OnCompare event built into it.

I just find it HARDDDDDDDDDDDDDDD to believe!
  >:D
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 24, 2019, 09:52:03 am
How quaint that just happen to be missing, considering there was already an OnCompare event built into it.

I just find it HARDDDDDDDDDDDDDDD to believe!
  >:D

WOW, builtin compare? What compared? And how builtin compare know our strange struct?
OnCompare enable the AVLTree to find out how to compare our structure! When add or find an object to the tree.
Of course, there was a FindGlyphNode function implemented based on AVLTree logic, But it not logical when the AVLTree sorted the objects based on its logic compare and sort  ;D
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: JuhaManninen on May 24, 2019, 06:26:56 pm
Is there a simple way to reproduce the problem in EasyLazFreeType without using fpGUI or BGRABitmap?
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 24, 2019, 06:49:57 pm
Is there a simple way to reproduce the problem in EasyLazFreeType without using fpGUI or BGRABitmap?
Sorry, Currently I don't know any way to use EasyLazFreeType, Except you mentioned.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 24, 2019, 06:54:02 pm
It seems that there is an example of use that,
~/lazarus/examples/lazfreetype
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: wp on May 24, 2019, 07:48:50 pm
Is there a simple way to reproduce the problem in EasyLazFreeType without using fpGUI or BGRABitmap?
I did not look into the details of this discussion, but I think the problem should be seen also with TAChart in the demo "savedemo" (folder "components/tachart/demo/save" of the standard Lazarus installation) after clicking on "Save as SVG" because the SVGDrawer uses LazFreeType. This demo requires only a standard Lazarus installation.

ϻαϻɾΣɀО, can you verify that this bug occurs in this demo, too?
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 24, 2019, 09:06:27 pm
Is there a simple way to reproduce the problem in EasyLazFreeType without using fpGUI or BGRABitmap?
I did not look into the details of this discussion, but I think the problem should be seen also with TAChart in the demo "savedemo" (folder "components/tachart/demo/save" of the standard Lazarus installation) after clicking on "Save as SVG" because the SVGDrawer uses LazFreeType. This demo requires only a standard Lazarus installation.

ϻαϻɾΣɀО, can you verify that this bug occurs in this demo, too?

Yes, it doses! Just look at memory increasing on your TaskManager!

Just change the TFreeTypeFont.GetGlyph to :
Code: Pascal  [Select]
  1. function TFreeTypeFont.GetGlyph(Index: integer): TFreeTypeGlyph;
  2. var
  3.   node: TAvlTreeNode;
  4.   lGlyph: TFreeTypeGlyph;
  5. begin
  6.   if not CheckInstance then
  7.   begin
  8.     result := nil;
  9.     exit;
  10.   end;
  11.   node := FindGlyphNode(Index);
  12.   if node = nil then
  13.   begin
  14.     lGlyph := TFreeTypeGlyph.Create(self, Index);
  15.     //Log what Index added to Tree, And Count of Glyphs
  16.     WriteLn(Index, FGlyphTable.Count: 8);
  17.     FGlyphTable.Add(lGlyph);
  18.   end else
  19.     lGlyph := TFreeTypeGlyph(node.Data);
  20.   result := lGlyph;
  21. end;  
  22.  
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: howardpc on May 24, 2019, 09:56:20 pm
Here the ../tachart/demo/save example produces good .bmp, .png, .jpg and clipboard copies, but bombs with an error when attempting the .svg save.
See attached image for the error.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 24, 2019, 10:13:54 pm
It`s Seems you guys look in the wrong example, Just try lazfreetypetest example located in "/lazarus/examples/lazfreetype".

For start, you must run it with three font name as parameters!
If the application finds the fonts, Its runs with a simple form that render your chosen fonts by moving mouse on the form.
As you move the mouse cursor on the form, Keep your eyes on memory usage of the app in the TaskManager/KSysGuard/GnomeSysMonitor or whatever you are using.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: wp on May 24, 2019, 10:56:02 pm
It`s Seems you guys look in the wrong example, Just try lazfreetypetest example located in "/lazarus/examples/lazfreetype".
OK - please note this in the bug report. You cannot expect a developer to install any third party libraries in order to see a bug. That's the background of Juha's request. Always provide a demo (as simple as possible) to show the bug.

Here the ../tachart/demo/save example produces good .bmp, .png, .jpg and clipboard copies, but bombs with an error when attempting the .svg save.
There has been a recent discussion about this (I don't want to search myself, sorry). The essence was that there seem to be some fonts around which cannot be read correctly by EasyFreeType. This particular exception is caught in the demo and appears only in the debugger, not outside the IDE:
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: circular on May 24, 2019, 11:27:03 pm
Thanks for finding that bug. That's probably my mistake as I wrote this unit.

I remember reading that the AVL tree was buggy so that it was the reason it was acting strangely. Well at least there was some error on my side.

Note: I don't have access to the code so please file a bug report.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: JuhaManninen on May 24, 2019, 11:37:05 pm
For start, you must run it with three font name as parameters!
What parameters should I use in a Linux system? The program always complains whatever I feed it. Not a good demo program IMO.

Maybe a stupid question but how does the OnCompare handler help with memory consumption?
 FGlyphTable.OnCompare := @GlyphTableOnCompare;
I understand it speeds up searches because the items get ordered.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 25, 2019, 12:18:12 am
What parameters should I use in a Linux system? The program always complains whatever I feed it. Not a good demo program IMO.
If you are in the correct example project, The "LazFreeTypeTest"
You can use mine one:[I'd just passed one thing as three time]
"/usr/share/fonts/TTF/DejaVuSans.ttf" "/usr/share/fonts/TTF/DejaVuSans.ttf" "/usr/share/fonts/TTF/DejaVuSans.ttf"
 
Maybe a stupid question but how does the OnCompare handler help with memory consumption?
 FGlyphTable.OnCompare := @GlyphTableOnCompare;

It's simple, As I know the AVLTree sort and makes a tree base on the difference of the added Data,
And not need to mention that the TAVLTree have not any idea about our Data/Object we trying to add.
When you set GlyphTableOnCompare, You'd just learn it how to measure them, sort them and put them the right position on the tree!
In the other hand, When the glyphs  get right position on the tree we can find them with GetGlyphs, But without GlyphTableOnCompare they(The Glyphs) are put somewhere unknown and looking inside a messed up place got you nothing.

After all, GetGlyph tries to find the right glyph inside the tree based on logic that not implemented, when it failed, tries to add it again thas it.
Code: Pascal  [Select]
  1. function TFreeTypeFont.GetGlyph(Index: integer): TFreeTypeGlyph;
  2. var
  3.   node: TAvlTreeNode;
  4.   lGlyph: TFreeTypeGlyph;
  5. begin
  6.   if not CheckInstance then
  7.   begin
  8.     result := nil;
  9.     exit;
  10.   end;
  11.   node := FindGlyphNode(Index);//Tries to find glyph base on index, But it failes cause on glyphs compared and sorted by FontFaceName!
  12.   if node = nil then
  13.   begin
  14.     lGlyph := TFreeTypeGlyph.Create(self, Index);//So It will add more times as ever as program darw a glyph!
  15.     FGlyphTable.Add(lGlyph);
  16.   end else
  17.     lGlyph := TFreeTypeGlyph(node.Data);
  18.   result := lGlyph;
  19. end;
  20.  
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 25, 2019, 12:27:03 am
Just for note,  AvlTree.OnCompare is same as TStringList custom sort.
That means you must identify how the List/Holder/Tree/Collection/HashList or everything has this handler, Must face to and measure what you added to it.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 25, 2019, 12:33:56 am
Thanks for finding that bug. That's probably my mistake as I wrote this unit.

I remember reading that the AVL tree was buggy so that it was the reason it was acting strangely. Well at least there was some error on my side.

Note: I don't have access to the code so please file a bug report.

Sorry for the mistake, There are some compare methods, Id just tries to trace the code when it wants to add glyphs, Id just finds "TFreeTypeFontCollection.CompareFamilyName", But that is wrong!
What happening is a huge mistake! The code sort the glyphs by the font name, And when tries to find them, Searching them by Index!
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 25, 2019, 12:50:29 am
Hey guys, after all of these replies,
There is the first public screenshot of the fpGUI wit BGRABitmap, Transparent roundrected controls, BidiMode enabled, RTL, And Arabic/Persian Font corrections with the minibidi! And platform independent rendering widget(Antialiased lines, Antialiased roundrect) with simple API instead of AggPass!
The font rendering is awesome, Special thanks to developers of LazFreeType and BGRABitmap.
I will turn it(the fpGUI) to a modern look like Applicable and operational widgetset.
Just not judge me with it, Its first tries  8).
I did these all with native canvas but the result was not acceptable for me!

A BGRAfpGUICanvas implemented, and a new theme that read Theme data from a file, It will read CSS (My Next challenge).
The FPC world needs something like Swing like Java or Qt for GUI.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 25, 2019, 01:07:33 am
OK - please note this in the bug report.

Reported as https://bugs.freepascal.org/view.php?id=35627 (https://bugs.freepascal.org/view.php?id=35627).

You cannot expect a developer to install any third party libraries in order to see a bug. That's the background of Juha's request. Always provide a demo (as simple as possible) to show the bug.
I don't expect them to do that!
Just look at the Lazarus examples folder "lazfreetype", The sample project provided by the Lazarus!
I have SVN one, And I don't know if it's with your installation vesion.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: JuhaManninen on May 25, 2019, 11:41:16 am
Reported as https://bugs.freepascal.org/view.php?id=35627 (https://bugs.freepascal.org/view.php?id=35627).
Please test.
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 25, 2019, 02:13:28 pm
Reported as https://bugs.freepascal.org/view.php?id=35627 (https://bugs.freepascal.org/view.php?id=35627).
Please test.
Testd, And problem solved. Thanks.

But what did you mean by "Widgetset should not be CustomDrawn but it cannot be removed for some reason."
As I know I'm just developing theme/style or whatever fpGUI call it the way they did it. Is that what you mentioned "Widgetset"?
"cannot be removed for some reason" What?
Title: Re: [SOLVED] EasyLazFreeType, Memory Load on drawing any charachter....
Post by: circular on May 25, 2019, 09:10:06 pm
Hi ϻαϻɾΣɀО

Beautiful work you did there.  :)

Happy you like the font rendering of LazFreeType and BGRABitmap.

I am wondering for what purpose you need minibidi as bidi is now handled by BGRABitmap?

EDIT: Oh I think I know. TFreeTypeFont does not reorder the glyphs.

I wonder one thing, as it renders glyph by glyph, how do you get the ligatures?
Title: Re: EasyLazFreeType, Memory Load on drawing any charachter....
Post by: JuhaManninen on May 25, 2019, 09:43:41 pm
But what did you mean by "Widgetset should not be CustomDrawn but it cannot be removed for some reason."
As I know I'm just developing theme/style or whatever fpGUI call it the way they did it. Is that what you mentioned "Widgetset"?
The issue was about LazUtils package which has nothing to do with LCL or its widgetsets.
As you know LCL binds into one native widgetset at a time. "CustomDrawn" is one of those widgetsets, maintained by Felipe, but unrelated to this FreeType font issue.
fpGUI is an external GUI library unrelated to LCL, although it has a beta-state widgetset binding for LCL.
Thus, widgetset in the bug report should have been empty, not CustomDrawn.

Quote
"cannot be removed for some reason" What?
It cannot be removed from the bug report. There is no way to deselect it.
Maybe this is due to the updated Mantis version configuration, I don't know.
Title: Re: [SOLVED] EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 26, 2019, 07:40:20 pm
Beautiful work you did there.  :)
Thakns Alot.

Happy you like the font rendering of LazFreeType and BGRABitmap.
It's my pleasure.

I am wondering for what purpose you need minibidi as bidi is now handled by BGRABitmap?
I read that code, It seems too heavy, I like what the minibidi did, Light and applicable.
But I have got a plan to speed up that, All of Shapetaypes will be cached into memory, About 192KB of ram instead of a quick search of shapetype for every charachter!

How do you get the ligatures?
Thats about minibidi, he "Zaher Dirkey" did it but it's not complete yet, I will do it.

Hah I have a long long todo list  :o, But that's so lovely 8-)
Title: Re: [SOLVED] EasyLazFreeType, Memory Load on drawing any charachter....
Post by: circular on May 27, 2019, 12:23:07 pm
Ok.

So minibidi replaces with ligatured glyphs. So I suppose there are Unicode characters that represent the ligature?

So implementing bidi and ligatures in TFreeTypeFont could interfere with minibidi?

By the way is there a link to your code?
Title: Re: [SOLVED] EasyLazFreeType, Memory Load on drawing any charachter....
Post by: benohb on May 27, 2019, 02:41:18 pm
Hello .ϻαϻɾΣɀО …

BGRATextBidi ???
Title: Re: [SOLVED] EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 31, 2019, 12:35:35 pm
So minibidi replaces with ligatured glyphs. So I suppose there are Unicode characters that represent the ligature?
Yes, it dose. Unicode characters of course. But no fully implementation!

So implementing bidi and ligatures in TFreeTypeFont could interfere with minibidi?
I think yes!
Currently, I use it mine function that passes my usual arguments and a new one that prevents it from reordering ar/fa strings(For controlling cursor/caret inside memo/edit box)!

By the way is there a link to your code?
May be, I will check is there a space on my website's host!
Title: Re: [SOLVED] EasyLazFreeType, Memory Load on drawing any charachter....
Post by: ϻαϻɾΣɀО on May 31, 2019, 12:39:29 pm
   
      I am wondering for what purpose you need minibidi as bidi is now handled by BGRABitmap?
   
         I read that code, It seems too heavy, I like what the minibidi did, Light and applicable.
         But I have got a plan to speed up that, All of Shapetaypes will be cached into memory, About 192KB of ram instead of a quick search of shapetype for every charachter!

Hello .ϻαϻɾΣɀО …

BGRATextBidi ???

Another thing that circular point to it: The minibidi provides ligatures and join characters even reorder them!