Recent

Author Topic: TBGRAFreeTypeFontRenderer garbling certain fonts  (Read 6428 times)

CCRDude

  • Hero Member
  • *****
  • Posts: 600
TBGRAFreeTypeFontRenderer garbling certain fonts
« on: November 23, 2015, 04:13:00 pm »
I've copied the example from the tutorial, and tried with a different font - Work Sans Black from Google Fonts.

Then I noticed this affects the whole Work Sans family. I tried a few more font families in Google Fonts, and also affects other Google Fonts fonts (Oswald, Anton, ...).

Texts show quite fine with the default renderer and everywhere else in LCL controls, they just garble when using the TBGRAFreeTypeFontRenderer.

Is this a hidden bug in the fonts? Or in TBGRAFreeTypeFontRenderer?

(BGRABitmapPack from LazPaint checkout from October 19th)
« Last Edit: November 23, 2015, 04:14:55 pm by CCRDude »

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #1 on: November 23, 2015, 05:45:20 pm »
I have seen bugs in fonts before, so thought I would test WorkSans. BTW: Many thanks for introducing me to WorkSans, it is a beautiful font.  :) Anyway, there doesn't seem to be issues with the font itself - I just downloaded the latest from Github, and tested with AggPas.

I understand that TBGRAFreeTypeFontRenderer uses the Lazarus FreeType font unit, which is based on a very old FreeType implementation - so that might be the cause [not 100% sure]. My copy of AggPas uses the standard FreeType library, not the Lazarus unit. But I am in the process on implementing support (mainly for testing purposes) for the LazFreeType unit in AggPas too - I would then be able to say more accurately if the issue is in the LazFreeType unit or in TBGRAFreeTypeFontRenderer. Give me a day or two and I should be able to answer that.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

CCRDude

  • Hero Member
  • *****
  • Posts: 600
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #2 on: November 25, 2015, 01:43:15 pm »
Since I just found out that for using BGRABitmap on OS X, I need TBGRAFreeTypeFontRenderer to display texts (the other three renderers do fail), that would be great.

AggPas looks great, but is so low level that it seems to have a much steeper learning curve. While I was able to draw a gradient, add text and a custom SVG on a TBGRABitmap without two hours (mostly due to the SVG not being plain SVG but Adobe SVG initially), I wasn't able to get either text nor custom SVG running in the same amount of time. Probably because BGRABitmap has a great tutorial, and AggPas comes with lots of examples, but they're all more complex with having to manually handle parsers, renderers, and an XML parser that doesn't understand the validated XML of my example SVG.

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #3 on: November 25, 2015, 03:12:28 pm »
AggPas looks great, but is so low level that it seems to have a much steeper learning curve.
Indeed, AggPas is more low level, but that too is where all the power of the framework lies. The idea with AGG (and AggPas) is that you can easily implement a class or procedure that renders exactly what you need with your own custom rendering pipeline. AggPas does include the TAgg2D class (and TAgg2d Object for gui framework independence). This gives a much easier interface to using AggPas, and is a great start. It does sacrifice some features, but most developers new to AggPas wouldn't notice.

Please note, my intention was not to convince you to use a different graphics framework. I simply used AggPas to test the WorkSans font, as you asked if there might be a bug in the font itself. From my tests the WorkSans font is just fine.

So the next step is to determine where your issue sits. In BGRABitmap or in the TBGRAFreeTypeFontRenderer class, or in the LazFreeType unit. I'm leaning towards the latter (as I mentioned, it is based on a very old FreeType), but haven't completed LazFreeType support as an optional Font Engine for AggPas yet.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

CCRDude

  • Hero Member
  • *****
  • Posts: 600
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #4 on: November 25, 2015, 03:46:10 pm »
I just tested this myself, since I noticed this is becoming essential when using BGRABmitmap on OS X :)

Basically did this (based on some simple code found on the Internet, this is just for testing of course):
Code: Pascal  [Select][+][-]
  1. procedure TFormEasyLazFreeTypeWorkSanssTest.UpdateBitmap;
  2. var
  3.    bmpTemp: TBitmap;
  4.    lazimg: TLazIntfImage;
  5.    drawer: TIntfFreeTypeDrawer;
  6.    ftFont1: TFreeTypeFont;
  7. begin
  8.    bmpTemp := TBitmap.Create;
  9.    lazimg := TLazIntfImage.Create(0, 0, [riqfRGB]);
  10.    drawer := TIntfFreeTypeDrawer.Create(lazimg);
  11.    try
  12.       ftFont1 := nil;
  13.       ftFont1 := TFreeTypeFont.Create;
  14.       ftFont1.Name := 'WorkSans-Regular.ttf';
  15.       ftFont1.SizeInPoints := 36;
  16.       lazimg.SetSize(Image1.Width, Image1.Height);
  17.       ftFont1.Hinted := True;
  18.       ftFont1.ClearType := True;
  19.       ftFont1.Quality := grqHighQuality;
  20.       ftFont1.SmallLinePadding := False;
  21.       drawer.FillPixels(TColorToFPColor(clWhite));
  22.       drawer.DrawTextRect('Hello World', ftFont1, 0, 0, 350, 90, colBlack, [ftaLeft, ftaBottom]);// <- Here work
  23.       SetBkMode(bmpTemp.Canvas.Handle, TRANSPARENT);
  24.       bmpTemp.LoadFromIntfImage(lazimg);
  25.       Image1.Canvas.Draw(0, 0, bmpTemp);// bmpTemp -> bmp
  26.    finally
  27.       bmpTemp.Free;
  28.       lazimg.Free;
  29.       drawer.Free;
  30.    end;
  31. end;

This uses just EasyLazFreeType, no BGRABitmap, and still shows the same issue.

I know you didn't want to persuade me to use a different framework. I'm thinking of testing AggPas again anyway, since I've got SVGs that seem to be too complex for BGRASVG.

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #5 on: November 25, 2015, 04:28:27 pm »
This uses just EasyLazFreeType, no BGRABitmap, and still shows the same issue.
I guess that answers your question then... LazFreeType is the issue. Good to know.

Just to be sure, I tried your example code and downloaded WorkSans-Regular.ttf (before I used .otf font files). I get the same issue as you showed in your first post. I'm using Lazarus under 64-bit FreeBSD. That example code also has a huge uses list dependency. :-/

Anyway, I then took the .ttf file and used that in my AggPas test project I used earlier. The OTF and TTF versions of WorkSans displayed 100% without errors.

Quote
I know you didn't want to persuade me to use a different framework. I'm thinking of testing AggPas again anyway
If you get stuck with AggPas, don't hesitate to ask. I'll try and help where I can. Also, AggPas is very portable code. I've tested it under Windows, Linux, FreeBSD, OSX, RPi running ARM Linux and OS/2 - this was with the AggPas version included with fpGUI.

By the way, here is the source code that generated the image I attached. I used the TAgg2D class. As you can see, the API is much easier than the low-level AggPas API, but it is good knowing both.  :)

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.DoAggPainting;
  2. begin
  3.   // Paint composedimage white
  4.   FAgg2D.ClearAll(255, 255, 255);
  5.  
  6.   FAgg2D.Font('WorkSans-Regular.ttf', 25, True, False);
  7.   FAgg2D.LineWidth(1.0);
  8.   FAgg2D.NoLine;
  9.   FAgg2D.FillColor(0, 0, 0);
  10.   FAgg2D.Text(20, 70, 'Hello World -> WorkSans-Regular.ttf', false, 0.3, 0);
  11.  
  12.   FAgg2D.Font('/home/graemeg/.fonts/WorkSans-ExtraBold.otf', 50, True, False);
  13.   FAgg2D.LineWidth(0.7);
  14.   FAgg2D.LineColor(0, 0, 0);
  15.   FAgg2D.NoFill;
  16.   FAgg2D.Text(100, 140, 'Hello World', false, 0.3, 0);
  17.  
  18.   FAgg2D.Font('/home/graemeg/.fonts/WorkSans-ExtraBold.otf', 50, True, False);
  19.   FAgg2D.LineColor($B3, 0, 0);
  20.   FAgg2D.LineWidth(2.0);
  21.   FAgg2D.FillColor(0, 0, 0);
  22.   FAgg2D.Text(100, 200, 'Hello World');
  23.  
  24.   FAgg2D.LineWidth(1.0);
  25.   FAgg2D.NoLine;
  26.   FAgg2D.FillColor(0, 0, 0);
  27.   FAgg2D.Text(100, 280, 'Hello World');
  28.  
  29.   FAgg2D.Font('/home/graemeg/.fonts/WorkSans-ExtraLight.otf', 50, True, False);
  30.   FAgg2D.LineWidth(1.0);
  31.   FAgg2D.NoLine;
  32.   FAgg2D.FillColor(0, 0, 0);
  33.   FAgg2D.Text(100, 360, 'Hello World');
  34.  
  35.   FAgg2D.Font('/home/graemeg/.fonts/WorkSans-ExtraLight.otf', 14);
  36.   FAgg2D.NoLine;
  37.   FAgg2D.TextHints(True);
  38.   FAgg2D.Text(100, 420, 'Hello World -> WorkSans-ExtraLight.otf');
  39.  
  40.   FAgg2D.Font('/home/graemeg/.fonts/WorkSans-Regular.otf', 14);
  41.   FAgg2D.NoLine;
  42.   FAgg2D.TextHints(True);
  43.   FAgg2D.Text(100, 440, 'Hello World -> WorkSans-Regular.otf');
  44. end;
  45.  
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

CCRDude

  • Hero Member
  • *****
  • Posts: 600
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #6 on: November 26, 2015, 10:04:03 am »
Thanks for your code example!

I tried this is my very simple LCL test application where I started evaluating AggPas, but here, all texts are drawn using the default font, not using the Work-Sans fonts.
I checked that the paths are correct by debugging into the .Font() calls and making sure the files are found (create_font_ returns true).

Do I need to initialize the fonts in a different location somehow, like I need to do with EasyLazFreeType and the font collection there?

full main form file

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #7 on: November 26, 2015, 11:54:18 am »
I'm assuming your are running under Windows. In that case LCL's AggPas copy normally defaults to the GDI font engine (AggPas supports two font engines) - in which case you don't specify the font file directly. Instead you install the font as per Windows instructions, then simply reference the font name in the vg.Font(...) call.

I do recommend you configure AggPas (via compiler defines) to rather use the FreeType font engine - even under Windows. FreeType has more font features than GDI. This has pros and cons. Pros being that you have more font features and can ship TTF files with your application and don't have to install them into Windows first. The Cons being that you need to ship the freetype.dll with your application (but this is not a big deal, as you will probably ship your custom *.ttf font files anyway).

On a side note:
LCL's AggPas and fpGUI's AggPas has diverged somewhat over the years. I don't think the LCL one is as regularly tested on all platforms like the fpGUI copy. eg: I just tried your latest code attachment under FreeBSD using the LCL's AggPas. The font files loaded without problem, but the whole bitmap is being rendered a bit weird. See screenshot attached. Maybe there is a Bitmap pixel format setting or something required - I don't know LCL too well. The AggPas examples included with Lazarus do render correctly though, but they all use TAggLCLCanvas or something, not a TImage like your code did.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

CCRDude

  • Hero Member
  • *****
  • Posts: 600
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #8 on: November 26, 2015, 12:16:13 pm »
Many thanks for the detailed answer!

So far, I've used this to avoid having to install (and depending on it being installed) my fonts, which works fine (plus Remove call on closing the app):
Code: Pascal  [Select][+][-]
  1. AddFontResourceEx(PChar('myfontname.ttf'), FR_PRIVATE, nil);
Thanks to your hint, when I did this, refering to the font by their display name worked fine in my example!
Which was copied from another example I found on another website, that's why it used TImage.

But I was looking to switch to FreeType anyway because of other of said features (font tracking for example).
As long as the freetype library either comes codesigned, or its license agreement allows to codesign it (this is a requirement by Microsoft), shipping it is fine :)

I've found the defines in agg_mode.inc you seem to refer to and will test this soon.
Will also test fpGUI, with focus on screen reader software.

CCRDude

  • Hero Member
  • *****
  • Posts: 600
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #9 on: November 05, 2018, 04:56:20 pm »
After having worked with the LCL renderer in BGRA over the past years, the situation on Linux and Mac has led me back to needing the FreeType renderer (installing fonts would have complicated things).

A 2.1 trunk Lazarus did not have its FreeType library fixed, so I tried another route this time. I converted the OTF versions of Work Sans into TTF using third party tools. I tried three:

* The Windows version of a tool named Trans Type 4 created TTF files that looked out of the way.
* The online converters at freefontconverter.com and onlinefontconverter.com created good versions.

I'm not associated with any of those three, they were simply the first search results I found.

Each of the good fonts was about 5k larger in size. To fix the issue in question, comparing original to "converted" output in a font structure analysis could lead to the actual problem.

I myself am happy now with my alternate files that work, but wanted to post this solution to the question above in case someone stumbles across the same (I actually found my own post through Google while searching for the problem ;) ).

circular

  • Hero Member
  • *****
  • Posts: 4220
    • Personal webpage
Re: TBGRAFreeTypeFontRenderer garbling certain fonts
« Reply #10 on: May 03, 2020, 06:31:17 pm »
It has been some time, but I have found a way to fix the problem.

It was related to applying SHR on a negative number.

Reported on the bugtracker:
https://bugs.freepascal.org/view.php?id=37012
Conscience is the debugger of the mind

 

TinyPortal © 2005-2018