Wednesday, December 17, 2014

Using Custom Fonts in Android - Delphi

Android

XE7

 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:


13 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