B4J Question How to Get the Real Path of Fonts

xulihang

Well-Known Member
Licensed User
Longtime User
I am using fx.GetAllFontFamilies to get the list of fonts, but I also need to know the real path of the fonts which is required by PDFBox.

I would like to know if there ways to do this.
 

DonManfred

Expert
Licensed User
Longtime User
I also need to know the real path of the fonts
Usually all fonts available are inside C:\Windows\Fonts\

I don´t know how to check for other paths or if there is a way.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
You can do it via PyBridge and a small script, returns a map like this

PDFBox usable font = Arial at : C:\Windows\Fonts\ariali.ttf

It just stores all fx.getAllFontFamilies, uses python to scan windows/fonts/ (read header info) and matches them and prints out which match.

B4X:
    ...
    fontnames.Initialize ' a list
    fontnames = Main.fx.GetAllFontFamilies
    Log(fontnames.Size)
    fontmap.Initialize ' a map
    wait for (getfontmap) complete (x As Boolean)
    For Each item In fontmap.Keys    ' fontmap populated by python
        Log(item & " : " & fontmap.Get(item))
    Next
    For Each fontThingy In fontnames
        If fontmap.GetDefault(fontThingy,"not found") <> "not found" Then
            Log("PDFBox usable font = " & fontThingy & " at :  " & fontmap.Get(fontThingy) )
        End If
    Next
....


private Sub getfontmap()As ResumableSub
    wait for ((Py.RunCode("build_font_map",Array(),File.ReadString(File.DirAssets,"script1.py"))).fetch) complete (res As PyWrapper)
    fontmap = res.Value
    Return True
End Sub

python script

B4X:
from fontTools.ttLib import TTFont
import os
def build_font_map():
    fontmap = {}
    dirs = [r"C:\Windows\Fonts", os.path.expanduser(r"~\AppData\Local\Microsoft\Windows\Fonts")]
    for d in dirs:
        for f in os.listdir(d):
            if f.lower().endswith((".ttf", ".otf", ".ttc")):
                path = os.path.join(d, f)
                try:
                    font = TTFont(path)
                    name = font["name"].getName(1, 3, 1)  # family name
                    if name:
                        fontmap[str(name)] = path
                except:
                    pass
    return fontmap
 
Last edited:
Upvote 0

xulihang

Well-Known Member
Licensed User
Longtime User
I came up with the following code:

B4X:
Public Sub GetFontPathMap As Map
    Dim allFontFamilies As List = fx.GetAllFontFamilies
    Dim fontPathMap As Map
    fontPathMap.Initialize
    Dim fontDirs As List
    fontDirs.Initialize
    Dim os As String = "window"
    If os = "window" Then
        fontDirs.Add("C:\Windows\Fonts")
    else if os = "mac" Then
        fontDirs.Add("/System/Library/Fonts")
        fontDirs.Add("/Library/Fonts/")
    Else
        fontDirs.Add("/usr/share/fonts/")
    End If
    
    For Each fontDir As String In fontDirs
        AddFontsToMap(fontPathMap,fontDir,allFontFamilies)
    Next
    Return fontPathMap
End Sub

Private Sub AddFontsToMap(fontPathMap As Map,dirPath As String,allFontFamilies As List)
    For Each filename As String In File.ListFiles(dirPath)
        If File.IsDirectory(dirPath,filename) Then
            AddFontsToMap(fontPathMap, File.Combine(dirPath,filename), allFontFamilies)
        Else If filename.EndsWith(".ttf") Or filename.EndsWith(".ttc") Then
            Dim font As Font = fx.LoadFont(dirPath,filename,16)
            If allFontFamilies.IndexOf(font.FamilyName) <> -1 Then
                fontPathMap.Put(font.FamilyName,File.Combine(dirPath,filename))
            End If
        End If
    Next
End Sub
 
Last edited:
Upvote 0

teddybear

Well-Known Member
Licensed User
I came up with the following code:

B4X:
Public Sub GetFontPathMap As Map
    Dim allFontFamilies As List = fx.GetAllFontFamilies
    Dim fontPathMap As Map
    fontPathMap.Initialize
    Dim fontDirs As List
    fontDirs.Initialize
    Dim os As String = "window"
    If os = "window" Then
        fontDirs.Add("C:\Windows\Fonts")
    else if os = "mac" Then
        fontDirs.Add("/System/Library/Fonts")
        fontDirs.Add("/Library/Fonts/")
    Else
        fontDirs.Add("/usr/share/fonts/")
    End If
   
    For Each fontDir As String In fontDirs
        AddFontsToMap(fontPathMap,fontDir,allFontFamilies)
    Next
    Return fontPathMap
End Sub

Private Sub AddFontsToMap(fontPathMap As Map,dirPath As String,allFontFamilies As List)
    For Each filename As String In File.ListFiles(dirPath)
        If File.IsDirectory(dirPath,filename) Then
            AddFontsToMap(fontPathMap, File.Combine(dirPath,filename), allFontFamilies)
        Else If filename.EndsWith(".ttf") Or filename.EndsWith(".ttc") Then
            Dim font As Font = fx.LoadFont(dirPath,filename,16)
            If allFontFamilies.IndexOf(font.FamilyName) <> -1 Then
                fontPathMap.Put(font.FamilyName,File.Combine(dirPath,filename))
            End If
        End If
    Next
End Sub
This code can‘t obtain all font files, such as those with suffixes like otf, fon,fnt etc, and those fonts installed in other folders
and if windir is not windows, you will get nothing
As Daestrum mentioned, you have also omitted font files installed under the current user.
 
Upvote 0
Top