Search Unity

Downloading dynamic fonts in parts

Discussion in 'UGUI & TextMesh Pro' started by De-Panther, Mar 10, 2021.

  1. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    I tried to do some searches for this, but I guess that I didn't search for the right keywords.

    We have a WebGL project, and we want to download fonts/glyphs/SDF on runtime.
    I guess we can create TMP Font Asset, set it as Dynamic SDF, and wrap it and a Font file in AssetBundle, then download them.
    It can work well on a small font file.
    But when we need a font with Japanese (CJK) with large character sets, a single Font file is around 8 MB.
    A solution would be to slice the Font file to multiple parts (batches?), creating Dynamic SDF for each part, and wrap each Dynamic SDF and part in a separate AssetBundle.

    Does anyone tried this? Is there a ready made solution? Other recommended solutions?

    Thanks
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Is the issue having to download these large font files or the lack of support for being able to use system fonts on the target platforms?
     
  3. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    Both.
    There's no system font support on WebGL for the non TMP text/font.

    But even if there was, you have some cases of user's device don't have a supported font on his device.
    In that case, a site would add in the css/style a list of fallback fonts.

    If Unity could use the page fonts as System Fonts, that could be great.
    (you can generate font map on the html and create a texture from it)
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Thank you for the additional information.

    I know that most platforms provide for a way to access system downloadable fonts. I'll take a look at this when I have a chance as I agree it might prove useful.

    Having said that, regardless of where the font comes from, it still needs to be delivered to the device. Most of these CJK fonts exceed 8mb with lots of them being more than twice that size. Since FontAssets can be created at runtime from a font file path or font object, could you implement your own mechanism to download / fetch the font file?
     
  5. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    Sites have their methods for downloading fonts in small batches.
    A site that uses CJK font from Google font, would download it in batches of 100~200 kb
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Until the whole font file is downloaded, it won't be useable even when using the web woff or woff2 formats. I'll take a look at adding support for WOFF and WOFF2 formats as these are compressed thus reducing the payload size. These are slower to access as they need to be decompressed first but that should not be an issue.

    Until then, perhaps using an Addressables or AssetBundles to deliver just the font file might be the way to go. Then once the font file is available, create a dynamic font asset from it.

    I'll explore additional options with the soon to be available Dynamic OS Font Assets where font assets will be able to access system font files by family and style names where perhaps I could add support for accessing fonts contained in Application.persistentDataPath.
     
  7. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    I looked more on web solutions for fonts handling.
    It seems that in CSS you can download fonts for "unicode range".

    You can look at that file:
    https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap
    In the case of the Noto Sans JP font, they divided it to 120 parts.
    upload_2021-3-11_21-41-8.png

    The browser downloads the specific small parts only when there's a request to display a character that it's part wasn't loaded yet.

    As we need a solution for a current project, I wonder what would be faster for us to implement.

    One option - as I described in the first post, creating lots of fonts files from a big one, and wrapping them in AssetBundles. Then loading with Dynamic SDF.

    The other option - Generating fonts map texture on the web page, and have a reference for this texture in Unity. Then using this texture in TMP.
    We know how to Generate the texture and reference it in Unity (we do need to see if we can have details about character size, position, kerning, etc...). But I'm not sure if it's possible in runtime to reference a texture in TMP and use it as a TMP Font.

    Thanks
     
  8. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    @Stephan_B do you have any hints or tips regarding those options?
    Thanks
     
    fherbst likes this.