mirror of
https://github.com/godotengine/godot.git
synced 2024-11-10 06:03:09 +00:00
[Font Import] Detect pixel fonts and disable subpixel positioning.
This commit is contained in:
parent
8e36f98ea5
commit
32bc1c2f33
@ -69,12 +69,13 @@
|
||||
<member name="script_support" type="Dictionary" setter="" getter="" default="{}">
|
||||
Override the list of language scripts supported by this font. If left empty, this is supplied by the font metadata. There is usually no need to change this. See also [member language_support].
|
||||
</member>
|
||||
<member name="subpixel_positioning" type="int" setter="" getter="" default="1">
|
||||
<member name="subpixel_positioning" type="int" setter="" getter="" default="4">
|
||||
Subpixel positioning improves font rendering appearance, especially at smaller font sizes. The downside is that it takes more time to initially render the font, which can cause stuttering during gameplay, especially if used with large font sizes. This should be set to [b]Disabled[/b] for fonts with a pixel art appearance.
|
||||
[b]Disabled:[/b] No subpixel positioning. Lowest quality, fastest rendering.
|
||||
[b]Auto:[/b] Use subpixel positioning at small font sizes (the chosen quality varies depending on font size). Large fonts will not use subpixel positioning. This is a good tradeoff between performance and quality.
|
||||
[b]One Half of a Pixel:[/b] Always perform intermediate subpixel positioning regardless of font size. High quality, slow rendering.
|
||||
[b]One Quarter of a Pixel:[/b] Always perform precise subpixel positioning regardless of font size. Highest quality, slowest rendering.
|
||||
[b]Auto (Except Pixel Fonts):[/b] [b]Disabled[/b] for the pixel style fonts (each glyph contours contain only straight horizontal and vertical lines), [b]Auto[/b] for the other fonts.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
@ -459,6 +459,13 @@
|
||||
Returns a string containing all the characters available in the font.
|
||||
</description>
|
||||
</method>
|
||||
<method name="font_get_supported_glyphs" qualifiers="const">
|
||||
<return type="PackedInt32Array" />
|
||||
<param index="0" name="font_rid" type="RID" />
|
||||
<description>
|
||||
Returns an array containing all glyph indices in the font.
|
||||
</description>
|
||||
</method>
|
||||
<method name="font_get_texture_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="font_rid" type="RID" />
|
||||
|
@ -496,6 +496,14 @@
|
||||
Returns a string containing all the characters available in the font.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_font_get_supported_glyphs" qualifiers="virtual const">
|
||||
<return type="PackedInt32Array" />
|
||||
<param index="0" name="font_rid" type="RID" />
|
||||
<description>
|
||||
[b]Required.[/b]
|
||||
Returns an array containing all glyph indices in the font.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_font_get_texture_count" qualifiers="virtual const">
|
||||
<return type="int" />
|
||||
<param index="0" name="font_rid" type="RID" />
|
||||
|
@ -118,7 +118,7 @@ void ResourceImporterDynamicFont::get_import_options(const String &p_path, List<
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "allow_system_fallback"), true));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), 1));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel,Auto (Except Pixel Fonts)"), 4));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0));
|
||||
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Fallbacks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
|
||||
@ -176,11 +176,44 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str
|
||||
font->set_fixed_size(0);
|
||||
font->set_force_autohinter(autohinter);
|
||||
font->set_allow_system_fallback(allow_system_fallback);
|
||||
font->set_subpixel_positioning((TextServer::SubpixelPositioning)subpixel_positioning);
|
||||
font->set_hinting((TextServer::Hinting)hinting);
|
||||
font->set_oversampling(oversampling);
|
||||
font->set_fallbacks(fallbacks);
|
||||
|
||||
if (subpixel_positioning == 4 /* Auto (Except Pixel Fonts) */) {
|
||||
PackedInt32Array glyphs = TS->font_get_supported_glyphs(font->get_rids()[0]);
|
||||
bool is_pixel = true;
|
||||
for (int32_t gl : glyphs) {
|
||||
Dictionary ct = TS->font_get_glyph_contours(font->get_rids()[0], 16, gl);
|
||||
PackedInt32Array contours = ct["contours"];
|
||||
PackedVector3Array points = ct["points"];
|
||||
int prev_start = 0;
|
||||
for (int i = 0; i < contours.size(); i++) {
|
||||
for (int j = prev_start; j <= contours[i]; j++) {
|
||||
int next_point = (j < contours[i]) ? (j + 1) : prev_start;
|
||||
if ((points[j].z != TextServer::CONTOUR_CURVE_TAG_ON) || (!Math::is_equal_approx(points[j].x, points[next_point].x) && !Math::is_equal_approx(points[j].y, points[next_point].y))) {
|
||||
is_pixel = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prev_start = contours[i] + 1;
|
||||
if (!is_pixel) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_pixel) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_pixel && !glyphs.is_empty()) {
|
||||
print_line(vformat("%s: Pixel font detected, disabling subpixel positioning.", p_source_file));
|
||||
subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED;
|
||||
} else {
|
||||
subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
|
||||
}
|
||||
}
|
||||
font->set_subpixel_positioning((TextServer::SubpixelPositioning)subpixel_positioning);
|
||||
|
||||
Dictionary langs = p_options["language_support"];
|
||||
for (int i = 0; i < langs.size(); i++) {
|
||||
String key = langs.get_key_at_index(i);
|
||||
|
@ -3528,6 +3528,37 @@ String TextServerAdvanced::_font_get_supported_chars(const RID &p_font_rid) cons
|
||||
return chars;
|
||||
}
|
||||
|
||||
PackedInt32Array TextServerAdvanced::_font_get_supported_glyphs(const RID &p_font_rid) const {
|
||||
FontAdvanced *fd = _get_font_data(p_font_rid);
|
||||
ERR_FAIL_NULL_V(fd, PackedInt32Array());
|
||||
|
||||
MutexLock lock(fd->mutex);
|
||||
if (fd->cache.is_empty()) {
|
||||
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0)), PackedInt32Array());
|
||||
}
|
||||
FontForSizeAdvanced *at_size = fd->cache.begin()->value;
|
||||
|
||||
PackedInt32Array glyphs;
|
||||
#ifdef MODULE_FREETYPE_ENABLED
|
||||
if (at_size && at_size->face) {
|
||||
FT_UInt gindex;
|
||||
FT_ULong charcode = FT_Get_First_Char(at_size->face, &gindex);
|
||||
while (gindex != 0) {
|
||||
glyphs.push_back(gindex);
|
||||
charcode = FT_Get_Next_Char(at_size->face, charcode, &gindex);
|
||||
}
|
||||
return glyphs;
|
||||
}
|
||||
#endif
|
||||
if (at_size) {
|
||||
const HashMap<int32_t, FontGlyph> &gl = at_size->glyph_map;
|
||||
for (const KeyValue<int32_t, FontGlyph> &E : gl) {
|
||||
glyphs.push_back(E.key);
|
||||
}
|
||||
}
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
void TextServerAdvanced::_font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
|
||||
FontAdvanced *fd = _get_font_data(p_font_rid);
|
||||
ERR_FAIL_NULL(fd);
|
||||
|
@ -871,6 +871,7 @@ public:
|
||||
|
||||
MODBIND2RC(bool, font_has_char, const RID &, int64_t);
|
||||
MODBIND1RC(String, font_get_supported_chars, const RID &);
|
||||
MODBIND1RC(PackedInt32Array, font_get_supported_glyphs, const RID &);
|
||||
|
||||
MODBIND4(font_render_range, const RID &, const Vector2i &, int64_t, int64_t);
|
||||
MODBIND3(font_render_glyph, const RID &, const Vector2i &, int64_t);
|
||||
|
@ -2477,6 +2477,37 @@ String TextServerFallback::_font_get_supported_chars(const RID &p_font_rid) cons
|
||||
return chars;
|
||||
}
|
||||
|
||||
PackedInt32Array TextServerFallback::_font_get_supported_glyphs(const RID &p_font_rid) const {
|
||||
FontFallback *fd = _get_font_data(p_font_rid);
|
||||
ERR_FAIL_NULL_V(fd, PackedInt32Array());
|
||||
|
||||
MutexLock lock(fd->mutex);
|
||||
if (fd->cache.is_empty()) {
|
||||
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0)), PackedInt32Array());
|
||||
}
|
||||
FontForSizeFallback *at_size = fd->cache.begin()->value;
|
||||
|
||||
PackedInt32Array glyphs;
|
||||
#ifdef MODULE_FREETYPE_ENABLED
|
||||
if (at_size && at_size->face) {
|
||||
FT_UInt gindex;
|
||||
FT_ULong charcode = FT_Get_First_Char(at_size->face, &gindex);
|
||||
while (gindex != 0) {
|
||||
glyphs.push_back(gindex);
|
||||
charcode = FT_Get_Next_Char(at_size->face, charcode, &gindex);
|
||||
}
|
||||
return glyphs;
|
||||
}
|
||||
#endif
|
||||
if (at_size) {
|
||||
const HashMap<int32_t, FontGlyph> &gl = at_size->glyph_map;
|
||||
for (const KeyValue<int32_t, FontGlyph> &E : gl) {
|
||||
glyphs.push_back(E.key);
|
||||
}
|
||||
}
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
void TextServerFallback::_font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
|
||||
FontFallback *fd = _get_font_data(p_font_rid);
|
||||
ERR_FAIL_NULL(fd);
|
||||
|
@ -739,6 +739,7 @@ public:
|
||||
|
||||
MODBIND2RC(bool, font_has_char, const RID &, int64_t);
|
||||
MODBIND1RC(String, font_get_supported_chars, const RID &);
|
||||
MODBIND1RC(PackedInt32Array, font_get_supported_glyphs, const RID &);
|
||||
|
||||
MODBIND4(font_render_range, const RID &, const Vector2i &, int64_t, int64_t);
|
||||
MODBIND3(font_render_glyph, const RID &, const Vector2i &, int64_t);
|
||||
|
@ -88,6 +88,7 @@ public:
|
||||
virtual int64_t font_get_char_from_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_glyph_index) const override { return 0; }
|
||||
virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override { return false; }
|
||||
virtual String font_get_supported_chars(const RID &p_font_rid) const override { return String(); }
|
||||
virtual PackedInt32Array font_get_supported_glyphs(const RID &p_font_rid) const override { return PackedInt32Array(); };
|
||||
virtual void font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const override {}
|
||||
virtual void font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const override {}
|
||||
|
||||
|
@ -196,6 +196,7 @@ void TextServerExtension::_bind_methods() {
|
||||
|
||||
GDVIRTUAL_BIND(_font_has_char, "font_rid", "char");
|
||||
GDVIRTUAL_BIND(_font_get_supported_chars, "font_rid");
|
||||
GDVIRTUAL_BIND(_font_get_supported_glyphs, "font_rid");
|
||||
|
||||
GDVIRTUAL_BIND(_font_render_range, "font_rid", "size", "start", "end");
|
||||
GDVIRTUAL_BIND(_font_render_glyph, "font_rid", "size", "index");
|
||||
@ -927,6 +928,12 @@ String TextServerExtension::font_get_supported_chars(const RID &p_font_rid) cons
|
||||
return ret;
|
||||
}
|
||||
|
||||
PackedInt32Array TextServerExtension::font_get_supported_glyphs(const RID &p_font_rid) const {
|
||||
PackedInt32Array ret;
|
||||
GDVIRTUAL_REQUIRED_CALL(_font_get_supported_glyphs, p_font_rid, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TextServerExtension::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
|
||||
GDVIRTUAL_CALL(_font_render_range, p_font_rid, p_size, p_start, p_end);
|
||||
}
|
||||
|
@ -323,8 +323,10 @@ public:
|
||||
|
||||
virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override;
|
||||
virtual String font_get_supported_chars(const RID &p_font_rid) const override;
|
||||
virtual PackedInt32Array font_get_supported_glyphs(const RID &p_font_rid) const override;
|
||||
GDVIRTUAL2RC(bool, _font_has_char, RID, int64_t);
|
||||
GDVIRTUAL1RC(String, _font_get_supported_chars, RID);
|
||||
GDVIRTUAL1RC(PackedInt32Array, _font_get_supported_glyphs, RID);
|
||||
|
||||
virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override;
|
||||
virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override;
|
||||
|
@ -352,6 +352,7 @@ void TextServer::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("font_has_char", "font_rid", "char"), &TextServer::font_has_char);
|
||||
ClassDB::bind_method(D_METHOD("font_get_supported_chars", "font_rid"), &TextServer::font_get_supported_chars);
|
||||
ClassDB::bind_method(D_METHOD("font_get_supported_glyphs", "font_rid"), &TextServer::font_get_supported_glyphs);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("font_render_range", "font_rid", "size", "start", "end"), &TextServer::font_render_range);
|
||||
ClassDB::bind_method(D_METHOD("font_render_glyph", "font_rid", "size", "index"), &TextServer::font_render_glyph);
|
||||
|
@ -396,6 +396,7 @@ public:
|
||||
|
||||
virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const = 0;
|
||||
virtual String font_get_supported_chars(const RID &p_font_rid) const = 0;
|
||||
virtual PackedInt32Array font_get_supported_glyphs(const RID &p_font_rid) const = 0;
|
||||
|
||||
virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) = 0;
|
||||
virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user