I’m working on a mobile app with multi-language support, including Japanese. I do not want to include the Japanese font in the app, but I also want to use TextMesh Pro.
The font should be loaded from the device and assigned as a fallback TMP_FontAsset to my standard TMP_FontAsset.
I know unitys ui text-component is using this kind of system to make all characters of all languages available.
I´m using Unity 2018.3.11f1 and TextMesh Pro 1.4.0 with Dynamic SDF.
This is my code, but it is not working as expected. Does anyone know what I’m making wrong or is it not possible how I try?
public TMP_FontAsset defaultFontAsset;
public TextMeshProUGUI testLabel;
private void AssignFallbackFont(){
string[] fonts = Font.GetOSInstalledFontNames();
for(int i = 0; i < fonts.Length; i++){
/*
I know my android device has this font
and it should have all japanese characters
*/
if( fonts[i] == "Noto Sans CJK JP" ){
Font font = Font.CreateDynamicFontFromOSFont(fonts[i], 12);
// some japanese characters to test
font.RequestCharactersInTexture("テスト");
TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(font, 44, 5, GlyphRenderMode.SDFAA, 512, 512, AtlasPopulationMode.Dynamic);
// this is not working it returns false
bool success = fontAsset.TryAddCharacters("テスト");
print(success);
defaultFontAsset.fallbackFontAssetTable.Add(fontAsset);
// I just see squares
testLabel.text = "テスト";
}
}
}
This is not working because the font created by using CreateDynamicFontFromOSFont does not have a reference to the font file / font data unlike font files imported in the project with the Include Font Data property set to true.
The FontEngine used by TMP, can create font assets from the file path of any given font. So if you have the path of this OS font files, then adding a new overload for the CreateFontAsset that would take this path could be added in TMP.
Alternatively, I would need to make changes to Unity to either force the fontData to be referenced by Fonts created using CreateDynamicFontFromOSFont or modify the Font class to expose a reference to the file path for the font. Both of these options, are problematic only because they would require back porting the changes.
I understand. I think it would be nice if TMP could create a FontAsset from a given font file path.
However, I have to find a way to get the OS font file paths. It´s a bit unfortunate that Unity has a function “GetOSInstalledFontNames”, but you only get the font names and not the absolute file path.
It think TMP Pro is almost perfect with the new Dynamic SDF support. If sometime there would be a more or less simple solution to automatically get the OS fonts as fallback like unitys Text-Component does, so we wouldn’t get any problems with different languages, I would be very grateful.
Absolutely agree! Mobile devices have at least one almost complete or very comprehensive Unicode font on board that would allow you to dynamically create whatever you haven’t pre-rendered as font asset. Plus you’d instantly get a full set of Emojiis, not just a very limited subset.
I am adding a new function called GetPathsToOSFonts() which will retrieve the paths to fonts installed on local devices.
I am also modifying the Font constructor to allow users to pass a path to a local on device font retrieved with the previous new function. This newly created font will include the Font Data needed for TMP to create TMP_FontAssets at runtime from these fonts.
This new functionality will be included in a future release of Unity 2018.4 and 2019.x. This will also require an updated version of the TMP package.
Thank you, it is working on Android. The android phones I tested all have “/system/fonts/NotoSansCJK-Regular.ttc”, which I can use to create the TMP_FontAsset for japanese characters. I also search for some fallback font names if “NotoSansCJK-Regular” not exists.
Unfortunately it is not working on iOS; GetPathsToOSFonts doesn’t return any font paths. Probably you can’t access iOS fonts? Although unitys Text component is able to load japanese fonts and GetOSInstalledFontNames() also returns valid japanese font names.
Prior to the inclusion of this feature, I did test GetPathsToOSFonts() on iOS so that should be working. I’ll try taking another look over the next few days.
No updates. Trying to get the next preview released. Should be able to provide an update early next week,
In the meantime and although the GetPathsToOSFonts() doesn’t return anything, assuming you know the path of an OS font on the device, we should be able to create a font asset. I haven’t tested it but I believe it should work.
Any update on this? It seems Apple restricts anyone from accessing iOS system fonts :(. I wonder if there’s a workaround to using iOS system fonts as fallback fonts.
@Stephan_B
Any update? I’m building a text editor so can TMPro be used to load system fonts with a dynamic atlas?
For example, user will type a “word” like “Stephan”
the we show a list of all system fonts via Font.GetOSInstalledFontNames();
then user select a font and we create TMpro based dynamic Font atlas and apply to that word? It this part doable with your recent updates?
Is there any update on this? We would really like to use this functionality as well and are also released on iOS or is there some sort of fallback to use it on iOS?
But then I noticed it was for the “old” legacy Textmesh, not TextMesh Pro. Wouldn’t it be great if TextMesh Pro also would just have a built-in fallback to a list of font names (maybe with a list or range of glyph codes each should cover) to then automagically do fallback rendering based on available system fonts?