Recent

Author Topic: [Fixed:] Bug in SVG drawer?  (Read 432 times)

jwdietrich

  • Hero Member
  • *****
  • Posts: 1011
    • formatio reticularis
[Fixed:] Bug in SVG drawer?
« on: May 18, 2019, 05:56:29 pm »
Saving a plot as SVG raises an exception with the message "Font \"default\" not found". As far as I know, this behaviour began to occur with Lazarus 2.0. In Lazarus 1.8 and older versions, everything goes fine.

This observation applies to the "save" demo app, too (see attachment), why I think that this is a bug.
« Last Edit: May 30, 2019, 08:40:09 pm by jwdietrich »
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.0.2 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

jwdietrich

  • Hero Member
  • *****
  • Posts: 1011
    • formatio reticularis
Re: Bug in SVG drawer?
« Reply #1 on: May 18, 2019, 06:01:05 pm »
Further checking the error I found that either the SetFont method of the TSVGDrawer class is not finished (at least the source code suggests so, see attachment) or the Arial font cannot be found (although it is installed, of course).
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.0.2 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

wp

  • Hero Member
  • *****
  • Posts: 5717
Re: Bug in SVG drawer?
« Reply #2 on: May 18, 2019, 06:11:13 pm »
You seem to be on a Mac. Unfortunately I don't have access to a Mac, so I can't test this issue. I even don't know if font "Arial" exists on Mac.

The "LoadFont" which is the reason of the exception is TAChart code. It belongs to unit TAFonts. The "LoadFont" calls a "PopulateFontDirList" which you can find immediately after the "implementation". Note that this procedure only contains defines for Windows and Linux, nothing for Mac. Please extend the procedure with the directories in which the Mac searches for fonts and test. If it works post the code and I'll add it to TAChart.

Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jwdietrich

  • Hero Member
  • *****
  • Posts: 1011
    • formatio reticularis
Re: Bug in SVG drawer?
« Reply #3 on: May 18, 2019, 10:32:21 pm »
You seem to be on a Mac. Unfortunately I don't have access to a Mac, so I can't test this issue. I even don't know if font "Arial" exists on Mac.

The "LoadFont" which is the reason of the exception is TAChart code. It belongs to unit TAFonts. The "LoadFont" calls a "PopulateFontDirList" which you can find immediately after the "implementation". Note that this procedure only contains defines for Windows and Linux, nothing for Mac. Please extend the procedure with the directories in which the Mac searches for fonts and test. If it works post the code and I'll add it to TAChart.

Well, it works partly. It is easy to modify the PopulateFontDirList procedure:

Code: Pascal  [Select]
  1. procedure PopulateFontDirList(AList: TStrings);
  2. const
  3.   CSIDL_FONTS = 20;
  4. var
  5.   s: String;
  6. begin
  7.   if AList = nil then
  8.     raise Exception.Create('PopulateFontDirList: list not allocated.');
  9.  
  10.  {$IFDEF WINDOWS}
  11.   s := SHGetFolderPathUTF8(CSIDL_FONTS);
  12.   if s <> '' then
  13.     AList.Add(s);
  14.  {$ENDIF}
  15.  {$IFDEF linux}
  16.   AList.Add('/usr/share/cups/fonts/');
  17.   AList.Add('/usr/share/fonts/truetype/');
  18.   AList.Add('/usr/local/lib/X11/fonts/');
  19.   AList.Add(GetUserDir + '.fonts/');
  20.  {$ENDIF}
  21.  {$IFDEF LCLCarbon}
  22.  AList.Add('/Library/Fonts/');
  23.  AList.Add('/System/Library/Fonts/');
  24.  AList.Add('/Network/Library/Fonts/');
  25.  AList.Add('~/Library/Fonts/');
  26.  {$ENDIF}
  27.  {$IFDEF LCLCocoa}
  28.  AList.Add('/Library/Fonts/');
  29.  AList.Add('/System/Library/Fonts/');
  30.  AList.Add('/Network/Library/Fonts/');
  31.  AList.Add('~/Library/Fonts/');
  32.  {$ENDIF}
  33. end;

I added the code that is after the conditionals {$IFDEF LCLCarbon} and {$IFDEF LCLCocoa} (lines 21 to 32). Now the four font directories of macOS are available to the code.

However, although the font folders are found and the first 19 fonts are correctly read the code stops with an exception, which is raised at the 20th font in my global font directory (/Library/Fonts/). It is the Font "Brush Script". The exception (TT_Error 1042) is thrown by the procedure TFreeTypeFont.UpdateInstance in the EasyLazFreeType unit (which is called by TFreeTypeFontCollection.AddFile in the LazFreeTypeFontCollection unit via TFreeTypeFont.GetFamily, TFreeTypeFont.GetInformation, TFreeTypeFont.FetchNames, TFreeTypeFont.CheckFace and TFreeTypeFont.UpdateInstance (in this sequence) in the EasyLazFreeType unit). Obviously, the essantial source of this error is the function TT_New_Instance in the same unit (see second screenshot).

Unfortunately, my knowledge ends here, also since I am unable to debug the code in this depth, which contains multiple pointers. I can't figure out where these pointers point at since the debugger only reveals their declaration. Additionally, I don't know, what the TrueType error 1042 is, and I am unable to find pertinent documentation. Help by someone who is experienced with fonts would be welcomed.
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.0.2 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

Thausand

  • Full Member
  • ***
  • Posts: 227
Re: Bug in SVG drawer?
« Reply #4 on: May 18, 2019, 10:50:29 pm »
However, although the font folders are found and the first 19 fonts are correctly read the code stops with an exception, which is raised at the 20th font in my global font directory (/Library/Fonts/). It is the Font "Brush Script". The exception (TT_Error 1042) is thrown by the procedure TFreeTypeFont.UpdateInstance in the EasyLazFreeType unit (which is called by TFreeTypeFontCollection.AddFile in the LazFreeTypeFontCollection unit via TFreeTypeFont.GetFamily, TFreeTypeFont.GetInformation, TFreeTypeFont.FetchNames, TFreeTypeFont.CheckFace and TFreeTypeFont.UpdateInstance (in this sequence) in the EasyLazFreeType unit). Obviously, the essantial source of this error is the function TT_New_Instance in the same unit (see second screenshot).

Unfortunately, my knowledge ends here, also since I am unable to debug the code in this depth, which contains multiple pointers. I can't figure out where these pointers point at since the debugger only reveals their declaration. Additionally, I don't know, what the TrueType error 1042 is, and I am unable to find pertinent documentation. Help by someone who is experienced with fonts would be welcomed.
I not know if can help but i have try make program linux arm many week ago and use BGRABitmap no use LCL and then have same truetype error. True type library make error when use some TTF font. I not have make many inspection and have try some font and not work. I make solution and have copy arial and then work. I think is maybe strange TrueType libary not can load some true type font ? (i not know many about truetype font and what make compatible)

wp

  • Hero Member
  • *****
  • Posts: 5717
Re: Bug in SVG drawer?
« Reply #5 on: May 18, 2019, 11:39:57 pm »
However, although the font folders are found and the first 19 fonts are correctly read the code stops with an exception, which is raised at the 20th font in my global font directory (/Library/Fonts/). It is the Font "Brush Script".
Can you make this font file available to me? I think the error should occur also on Windows or Linux. I cannot promise to fix the bug in the truetype library, but probably there is a way within TAChart to by-pass misbehaving fonts.

If you don't want to make the font file publicly available (because it may be copyright protected) store it in some cloud and send me the link via PM.

------------

Reading some comments in TAFonts there is another option: Call the funtion InitFonts at the beginning of your program.
« Last Edit: May 18, 2019, 11:58:01 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jwdietrich

  • Hero Member
  • *****
  • Posts: 1011
    • formatio reticularis
Re: Bug in SVG drawer?
« Reply #6 on: May 19, 2019, 12:58:09 am »
If you don't want to make the font file publicly available (because it may be copyright protected) store it in some cloud and send me the link via PM.
Reading some comments in TAFonts there is another option: Call the funtion InitFonts at the beginning of your program.

Thanks. I have sent you a PM.

In which unit do I find the InitFonts function? It doesn't seem to be in Lazarus' standard search path.
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.0.2 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

wp

  • Hero Member
  • *****
  • Posts: 5717
Re: Bug in SVG drawer?
« Reply #7 on: May 19, 2019, 01:28:56 am »
InitFonts is in the TAChart unit TAFonts. But forget this hint, it is called automatically when the SVGDrawer is created for the first time.

I could reproduce the exception with your font file on Windows 10. But it looks as if the exception is handled correctly. When you run the application outside the IDE the exception is not fired.

Since EasyLazFreeType only raises the general Exception type I added in r61244 a specific exception class, EFreeType, which is raised now instead of Exception and which you can ignore in your application. This way the error should not happen in the IDE, either.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jwdietrich

  • Hero Member
  • *****
  • Posts: 1011
    • formatio reticularis
Re: Bug in SVG drawer?
« Reply #8 on: May 23, 2019, 08:34:24 am »
I could reproduce the exception with your font file on Windows 10. But it looks as if the exception is handled correctly. When you run the application outside the IDE the exception is not fired.

Since EasyLazFreeType only raises the general Exception type I added in r61244 a specific exception class, EFreeType, which is raised now instead of Exception and which you can ignore in your application. This way the error should not happen in the IDE, either.
You are right, outside the IDE the application seems to run smoothly, even with the current release version of Lazarus (2.0.2). Thanks for fixing this anyway.
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.0.2 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux