Skip to content

Commit

Permalink
Add TextServer set/get lcd subpixel layout.
Browse files Browse the repository at this point in the history
  • Loading branch information
WhalesState committed Dec 12, 2024
1 parent c51c7f6 commit 6828026
Show file tree
Hide file tree
Showing 18 changed files with 358 additions and 95 deletions.
3 changes: 3 additions & 0 deletions doc/classes/FontFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,9 @@
<member name="keep_rounding_remainders" type="bool" setter="set_keep_rounding_remainders" getter="get_keep_rounding_remainders" default="true">
If set to [code]true[/code], when aligning glyphs to the pixel boundaries rounding remainders are accumulated to ensure more uniform glyph distribution. This setting has no effect if subpixel positioning is enabled.
</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 @@ -46,6 +46,9 @@
<member name="keep_rounding_remainders" type="bool" setter="set_keep_rounding_remainders" getter="get_keep_rounding_remainders" default="true">
If set to [code]true[/code], when aligning glyphs to the pixel boundaries rounding remainders are accumulated to ensure more uniform glyph distribution. This setting has no effect if subpixel positioning is enabled.
</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 @@ -356,6 +356,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 @@ -858,6 +865,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 @@ -373,6 +373,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 @@ -942,6 +949,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
16 changes: 16 additions & 0 deletions editor/import/dynamic_font_import_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

/**************************************************************************/
/* PIXEL ENGINE */
/* Copyright (c) 2024-present Pixel Engine contributors (see AUTHORS.md). */
/**************************************************************************/
/* NOTICE: */
/* This file contains modifications and additions specific to the Pixel */
/* Engine project. While these changes are licensed under the MIT license */
/* for compatibility, we request proper attribution if reused in any */
/* derivative works, including meta-forks. */
/**************************************************************************/

#include "dynamic_font_import_settings.h"

#include "core/config/project_settings.h"
Expand Down Expand Up @@ -474,6 +485,8 @@ void DynamicFontImportSettingsDialog::_main_prop_changed(const String &p_edited_
if (font_preview.is_valid()) {
if (p_edited_property == "antialiasing") {
font_preview->set_antialiasing((TextServer::FontAntialiasing)import_settings_data->get("antialiasing").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 == "generate_mipmaps") {
font_preview->set_generate_mipmaps(import_settings_data->get("generate_mipmaps"));
} else if (p_edited_property == "disable_embedded_bitmaps") {
Expand Down Expand Up @@ -953,6 +966,7 @@ void DynamicFontImportSettingsDialog::_re_import() {

main_settings["face_index"] = import_settings_data->get("face_index");
main_settings["antialiasing"] = import_settings_data->get("antialiasing");
main_settings["lcd_subpixel_layout"] = import_settings_data->get("lcd_subpixel_layout");
main_settings["generate_mipmaps"] = import_settings_data->get("generate_mipmaps");
main_settings["disable_embedded_bitmaps"] = import_settings_data->get("disable_embedded_bitmaps");
main_settings["multichannel_signed_distance_field"] = import_settings_data->get("multichannel_signed_distance_field");
Expand Down Expand Up @@ -1232,6 +1246,7 @@ void DynamicFontImportSettingsDialog::open_settings(const String &p_path) {

if (font_preview.is_valid()) {
font_preview->set_antialiasing((TextServer::FontAntialiasing)import_settings_data->get("antialiasing").operator int());
font_preview->set_lcd_subpixel_layout((TextServer::FontLCDSubpixelLayout)import_settings_data->get("lcd_subpixel_layout").operator int());
font_preview->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field"));
font_preview->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range"));
font_preview->set_msdf_size(import_settings_data->get("msdf_size"));
Expand Down Expand Up @@ -1263,6 +1278,7 @@ DynamicFontImportSettingsDialog::DynamicFontImportSettingsDialog() {
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));

options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD Subpixel"), 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::BOOL, "generate_mipmaps"), false));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "disable_embedded_bitmaps"), true));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
Expand Down
91 changes: 52 additions & 39 deletions modules/text_server_adv/text_server_adv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,33 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

/**************************************************************************/
/* PIXEL ENGINE */
/* Copyright (c) 2024-present Pixel Engine contributors (see AUTHORS.md). */
/**************************************************************************/
/* NOTICE: */
/* This file contains modifications and additions specific to the Pixel */
/* Engine project. While these changes are licensed under the MIT license */
/* for compatibility, we request proper attribution if reused in any */
/* derivative works, including meta-forks. */
/**************************************************************************/

#include "text_server_adv.h"

#ifdef GDEXTENSION
// Headers for building as GDExtension plug-in.

#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 @@ -2279,6 +2286,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 @@ -3046,9 +3074,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 = lcd_subpixel_layout.get();
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 @@ -3106,9 +3133,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 = lcd_subpixel_layout.get();
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 @@ -3158,9 +3184,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 = lcd_subpixel_layout.get();
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 @@ -3210,9 +3235,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 = lcd_subpixel_layout.get();
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 @@ -3252,9 +3276,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 = lcd_subpixel_layout.get();
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 @@ -3294,9 +3317,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 = lcd_subpixel_layout.get();
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 @@ -3342,9 +3364,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 = lcd_subpixel_layout.get();
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 @@ -3770,10 +3791,9 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
if (!fd->msdf && ffsd->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = lcd_subpixel_layout.get();
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 @@ -3879,10 +3899,9 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
if (!fd->msdf && ffsd->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = lcd_subpixel_layout.get();
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 @@ -6207,9 +6226,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star

int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
TextServer::FontLCDSubpixelLayout layout = lcd_subpixel_layout.get();
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 @@ -7571,15 +7589,10 @@ bool TextServerAdvanced::_is_valid_letter(uint64_t p_unicode) const {
return u_isalpha(p_unicode);
}

void TextServerAdvanced::_update_settings() {
lcd_subpixel_layout.set((TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout"));
}

TextServerAdvanced::TextServerAdvanced() {
_insert_num_systems_lang();
_insert_feature_sets();
_bmp_create_font_funcs();
ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &TextServerAdvanced::_update_settings));
}

void TextServerAdvanced::_cleanup() {
Expand Down
18 changes: 15 additions & 3 deletions modules/text_server_adv/text_server_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

/**************************************************************************/
/* PIXEL ENGINE */
/* Copyright (c) 2024-present Pixel Engine contributors (see AUTHORS.md). */
/**************************************************************************/
/* NOTICE: */
/* This file contains modifications and additions specific to the Pixel */
/* Engine project. While these changes are licensed under the MIT license */
/* for compatibility, we request proper attribution if reused in any */
/* derivative works, including meta-forks. */
/**************************************************************************/

#ifndef TEXT_SERVER_ADV_H
#define TEXT_SERVER_ADV_H

Expand Down Expand Up @@ -162,9 +173,6 @@ class TextServerAdvanced : public TextServerExtension {
HashMap<StringName, int32_t> feature_sets;
HashMap<int32_t, FeatureInfo> feature_sets_inv;

SafeNumeric<TextServer::FontLCDSubpixelLayout> lcd_subpixel_layout{ TextServer::FontLCDSubpixelLayout::FONT_LCD_SUBPIXEL_LAYOUT_NONE };
void _update_settings();

void _insert_num_systems_lang();
void _insert_feature_sets();
_FORCE_INLINE_ void _insert_feature(const StringName &p_name, int32_t p_tag, Variant::Type p_vtype = Variant::INT, bool p_hidden = false);
Expand Down Expand Up @@ -317,6 +325,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 @@ -774,6 +783,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 6828026

Please sign in to comment.