[SOLVED] EasyLazFreeType, Memory Load on drawing any charachter.... lazarus / 31-LCL ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-23 15:01 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  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! On the EasyLazFreeType(Managing glyphs for drawing Text independently ) 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  ... My Changes: 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   // ~/lazarus/components/lazutils/easylazfreetype.pas line1441constructor TFreeTypeFont.Create;begin  EnsureFreeTypeInitialized;  FFaceLoaded := false;  FFaceItem := nil;  FInstanceCreated := false;  FCharmapOk := false;  FPointSize := 10;  FDPI := 96;  FGlyphTable := TAvlTree.Create;  FGlyphTable.OnCompare := @GlyphTableOnCompare;   //What need it is...  And the GlyphTableOnCompare 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 function GlyphTableOnCompare(Item1, Item2: Pointer): Integer;begin  if TFreeTypeGlyph(Item1).Index = TFreeTypeGlyph(Item2).Index then    Result := 0  else if TFreeTypeGlyph(Item1).Index > TFreeTypeGlyph(Item2).Index then    Result := 1  else if TFreeTypeGlyph(Item1).Index < TFreeTypeGlyph(Item2).Index then    Result := -1;end; I did it, But for my knowledge, How I can report these kinds of  [improvment/currections]? ---------------------------------------------------------------------- valdir.marcos · 2019-05-23 17:04 Quote from: ϻαϻɾΣɀО on May 23, 2019, 05:01:51 pmHi, 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  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! On the EasyLazFreeType(Managing glyphs for drawing Text independently ) 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  ... My Changes: 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   // ~/lazarus/components/lazutils/easylazfreetype.pas line1441constructor TFreeTypeFont.Create;begin  EnsureFreeTypeInitialized;  FFaceLoaded := false;  FFaceItem := nil;  FInstanceCreated := false;  FCharmapOk := false;  FPointSize := 10;  FDPI := 96;  FGlyphTable := TAvlTree.Create;  FGlyphTable.OnCompare := @GlyphTableOnCompare;   //What need it is...  And the GlyphTableOnCompare 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 function GlyphTableOnCompare(Item1, Item2: Pointer): Integer;begin  if TFreeTypeGlyph(Item1).Index = TFreeTypeGlyph(Item2).Index then    Result := 0  else if TFreeTypeGlyph(Item1).Index > TFreeTypeGlyph(Item2).Index then    Result := 1  else if TFreeTypeGlyph(Item1).Index < TFreeTypeGlyph(Item2).Index then    Result := -1;end; 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 ---------------------------------------------------------------------- korba812 · 2019-05-23 18:04 Quote from: ϻαϻɾΣɀО on May 23, 2019, 05:01:51 pmHow I can report these kinds of  [improvment/currections]? You should report it in the bugtracker: http://bugs.freepascal.org/ Quote from: valdir.marcos on May 23, 2019, 07:04:15 pmTry to contact Graeme directly: This problem is in "lazutils" package, not fpGui. ---------------------------------------------------------------------- valdir.marcos · 2019-05-23 19:54 Quote from: korba812 on May 23, 2019, 08:04:14 pmQuote from: ϻαϻɾΣɀО on May 23, 2019, 05:01:51 pmHow I can report these kinds of  [improvment/currections]?You should report it in the bugtracker: http://bugs.freepascal.org/ Quote from: valdir.marcos on May 23, 2019, 07:04:15 pmTry to contact Graeme directly:This problem is in "lazutils" package, not fpGui.I am sorry, I missed that detail. ---------------------------------------------------------------------- jamie · 2019-05-24 01:22 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! ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 07:52 Quote from: jamie on May 24, 2019, 03:22:25 amHow quaint that just happen to be missing, considering there was already an OnCompare event built into it. I just find it HARDDDDDDDDDDDDDDD to believe!   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 ---------------------------------------------------------------------- JuhaManninen · 2019-05-24 16:26 Is there a simple way to reproduce the problem in EasyLazFreeType without using fpGUI or BGRABitmap? ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 16:49 Quote from: JuhaManninen on May 24, 2019, 06:26:56 pmIs 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. ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 16:54 It seems that there is an example of use that, ~/lazarus/examples/lazfreetype ---------------------------------------------------------------------- wp · 2019-05-24 17:48 Quote from: JuhaManninen on May 24, 2019, 06:26:56 pmIs 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? ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 19:06 Quote from: wp on May 24, 2019, 07:48:50 pmQuote from: JuhaManninen on May 24, 2019, 06:26:56 pmIs 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TFreeTypeFont.GetGlyph(Index: integer): TFreeTypeGlyph;var  node: TAvlTreeNode;  lGlyph: TFreeTypeGlyph;begin  if not CheckInstance then  begin    result := nil;    exit;  end;  node := FindGlyphNode(Index);  if node = nil then  begin    lGlyph := TFreeTypeGlyph.Create(self, Index);    //Log what Index added to Tree, And Count of Glyphs    WriteLn(Index, FGlyphTable.Count: 8);    FGlyphTable.Add(lGlyph);  end else    lGlyph := TFreeTypeGlyph(node.Data);  result := lGlyph;end; ---------------------------------------------------------------------- howardpc · 2019-05-24 19:56 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. ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 20:13 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. ---------------------------------------------------------------------- wp · 2019-05-24 20:56 Quote from: ϻαϻɾΣɀО on May 24, 2019, 10:13:54 pmIt`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. Quote from: howardpc on May 24, 2019, 09:56:20 pmHere 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: ---------------------------------------------------------------------- circular · 2019-05-24 21:27 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. ---------------------------------------------------------------------- JuhaManninen · 2019-05-24 21:37 Quote from: ϻαϻɾΣɀО on May 24, 2019, 10:13:54 pmFor 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. ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 22:18 Quote from: JuhaManninen on May 24, 2019, 11:37:05 pmWhat 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" Quote from: JuhaManninen on May 24, 2019, 11:37:05 pmMaybe 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TFreeTypeFont.GetGlyph(Index: integer): TFreeTypeGlyph;var  node: TAvlTreeNode;  lGlyph: TFreeTypeGlyph;begin  if not CheckInstance then  begin    result := nil;    exit;  end;  node := FindGlyphNode(Index);//Tries to find glyph base on index, But it failes cause on glyphs compared and sorted by FontFaceName!  if node = nil then  begin    lGlyph := TFreeTypeGlyph.Create(self, Index);//So It will add more times as ever as program darw a glyph!    FGlyphTable.Add(lGlyph);  end else    lGlyph := TFreeTypeGlyph(node.Data);  result := lGlyph;end; ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 22:27 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. ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 22:33 Quote from: circular on May 24, 2019, 11:27:03 pmThanks 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! ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 22:50 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  . 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. ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-24 23:07 Quote from: wp on May 24, 2019, 10:56:02 pmOK - please note this in the bug report. Reported as https://bugs.freepascal.org/view.php?id=35627. Quote from: wp on May 24, 2019, 10:56:02 pmYou 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. ---------------------------------------------------------------------- JuhaManninen · 2019-05-25 09:41 Quote from: ϻαϻɾΣɀО on May 25, 2019, 01:07:33 amReported as https://bugs.freepascal.org/view.php?id=35627. Please test. ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-25 12:13 Quote from: JuhaManninen on May 25, 2019, 11:41:16 amQuote from: ϻαϻɾΣɀО on May 25, 2019, 01:07:33 amReported as 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? ---------------------------------------------------------------------- circular · 2019-05-25 19:10 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? ---------------------------------------------------------------------- JuhaManninen · 2019-05-25 19:43 Quote from: ϻαϻɾΣɀО on May 25, 2019, 02:13:28 pmBut 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. ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-26 17:40 Quote from: circular on May 25, 2019, 09:10:06 pmBeautiful work you did there.  Thakns Alot. Quote from: circular on May 25, 2019, 09:10:06 pmHappy you like the font rendering of LazFreeType and BGRABitmap. It's my pleasure. Quote from: circular on May 25, 2019, 09:10:06 pmI 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! Quote from: circular on May 25, 2019, 09:10:06 pmHow 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  , But that's so lovely ---------------------------------------------------------------------- circular · 2019-05-27 10:23 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? ---------------------------------------------------------------------- benohb · 2019-05-27 12:41 Hello .ϻαϻɾΣɀО … BGRATextBidi ??? ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-31 10:35 Quote from: circular on May 27, 2019, 12:23:07 pmSo 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! Quote from: circular on May 27, 2019, 12:23:07 pmSo 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)! Quote from: circular on May 27, 2019, 12:23:07 pmBy the way is there a link to your code? May be, I will check is there a space on my website's host! ---------------------------------------------------------------------- ϻαϻɾΣɀО · 2019-05-31 10:39 Quote from: benohb on May 27, 2019, 02:41:18 pm   Quote from: circular on May 25, 2019, 09:10:06 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!