Wednesday, December 17, 2014

Using Custom Fonts in Android - Delphi

Android

For XE7  to 10.2.1 Tokyo

 You should be able to use any True Type Font in an android app.

Example using the font Script MT Bold. This font is in the Windows Font Folder. The font file name is SCRIPTBL.TTF.

1. copy SCRIPTBL.TTF to the project folder.
2. In Deployment window, add SCRIPTBL.TTF file. Set Remote Path to .\assets\internal\
Set Remote Name to .SCRIPTBL.ttf (make the ttf extension lower case so we can hard code it into the program)



3. Load FMX.FontGlyphs.Android.pas into the editor. ( the file is in C:\Program Files (x86)\Embarcadero\Studio\15.0\source\fmx)
If it is read only, right click in editor and turn off Read-Only.
Save the file to the project folder. Don't change the file name. Then you can edit it in the Delphi editor.
  A. Add System.IOUtils to the uses clause.
  B. Go to procedure TAndroidFontGlyphManager.LoadResource;
  • Add a var FontFile: string;
  • There is a line in the procedure that says:Typeface := TJTypeface.JavaClass.create(FamilyName, TypefaceFlag);
  • Replace that line with:
 FontFile := TPath.GetDocumentsPath + PathDelim + CurrentSettings.Family + '.ttf';
 if FileExists(FontFile) then
   Typeface := TJTypeface.JavaClass.createFromFile(StringToJString(FontFile))
   else
     Typeface := TJTypeface.JavaClass.Create(FamilyName, TypefaceFlag); 
This will make it look for a font file by that name first.

4. For each component you want to use this font on, set the TextSettings Font Family property to SCRIPTBL
This is the name of the font file without the file extension. Don't put "SCRIPTBL.ttf" and don't put "Script MT Bold".
You will have to type or paste it in to the property box.

Note: filenames in Android are case sensitive, so you have to get them all the same.

This is a form with label, textbox, memo, checkbox, radio button:
Note: an easier idea for the filename is:
If the font family name is not the same as the file name of the font, you can just make a copy of the font file and rename it to the Font FamilyName and use that. Then the font will show up at both design time and runtime.
 

23 comments:

  1. Can you attach an example of this project?
    It did not work with me. I have reviewed all the steps and nothing :(
    I'm using Delphi XE8.

    ReplyDelete
    Replies
    1. I checked it for XE8 and it works the same. The FMX.FontGlyphs.Android.pas file is identical in XE6,XE7 and XE8.

      First, I suggest when in debug mode, you can put a breakpoint in FMX.FontGlyphs.Android.pas where it has
      "if FileExists(FontFile) then" and see if it finds the file.

      If not, check out why not. Is the filename exactly the same? Did the file ever get deployed on there at all?

      Delete
  2. Doug mate, I used your ideas to put the Tahoma font from windows across to a Samsung S5. I had to rename the font from tahoma to Tahoma, as every button etc had the capital. It worked beautifully.
    Then I tried as well to get the bold version, tahomabd, renamed to Tahomabd, with that as the family name. This did not work - it just went back to the android font.
    Any ideas please?

    ReplyDelete
    Replies
    1. I tried it with tahomabd.ttf and it seemed to work fine. You sure you have the ".ttf" in the right case? I notice on Windows XP font folder it has the filename with upper case ".TTF".

      In debug mode, you can put a breakpoint in FMX.FontGlyphs.Android.pas where it has
      "if FileExists(FontFile) then" and see if it finds the file.

      Delete
    2. Thank you, Doug. Yes, the files were found. I think the problem is that the bold of Tahoma (and Arial, which I tried too) are so like the native Android font that I could not tell them apart. I used a serif font (Lucida Bright, Lbrite.ttf and Lbrited.ttf) and this worked fine, with no risk of mixing it up with the native sans-serif font!

      Delete
  3. Do you have a project of this exemple? In my xe8 not work.

    ReplyDelete
  4. Ivan, I have done a bit of playing, and slightly expanded on Doug's brilliant work. See if this is any help:

    Notes on putting a .ttf font in: (Use Tahoma as an example, as that is the one we used first)

    copy \windows\fonts\tahoma.ttf delphiprogrammedirectory\Tahoma.ttf (as the font we get in the Object Inspector has the capital)
    In the deployment window (Project / Deployment, then use the tiny little button on the top left of this window to Add), add Tahoma.ttf. Set the remote path to .\assets\internal\, and set the remote name to Tahoma.ttf

    (Others I used were Arial.ttf, Arialbd.ttf [renamed to get the initial capital only], and
    for a serif font, Lucida Bright, which comes as LBRITE.TTF and LBRITED.TTF, which were renamed Lbrite.ttf and Lbrited.ttf)

    Get a copy of FMX.FontGlyphs.Android.pas (from c:\program files (x86)\Embarcadero\Studio\15.0\source\fmx)
    and edit it as follows:
    Add System.IOUtils to the uses clause
    Go to procedure tAndroidFontGlyphManager.LoadResource
    Add var FontFile : string
    There is a line in the procedure that says
    Typeface := TJTypeface.JavaClass.Create(FamilyName, TypefaceFlag).
    Replace that line with
    FontFile := tPath.GetDocumentsPath + PathDelim + CurrentSettings.Family + '.ttf';
    if FileExists(FontFile) then
    Typeface := TJTypeface.JavaClass.CreateFromFile(StringToJString(FontFile))
    else
    Typeface := TJTypeface.JavaClass.Create(FamilyName, TypefaceFlag);

    (Note that the last line is the same as the line that was there in the first place,
    so if you don't like typing, just add the 4 lines above it and the extra to
    space it out!)

    In the main programme, add FMX.FontGlyphs.Android to the uses clause (you can also use Project / Add to Project and add this file - then you can debug with it if you wish)

    The single files won't give you bold type. You will need the additional fonts
    (eg Tahomabd.ttf) for that. Unfortunately (certainly at 24 point) the native Android font, Arial Bold and Tahoma Bold all look the same, which is why I tried the sans serif font as I did not think it was working.
    Lucida Bright does not come with Windows - you could try Times New Roman = times.ttf, timesbd et cetera, and they should work.
    Good luck! If you can't get it to work with this, I will construct a test programme for the purpose and send it to you, if you like.

    ReplyDelete
    Replies
    1. Sorry, Ivan: I forgot to specify that the modified FMX.FontGlyphs.Android.pas has to be in the same directory as your Delphi programme. (You probably worked that out!)

      Delete
  5. Do you have a solution in Mac OS X? I can'y find a solution.

    ReplyDelete
    Replies
    1. In OSX you just copy your font file to:
      '/Users/'+user_name+'/Library/Fonts/' and you can use it.

      Delete
  6. Thank You It Works! But I have a problem. I use hungarian .ttf with Á,Í,É,etc... characters and it shows A,I,E in the app. The lower case characters (á,í,é) works fine. Is there a solution to fix it?

    ReplyDelete
    Replies
    1. I don't know. Do you know that those characters are in the font at the correct unicode position? Check the font in the Windows Character Map app and see if they are in the same numbered position as ttf that works in Windows. How are you inputting the characters, from the Android keyboard?

      Delete
  7. Works great on XE8. Also tried Roboto-Thin font
    Thanks a lot man

    ReplyDelete
  8. I tested on the XE10 Seatle , Congratulations, excellent !!!!!

    ReplyDelete
  9. Dafont.com is a site where you can download a ton of free fonts. You can search for a specific typeface, or search by the type of lettering you want, whether it’s serif or sans serif, hand lettered or grunge style. You can also put in your own phrase to see how it looks in a particular font. A lot of these fonts are very decorative and many are handdrawn, so it’s not always the best place to search for body text fonts. Each selection also tells you whether your download is free for personal or commercial use. The download is easy – you get a zip file with the font file inside. Unzip, install, and you’re ready to go.

    ReplyDelete
  10. Dafont.com is a site where you can download a ton of free fonts. You can search for a specific typeface, or search by the type of lettering you want, whether it’s serif or sans serif, hand lettered or grunge style. You can also put in your own phrase to see how it looks in a particular font. A lot of these fonts are very decorative and many are handdrawn, so it’s not always the best place to search for body text fonts. Each selection also tells you whether your download is free for personal or commercial use. The download is easy – you get a zip file with the font file inside. Unzip, install, and you’re ready to go.

    ReplyDelete
  11. Hi there! The smaller font under each word tells the actual name of the font. The "sparkling" one is called Sweet Pea font and the link is: http://www.dafont.com/sweet-pea.font
    The clickable links to all of them are right under the image!
    Thanks!

    ReplyDelete
  12. Thanks, it works for me on Delphi Tokio

    ReplyDelete
  13. This works fine on 10.3 for most TTF fonts, EXCEPT for fonts with musical symbols! I try with different font files: Anastasia (GVOX or Altsys Phontographer, Maestro, MusicalSymbols). All of them are working in Windows, but not on Android. Deployment is successfull, the font file is on mobile device where it should be, something is read from the metrics, but the symbols are not displayed, the normal alphabet is rendered instead. Any idea what I'm doing wrong?

    ReplyDelete
    Replies
    1. Apparently its because those fonts are not Unicode fonts. I downloaded three free musical fonts and one of them worked but two were like you said - only showing the Letters. Looked at them in the Windows Character Map app and noticed the ones that didn't work were not Unicode fonts. I change them to Unicode fonts in FontCreator software and now they work.

      Probably the same issue for all other fonts that don't seem to work.
      Here are the music fonts that work:
      https://i-logic.com/ftp/MusicalFonts.zip

      Delete
    2. Douglas, it works!! Thank you very much! Honestly, I wasn’t hoping for such a quick answer. Thanks again!

      Delete
    3. Dear Douglas, Excuse me. I had foreseen that deploy had a separate release configuration, so the fonts weren't even listed. Everything is working for me now. Many thanks again.

      Delete
  14. Hm, now I have new question: when I'm debuging on connected mobile device, everything works fine. But, how the additional font files should be deployed to customers device? The font is not contained in .apk file, or?

    ReplyDelete