From 99c1e7017de51fda8c1418d649a38bc6318c5587 Mon Sep 17 00:00:00 2001 From: JCash Date: Mon, 30 Jun 2025 16:25:43 +0200 Subject: [PATCH 1/2] Added updated font generation documentation --- docs/en/manuals/font.md | 83 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/docs/en/manuals/font.md b/docs/en/manuals/font.md index bf4dc9cf..b6d1a422 100644 --- a/docs/en/manuals/font.md +++ b/docs/en/manuals/font.md @@ -16,11 +16,6 @@ Fonts added to your project are automatically converted into a texture format th - Bitmap - Distance field -::: sidenote -It is possible to [generate font glyphs at runtime](/extension-fontgen) from a bundled TrueType font instead of generating and including a font texture in the application bundle. This approach can greatly reduce the download size and runtime memory consumption of a Defold game. -::: - - ## Creating a font To create a font for use in Defold, create a new Font file by selecting File ▸ New... from the menu, then select Font. You can also right click a location in the *Assets* browser and select New... ▸ Font. @@ -97,7 +92,7 @@ space ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E *Cache Width/Height* : Constrains the size of the glyph cache bitmap. When the engine renders text, it looks up the glyph from the cache bitmap. If it does not exist there, it will be added to the cache before rendering. If the cache bitmap is too small to contain all the glyphs the engine is asked to render, an error is signalled (`ERROR:RENDER: Out of available cache cells! Consider increasing cache_width or cache_height for the font.`). - If set to 0 the cache size is set automatically. + If set to 0 the cache size is set automatically, and will grow to 2048x4096 max. ## Distance field fonts @@ -167,3 +162,79 @@ For example - to generate a gradient in a shader fragment, simply write: `float horizontal_gradient = fract(var_texcoord0.y / texture_size_recip.w);` For more information about shader uniforms, see the [Shader manual](/manuals/shader). + +## Runtime generation + +It is possible to use runtime generation for SDF type fonts, when using TrueType (.ttf) fonts. +This approach can greatly reduce the download size and runtime memory consumption of a Defold game. +The small downside is a very small delay for each glyph generated at runtime. + +Enable the feature by setting `font.runtime_generation` in game.project. + +::: sidenote +This feature is currently experimental, but with the intention to be used as the default workflow in the future. +::: + +::: important +This setting affects all .ttf fonts in the project. +::: + +### Prewarming glyph cache + +In order to make the runtime fonts easier to use, they support prewarming of the glyph cache. +This means the font will generate the glyphs listed in *Characters* in the font. + +::: sidenote +If `All Chars` is selected, there will be no prewarming as it defeats the purpose of not having to generate load all glyphs at the same time. +::: + +### Font Scripting + +For runtime fonts, it's possible to add or removed sub fonts. +This is useful when a large font has been split up into multiple for different character sets (e.g. CJK) + +::: important +Adding a subfont doesn't automatically load or render all the glyphs. +::: + +```lua +-- Add the range A-Z to the .fontc +local font_hash = hash("/assets/fonts/roboto.fontc") +local ttf_hash = hash("/assets/fonts/Roboto/Roboto-Bold.ttf") +local codepoint_min = 0x00000041 -- A +local codepoint_max = 0x0000005A -- Z +font.add_source(font_hash, ttf_hash, codepoint_min, codepoint_max) +``` + +```lua +-- Remove the associated ttf resource +local font_hash = hash("/assets/fonts/roboto.fontc") +local ttf_hash = hash("/assets/fonts/Roboto/Roboto-Bold.ttf") +font.remove_source(font_hash, ttf_hash) +``` + +To load the glyphs to the font, you will need to call the `font.add_glyphs()`. +It is an asynchronous operation, and once it's done, it's safe to progress to show any message containing the glyphs. + +```lua +local function add_glyph_callback(self, id, result, errmsg) + if not result then + print("Request " .. id .." finished with error:", errmsg) + else + msg.post(some_url, "show_dialog") + end +end + +-- Load glyphs into the font +local font_hash = hash("/assets/fonts/roboto.fontc") +local glyphs = "Some text to be shown!" -- for optimal performance, make this a list of unique glyphs +local request_id = font.add_glyphs(font_hash, ttf_hash, add_glyph_callback) +``` + +And, once the characters aren't needed anymore, you can discard that memory: +```lua +-- Remove the associated ttf resource +local font_hash = hash("/assets/fonts/roboto.fontc") +font.remove_glyphs(font_hash, "All the characters in the set") +``` + From 7ca03702016491500b5e40d18662ea35bb73c424 Mon Sep 17 00:00:00 2001 From: JCash Date: Tue, 1 Jul 2025 09:35:53 +0200 Subject: [PATCH 2/2] review fixes --- docs/en/manuals/font.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/manuals/font.md b/docs/en/manuals/font.md index b6d1a422..d163f053 100644 --- a/docs/en/manuals/font.md +++ b/docs/en/manuals/font.md @@ -185,13 +185,13 @@ In order to make the runtime fonts easier to use, they support prewarming of the This means the font will generate the glyphs listed in *Characters* in the font. ::: sidenote -If `All Chars` is selected, there will be no prewarming as it defeats the purpose of not having to generate load all glyphs at the same time. +If `All Chars` is selected, there will be no prewarming as it defeats the purpose of not having to generate all glyphs at the same time. ::: ### Font Scripting For runtime fonts, it's possible to add or removed sub fonts. -This is useful when a large font has been split up into multiple for different character sets (e.g. CJK) +This is useful when a large font has been split up into multiple files for different character sets (e.g. CJK) ::: important Adding a subfont doesn't automatically load or render all the glyphs.