Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Complex Text Layouts: 2/4] Font fallback, substitution and management refactoring. #1181

Closed
bruvzg opened this issue Jul 10, 2020 · 2 comments

Comments

@bruvzg
Copy link
Member

bruvzg commented Jul 10, 2020

This proposal is follow up to #4, to get some community feedback/preferences on a specific parts of CTL support implementation.

Describe the project you are working on:
The Godot Engine


Describe the problem or limitation you are having in your project:

Current font fallback methods are inconsistent and inconvenient for use with complex text layouts.

🔹 BitmapFont: have single pointer to another BitmapFont, in the manner of single-linked list.

🔹 DynamicFont: have main DynamicFontData and the list of fallback DynamicFontDatas.

🔹 Font size is currently a property of the Font and only exist in DynamicFont.

🔹 Font ascent/descent take in account only the main FontData / first BitmapFont in the list.

🔹 DynamicFont have outline_color and draw function do have outline_modulate argument, these are multiplied on drawing, Fonts outline color seems to be excessive and misleading.

🔹 Nothing is drawing in place of missing characters.


Describe the feature / enhancement and how it helps to overcome the problem or limitation:

🔹 Processed text usually consists of glyph indices that are specific the font file, therefore it should have direct and safe (cached text can outlive its source font) reference to the specific fallback font (FontDataAtSize in case of DynamicFont and font itself for bitmap).

🔹 One fallback might be preferred over the other for use with the text in particular language (even if both fallbacks have the same charset/script).

🔹 Shaping is quite expensive process, and in case large number of fallbacks is used (e.g. full Noto font set for all languages) trying fallbacks with the support for script (which is known in advance) first might improve performance significantly.

🔹 Font built-in language/script info is not fully reliable and consistent, possibility for the user override is also required.

🔹 It's much more convenient to be able to select font sizes for specific controls (and by using [size=x] tag in bbcode), instead of creating multiple instances of Font for each size.

🔹 For some languages elements of the text can be shifted from the baseline significantly, using Font ascend/descent can cause overlapping and clipping.

🔹 Base font ascent/descent can be significantly different even within the same font set.


Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

Font as container for the "fallbacks" (with the implementation of high level functions only, like draw):
🔹 List of the FontData, with the ability to return it sorted by script/language support.

🔹 Do not use ascent/descent for the Font as whole, instead each individual FontData ascent/descent for estimated size calculation (e.g. size of empty input field), and string ascent/descent for actual text (Use ShapedString function or Fonts get_string_size can return Vector3 (ascent, descent, width) instead of Vector2 to get exact string metrics).

🔹 Do not use size as the property of the Font, instead pass it as an argument to the draw/get_string_size functions.

🔹 Remove draw_char/get_char_size function completely, to avoid incorrect usage (drawing text as individual chars), in case someone need to draw single char there's always draw function for a string.

🔹 Remove fonts outline_color and use only argument of the draw function directly.

FontData (virtual) and its Bitmap/Dynamic font implementation:
🔹 Properties for script/language support override properties.

🔹 Implementation specific properties (hinting/aa/distance field for bitmaps), while this is unlikely a common use case, there's no reason why Font can't hold both Bitmap and Dynamic fallbacks or different fallbacks use different hinting/aa settings.

🔹 To allow future use of the system text shaping engines and fonts, and since shaping engine will require low level access to fonts internals, FontData implementation probably should share the same module with the shaping engine (or have complex private API for the shaping engine, e.g. https://github.com/harfbuzz/harfbuzz/blob/master/src/hb-ft.cc).

Missing chars, what should be displayed:
🔹 Nothing?
🔹 Box / Static replacement character?
🔹 Box with the missing character hex code?

I'm not sure about exact API structure, convenient for both users and shaping engine usage.


If this enhancement will not be used often, can it be worked around with a few lines of script?:
It will be used by all editor and exported apps UI.


Is there a reason why this should be core and not an add-on in the asset library?:
Fonts are part of core, but particular implementation can be moved to module.

Note: In this proposal script is always used in the "writing system" meaning.

@Calinou
Copy link
Member

Calinou commented Jul 10, 2020

🔹 Nothing is drawing in place of missing characters.

This was also brought up in #591.

small_blue_diamond Remove fonts outline_color and use only argument of the draw function directly.

While we're at it, we should remove the legacy font outlines that Label currently supports. These are no longer relevant since Godot 3.1 was released. (The font shadows should remain unless we intend to support them directly in Font, though.)

@bruvzg
Copy link
Member Author

bruvzg commented Dec 14, 2020

Proposal is implemented in godotengine/godot#41100 and godotengine/godot#42595.

@bruvzg bruvzg closed this as completed Dec 14, 2020
@Calinou Calinou added this to the 4.0 milestone Dec 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants