godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.15k stars 97 forks source link

Allow extending Font class #193

Open BenMcLean opened 4 years ago

BenMcLean commented 4 years ago

Describe the project you are working on:

I'm working on re-creating Wolfenstein 3-D in VR for the Oculus Quest using Godot Mono / C#.

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

I'm working on loading binary font data directly from the original unaltered 1992 Wolfenstein 3-D files at runtime and then using it as the font for a Godot GUI theme also generated in code at runtime. (the goal being for the new theme to closely mimic the style of the Wolfenstein 3-D menus) I've already converted the font data to ImageTextures of letters that I can display in Godot. So my thought was to try extending the Font class to enable using this data as a Godot Font. But I found that I cannot extend the Godot Font class (or at least not in C#) because its constructor(s) are not public.

Describe how this feature / enhancement will help you overcome this problem or limitation:

Rather than trying to support literally every font format under the sun (there are tons) it would make more sense to provide an interface that allows any kind of underlying font data to be used as long as users write the code to support it. I think that providing a public constructor interface for Font would allow this.

If this enhancement will not be used often, can it be worked around with a few lines of script?:

No. The workaround I envision is probably figuring out some way to convert from the Wolfenstein 3-D font format to the FNT format and then loading that into a BitmapFont, but since I don't know how the FNT format works, that'll require tedious research.

Is there a reason why this should be core and not an add-on in the asset library?:

It prevents a whole category of addons (Font format support addons) from even being made, or it seems to.

BenMcLean commented 4 years ago

Note: Also, please add arbitrary nearest-neighbor scaling to the BitmapFont class, and to the GUI in general.

Calinou commented 4 years ago

and to the GUI in general.

This should be a matter of disabling the Filter flag on the GUI textures (some_texture.flags ^= Texture.FLAG_FILTER). As for BitmapFont, I don't know, I thought it supported nearest-neighbor interpolation but I don't see any options for it…

Calinou commented 3 years ago

@bruvzg With the TextServer implementation in the master branch, is it possible for people to handle custom bitmapfont formats? Or should this be left for the user to handle the conversion to Godot's bitmap font format?

bruvzg commented 3 years ago

With the TextServer implementation in the master branch, is it possible for people to handle custom bitmapfont formats? Or should this be left for the user to handle the conversion to Godot's bitmap font format?

It is possible to create bitmap fonts from custom textures, but features are limited. Expanding Font class directly is not supported ¹:

In 4.0:

var font = Font.new()
var font_data = FontData.new()
font_data.new_bitmap(height, ascent)

font_data.bitmap_add_texture(texture)
font_data.bitmap_add_char(char, texture_index, rect, align, advance)
font_data.bitmap_add_kerning(char_a, char_b, kerning_value)

font.add_data(font_data)

In 3.x:

var font = BitmapFont.new()
font.set_height(height)
font.set_ascent(ascent)

font.add_texture(texture)
font.add_char(char, texture_index, rect, align, advance)
font.add_kerning(char_a, char_b, kerning_value)

¹ It is possible to implement a custom text server with support for any font formats using GDNative, but GDNative won't be able to expand it, only reimplement.