HOWTO: Use true type fonts (and others) to render text on Graphics Window

Anything and everything about programming graphics with Ultibo
pjde
Posts: 252
Joined: Tue Feb 09, 2016 6:21 am
Location: Sydney, Australia

HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby pjde » Mon Jan 02, 2017 1:05 am

Now with C and Freetype2 support, it is possible to write text onto a Graphics window using a standard font like Arial and Times New Roman without the need to create a font pascal unit.

You can also make the font rendering utilise anti-aliasing for a smoother look.

For how it works look at https://www.freetype.org/freetype2/docs/tutorial/step1.html which describes the steps in creating the rendered font images.

With the settings in the example, the glyph images are 8 bit bitmaps which are then alpha blended (using the nominated foreground colour) onto the background.

This is a very basic example, as the possibilities are extensive.

Enjoy

Paul

P.S. You need to copy the relevant font files onto the SD card.
Attachments
FreeTypeDemo.zip
Demo Program
(4.1 KiB) Downloaded 125 times
pjde
Posts: 252
Joined: Tue Feb 09, 2016 6:21 am
Location: Sydney, Australia

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby pjde » Tue Jan 03, 2017 3:47 am

According to the Freetype website, the following font file types can be utilised :-

  • TrueType fonts (TTF) and TrueType collections (TTC)
  • CFF fonts
  • WOFF fonts
  • OpenType fonts (OTF, both TrueType and CFF variants) and OpenType collections (OTC)
  • Type 1 fonts (PFA and PFB)
  • CID-keyed Type 1 fonts
  • SFNT-based bitmap fonts, including color Emoji
  • X11 PCF fonts
  • Windows FNT fonts
  • BDF fonts (including anti-aliased ones)
  • PFR fonts
  • Type 42 fonts (limited support)

Regards

Paul
pik33
Posts: 576
Joined: Fri Sep 30, 2016 6:30 pm
Location: Poland
Contact:

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby pik33 » Tue Jan 03, 2017 7:16 pm

Tested this. It works. Time to some playing with these new possibilities :)
pjde
Posts: 252
Joined: Tue Feb 09, 2016 6:21 am
Location: Sydney, Australia

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby pjde » Sat May 06, 2017 5:39 am

Note to anyone interested.

Rendering text can be sped up by avoiding the need to continuously load the fonts from file.

Instead they can be loaded into memory and accessed from there. To do so, use the "FT_New_Memory_Face" function rather than the "FT_New_Face" one.

Regards

Paul
Gavinmc42
Posts: 1003
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby Gavinmc42 » Fri May 12, 2017 7:30 am

It looks like these fonts use background colour and when it is COLOR_NONE it is transparent?
These are going to be fun to use now that I am figuring out bitmaps too.

Text over Bitmaps,that is going to make some interesting display Pi's.
Hmm wonder if transparency can be used for animation?
Chord
Posts: 18
Joined: Sat Jan 07, 2017 6:02 am

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby Chord » Sat Sep 30, 2017 4:28 pm

Sample has no Unicode compatibility.
I tested a little, and sample needs some modifications to work properly with UTF-8 text strings.

I changed string data type to UnicodeString and manually check every bytes if it's 2-bytes, 3-bytes, or 4-bytes surrogate and re-encoded bytes to character code.
I heard that lazarus's freepascal has built in unicode length function, but couldn't find unbroken length() function for unicode string and uses package of UTF8Length() function. So my approach was all manual and crude(slow).


for example, some code in DrawChar: (Refactored some parameter names for readability. CamelCase is Love :lol: )

Code: Select all

              FirstByte := cardinal(DrawString[i]);
              UTF8Bytes := 1;

              //begin //
              //ConsoleWindowWrite (Console1, 'Character Bytelen list: ');
              if FirstByte >= $80 then //  110xxxxx 10xxxxxx
                begin
                    UTF8Bytes := UTF8Bytes + 1;
                    //ConsoleWindowWrite (Console1, '2 ');
                end;
              if FirstByte >= $E0 then //  1110xxxx 10xxxxxx 10xxxxxx
                begin
                    UTF8Bytes := UTF8Bytes + 1;
                    //ConsoleWindowWrite (Console1, '3 ');
                end;
              if FirstByte >= $F0 then //  11110zzz 11zzxxxx 10xxxxxx 10xxxxxx
                begin
                    UTF8Bytes := UTF8Bytes + 1;
                    //ConsoleWindowWrite (Console1, '4 ');
                end;
              //ConsoleWindowWriteLn (Console1, '');
              //end;

              //begin // UTF-8
              //ConsoleWindowWrite (Console1, 'Character charcode list: ');
              if UTF8Bytes = 1 then
                begin
                  CharCode := cardinal(DrawString[i]); // 1Byte
                                end;
              if UTF8Bytes = 2 then
                begin
                  CharCode := (cardinal(DrawString[i  ]) and $1F)*$40 + // 000xxxxx
                              (cardinal(DrawString[i+1]) and $3F);      // 00xxxxxx
                end;
              if UTF8Bytes = 3 then
                begin
                  CharCode := (cardinal(DrawString[i  ]) and $0F)*$1000 + // 0000xxxx
                              (cardinal(DrawString[i+1]) and $3F)*$40 +   // 00xxxxxx
                              (cardinal(DrawString[i+2]) and $3F);        // 00xxxxxx
                end;
              if UTF8Bytes = 4 then
                begin
                  CharCode := (cardinal(DrawString[i+1]) and $0F)*$1000 + // 0000xxxx
                              (cardinal(DrawString[i+2]) and $3F)*$40 +   // 00xxxxxx
                              (cardinal(DrawString[i+3]) and $3F);        // 00xxxxxx
                end;
              //end;
           
User avatar
Ultibo
Site Admin
Posts: 1476
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby Ultibo » Mon Oct 02, 2017 12:37 am

Chord wrote:Sample has no Unicode compatibility.

It could be very easily adapted to use UnicodeString type because the FT_Get_Char_Index() function supports unicode character codes, so just changing the DrawText() function to pass a UnicodeString instead of a String should work.

Chord wrote:I heard that lazarus's freepascal has built in unicode length function, but couldn't find unbroken length() function for unicode string and uses package of UTF8Length() function. So my approach was all manual and crude(slow).

The UTF8Length() and many other UTF8 functions are part of the LazUTF8 unit which is not included in Ultibo yet, if you look at the source it does similar to what you have done. There are also some helper functions in the System unit such as Utf8CodePointLen, UTF8Encode, UTF8Decode, Utf8ToAnsi and Utf8ToUnicode which might be helpful as well.
Ultibo.org | Make something amazing
https://ultibo.org
Chord
Posts: 18
Joined: Sat Jan 07, 2017 6:02 am

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby Chord » Sun Oct 08, 2017 9:37 am

Ultibo wrote:It could be very easily adapted to use UnicodeString type because the FT_Get_Char_Index() function supports unicode character codes, so just changing the DrawText() function to pass a UnicodeString instead of a String should work.


Of course I tried the approach firstly, but unfortunately UnicodeString didn't pass proper character code for unicode. Despite of several experiments ultibo-bundled freepascal datatype seems not parse literals of source code(UTF-8 formatted) properly, returns just single byte raw data anyhow. Example I made was reinventing wheels, but I couldn't find any working case with multibyte literals.
Last edited by Chord on Sun Oct 08, 2017 10:18 am, edited 1 time in total.
Chord
Posts: 18
Joined: Sat Jan 07, 2017 6:02 am

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby Chord » Sun Oct 08, 2017 10:17 am

Searched lazarus options little more.
UnicodeString in freepascal can only recognize literals properly when compiled with compilerswitch -FcUTF8. Otherwise UTF8String and UnicodeString cannot assign unicode literals properly in most cases.
http://wiki.lazarus.freepascal.org/Unicode_Support_in_Lazarus#Assign_string_literals_to_different_string_types

You should add -FcUTF8 custom option at Lazarus IDE's Project Menu -> Project Options -> Compiler Options -> Custom Options -> Custom options box to make UnicodeString works.
User avatar
Ultibo
Site Admin
Posts: 1476
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: HOWTO: Use true type fonts (and others) to render text on Graphics Window

Postby Ultibo » Mon Oct 09, 2017 12:29 am

Chord wrote:Of course I tried the approach firstly, but unfortunately UnicodeString didn't pass proper character code for unicode. Despite of several experiments ultibo-bundled freepascal datatype seems not parse literals of source code(UTF-8 formatted) properly, returns just single byte raw data anyhow. Example I made was reinventing wheels, but I couldn't find any working case with multibyte literals.

Is it possible to provide a very simple example that shows the problem you were having with this?

It is not quite clear from your description because Unicode and UTF8 are not at all related, Unicode is double byte values (eg UnicodeString, WideChar etc) and UTF8 is really just a normal single byte string (AnsiString, Char etc) with the CodePage value set to CP_UTF8.

We don't actually have correct support yet for the UTF8 codepage but it would be relatively easy to complete if that is the only missing element for what you are doing.
Ultibo.org | Make something amazing
https://ultibo.org

Return to “Graphics”

Who is online

Users browsing this forum: No registered users and 1 guest