Skip to content

Commit e5db663

Browse files
Site changes [skip-ci]
1 parent 160db1d commit e5db663

File tree

5 files changed

+167
-87
lines changed

5 files changed

+167
-87
lines changed

_data/learnindex.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,6 @@
432432
"name": "Font",
433433
"path": "/manuals/font"
434434
},
435-
{
436-
"languages": [],
437-
"name": "Runtime TTF Font",
438-
"path": "/extension-fontgen"
439-
},
440435
{
441436
"languages": [
442437
"en",

llms-full.txt

Lines changed: 80 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ If you find any issues, please report them [as a GitHub issue](https://github.co
5252
- [Atlas](#manuals:atlas)
5353
- [Buffer](#manuals:buffer)
5454
- [Font](#manuals:font)
55-
- [Runtime TTF Font](https://defold.com/extension-fontgen)
5655
- [Resource management](#manuals:resource)
5756
- [Tile source](#manuals:tilesource)
5857
- [Texture filtering](#manuals:texture-filtering)
@@ -5121,6 +5120,27 @@ Fonts added to your project are automatically converted into a texture format th
51215120
- Bitmap
51225121
- Distance field
51235122

5123+
## Offline or Runtime fonts
5124+
5125+
By default, the conversion to rasterized glyph images happens at build time (offline). This has the drawback that each font needs to rasterize all possible glyphs in the build stage, producing potentially very large textures that consume memory and also increase the bundle size.
5126+
5127+
By using "runtime fonts", the .ttf fonts will be bundled as-is, and the rasterization will happen on-demand at runtime. This minimizes both runtime memory usage and the bundle size.
5128+
5129+
## Text layout support (e.g. Right-to-left)
5130+
5131+
The runtime fonts also have the benefit of supporting full text layout, e.g. right-to-left.
5132+
We currently use the libraries [HarfBuzz](https://github.com/harfbuzz/harfbuzz), [SheenBidi](https://github.com/Tehreer/SheenBidi), [libunibreak](https://github.com/adah1972/libunibreak) and [SkriBidi](https://github.com/memononen/Skribidi).
5133+
5134+
See [Enabling Runtime Fonts](#manuals:font#enabling-runtime-fonts)
5135+
5136+
## Font collection
5137+
5138+
The `.fontc` file format is also known as a font collection. In offline mode, only one font is associated with it.
5139+
When using runtime fonts, you can associate more than one font file (.ttf) with the font collection.
5140+
5141+
This allows for using the a font collection when rendering multiple texts in different languages, while also keeping the memory footprint low.
5142+
E.g. loading a collection with the Japanese font, then associate that font with the current main font, followed by unloading the Japanese font collection.
5143+
51245144
## Creating a font
51255145

51265146
To create a font for use in Defold, create a new Font file by selecting <kbd>File ▸ New...</kbd> from the menu, then select <kbd>Font</kbd>. You can also <kbd>right click</kbd> a location in the *Assets* browser and select <kbd>New... ▸ Font</kbd>.
@@ -5186,6 +5206,8 @@ Shadow support is enabled by the built-in font material shaders and handles both
51865206
*Characters*
51875207
: Which characters to include in the font. By default this field include the ASCII printable characters (character codes 32-126). You can add or remove characters from this field to include more or less characters in the font..
51885208

5209+
For runtime fonts, this text acts as a cache prewarming with the correct glyphs. This happens during load time. See `font.prewarm_text()`.
5210+
51895211
<div class='sidenote' markdown='1'>
51905212
The ASCII printable characters are:
51915213
space ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ \` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
@@ -5268,23 +5290,29 @@ For example - to generate a gradient in a shader fragment, simply write:
52685290

52695291
For more information about shader uniforms, see the [Shader manual](#manuals:shader).
52705292

5271-
## Runtime generation
5293+
## Enabling Runtime Fonts
52725294

52735295
It is possible to use runtime generation for SDF type fonts, when using TrueType (.ttf) fonts.
52745296
This approach can greatly reduce the download size and runtime memory consumption of a Defold game.
5275-
The small downside is a very small delay for each glyph generated at runtime.
5297+
The small downside is the asynchronous nature of generating each glyph.
52765298

5277-
Enable the feature by setting `font.runtime_generation` in game.project.
5299+
* Enable the feature by setting `font.runtime_generation` in game.project.
5300+
5301+
* Add an [App Manifest](#manuals:app-manifest) and enable the `Use full text layout system` option.
5302+
This builds a custom engine that has this feature enabled.
52785303

52795304
<div class='sidenote' markdown='1'>
52805305
This feature is currently experimental, but with the intention to be used as the default workflow in the future.
52815306
</div>
52825307

52835308
<div class='important' markdown='1'>
5284-
This setting affects all .ttf fonts in the project.
5309+
The `font.runtime_generation` setting affects all .ttf fonts in the project.
52855310
</div>
52865311

5287-
### Prewarming glyph cache
5312+
5313+
### Font Scripting
5314+
5315+
#### Prewarming glyph cache
52885316

52895317
In order to make the runtime fonts easier to use, they support prewarming of the glyph cache.
52905318
This means the font will generate the glyphs listed in *Characters* in the font.
@@ -5293,54 +5321,54 @@ This means the font will generate the glyphs listed in *Characters* in the font.
52935321
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.
52945322
</div>
52955323

5296-
### Font Scripting
5324+
If the `Characters` field of the `.fontc` file is set, this is used as a text, to figure out which glyphs needs to be updated in the glyph cache.
52975325

5298-
For runtime fonts, it's possible to add or removed sub fonts.
5326+
It is also possible to manually update the glyph cache by calling `font.prewarm_text(font_collection, text, callback)`. It provides a callback to let you know when all the missing glyphs have been added to the glyph cache, and it's safe to present the text on screen.
5327+
5328+
### Adding/removing fonts to a font collection
5329+
5330+
For runtime fonts, it's possible to add or remove fonts (.ttf) to a font collection.
52995331
This is useful when a large font has been split up into multiple files for different character sets (e.g. CJK)
53005332

53015333
<div class='important' markdown='1'>
5302-
Adding a subfont doesn't automatically load or render all the glyphs.
5334+
Adding a font to a font collection doesn't automatically load or render all the glyphs.
53035335
</div>
53045336

53055337
```lua
5306-
-- Add the range A-Z to the .fontc
5307-
local font_hash = hash("/assets/fonts/roboto.fontc")
5308-
local ttf_hash = hash("/assets/fonts/Roboto/Roboto-Bold.ttf")
5309-
local codepoint_min = 0x00000041 -- A
5310-
local codepoint_max = 0x0000005A -- Z
5311-
font.add_source(font_hash, ttf_hash, codepoint_min, codepoint_max)
5338+
-- get the main font
5339+
local font_collection = go.get("#label", "font")
5340+
font.add_font(font_collection, self.language_ttf_hash)
5341+
5342+
-- get the selected language font
5343+
local font_collection_language = go.get("localization_japanese#label", "font")
5344+
local font_info = font.get_info(font_collection_language)
5345+
self.language_ttf_hash = font_info.fonts[1].path_hash -- get the first font (the one specified in the editor)
5346+
font.add_font(self.font_collection, self.language_ttf_hash) -- increases the reference count to the font
53125347
```
53135348

53145349
```lua
5315-
-- Remove the associated ttf resource
5316-
local font_hash = hash("/assets/fonts/roboto.fontc")
5317-
local ttf_hash = hash("/assets/fonts/Roboto/Roboto-Bold.ttf")
5318-
font.remove_source(font_hash, ttf_hash)
5350+
-- remove the font reference
5351+
font.add_font(self.font_collection, self.language_ttf_hash)
53195352
```
53205353

5321-
To load the glyphs to the font, you will need to call the `font.add_glyphs()`.
5322-
It is an asynchronous operation, and once it's done, it's safe to progress to show any message containing the glyphs.
5354+
### Prewarming glyphs
53235355

5324-
```lua
5325-
local function add_glyph_callback(self, id, result, errmsg)
5326-
if not result then
5327-
print("Request " .. id .." finished with error:", errmsg)
5328-
else
5329-
msg.post(some_url, "show_dialog")
5330-
end
5331-
end
5356+
To properly show a text with a runtime font, the glyphs need to be resolved. The `font.prewarm_text()` does this for you.
5357+
It is an asynchronous operation, and once it's done and you get the callback, it's safe to progress to show any message containing the glyphs.
53325358

5333-
-- Load glyphs into the font
5334-
local font_hash = hash("/assets/fonts/roboto.fontc")
5335-
local glyphs = "Some text to be shown!" -- for optimal performance, make this a list of unique glyphs
5336-
local request_id = font.add_glyphs(font_hash, ttf_hash, add_glyph_callback)
5337-
```
5359+
<div class='important' markdown='1'>
5360+
If the glyph cache gets full, the oldest glyph in the cache will be evicted.
5361+
</div>
53385362

5339-
And, once the characters aren't needed anymore, you can discard that memory:
53405363
```lua
5341-
-- Remove the associated ttf resource
5342-
local font_hash = hash("/assets/fonts/roboto.fontc")
5343-
font.remove_glyphs(font_hash, "All the characters in the set")
5364+
font.prewarm_text(self.font_collection, info.text, function (self, request_id, result, err)
5365+
if result then
5366+
print("PREWARMING OK!")
5367+
label.set_text(self.label, info.text)
5368+
else
5369+
print("Error prewarming text:", err)
5370+
end
5371+
end)
53445372
```
53455373

53465374
<!-- /manuals/resource -->
@@ -7668,7 +7696,12 @@ Apart from the properties *Id*, *Position* and *Rotation* the following componen
76687696
: This property should refer to the glTF *.gltf* or Collada *.dae* file that contains the mesh to use. If the file contains multiple meshes, only the first one is read.
76697697

76707698
*Material*
7671-
: Set this property to a material you have created that is suitable for a textured 3D object. There is a built-in *model.material* file that you can use as a starting point.
7699+
: Set this property to a material you have created that is suitable for a textured 3D object. There are a number of built-in materials that you can use as a starting point:
7700+
7701+
* Use *model.material* for static non-instanced models
7702+
* Use *model_instances.material* for static instanced models
7703+
* Use *model_skinned.material* for skinned (animated) non-instanced models
7704+
* Use *model_skinned_instances.material* for skinned (animated) instanced models
76727705

76737706
*Texture*
76747707
: This property should point to the texture image file that you want applied to the object.
@@ -7734,7 +7767,14 @@ A model also has a number of different properties that can be manipulated using
77347767

77357768
3D software commonly allows you to set properties on your object vertices, like coloring and texturing. This information goes into the glTF *.gltf* or Collada *.dae* file that you export from your 3D software. Depending on the requirements of your game you will have to select and/or create appropriate and _performant_ materials for your objects. A material combines _shader programs_ with a set of parameters for rendering of the object.
77367769

7737-
There is a simple 3D model material available in the built-in materials folder. If you need to create custom materials for your models, see the [Material documentation](#manuals:material) for information. The [Shader manual](#manuals:shader) contains information on how shader programs work.
7770+
There are a number of built-in materials that you can use as a starting point:
7771+
7772+
* Use *model.material* for static non-instanced models
7773+
* Use *model_instances.material* for static instanced models
7774+
* Use *model_skinned.material* for skinned (animated) non-instanced models
7775+
* Use *model_skinned_instances.material* for skinned (animated) instanced models
7776+
7777+
If you need to create custom materials for your models, see the [Material documentation](#manuals:material) for information. The [Shader manual](#manuals:shader) contains information on how shader programs work.
77387778

77397779

77407780
### Material constants

manuals/font.md

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ layout: manual
66
title: Fonts in Defold manual
77
toc:
88
- Font files
9+
- Offline or Runtime fonts
10+
- Text layout support (e.g. Right-to-left)
11+
- Font collection
912
- Creating a font
1013
- Properties
1114
- Distance field fonts
1215
- Bitmap BMFonts
1316
- Artifacts and best practices
1417
- Font Cache
15-
- Runtime generation
16-
- Prewarming glyph cache
18+
- Enabling Runtime Fonts
1719
- Font Scripting
20+
- Adding/removing fonts to a font collection
21+
- Prewarming glyphs
1822
---
1923

2024
# Font files
@@ -30,6 +34,27 @@ Fonts added to your project are automatically converted into a texture format th
3034
- Bitmap
3135
- Distance field
3236

37+
## Offline or Runtime fonts
38+
39+
By default, the conversion to rasterized glyph images happens at build time (offline). This has the drawback that each font needs to rasterize all possible glyphs in the build stage, producing potentially very large textures that consume memory and also increase the bundle size.
40+
41+
By using "runtime fonts", the .ttf fonts will be bundled as-is, and the rasterization will happen on-demand at runtime. This minimizes both runtime memory usage and the bundle size.
42+
43+
## Text layout support (e.g. Right-to-left)
44+
45+
The runtime fonts also have the benefit of supporting full text layout, e.g. right-to-left.
46+
We currently use the libraries [HarfBuzz](https://github.com/harfbuzz/harfbuzz), [SheenBidi](https://github.com/Tehreer/SheenBidi), [libunibreak](https://github.com/adah1972/libunibreak) and [SkriBidi](https://github.com/memononen/Skribidi).
47+
48+
See [Enabling Runtime Fonts](/manuals/font#enabling-runtime-fonts)
49+
50+
## Font collection
51+
52+
The `.fontc` file format is also known as a font collection. In offline mode, only one font is associated with it.
53+
When using runtime fonts, you can associate more than one font file (.ttf) with the font collection.
54+
55+
This allows for using the a font collection when rendering multiple texts in different languages, while also keeping the memory footprint low.
56+
E.g. loading a collection with the Japanese font, then associate that font with the current main font, followed by unloading the Japanese font collection.
57+
3358
## Creating a font
3459

3560
To create a font for use in Defold, create a new Font file by selecting <kbd>File ▸ New...</kbd> from the menu, then select <kbd>Font</kbd>. You can also <kbd>right click</kbd> a location in the *Assets* browser and select <kbd>New... ▸ Font</kbd>.
@@ -95,6 +120,8 @@ Shadow support is enabled by the built-in font material shaders and handles both
95120
*Characters*
96121
: Which characters to include in the font. By default this field include the ASCII printable characters (character codes 32-126). You can add or remove characters from this field to include more or less characters in the font..
97122

123+
For runtime fonts, this text acts as a cache prewarming with the correct glyphs. This happens during load time. See `font.prewarm_text()`.
124+
98125
<div class='sidenote' markdown='1'>
99126
The ASCII printable characters are:
100127
space ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ \` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
@@ -177,23 +204,29 @@ For example - to generate a gradient in a shader fragment, simply write:
177204

178205
For more information about shader uniforms, see the [Shader manual](/manuals/shader).
179206

180-
## Runtime generation
207+
## Enabling Runtime Fonts
181208

182209
It is possible to use runtime generation for SDF type fonts, when using TrueType (.ttf) fonts.
183210
This approach can greatly reduce the download size and runtime memory consumption of a Defold game.
184-
The small downside is a very small delay for each glyph generated at runtime.
211+
The small downside is the asynchronous nature of generating each glyph.
212+
213+
* Enable the feature by setting `font.runtime_generation` in game.project.
185214

186-
Enable the feature by setting `font.runtime_generation` in game.project.
215+
* Add an [App Manifest](/manuals/app-manifest) and enable the `Use full text layout system` option.
216+
This builds a custom engine that has this feature enabled.
187217

188218
<div class='sidenote' markdown='1'>
189219
This feature is currently experimental, but with the intention to be used as the default workflow in the future.
190220
</div>
191221

192222
<div class='important' markdown='1'>
193-
This setting affects all .ttf fonts in the project.
223+
The `font.runtime_generation` setting affects all .ttf fonts in the project.
194224
</div>
195225

196-
### Prewarming glyph cache
226+
227+
### Font Scripting
228+
229+
#### Prewarming glyph cache
197230

198231
In order to make the runtime fonts easier to use, they support prewarming of the glyph cache.
199232
This means the font will generate the glyphs listed in *Characters* in the font.
@@ -202,52 +235,52 @@ This means the font will generate the glyphs listed in *Characters* in the font.
202235
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.
203236
</div>
204237

205-
### Font Scripting
238+
If the `Characters` field of the `.fontc` file is set, this is used as a text, to figure out which glyphs needs to be updated in the glyph cache.
239+
240+
It is also possible to manually update the glyph cache by calling `font.prewarm_text(font_collection, text, callback)`. It provides a callback to let you know when all the missing glyphs have been added to the glyph cache, and it's safe to present the text on screen.
241+
242+
### Adding/removing fonts to a font collection
206243

207-
For runtime fonts, it's possible to add or removed sub fonts.
244+
For runtime fonts, it's possible to add or remove fonts (.ttf) to a font collection.
208245
This is useful when a large font has been split up into multiple files for different character sets (e.g. CJK)
209246

210247
<div class='important' markdown='1'>
211-
Adding a subfont doesn't automatically load or render all the glyphs.
248+
Adding a font to a font collection doesn't automatically load or render all the glyphs.
212249
</div>
213250

214251
```lua
215-
-- Add the range A-Z to the .fontc
216-
local font_hash = hash("/assets/fonts/roboto.fontc")
217-
local ttf_hash = hash("/assets/fonts/Roboto/Roboto-Bold.ttf")
218-
local codepoint_min = 0x00000041 -- A
219-
local codepoint_max = 0x0000005A -- Z
220-
font.add_source(font_hash, ttf_hash, codepoint_min, codepoint_max)
252+
-- get the main font
253+
local font_collection = go.get("#label", "font")
254+
font.add_font(font_collection, self.language_ttf_hash)
255+
256+
-- get the selected language font
257+
local font_collection_language = go.get("localization_japanese#label", "font")
258+
local font_info = font.get_info(font_collection_language)
259+
self.language_ttf_hash = font_info.fonts[1].path_hash -- get the first font (the one specified in the editor)
260+
font.add_font(self.font_collection, self.language_ttf_hash) -- increases the reference count to the font
221261
```
222262

223263
```lua
224-
-- Remove the associated ttf resource
225-
local font_hash = hash("/assets/fonts/roboto.fontc")
226-
local ttf_hash = hash("/assets/fonts/Roboto/Roboto-Bold.ttf")
227-
font.remove_source(font_hash, ttf_hash)
264+
-- remove the font reference
265+
font.add_font(self.font_collection, self.language_ttf_hash)
228266
```
229267

230-
To load the glyphs to the font, you will need to call the `font.add_glyphs()`.
231-
It is an asynchronous operation, and once it's done, it's safe to progress to show any message containing the glyphs.
268+
### Prewarming glyphs
232269

233-
```lua
234-
local function add_glyph_callback(self, id, result, errmsg)
235-
if not result then
236-
print("Request " .. id .." finished with error:", errmsg)
237-
else
238-
msg.post(some_url, "show_dialog")
239-
end
240-
end
241-
242-
-- Load glyphs into the font
243-
local font_hash = hash("/assets/fonts/roboto.fontc")
244-
local glyphs = "Some text to be shown!" -- for optimal performance, make this a list of unique glyphs
245-
local request_id = font.add_glyphs(font_hash, ttf_hash, add_glyph_callback)
246-
```
270+
To properly show a text with a runtime font, the glyphs need to be resolved. The `font.prewarm_text()` does this for you.
271+
It is an asynchronous operation, and once it's done and you get the callback, it's safe to progress to show any message containing the glyphs.
272+
273+
<div class='important' markdown='1'>
274+
If the glyph cache gets full, the oldest glyph in the cache will be evicted.
275+
</div>
247276

248-
And, once the characters aren't needed anymore, you can discard that memory:
249277
```lua
250-
-- Remove the associated ttf resource
251-
local font_hash = hash("/assets/fonts/roboto.fontc")
252-
font.remove_glyphs(font_hash, "All the characters in the set")
278+
font.prewarm_text(self.font_collection, info.text, function (self, request_id, result, err)
279+
if result then
280+
print("PREWARMING OK!")
281+
label.set_text(self.label, info.text)
282+
else
283+
print("Error prewarming text:", err)
284+
end
285+
end)
253286
```

0 commit comments

Comments
 (0)