Skip to content

Commit

Permalink
Merge pull request #168 from WhalesState/lcd-subpixel-layout
Browse files Browse the repository at this point in the history
Add TextServer set/get lcd subpixel layout.
  • Loading branch information
jss2a98aj authored Dec 2, 2024
2 parents d5c0df7 + a4a3bed commit 00526ee
Show file tree
Hide file tree
Showing 18 changed files with 215 additions and 79 deletions.
3 changes: 3 additions & 0 deletions doc/classes/FontFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,9 @@
<member name="hinting" type="int" setter="set_hinting" getter="get_hinting" enum="TextServer.Hinting" default="1">
Font hinting mode. Used by dynamic fonts only.
</member>
<member name="lcd_subpixel_layout" type="int" setter="set_lcd_subpixel_layout" getter="get_lcd_subpixel_layout" enum="TextServer.FontLCDSubpixelLayout" default="1">
LCD subpixel layout used for font anti-aliasing. See [enum TextServer.FontLCDSubpixelLayout].
</member>
<member name="msdf_pixel_range" type="int" setter="set_msdf_pixel_range" getter="get_msdf_pixel_range" default="16">
The width of the range around the shape between the minimum and maximum representable signed distance. If using font outlines, [member msdf_pixel_range] must be set to at least [i]twice[/i] the size of the largest font outline. The default [member msdf_pixel_range] value of [code]16[/code] allows outline sizes up to [code]8[/code] to look correct.
</member>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/SystemFont.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
<member name="hinting" type="int" setter="set_hinting" getter="get_hinting" enum="TextServer.Hinting" default="1">
Font hinting mode.
</member>
<member name="lcd_subpixel_layout" type="int" setter="set_lcd_subpixel_layout" getter="get_lcd_subpixel_layout" enum="TextServer.FontLCDSubpixelLayout" default="1">
LCD subpixel layout used for font anti-aliasing. See [enum TextServer.FontLCDSubpixelLayout].
</member>
<member name="msdf_pixel_range" type="int" setter="set_msdf_pixel_range" getter="get_msdf_pixel_range" default="16">
The width of the range around the shape between the minimum and maximum representable signed distance. If using font outlines, [member msdf_pixel_range] must be set to at least [i]twice[/i] the size of the largest font outline. The default [member msdf_pixel_range] value of [code]16[/code] allows outline sizes up to [code]8[/code] to look correct.
</member>
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/TextServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,13 @@
Returns list of language support overrides.
</description>
</method>
<method name="font_get_lcd_subpixel_layout" qualifiers="const">
<return type="int" enum="TextServer.FontLCDSubpixelLayout" />
<param index="0" name="font_rid" type="RID" />
<description>
Returns the LCD subpixel layout used for font anti-aliasing. See [enum TextServer.FontLCDSubpixelLayout].
</description>
</method>
<method name="font_get_msdf_pixel_range" qualifiers="const">
<return type="int" />
<param index="0" name="font_rid" type="RID" />
Expand Down Expand Up @@ -831,6 +838,14 @@
Adds override for [method font_is_language_supported].
</description>
</method>
<method name="font_set_lcd_subpixel_layout">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="lcd_subpixel_layout" type="int" enum="TextServer.FontLCDSubpixelLayout" />
<description>
Sets the LCD subpixel layout used for font anti-aliasing. See [enum TextServer.FontLCDSubpixelLayout].
</description>
</method>
<method name="font_set_msdf_pixel_range">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/TextServerExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,13 @@
Returns list of language support overrides.
</description>
</method>
<method name="_font_get_lcd_subpixel_layout" qualifiers="virtual const">
<return type="int" enum="TextServer.FontLCDSubpixelLayout" />
<param index="0" name="font_rid" type="RID" />
<description>
LCD subpixel layout used for font anti-aliasing. See [enum TextServer.FontLCDSubpixelLayout].
</description>
</method>
<method name="_font_get_msdf_pixel_range" qualifiers="virtual const">
<return type="int" />
<param index="0" name="font_rid" type="RID" />
Expand Down Expand Up @@ -917,6 +924,14 @@
Adds override for [method _font_is_language_supported].
</description>
</method>
<method name="_font_set_lcd_subpixel_layout" qualifiers="virtual">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="subpixel_layout" type="int" enum="TextServer.FontLCDSubpixelLayout" />
<description>
LCD subpixel layout used for font anti-aliasing. See [enum TextServer.FontLCDSubpixelLayout].
</description>
</method>
<method name="_font_set_msdf_pixel_range" qualifiers="virtual">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
Expand Down
5 changes: 5 additions & 0 deletions editor/import/dynamic_font_import_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ void DynamicFontImportSettingsDialog::_main_prop_changed(const String &p_edited_
font_preview->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int());
} else if (p_edited_property == "subpixel_positioning") {
font_preview->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int());
} else if (p_edited_property == "lcd_subpixel_layout") {
font_preview->set_lcd_subpixel_layout((TextServer::FontLCDSubpixelLayout)import_settings_data->get("lcd_subpixel_layout").operator int());
} else if (p_edited_property == "oversampling") {
font_preview->set_oversampling(import_settings_data->get("oversampling"));
}
Expand Down Expand Up @@ -956,6 +958,7 @@ void DynamicFontImportSettingsDialog::_re_import() {
main_settings["force_autohinter"] = import_settings_data->get("force_autohinter");
main_settings["hinting"] = import_settings_data->get("hinting");
main_settings["subpixel_positioning"] = import_settings_data->get("subpixel_positioning");
main_settings["lcd_subpixel_layout"] = import_settings_data->get("lcd_subpixel_layout");
main_settings["oversampling"] = import_settings_data->get("oversampling");
main_settings["fallbacks"] = import_settings_data->get("fallbacks");
main_settings["compress"] = import_settings_data->get("compress");
Expand Down Expand Up @@ -1232,6 +1235,7 @@ void DynamicFontImportSettingsDialog::open_settings(const String &p_path) {
font_preview->set_force_autohinter(import_settings_data->get("force_autohinter"));
font_preview->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int());
font_preview->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int());
font_preview->set_lcd_subpixel_layout((TextServer::FontLCDSubpixelLayout)import_settings_data->get("lcd_subpixel_layout").operator int());
font_preview->set_oversampling(import_settings_data->get("oversampling"));
}
font_preview_label->add_theme_font_override(SceneStringName(font), font_preview);
Expand Down Expand Up @@ -1264,6 +1268,7 @@ DynamicFontImportSettingsDialog::DynamicFontImportSettingsDialog() {
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), 1));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "lcd_subpixel_layout", PROPERTY_HINT_ENUM, "Disabled,Horizontal RGB,Horizontal BGR,Vertical RGB,Vertical BGR"), 1));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0));

options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Metadata Overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
Expand Down
75 changes: 41 additions & 34 deletions modules/text_server_adv/text_server_adv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,15 @@

#include <godot_cpp/classes/file_access.hpp>
#include <godot_cpp/classes/os.hpp>
#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/translation_server.hpp>
#include <godot_cpp/core/error_macros.hpp>

using namespace godot;

#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get_setting_with_override(m_var)

#elif defined(GODOT_MODULE)
// Headers for building as built-in module.

#include "core/config/project_settings.h"
#include "core/error/error_macros.h"
#include "core/object/worker_thread_pool.h"
#include "core/string/print_string.h"
Expand Down Expand Up @@ -2215,6 +2211,27 @@ TextServer::FontAntialiasing TextServerAdvanced::_font_get_antialiasing(const RI
return fd->antialiasing;
}

void TextServerAdvanced::_font_set_lcd_subpixel_layout(const RID &p_font_rid, TextServer::FontLCDSubpixelLayout p_lcd_subpixel_layout) {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);

MutexLock lock(fd->mutex);
if (fd->lcd_subpixel_layout != p_lcd_subpixel_layout) {
if (fd->antialiasing == TextServer::FONT_ANTIALIASING_LCD) {
_font_clear_cache(fd);
}
fd->lcd_subpixel_layout = p_lcd_subpixel_layout;
}
}

TextServer::FontLCDSubpixelLayout TextServerAdvanced::_font_get_lcd_subpixel_layout(const RID &p_font_rid) const {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, TextServer::FontLCDSubpixelLayout::FONT_LCD_SUBPIXEL_LAYOUT_NONE);

MutexLock lock(fd->mutex);
return fd->lcd_subpixel_layout;
}

void TextServerAdvanced::_font_set_disable_embedded_bitmaps(const RID &p_font_rid, bool p_disable_embedded_bitmaps) {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);
Expand Down Expand Up @@ -2944,9 +2961,8 @@ Vector2 TextServerAdvanced::_font_get_glyph_advance(const RID &p_font_rid, int64

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down Expand Up @@ -3003,9 +3019,8 @@ Vector2 TextServerAdvanced::_font_get_glyph_offset(const RID &p_font_rid, const

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down Expand Up @@ -3054,9 +3069,8 @@ Vector2 TextServerAdvanced::_font_get_glyph_size(const RID &p_font_rid, const Ve

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down Expand Up @@ -3105,9 +3119,8 @@ Rect2 TextServerAdvanced::_font_get_glyph_uv_rect(const RID &p_font_rid, const V

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down Expand Up @@ -3145,9 +3158,8 @@ int64_t TextServerAdvanced::_font_get_glyph_texture_idx(const RID &p_font_rid, c

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down Expand Up @@ -3185,9 +3197,8 @@ RID TextServerAdvanced::_font_get_glyph_texture_rid(const RID &p_font_rid, const

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down Expand Up @@ -3232,9 +3243,8 @@ Size2 TextServerAdvanced::_font_get_glyph_texture_size(const RID &p_font_rid, co

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down Expand Up @@ -3612,10 +3622,9 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
if (!fd->msdf && fd->cache[size]->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
lcd_aa = true;
index = index | (layout << 24);
index = index | (fd->lcd_subpixel_layout << 24);
}
}
// Subpixel X-shift, bits 27, 28
Expand Down Expand Up @@ -3720,10 +3729,9 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
if (!fd->msdf && fd->cache[size]->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
lcd_aa = true;
index = index | (layout << 24);
index = index | (fd->lcd_subpixel_layout << 24);
}
}
// Subpixel X-shift, bits 27, 28
Expand Down Expand Up @@ -6037,9 +6045,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
if (fd->lcd_subpixel_layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (fd->lcd_subpixel_layout << 24);
}
}

Expand Down
4 changes: 4 additions & 0 deletions modules/text_server_adv/text_server_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ class TextServerAdvanced : public TextServerExtension {
Mutex mutex;

TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
TextServer::FontLCDSubpixelLayout lcd_subpixel_layout = TextServer::FontLCDSubpixelLayout::FONT_LCD_SUBPIXEL_LAYOUT_NONE;
bool disable_embedded_bitmaps = true;
bool mipmaps = false;
bool msdf = false;
Expand Down Expand Up @@ -755,6 +756,9 @@ class TextServerAdvanced : public TextServerExtension {
MODBIND2(font_set_antialiasing, const RID &, TextServer::FontAntialiasing);
MODBIND1RC(TextServer::FontAntialiasing, font_get_antialiasing, const RID &);

MODBIND2(font_set_lcd_subpixel_layout, const RID &, TextServer::FontLCDSubpixelLayout);
MODBIND1RC(TextServer::FontLCDSubpixelLayout, font_get_lcd_subpixel_layout, const RID &);

MODBIND2(font_set_disable_embedded_bitmaps, const RID &, bool);
MODBIND1RC(bool, font_get_disable_embedded_bitmaps, const RID &);

Expand Down
Loading

0 comments on commit 00526ee

Please sign in to comment.