Implement TextServer GDExtension interface, remove TextServer GDNative interface.

This commit is contained in:
bruvzg 2021-08-28 00:19:51 +03:00
parent 06c1b40b84
commit 0c0b5c84b0
58 changed files with 4388 additions and 3388 deletions

View File

@ -841,6 +841,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
{
Array native_structures;
// AudioStream structures
{
Dictionary d;
d["name"] = "AudioFrame";
@ -849,6 +850,22 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
native_structures.push_back(d);
}
// TextServer structures
{
Dictionary d;
d["name"] = "Glyph";
d["format"] = "int start,int end,uint8_t count,uint8_t repeat,uint16_t flags,float x_off,float y_off,float advance,RID font_rid,int font_size,int32_t index";
native_structures.push_back(d);
}
{
Dictionary d;
d["name"] = "CaretInfo";
d["format"] = "Rect2 leading_caret,Rect2 trailing_caret,TextServer::Direction leading_direction,TextServer::Direction trailing_direction";
native_structures.push_back(d);
}
api_dump["native_structures"] = native_structures;
}

View File

@ -150,7 +150,7 @@
<argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
<argument index="8" name="outline_size" type="int" default="0" />
<argument index="9" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
<argument index="10" name="flags" type="int" default="51" />
<argument index="10" name="flags" type="int" default="99" />
<description>
Breaks [code]text[/code] to the lines and draws it using the specified [code]font[/code] at the [code]position[/code] (top-left corner). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
</description>

View File

@ -103,7 +103,7 @@
<argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
<argument index="8" name="outline_size" type="int" default="0" />
<argument index="9" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
<argument index="10" name="flags" type="int" default="51" />
<argument index="10" name="flags" type="int" default="99" />
<description>
Breaks [code]text[/code] to the lines using rules specified by [code]flags[/code] and draws it into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
See also [method CanvasItem.draw_multiline_string].
@ -185,7 +185,7 @@
<argument index="0" name="text" type="String" />
<argument index="1" name="width" type="float" default="-1" />
<argument index="2" name="size" type="int" default="-1" />
<argument index="3" name="flags" type="int" default="48" />
<argument index="3" name="flags" type="int" default="96" />
<description>
Returns the size of a bounding box of a string broken into the lines, taking kerning and advance into account.
See also [method draw_multiline_string].

View File

@ -246,7 +246,7 @@
<method name="get_name" qualifiers="const">
<return type="String" />
<description>
Returns the name of the host OS. Possible values are: [code]"Android"[/code], [code]"iOS"[/code], [code]"HTML5"[/code], [code]"OSX"[/code], [code]"Server"[/code], [code]"Windows"[/code], [code]"UWP"[/code], [code]"X11"[/code].
Returns the name of the host OS. Possible values are: [code]"Android"[/code], [code]"iOS"[/code], [code]"HTML5"[/code], [code]"macOS"[/code], [code]"Server"[/code], [code]"Windows"[/code], [code]"UWP"[/code], [code]"X11"[/code].
</description>
</method>
<method name="get_process_id" qualifiers="const">

View File

@ -185,6 +185,18 @@
<description>
</description>
</method>
<method name="canvas_item_add_msdf_texture_rect_region">
<return type="void" />
<argument index="0" name="item" type="RID" />
<argument index="1" name="rect" type="Rect2" />
<argument index="2" name="texture" type="RID" />
<argument index="3" name="src_rect" type="Rect2" />
<argument index="4" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
<argument index="5" name="outline_size" type="int" default="0" />
<argument index="6" name="px_range" type="float" default="1.0" />
<description>
</description>
</method>
<method name="canvas_item_add_multimesh">
<return type="void" />
<argument index="0" name="item" type="RID" />

View File

@ -281,7 +281,7 @@
<member name="direction" type="int" setter="set_direction" getter="get_direction" enum="TextServer.Direction" default="0">
Text writing direction.
</member>
<member name="flags" type="int" setter="set_flags" getter="get_flags" default="51">
<member name="flags" type="int" setter="set_flags" getter="get_flags" default="99">
Line breaking and alignment rules. For more info see [TextServer].
</member>
<member name="max_lines_visible" type="int" setter="set_max_lines_visible" getter="get_max_lines_visible" default="-1">

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServer" inherits="Object" version="4.0">
<class name="TextServer" inherits="RefCounted" version="4.0">
<brief_description>
Interface for the fonts and complex text layouts.
</brief_description>
@ -487,8 +487,8 @@
</method>
<method name="font_set_data">
<return type="void" />
<argument index="0" name="data" type="RID" />
<argument index="1" name="arg1" type="PackedByteArray" />
<argument index="0" name="font_rid" type="RID" />
<argument index="1" name="data" type="PackedByteArray" />
<description>
Sets font source data, e.g contents of the dynamic font source file.
</description>
@ -714,12 +714,14 @@
<return type="Dictionary" />
<argument index="0" name="font_rid" type="RID" />
<description>
Returns the dictionary of the supported OpenType features.
</description>
</method>
<method name="font_supported_variation_list" qualifiers="const">
<return type="Dictionary" />
<argument index="0" name="font_rid" type="RID" />
<description>
Returns the dictionary of the supported OpenType variation coordinates.
</description>
</method>
<method name="format_number" qualifiers="const">
@ -737,6 +739,12 @@
Frees an object created by this [TextServer].
</description>
</method>
<method name="get_features" qualifiers="const">
<return type="int" />
<description>
Returns text server features, see [enum Feature].
</description>
</method>
<method name="get_hex_code_box_size" qualifiers="const">
<return type="Vector2" />
<argument index="0" name="size" type="int" />
@ -751,6 +759,18 @@
Returns the name of the server interface.
</description>
</method>
<method name="get_support_data_filename" qualifiers="const">
<return type="String" />
<description>
Returns default TextServer database (e.g. ICU break iterators and dictionaries) filename.
</description>
</method>
<method name="get_support_data_info" qualifiers="const">
<return type="String" />
<description>
Returns TextServer database (e.g. ICU break iterators and dictionaries) description.
</description>
</method>
<method name="has">
<return type="bool" />
<argument index="0" name="rid" type="RID" />
@ -758,14 +778,14 @@
Returns [code]true[/code] if [code]rid[/code] is valid resource owned by this text server.
</description>
</method>
<method name="has_feature">
<method name="has_feature" qualifiers="const">
<return type="bool" />
<argument index="0" name="feature" type="int" enum="TextServer.Feature" />
<description>
Returns [code]true[/code] if the server supports a feature.
</description>
</method>
<method name="is_locale_right_to_left">
<method name="is_locale_right_to_left" qualifiers="const">
<return type="bool" />
<argument index="0" name="locale" type="String" />
<description>
@ -802,6 +822,14 @@
Returns percent sign used in the [code]language[/code].
</description>
</method>
<method name="save_support_data" qualifiers="const">
<return type="bool" />
<argument index="0" name="filename" type="String" />
<description>
Saves optional TextServer database (e.g. ICU break iterators and dictionaries) to the file.
Note: This function is used by during project export, to include TextServer database.
</description>
</method>
<method name="shaped_text_add_object">
<return type="bool" />
<argument index="0" name="shaped" type="RID" />
@ -898,7 +926,7 @@
Returns direction of the text.
</description>
</method>
<method name="shaped_text_get_dominant_direciton_in_range" qualifiers="const">
<method name="shaped_text_get_dominant_direction_in_range" qualifiers="const">
<return type="int" enum="TextServer.Direction" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="start" type="int" />
@ -907,30 +935,58 @@
Returns dominant direction of in the range of text.
</description>
</method>
<method name="shaped_text_get_ellipsis_glyph_count" qualifiers="const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns number of glyphs in the ellipsis.
</description>
</method>
<method name="shaped_text_get_ellipsis_glyphs" qualifiers="const">
<return type="Array" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns array of the glyphs in the ellipsis.
</description>
</method>
<method name="shaped_text_get_ellipsis_pos" qualifiers="const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns position of the ellipsis.
</description>
</method>
<method name="shaped_text_get_glyph_count" qualifiers="const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns number of glyphs in the buffer.
</description>
</method>
<method name="shaped_text_get_glyphs" qualifiers="const">
<return type="Array" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns text glyphs.
Returns text glyphs in the visual order.
</description>
</method>
<method name="shaped_text_get_line_breaks" qualifiers="const">
<return type="Array" />
<return type="PackedInt32Array" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="float" />
<argument index="2" name="start" type="int" default="0" />
<argument index="3" name="break_flags" type="int" default="48" />
<argument index="3" name="break_flags" type="int" default="96" />
<description>
Breaks text to the lines and returns character ranges for each line.
</description>
</method>
<method name="shaped_text_get_line_breaks_adv" qualifiers="const">
<return type="Array" />
<return type="PackedInt32Array" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="PackedFloat32Array" />
<argument index="2" name="start" type="int" default="0" />
<argument index="3" name="once" type="bool" default="true" />
<argument index="4" name="break_flags" type="int" default="48" />
<argument index="4" name="break_flags" type="int" default="96" />
<description>
Breaks text to the lines and columns. Returns character ranges for each segment.
</description>
@ -987,7 +1043,7 @@
</description>
</method>
<method name="shaped_text_get_selection" qualifiers="const">
<return type="Array" />
<return type="PackedVector2Array" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="start" type="int" />
<argument index="2" name="end" type="int" />
@ -1002,6 +1058,13 @@
Returns size of the text.
</description>
</method>
<method name="shaped_text_get_trim_pos" qualifiers="const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns position of the trim.
</description>
</method>
<method name="shaped_text_get_underline_position" qualifiers="const">
<return type="float" />
<argument index="0" name="shaped" type="RID" />
@ -1024,8 +1087,9 @@
</description>
</method>
<method name="shaped_text_get_word_breaks" qualifiers="const">
<return type="Array" />
<return type="PackedInt32Array" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="grapheme_flags" type="int" />
<description>
Breaks text into words and returns array of character ranges.
</description>
@ -1053,7 +1117,7 @@
Returns [code]true[/code] if buffer is successfully shaped.
</description>
</method>
<method name="shaped_text_next_grapheme_pos">
<method name="shaped_text_next_grapheme_pos" qualifiers="const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="pos" type="int" />
@ -1070,7 +1134,7 @@
Trims text if it exceeds the given width.
</description>
</method>
<method name="shaped_text_prev_grapheme_pos">
<method name="shaped_text_prev_grapheme_pos" qualifiers="const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="pos" type="int" />
@ -1139,6 +1203,13 @@
Note: It is not necessary to call this function manually, buffer will be shaped automatically as soon as any of its output data is requested.
</description>
</method>
<method name="shaped_text_sort_logical">
<return type="Array" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns text glyphs in the logical order.
</description>
</method>
<method name="shaped_text_substr" qualifiers="const">
<return type="RID" />
<argument index="0" name="shaped" type="RID" />
@ -1196,18 +1267,24 @@
<constant name="JUSTIFICATION_AFTER_LAST_TAB" value="8" enum="JustificationFlag">
Only apply justification to the part of the text after the last tab.
</constant>
<constant name="JUSTIFICATION_CONSTRAIN_ELLIPSIS" value="16" enum="JustificationFlag">
Apply justification to the trimmed line with ellipsis.
</constant>
<constant name="BREAK_NONE" value="0" enum="LineBreakFlag">
Do not break the line.
</constant>
<constant name="BREAK_MANDATORY" value="16" enum="LineBreakFlag">
<constant name="BREAK_MANDATORY" value="32" enum="LineBreakFlag">
Break the line at the line mandatory break characters (e.g. [code]"\n"[/code]).
</constant>
<constant name="BREAK_WORD_BOUND" value="32" enum="LineBreakFlag">
<constant name="BREAK_WORD_BOUND" value="64" enum="LineBreakFlag">
Break the line between the words.
</constant>
<constant name="BREAK_GRAPHEME_BOUND" value="64" enum="LineBreakFlag">
<constant name="BREAK_GRAPHEME_BOUND" value="128" enum="LineBreakFlag">
Break the line between any unconnected graphemes.
</constant>
<constant name="BREAK_WORD_BOUND_ADAPTIVE" value="320" enum="LineBreakFlag">
Break the line between the words, or any unconnected graphemes if line is too short to fit the whole word.
</constant>
<constant name="OVERRUN_NO_TRIMMING" value="0" enum="TextOverrunFlag">
No trimming is performed.
</constant>
@ -1223,6 +1300,11 @@
<constant name="OVERRUN_ENFORCE_ELLIPSIS" value="8" enum="TextOverrunFlag">
Determines whether the ellipsis at the end of the text is enforced and may not be hidden.
</constant>
<constant name="OVERRUN_JUSTIFICATION_AWARE" value="16" enum="TextOverrunFlag">
</constant>
<constant name="GRAPHEME_IS_VALID" value="1" enum="GraphemeFlag">
Grapheme is supprted by the font, and can be drawn.
</constant>
<constant name="GRAPHEME_IS_RTL" value="2" enum="GraphemeFlag">
Grapheme is part of right-to-left or bottom-to-top run.
</constant>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,13 @@
<tutorials>
</tutorials>
<methods>
<method name="add_interface">
<return type="void" />
<argument index="0" name="interface" type="TextServer" />
<description>
Registers an [TextServer] interface.
</description>
</method>
<method name="find_interface" qualifiers="const">
<return type="TextServer" />
<argument index="0" name="name" type="String" />
@ -19,7 +26,7 @@
</method>
<method name="get_interface" qualifiers="const">
<return type="TextServer" />
<argument index="0" name="index" type="int" />
<argument index="0" name="idx" type="int" />
<description>
Returns the interface registered at a given index.
</description>
@ -30,20 +37,6 @@
Returns the number of interfaces currently registered.
</description>
</method>
<method name="get_interface_features" qualifiers="const">
<return type="int" />
<argument index="0" name="index" type="int" />
<description>
Returns text server supported features (binary OR).
</description>
</method>
<method name="get_interface_name" qualifiers="const">
<return type="String" />
<argument index="0" name="index" type="int" />
<description>
Returns the interface name registered at a given index.
</description>
</method>
<method name="get_interfaces" qualifiers="const">
<return type="Array" />
<description>
@ -53,15 +46,36 @@
<method name="get_primary_interface" qualifiers="const">
<return type="TextServer" />
<description>
Returns the primary [TextServer] interface.
Returns the primary [TextServer] interface currently in use.
</description>
</method>
<method name="remove_interface">
<return type="void" />
<argument index="0" name="interface" type="TextServer" />
<description>
Removes interface. All fonts and shaped text caches should be freed before removing interface.
</description>
</method>
<method name="set_primary_interface">
<return type="bool" />
<argument index="0" name="index" type="int" />
<return type="void" />
<argument index="0" name="index" type="TextServer" />
<description>
Sets (and initializes it if required) interface registered at a given index as the primary. Invalidates all references to the fonts and text buffers.
Sets the primary [TextServer] interface.
</description>
</method>
</methods>
<signals>
<signal name="interface_added">
<argument index="0" name="interface_name" type="StringName" />
<description>
Emitted when a new interface has been added.
</description>
</signal>
<signal name="interface_removed">
<argument index="0" name="interface_name" type="StringName" />
<description>
Emitted when an interface is removed.
</description>
</signal>
</signals>
</class>

View File

@ -330,9 +330,8 @@ void EditorSpinSlider::_draw_spin_slider() {
float text_start = rtl ? Math::round(sb->get_offset().x) : Math::round(sb->get_offset().x + label_width + sep);
Vector2 text_ofs = rtl ? Vector2(text_start + (number_width - TS->shaped_text_get_width(num_rid)), vofs) : Vector2(text_start, vofs);
const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(num_rid);
int v_size = visual.size();
const TextServer::Glyph *glyphs = visual.ptr();
int v_size = TS->shaped_text_get_glyph_count(num_rid);
const Glyph *glyphs = TS->shaped_text_get_glyphs(num_rid);
for (int i = 0; i < v_size; i++) {
for (int j = 0; j < glyphs[i].repeat; j++) {
if (text_ofs.x >= text_start && (text_ofs.x + glyphs[i].advance) <= (text_start + number_width)) {

View File

@ -1011,9 +1011,10 @@ void DynamicFontImportSettings::_glyph_text_selected() {
if (text_rid.is_valid()) {
TS->shaped_text_add_string(text_rid, text_edit->get_text(), font_main->get_rids(), 16, ftrs, text_edit->get_language());
TS->shaped_text_shape(text_rid);
const Vector<TextServer::Glyph> &gl = TS->shaped_text_get_glyphs(text_rid);
const Glyph *gl = TS->shaped_text_get_glyphs(text_rid);
const int gl_size = TS->shaped_text_get_glyph_count(text_rid);
for (int i = 0; i < gl.size(); i++) {
for (int i = 0; i < gl_size; i++) {
if (gl[i].font_rid.is_valid() && gl[i].index != 0) {
selected_glyphs.insert(gl[i].index);
}

View File

@ -407,6 +407,7 @@ Error Main::test_setup() {
GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2);
translation_server = memnew(TranslationServer);
tsman = memnew(TextServerManager);
register_core_extensions();
@ -440,6 +441,9 @@ Error Main::test_setup() {
register_module_types();
register_driver_types();
ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE);
TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(0));
ClassDB::set_current_api(ClassDB::API_NONE);
_start_success = true;
@ -459,6 +463,7 @@ void Main::test_cleanup() {
#ifdef TOOLS_ENABLED
EditorNode::unregister_editor_types();
#endif
unregister_module_types();
unregister_platform_apis();
unregister_scene_types();
@ -469,6 +474,9 @@ void Main::test_cleanup() {
if (translation_server) {
memdelete(translation_server);
}
if (tsman) {
memdelete(tsman);
}
if (globals) {
memdelete(globals);
}
@ -1461,6 +1469,8 @@ error:
}
Error Main::setup2(Thread::ID p_main_tid_override) {
tsman = memnew(TextServerManager);
preregister_module_types();
preregister_server_types();
@ -1479,64 +1489,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
}
#endif
/* Determine text driver */
if (text_driver == "") {
text_driver = GLOBAL_GET("internationalization/rendering/text_driver");
}
if (text_driver != "") {
/* Load user selected text server. */
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
if (text_driver == TextServerManager::get_interface_name(i)) {
text_driver_idx = i;
break;
}
}
}
if (text_driver_idx < 0) {
/* If not selected, use one with the most features available. */
int max_features = 0;
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
uint32_t ftrs = TextServerManager::get_interface_features(i);
int features = 0;
while (ftrs) {
features += ftrs & 1;
ftrs >>= 1;
}
if (features >= max_features) {
max_features = features;
text_driver_idx = i;
}
}
}
print_verbose("Using \"" + TextServerManager::get_interface_name(text_driver_idx) + "\" text server...");
/* Initialize Text Server */
{
tsman = memnew(TextServerManager);
Error err;
TextServer *text_server = TextServerManager::initialize(text_driver_idx, err);
if (err != OK || text_server == nullptr) {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
if (i == text_driver_idx) {
continue; //don't try the same twice
}
text_server = TextServerManager::initialize(i, err);
if (err == OK && text_server != nullptr) {
break;
}
}
}
if (err != OK || text_server == nullptr) {
ERR_PRINT("Unable to create TextServer, all text drivers failed.");
return err;
}
}
/* Initialize Input */
input = memnew(Input);
@ -1781,6 +1733,57 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
ResourceLoader::load_path_remaps();
MAIN_PRINT("Main: Load TextServer");
/* Enum text drivers */
GLOBAL_DEF("internationalization/rendering/text_driver", "");
String text_driver_options;
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
if (i > 0) {
text_driver_options += ",";
}
text_driver_options += TextServerManager::get_singleton()->get_interface(i)->get_name();
}
ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options));
/* Determine text driver */
if (text_driver == "") {
text_driver = GLOBAL_GET("internationalization/rendering/text_driver");
}
if (text_driver != "") {
/* Load user selected text server. */
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
if (TextServerManager::get_singleton()->get_interface(i)->get_name() == text_driver) {
text_driver_idx = i;
break;
}
}
}
if (text_driver_idx < 0) {
/* If not selected, use one with the most features available. */
int max_features = 0;
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
uint32_t features = TextServerManager::get_singleton()->get_interface(i)->get_features();
int feature_number = 0;
while (features) {
feature_number += features & 1;
features >>= 1;
}
if (feature_number >= max_features) {
max_features = feature_number;
text_driver_idx = i;
}
}
}
if (text_driver_idx >= 0) {
TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(text_driver_idx));
} else {
ERR_PRINT("TextServer: Unable to create TextServer interface.");
return ERR_CANT_CREATE;
}
MAIN_PRINT("Main: Load Scene Types");
register_scene_types();
@ -1793,7 +1796,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
#endif
MAIN_PRINT("Main: Load Modules, Physics, Drivers, Scripts");
MAIN_PRINT("Main: Load Modules");
register_platform_apis();
register_module_types();
@ -1817,6 +1820,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
camera_server = CameraServer::create();
MAIN_PRINT("Main: Load Physics, Drivers, Scripts");
initialize_physics();
initialize_navigation_server();
register_server_singletons();
@ -2728,10 +2733,6 @@ void Main::cleanup(bool p_force) {
finalize_navigation_server();
finalize_display();
if (tsman) {
memdelete(tsman);
}
if (input) {
memdelete(input);
}
@ -2754,6 +2755,9 @@ void Main::cleanup(bool p_force) {
if (translation_server) {
memdelete(translation_server);
}
if (tsman) {
memdelete(tsman);
}
if (globals) {
memdelete(globals);
}

View File

@ -18,7 +18,6 @@ Export("env_gdnative")
SConscript("pluginscript/SCsub")
SConscript("videodecoder/SCsub")
SConscript("text/SCsub")
import gdnative_builders

View File

@ -5103,489 +5103,6 @@
]
}
]
},
{
"name": "text",
"type": "TEXT",
"version": {
"major": 1,
"minor": 0
},
"next": null,
"api": [
{
"name": "godot_text_register_interface",
"return_type": "void",
"arguments": [
[
"const godot_text_interface_gdnative *",
"p_interface"
],
[
"const godot_string *",
"p_name"
],
[
"uint32_t",
"p_features"
]
]
},
{
"name": "godot_glyph_new",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"r_dest"
]
]
},
{
"name": "godot_glyph_get_range",
"return_type": "godot_vector2i",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_range",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"const godot_vector2i *",
"p_range"
]
]
},
{
"name": "godot_glyph_get_count",
"return_type": "godot_int",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_count",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"godot_int",
"p_count"
]
]
},
{
"name": "godot_glyph_get_repeat",
"return_type": "godot_int",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_repeat",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"godot_int",
"p_repeat"
]
]
},
{
"name": "godot_glyph_get_flags",
"return_type": "godot_int",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_flags",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"godot_int",
"p_flags"
]
]
},
{
"name": "godot_glyph_get_offset",
"return_type": "godot_vector2",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_offset",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"const godot_vector2 *",
"p_offset"
]
]
},
{
"name": "godot_glyph_get_advance",
"return_type": "godot_real_t",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_advance",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"godot_real_t",
"p_advance"
]
]
},
{
"name": "godot_glyph_get_font",
"return_type": "godot_rid",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_font",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"godot_rid *",
"p_font"
]
]
},
{
"name": "godot_glyph_get_font_size",
"return_type": "godot_int",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_font_size",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"godot_int",
"p_size"
]
]
},
{
"name": "godot_glyph_get_index",
"return_type": "godot_int",
"arguments": [
[
"const godot_glyph *",
"p_self"
]
]
},
{
"name": "godot_glyph_set_index",
"return_type": "void",
"arguments": [
[
"godot_glyph *",
"p_self"
],
[
"godot_int",
"p_index"
]
]
},
{
"name": "godot_packed_glyph_array_new",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"r_dest"
]
]
},
{
"name": "godot_packed_glyph_array_new_copy",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"r_dest"
],
[
"const godot_packed_glyph_array *",
"p_src"
]
]
},
{
"name": "godot_packed_glyph_array_is_empty",
"return_type": "godot_bool",
"arguments": [
[
"const godot_packed_glyph_array *",
"p_self"
]
]
},
{
"name": "godot_packed_glyph_array_append",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_glyph *",
"p_data"
]
]
},
{
"name": "godot_packed_glyph_array_append_array",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_packed_glyph_array *",
"p_array"
]
]
},
{
"name": "godot_packed_glyph_array_insert",
"return_type": "godot_error",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_int",
"p_idx"
],
[
"const godot_glyph *",
"p_data"
]
]
},
{
"name": "godot_packed_glyph_array_has",
"return_type": "godot_bool",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_glyph *",
"p_value"
]
]
},
{
"name": "godot_packed_glyph_array_sort",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
]
]
},
{
"name": "godot_packed_glyph_array_reverse",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
]
]
},
{
"name": "godot_packed_glyph_array_push_back",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_glyph *",
"p_data"
]
]
},
{
"name": "godot_packed_glyph_array_remove",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_int",
"p_idx"
]
]
},
{
"name": "godot_packed_glyph_array_resize",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_int",
"p_size"
]
]
},
{
"name": "godot_packed_glyph_array_ptr",
"return_type": "const godot_glyph *",
"arguments": [
[
"const godot_packed_glyph_array *",
"p_self"
]
]
},
{
"name": "godot_packed_glyph_array_ptrw",
"return_type": "godot_glyph *",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
]
]
},
{
"name": "godot_packed_glyph_array_set",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
],
[
"const godot_int",
"p_idx"
],
[
"const godot_glyph *",
"p_data"
]
]
},
{
"name": "godot_packed_glyph_array_get",
"return_type": "godot_glyph",
"arguments": [
[
"const godot_packed_glyph_array *",
"p_self"
],
[
"const godot_int",
"p_idx"
]
]
},
{
"name": "godot_packed_glyph_array_size",
"return_type": "godot_int",
"arguments": [
[
"const godot_packed_glyph_array *",
"p_self"
]
]
},
{
"name": "godot_packed_glyph_array_destroy",
"return_type": "void",
"arguments": [
[
"godot_packed_glyph_array *",
"p_self"
]
]
}
]
}
]
}

View File

@ -22,7 +22,6 @@ def _build_gdnative_api_struct_header(api):
"#include <nativescript/godot_nativescript.h>",
"#include <pluginscript/godot_pluginscript.h>",
"#include <videodecoder/godot_videodecoder.h>",
"#include <text/godot_text.h>",
"",
"#ifdef __cplusplus",
'extern "C" {',

View File

@ -1,283 +0,0 @@
/*************************************************************************/
/* godot_text.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef GODOT_NATIVETEXT_H
#define GODOT_NATIVETEXT_H
#include <gdnative/gdnative.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GODOT_TEXT_API_MAJOR 1
#define GODOT_TEXT_API_MINOR 0
#define GODOT_GLYPH_SIZE 40
#ifndef GODOT_TEXT_API_GODOT_GLYPH_TYPE_DEFINED
#define GODOT_TEXT_API_GODOT_GLYPH_TYPE_DEFINED
typedef struct {
uint8_t _dont_touch_that[GODOT_GLYPH_SIZE];
} godot_glyph;
#endif
#define GODOT_PACKED_GLYPH_ARRAY_SIZE (2 * sizeof(void *))
#ifndef GODOT_TEXT_API_GODOT_PACKED_GLYPH_ARRAY_TYPE_DEFINED
#define GODOT_TEXT_API_GODOT_PACKED_GLYPH_ARRAY_TYPE_DEFINED
typedef struct {
uint8_t _dont_touch_that[GODOT_PACKED_GLYPH_ARRAY_SIZE];
} godot_packed_glyph_array;
#endif
typedef struct {
godot_gdnative_api_version version;
void *(*constructor)(godot_object *);
void (*destructor)(void *);
godot_string (*get_name)(const void *);
godot_bool (*has_feature)(const void *, godot_int);
void (*free)(void *, godot_rid *);
bool (*has)(void *, godot_rid *);
bool (*load_support_data)(void *, const godot_string *);
godot_string (*get_support_data_filename)(const void *);
godot_string (*get_support_data_info)(const void *);
bool (*save_support_data)(void *, const godot_string *);
bool (*is_locale_right_to_left)(void *, const godot_string *);
int32_t (*name_to_tag)(const void *, const godot_string *);
godot_string (*tag_to_name)(const void *, int32_t);
godot_rid (*create_font)(void *);
void (*font_set_data)(void *, godot_rid *, const godot_packed_byte_array *);
void (*font_set_data_ptr)(void *, godot_rid *, const uint8_t *, size_t);
void (*font_set_antialiased)(void *, godot_rid *, bool);
bool (*font_is_antialiased)(const void *, godot_rid *);
void (*font_set_multichannel_signed_distance_field)(void *, godot_rid *, bool);
bool (*font_is_multichannel_signed_distance_field)(const void *, godot_rid *);
void (*font_set_msdf_pixel_range)(void *, godot_rid *, godot_int);
godot_int (*font_get_msdf_pixel_range)(const void *, godot_rid *);
void (*font_set_msdf_size)(void *, godot_rid *, godot_int);
godot_int (*font_get_msdf_size)(const void *, godot_rid *);
void (*font_set_fixed_size)(void *, godot_rid *, godot_int);
godot_int (*font_get_fixed_size)(const void *, godot_rid *);
void (*font_set_force_autohinter)(void *, godot_rid *, bool);
bool (*font_is_force_autohinter)(const void *, godot_rid *);
void (*font_set_hinting)(void *, godot_rid *, godot_int);
godot_int (*font_get_hinting)(const void *, godot_rid *);
void (*font_set_variation_coordinates)(void *, godot_rid *, const godot_dictionary *);
godot_dictionary (*font_get_variation_coordinates)(const void *, godot_rid *);
void (*font_set_oversampling)(void *, godot_rid *, godot_real_t);
godot_real_t (*font_get_oversampling)(const void *, godot_rid *);
godot_array (*font_get_size_cache_list)(const void *, godot_rid *);
void (*font_clear_size_cache)(void *, godot_rid *);
void (*font_remove_size_cache)(void *, godot_rid *, const godot_vector2i *);
void (*font_set_ascent)(void *, godot_rid *, godot_int, godot_real_t);
godot_real_t (*font_get_ascent)(const void *, godot_rid *, godot_int);
void (*font_set_descent)(void *, godot_rid *, godot_int, godot_real_t);
godot_real_t (*font_get_descent)(const void *, godot_rid *, godot_int);
void (*font_set_underline_position)(void *, godot_rid *, godot_int, godot_real_t);
godot_real_t (*font_get_underline_position)(const void *, godot_rid *, godot_int);
void (*font_set_underline_thickness)(void *, godot_rid *, godot_int, godot_real_t);
godot_real_t (*font_get_underline_thickness)(const void *, godot_rid *, godot_int);
void (*font_set_scale)(void *, godot_rid *, godot_int, godot_real_t);
godot_real_t (*font_get_scale)(const void *, godot_rid *, godot_int);
void (*font_set_spacing)(void *, godot_rid *, godot_int, godot_int, godot_int);
godot_int (*font_get_spacing)(const void *, godot_rid *, godot_int, godot_int);
godot_int (*font_get_texture_count)(const void *, godot_rid *, const godot_vector2i *);
void (*font_clear_textures)(void *, godot_rid *, const godot_vector2i *);
void (*font_remove_texture)(void *, godot_rid *, const godot_vector2i *, godot_int);
void (*font_set_texture_image)(void *, godot_rid *, const godot_vector2i *, godot_int, const godot_object *);
godot_object *(*font_get_texture_image)(const void *, godot_rid *, const godot_vector2i *, godot_int);
void (*font_set_texture_offsets)(void *, godot_rid *, const godot_vector2i *, godot_int, const godot_packed_int32_array *);
godot_packed_int32_array (*font_get_texture_offsets)(const void *, godot_rid *, const godot_vector2i *, godot_int);
godot_array (*font_get_glyph_list)(const void *, godot_rid *, const godot_vector2i *);
void (*font_clear_glyphs)(void *, godot_rid *, const godot_vector2i *);
void (*font_remove_glyph)(void *, godot_rid *, const godot_vector2i *, int32_t);
godot_vector2 (*font_get_glyph_advance)(const void *, godot_rid *, godot_int, int32_t);
void (*font_set_glyph_advance)(void *, godot_rid *, godot_int, int32_t, const godot_vector2 *);
godot_vector2 (*font_get_glyph_offset)(const void *, godot_rid *, const godot_vector2i *, int32_t);
void (*font_set_glyph_offset)(void *, godot_rid *, const godot_vector2i *, int32_t, const godot_vector2 *);
godot_vector2 (*font_get_glyph_size)(const void *, godot_rid *, const godot_vector2i *, int32_t);
void (*font_set_glyph_size)(void *, godot_rid *, const godot_vector2i *, int32_t, const godot_vector2 *);
godot_rect2 (*font_get_glyph_uv_rect)(const void *, godot_rid *, const godot_vector2i *, int32_t);
void (*font_set_glyph_uv_rect)(void *, godot_rid *, const godot_vector2i *, int32_t, const godot_rect2 *);
godot_int (*font_get_glyph_texture_idx)(const void *, godot_rid *, const godot_vector2i *, int32_t);
void (*font_set_glyph_texture_idx)(void *, godot_rid *, const godot_vector2i *, int32_t, godot_int);
bool (*font_get_glyph_contours)(const void *, godot_rid *, godot_int, int32_t, godot_packed_vector3_array *, godot_packed_int32_array *, bool *);
godot_array (*font_get_kerning_list)(const void *, godot_rid *, godot_int);
void (*font_clear_kerning_map)(void *, godot_rid *, godot_int);
void (*font_remove_kerning)(void *, godot_rid *, godot_int, const godot_vector2i *);
void (*font_set_kerning)(void *, godot_rid *, godot_int, const godot_vector2i *, const godot_vector2 *);
godot_vector2 (*font_get_kerning)(const void *, godot_rid *, godot_int, const godot_vector2i *);
int32_t (*font_get_glyph_index)(const void *, godot_rid *, godot_int, char32_t, char32_t);
bool (*font_has_char)(const void *, godot_rid *, char32_t);
godot_string (*font_get_supported_chars)(const void *, godot_rid *);
void (*font_render_range)(void *, godot_rid *, const godot_vector2i *, char32_t, char32_t);
void (*font_render_glyph)(void *, godot_rid *, const godot_vector2i *, int32_t);
void (*font_draw_glyph)(const void *, godot_rid *, godot_rid *, godot_int, const godot_vector2 *, int32_t, const godot_color *);
void (*font_draw_glyph_outline)(const void *, godot_rid *, godot_rid *, godot_int, godot_int, const godot_vector2 *, int32_t, const godot_color *);
bool (*font_is_language_supported)(const void *, godot_rid *, const godot_string *);
void (*font_set_language_support_override)(void *, godot_rid *, const godot_string *, bool);
bool (*font_get_language_support_override)(const void *, godot_rid *, const godot_string *);
void (*font_remove_language_support_override)(void *, godot_rid *, const godot_string *);
godot_packed_string_array (*font_get_language_support_overrides)(const void *, godot_rid *);
bool (*font_is_script_supported)(const void *, godot_rid *, const godot_string *);
void (*font_set_script_support_override)(void *, godot_rid *, const godot_string *, bool);
bool (*font_get_script_support_override)(const void *, godot_rid *, const godot_string *);
void (*font_remove_script_support_override)(void *, godot_rid *, const godot_string *);
godot_packed_string_array (*font_get_script_support_overrides)(const void *, godot_rid *);
godot_dictionary (*font_supported_feature_list)(const void *, godot_rid *);
godot_dictionary (*font_supported_variation_list)(const void *, godot_rid *);
godot_real_t (*font_get_global_oversampling)(const void *);
void (*font_set_global_oversampling)(void *, godot_real_t);
godot_rid (*create_shaped_text)(void *, godot_int, godot_int);
void (*shaped_text_clear)(void *, godot_rid *);
void (*shaped_text_set_direction)(void *, godot_rid *, godot_int);
godot_int (*shaped_text_get_direction)(void *, godot_rid *);
void (*shaped_text_set_bidi_override)(void *, godot_rid *, const godot_packed_vector2i_array *);
void (*shaped_text_set_orientation)(void *, godot_rid *, godot_int);
godot_int (*shaped_text_get_orientation)(void *, godot_rid *);
void (*shaped_text_set_preserve_invalid)(void *, godot_rid *, bool);
bool (*shaped_text_get_preserve_invalid)(void *, godot_rid *);
void (*shaped_text_set_preserve_control)(void *, godot_rid *, bool);
bool (*shaped_text_get_preserve_control)(void *, godot_rid *);
bool (*shaped_text_add_string)(void *, godot_rid *, const godot_string *, const godot_rid **, int, const godot_dictionary *, const godot_string *);
bool (*shaped_text_add_object)(void *, godot_rid *, const godot_variant *, const godot_vector2 *, godot_int, godot_int);
bool (*shaped_text_resize_object)(void *, godot_rid *, const godot_variant *, const godot_vector2 *, godot_int);
godot_rid (*shaped_text_substr)(void *, godot_rid *, godot_int, godot_int);
godot_rid (*shaped_text_get_parent)(void *, godot_rid *);
godot_real_t (*shaped_text_fit_to_width)(void *, godot_rid *, godot_real_t, uint8_t);
godot_real_t (*shaped_text_tab_align)(void *, godot_rid *, godot_packed_float32_array *);
bool (*shaped_text_shape)(void *, godot_rid *);
bool (*shaped_text_update_breaks)(void *, godot_rid *);
bool (*shaped_text_update_justification_ops)(void *, godot_rid *);
void (*shaped_text_overrun_trim_to_width)(void *, godot_rid *, godot_real_t, uint8_t);
bool (*shaped_text_is_ready)(void *, godot_rid *);
godot_packed_glyph_array (*shaped_text_get_glyphs)(void *, godot_rid *);
godot_vector2i (*shaped_text_get_range)(void *, godot_rid *);
godot_packed_glyph_array (*shaped_text_sort_logical)(void *, godot_rid *);
godot_packed_vector2i_array (*shaped_text_get_line_breaks_adv)(void *, godot_rid *, godot_packed_float32_array *, int, bool, uint8_t);
godot_packed_vector2i_array (*shaped_text_get_line_breaks)(void *, godot_rid *, godot_real_t, int, uint8_t);
godot_packed_vector2i_array (*shaped_text_get_word_breaks)(void *, godot_rid *, int);
godot_array (*shaped_text_get_objects)(void *, godot_rid *);
godot_rect2 (*shaped_text_get_object_rect)(void *, godot_rid *, const godot_variant *);
godot_vector2 (*shaped_text_get_size)(void *, godot_rid *);
godot_real_t (*shaped_text_get_ascent)(void *, godot_rid *);
godot_real_t (*shaped_text_get_descent)(void *, godot_rid *);
godot_real_t (*shaped_text_get_width)(void *, godot_rid *);
godot_real_t (*shaped_text_get_underline_position)(void *, godot_rid *);
godot_real_t (*shaped_text_get_underline_thickness)(void *, godot_rid *);
godot_string (*format_number)(void *, const godot_string *, const godot_string *);
godot_string (*parse_number)(void *, const godot_string *, const godot_string *);
godot_string (*percent_sign)(void *, const godot_string *);
} godot_text_interface_gdnative;
void GDAPI godot_text_register_interface(const godot_text_interface_gdnative *p_interface, const godot_string *p_name, uint32_t p_features);
// Glyph
void GDAPI godot_glyph_new(godot_glyph *r_dest);
godot_vector2i GDAPI godot_glyph_get_range(const godot_glyph *p_self);
void GDAPI godot_glyph_set_range(godot_glyph *p_self, const godot_vector2i *p_range);
godot_int GDAPI godot_glyph_get_count(const godot_glyph *p_self);
void GDAPI godot_glyph_set_count(godot_glyph *p_self, godot_int p_count);
godot_int GDAPI godot_glyph_get_repeat(const godot_glyph *p_self);
void GDAPI godot_glyph_set_repeat(godot_glyph *p_self, godot_int p_repeat);
godot_int GDAPI godot_glyph_get_flags(const godot_glyph *p_self);
void GDAPI godot_glyph_set_flags(godot_glyph *p_self, godot_int p_flags);
godot_vector2 GDAPI godot_glyph_get_offset(const godot_glyph *p_self);
void GDAPI godot_glyph_set_offset(godot_glyph *p_self, const godot_vector2 *p_offset);
godot_real_t GDAPI godot_glyph_get_advance(const godot_glyph *p_self);
void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_real_t p_advance);
godot_rid GDAPI godot_glyph_get_font(const godot_glyph *p_self);
void GDAPI godot_glyph_set_font(godot_glyph *p_self, godot_rid *p_font);
godot_int GDAPI godot_glyph_get_font_size(const godot_glyph *p_self);
void GDAPI godot_glyph_set_font_size(godot_glyph *p_self, godot_int p_size);
godot_int GDAPI godot_glyph_get_index(const godot_glyph *p_self);
void GDAPI godot_glyph_set_index(godot_glyph *p_self, godot_int p_index);
// GlyphArray
void GDAPI godot_packed_glyph_array_new(godot_packed_glyph_array *r_dest);
void GDAPI godot_packed_glyph_array_new_copy(godot_packed_glyph_array *r_dest, const godot_packed_glyph_array *p_src);
const godot_glyph GDAPI *godot_packed_glyph_array_ptr(const godot_packed_glyph_array *p_self);
godot_glyph GDAPI *godot_packed_glyph_array_ptrw(godot_packed_glyph_array *p_self);
void GDAPI godot_packed_glyph_array_append(godot_packed_glyph_array *p_self, const godot_glyph *p_data);
void GDAPI godot_packed_glyph_array_append_array(godot_packed_glyph_array *p_self, const godot_packed_glyph_array *p_array);
godot_error GDAPI godot_packed_glyph_array_insert(godot_packed_glyph_array *p_self, const godot_int p_idx, const godot_glyph *p_data);
godot_bool GDAPI godot_packed_glyph_array_has(godot_packed_glyph_array *p_self, const godot_glyph *p_value);
void GDAPI godot_packed_glyph_array_sort(godot_packed_glyph_array *p_self);
void GDAPI godot_packed_glyph_array_reverse(godot_packed_glyph_array *p_self);
void GDAPI godot_packed_glyph_array_push_back(godot_packed_glyph_array *p_self, const godot_glyph *p_data);
void GDAPI godot_packed_glyph_array_remove(godot_packed_glyph_array *p_self, godot_int p_idx);
void GDAPI godot_packed_glyph_array_resize(godot_packed_glyph_array *p_self, godot_int p_size);
void GDAPI godot_packed_glyph_array_set(godot_packed_glyph_array *p_self, godot_int p_idx, const godot_glyph *p_data);
godot_glyph GDAPI godot_packed_glyph_array_get(const godot_packed_glyph_array *p_self, godot_int p_idx);
godot_int GDAPI godot_packed_glyph_array_size(const godot_packed_glyph_array *p_self);
godot_bool GDAPI godot_packed_glyph_array_is_empty(const godot_packed_glyph_array *p_self);
void GDAPI godot_packed_glyph_array_destroy(godot_packed_glyph_array *p_self);
// Grapheme
#ifdef __cplusplus
}
#endif
#endif /* !GODOT_NATIVETEXT_H */

View File

@ -1,6 +0,0 @@
#!/usr/bin/env python
Import("env")
Import("env_gdnative")
env_gdnative.add_source_files(env.modules_sources, "*.cpp")

View File

@ -1,6 +0,0 @@
def can_build(env, platform):
return True
def configure(env):
pass

View File

@ -1,36 +0,0 @@
/*************************************************************************/
/* register_types.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_types.h"
#include "text_server_gdnative.h"
void register_text_server_gdn_types() {}
void unregister_text_server_gdn_types() {}

View File

@ -1,37 +0,0 @@
/*************************************************************************/
/* register_types.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEXT_REGISTER_TYPES_H
#define TEXT_REGISTER_TYPES_H
void register_text_server_gdn_types();
void unregister_text_server_gdn_types();
#endif // TEXT_REGISTER_TYPES_H

File diff suppressed because it is too large Load Diff

View File

@ -1,254 +0,0 @@
/*************************************************************************/
/* text_server_gdnative.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEXT_SERVER_GDNATIVE_H
#define TEXT_SERVER_GDNATIVE_H
#include "modules/gdnative/gdnative.h"
#include "servers/text_server.h"
class TextServerGDNative : public TextServer {
GDCLASS(TextServerGDNative, TextServer);
const godot_text_interface_gdnative *interface = nullptr;
void *data = nullptr;
protected:
static void _bind_methods(){};
public:
virtual bool has_feature(Feature p_feature) override;
virtual String get_name() const override;
virtual void free(RID p_rid) override;
virtual bool has(RID p_rid) override;
virtual bool load_support_data(const String &p_filename) override;
#ifdef TOOLS_ENABLED
virtual String get_support_data_filename() override;
virtual String get_support_data_info() override;
virtual bool save_support_data(const String &p_filename) override;
#endif
virtual bool is_locale_right_to_left(const String &p_locale) override;
virtual int32_t name_to_tag(const String &p_name) const override;
virtual String tag_to_name(int32_t p_tag) const override;
/* Font interface */
virtual RID create_font() override;
virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override;
virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override;
virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override;
virtual bool font_is_antialiased(RID p_font_rid) const override;
virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) override;
virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const override;
virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) override;
virtual int font_get_msdf_pixel_range(RID p_font_rid) const override;
virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) override;
virtual int font_get_msdf_size(RID p_font_rid) const override;
virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) override;
virtual int font_get_fixed_size(RID p_font_rid) const override;
virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) override;
virtual bool font_is_force_autohinter(RID p_font_rid) const override;
virtual void font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) override;
virtual TextServer::Hinting font_get_hinting(RID p_font_rid) const override;
virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override;
virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override;
virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) override;
virtual real_t font_get_oversampling(RID p_font_rid) const override;
virtual Array font_get_size_cache_list(RID p_font_rid) const override;
virtual void font_clear_size_cache(RID p_font_rid) override;
virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override;
virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) override;
virtual real_t font_get_ascent(RID p_font_rid, int p_size) const override;
virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) override;
virtual real_t font_get_descent(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) override;
virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) override;
virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const override;
virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) override;
virtual real_t font_get_scale(RID p_font_rid, int p_size) const override;
virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override;
virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override;
virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) override;
virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) override;
virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override;
virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) override;
virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override;
virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) override;
virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) override;
virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) override;
virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) override;
virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) override;
virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override;
virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override;
virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override;
virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) override;
virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override;
virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const override;
virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector = 0) const override;
virtual bool font_has_char(RID p_font_rid, char32_t p_char) const override;
virtual String font_get_supported_chars(RID p_font_rid) const override;
virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) override;
virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) override;
virtual void font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual void font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const override;
virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) override;
virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) override;
virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) override;
virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) override;
virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const override;
virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) override;
virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) override;
virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override;
virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override;
virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
virtual real_t font_get_global_oversampling() const override;
virtual void font_set_global_oversampling(real_t p_oversampling) override;
/* Shaped text buffer interface */
virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
virtual void shaped_text_clear(RID p_shaped) override;
virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override;
virtual Direction shaped_text_get_direction(RID p_shaped) const override;
virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) override;
virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
virtual Orientation shaped_text_get_orientation(RID p_shaped) const override;
virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const override;
virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_control(RID p_shaped) const override;
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override;
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override;
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) override;
virtual bool shaped_text_shape(RID p_shaped) override;
virtual bool shaped_text_update_breaks(RID p_shaped) override;
virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) override;
virtual bool shaped_text_is_ready(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override;
virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) override;
virtual Vector<Vector2i> shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start = 0, bool p_once = true, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
virtual Vector<Vector2i> shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start = 0, uint8_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override;
virtual Array shaped_text_get_objects(RID p_shaped) const override;
virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override;
virtual Size2 shaped_text_get_size(RID p_shaped) const override;
virtual real_t shaped_text_get_ascent(RID p_shaped) const override;
virtual real_t shaped_text_get_descent(RID p_shaped) const override;
virtual real_t shaped_text_get_width(RID p_shaped) const override;
virtual real_t shaped_text_get_underline_position(RID p_shaped) const override;
virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const override;
virtual String format_number(const String &p_string, const String &p_language = "") const override;
virtual String parse_number(const String &p_string, const String &p_language = "") const override;
virtual String percent_sign(const String &p_language = "") const override;
static TextServer *create_func(Error &r_error, void *p_user_data);
TextServerGDNative();
~TextServerGDNative();
};
#endif // TEXT_SERVER_GDNATIVE_H

View File

@ -4,3 +4,13 @@ def can_build(env, platform):
def configure(env):
pass
def get_doc_classes():
return [
"TextServerAdvanced",
]
def get_doc_path():
return "doc_classes"

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServerAdvanced" inherits="TextServer" version="4.0">
<brief_description>
Text Server using HarfBuzz, ICU and SIL Graphite to support BiDi, complex text layouts and contextual OpenType features.
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
</class>

View File

@ -33,7 +33,12 @@
#include "text_server_adv.h"
void preregister_text_server_adv_types() {
TextServerAdvanced::register_server();
GDREGISTER_CLASS(TextServerAdvanced);
if (TextServerManager::get_singleton()) {
Ref<TextServerAdvanced> ts;
ts.instantiate();
TextServerManager::get_singleton()->add_interface(ts);
}
}
void register_text_server_adv_types() {

View File

@ -322,7 +322,7 @@ _FORCE_INLINE_ bool is_underscore(char32_t p_char) {
String TextServerAdvanced::interface_name = "ICU / HarfBuzz / Graphite";
uint32_t TextServerAdvanced::interface_features = FEATURE_BIDI_LAYOUT | FEATURE_VERTICAL_LAYOUT | FEATURE_SHAPING | FEATURE_KASHIDA_JUSTIFICATION | FEATURE_BREAK_ITERATORS | FEATURE_USE_SUPPORT_DATA | FEATURE_FONT_VARIABLE;
bool TextServerAdvanced::has_feature(Feature p_feature) {
bool TextServerAdvanced::has_feature(Feature p_feature) const {
return (interface_features & p_feature) == p_feature;
}
@ -330,6 +330,10 @@ String TextServerAdvanced::get_name() const {
return interface_name;
}
uint32_t TextServerAdvanced::get_features() const {
return interface_features;
}
void TextServerAdvanced::free(RID p_rid) {
_THREAD_SAFE_METHOD_
if (font_owner.owns(p_rid)) {
@ -394,9 +398,23 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) {
return true;
}
#ifdef TOOLS_ENABLED
String TextServerAdvanced::get_support_data_filename() const {
#ifdef ICU_STATIC_DATA
return _MKSTR(ICU_DATA_NAME);
#else
return String();
#endif
}
bool TextServerAdvanced::save_support_data(const String &p_filename) {
String TextServerAdvanced::get_support_data_info() const {
#ifdef ICU_STATIC_DATA
return String("ICU break iteration data (") + _MKSTR(ICU_DATA_NAME) + String(").");
#else
return String();
#endif
}
bool TextServerAdvanced::save_support_data(const String &p_filename) const {
_THREAD_SAFE_METHOD_
#ifdef ICU_STATIC_DATA
@ -415,9 +433,7 @@ bool TextServerAdvanced::save_support_data(const String &p_filename) {
#endif
}
#endif
bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) {
bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) const {
String l = p_locale.get_slicec('_', 0);
if ((l == "ar") || (l == "dv") || (l == "he") || (l == "fa") || (l == "ff") || (l == "ku") || (l == "ur")) {
return true;
@ -1142,7 +1158,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontDataAdvanced *p_font_d
int error = FT_Load_Glyph(fd->face, p_glyph, flags);
if (error) {
fd->glyph_map[p_glyph] = FontGlyph();
ERR_FAIL_V_MSG(false, "FreeType: Failed to load glyph.");
return false;
}
if (!outline) {
@ -1236,7 +1252,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced
fd->oversampling = 1.0f;
fd->size.x = p_font_data->msdf_source_size;
} else if (p_font_data->oversampling <= 0.0f) {
fd->oversampling = TS->font_get_global_oversampling();
fd->oversampling = font_get_global_oversampling();
} else {
fd->oversampling = p_font_data->oversampling;
}
@ -1244,13 +1260,13 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced
if (FT_HAS_COLOR(fd->face) && fd->face->num_fixed_sizes > 0) {
int best_match = 0;
int diff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[0].width));
fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width;
fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width;
for (int i = 1; i < fd->face->num_fixed_sizes; i++) {
int ndiff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[i].width));
if (ndiff < diff) {
best_match = i;
diff = ndiff;
fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width;
fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width;
}
}
FT_Select_Size(fd->face, best_match);
@ -1786,7 +1802,7 @@ Dictionary TextServerAdvanced::font_get_variation_coordinates(RID p_font_rid) co
return fd->variation_coordinates;
}
void TextServerAdvanced::font_set_oversampling(RID p_font_rid, real_t p_oversampling) {
void TextServerAdvanced::font_set_oversampling(RID p_font_rid, float p_oversampling) {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1797,7 +1813,7 @@ void TextServerAdvanced::font_set_oversampling(RID p_font_rid, real_t p_oversamp
}
}
real_t TextServerAdvanced::font_get_oversampling(RID p_font_rid) const {
float TextServerAdvanced::font_get_oversampling(RID p_font_rid) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1839,7 +1855,7 @@ void TextServerAdvanced::font_remove_size_cache(RID p_font_rid, const Vector2i &
}
}
void TextServerAdvanced::font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) {
void TextServerAdvanced::font_set_ascent(RID p_font_rid, int p_size, float p_ascent) {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1850,7 +1866,7 @@ void TextServerAdvanced::font_set_ascent(RID p_font_rid, int p_size, real_t p_as
fd->cache[size]->ascent = p_ascent;
}
real_t TextServerAdvanced::font_get_ascent(RID p_font_rid, int p_size) const {
float TextServerAdvanced::font_get_ascent(RID p_font_rid, int p_size) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1860,13 +1876,13 @@ real_t TextServerAdvanced::font_get_ascent(RID p_font_rid, int p_size) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->ascent * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->ascent * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->ascent;
}
}
void TextServerAdvanced::font_set_descent(RID p_font_rid, int p_size, real_t p_descent) {
void TextServerAdvanced::font_set_descent(RID p_font_rid, int p_size, float p_descent) {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1876,7 +1892,7 @@ void TextServerAdvanced::font_set_descent(RID p_font_rid, int p_size, real_t p_d
fd->cache[size]->descent = p_descent;
}
real_t TextServerAdvanced::font_get_descent(RID p_font_rid, int p_size) const {
float TextServerAdvanced::font_get_descent(RID p_font_rid, int p_size) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1886,13 +1902,13 @@ real_t TextServerAdvanced::font_get_descent(RID p_font_rid, int p_size) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->descent * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->descent * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->descent;
}
}
void TextServerAdvanced::font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) {
void TextServerAdvanced::font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1903,7 +1919,7 @@ void TextServerAdvanced::font_set_underline_position(RID p_font_rid, int p_size,
fd->cache[size]->underline_position = p_underline_position;
}
real_t TextServerAdvanced::font_get_underline_position(RID p_font_rid, int p_size) const {
float TextServerAdvanced::font_get_underline_position(RID p_font_rid, int p_size) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1913,13 +1929,13 @@ real_t TextServerAdvanced::font_get_underline_position(RID p_font_rid, int p_siz
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->underline_position * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->underline_position * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->underline_position;
}
}
void TextServerAdvanced::font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) {
void TextServerAdvanced::font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1930,7 +1946,7 @@ void TextServerAdvanced::font_set_underline_thickness(RID p_font_rid, int p_size
fd->cache[size]->underline_thickness = p_underline_thickness;
}
real_t TextServerAdvanced::font_get_underline_thickness(RID p_font_rid, int p_size) const {
float TextServerAdvanced::font_get_underline_thickness(RID p_font_rid, int p_size) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1940,13 +1956,13 @@ real_t TextServerAdvanced::font_get_underline_thickness(RID p_font_rid, int p_si
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->underline_thickness * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->underline_thickness * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->underline_thickness;
}
}
void TextServerAdvanced::font_set_scale(RID p_font_rid, int p_size, real_t p_scale) {
void TextServerAdvanced::font_set_scale(RID p_font_rid, int p_size, float p_scale) {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1957,7 +1973,7 @@ void TextServerAdvanced::font_set_scale(RID p_font_rid, int p_size, real_t p_sca
fd->cache[size]->scale = p_scale;
}
real_t TextServerAdvanced::font_get_scale(RID p_font_rid, int p_size) const {
float TextServerAdvanced::font_get_scale(RID p_font_rid, int p_size) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1967,7 +1983,7 @@ real_t TextServerAdvanced::font_get_scale(RID p_font_rid, int p_size) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->scale * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->scale * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->scale / fd->cache[size]->oversampling;
}
@ -2006,14 +2022,14 @@ int TextServerAdvanced::font_get_spacing(RID p_font_rid, int p_size, TextServer:
switch (p_spacing) {
case TextServer::SPACING_GLYPH: {
if (fd->msdf) {
return fd->cache[size]->spacing_glyph * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->spacing_glyph * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->spacing_glyph;
}
} break;
case TextServer::SPACING_SPACE: {
if (fd->msdf) {
return fd->cache[size]->spacing_space * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->spacing_space * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->spacing_space;
}
@ -2182,7 +2198,7 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(RID p_font_rid, int p_size, i
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
if (fd->msdf) {
return gl[p_glyph].advance * (real_t)p_size / (real_t)fd->msdf_source_size;
return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size;
} else {
return gl[p_glyph].advance;
}
@ -2218,7 +2234,7 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(RID p_font_rid, const Vector2i
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
if (fd->msdf) {
return gl[p_glyph].rect.position * (real_t)p_size.x / (real_t)fd->msdf_source_size;
return gl[p_glyph].rect.position * (float)p_size.x / (float)fd->msdf_source_size;
} else {
return gl[p_glyph].rect.position;
}
@ -2254,7 +2270,7 @@ Vector2 TextServerAdvanced::font_get_glyph_size(RID p_font_rid, const Vector2i &
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
if (fd->msdf) {
return gl[p_glyph].rect.size * (real_t)p_size.x / (real_t)fd->msdf_source_size;
return gl[p_glyph].rect.size * (float)p_size.x / (float)fd->msdf_source_size;
} else {
return gl[p_glyph].rect.size;
}
@ -2337,38 +2353,46 @@ void TextServerAdvanced::font_set_glyph_texture_idx(RID p_font_rid, const Vector
gl[p_glyph].found = true;
}
bool TextServerAdvanced::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
Dictionary TextServerAdvanced::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
Vector2i size = _get_size(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), false);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Dictionary());
Vector<Vector3> points;
Vector<int32_t> contours;
bool orientation;
#ifdef MODULE_FREETYPE_ENABLED
int error = FT_Load_Glyph(fd->cache[size]->face, p_index, FT_LOAD_NO_BITMAP | (fd->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0));
ERR_FAIL_COND_V(error, false);
ERR_FAIL_COND_V(error, Dictionary());
r_points.clear();
r_contours.clear();
points.clear();
contours.clear();
real_t h = fd->cache[size]->ascent;
real_t scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale;
float h = fd->cache[size]->ascent;
float scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale;
if (fd->msdf) {
scale = scale * (real_t)p_size / (real_t)fd->msdf_source_size;
scale = scale * (float)p_size / (float)fd->msdf_source_size;
}
for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_points; i++) {
r_points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i])));
points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i])));
}
for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_contours; i++) {
r_contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]);
contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]);
}
r_orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
#else
return false;
return Dictionary();
#endif
return true;
Dictionary out;
out["points"] = points;
out["contours"] = contours;
out["orientation"] = orientation;
return out;
}
Array TextServerAdvanced::font_get_kerning_list(RID p_font_rid, int p_size) const {
@ -2433,7 +2457,7 @@ Vector2 TextServerAdvanced::font_get_kerning(RID p_font_rid, int p_size, const V
if (kern.has(p_glyph_pair)) {
if (fd->msdf) {
return kern[p_glyph_pair] * (real_t)p_size / (real_t)fd->msdf_source_size;
return kern[p_glyph_pair] * (float)p_size / (float)fd->msdf_source_size;
} else {
return kern[p_glyph_pair];
}
@ -2443,7 +2467,7 @@ Vector2 TextServerAdvanced::font_get_kerning(RID p_font_rid, int p_size, const V
FT_Vector delta;
FT_Get_Kerning(fd->cache[size]->face, p_glyph_pair.x, p_glyph_pair.y, FT_KERNING_DEFAULT, &delta);
if (fd->msdf) {
return Vector2(delta.x, delta.y) * (real_t)p_size / (real_t)fd->msdf_source_size;
return Vector2(delta.x, delta.y) * (float)p_size / (float)fd->msdf_source_size;
} else {
return Vector2(delta.x, delta.y);
}
@ -2582,8 +2606,8 @@ void TextServerAdvanced::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz
RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid();
if (fd->msdf) {
Point2 cpos = p_pos;
cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size;
Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size;
cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size;
Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size;
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range);
} else {
Point2i cpos = p_pos;
@ -2622,8 +2646,8 @@ void TextServerAdvanced::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i
RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid();
if (fd->msdf) {
Point2 cpos = p_pos;
cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size;
Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size;
cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size;
Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size;
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range);
} else {
Point2i cpos = p_pos;
@ -2694,7 +2718,7 @@ bool TextServerAdvanced::font_is_script_supported(RID p_font_rid, const String &
} else {
Vector2i size = _get_size(fd, 16);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), false);
return fd->supported_scripts.has(TS->name_to_tag(p_script));
return fd->supported_scripts.has(hb_tag_from_string(p_script.ascii().get_data(), -1));
}
}
@ -2754,11 +2778,11 @@ Dictionary TextServerAdvanced::font_supported_variation_list(RID p_font_rid) con
return fd->supported_varaitions;
}
real_t TextServerAdvanced::font_get_global_oversampling() const {
float TextServerAdvanced::font_get_global_oversampling() const {
return oversampling;
}
void TextServerAdvanced::font_set_global_oversampling(real_t p_oversampling) {
void TextServerAdvanced::font_set_global_oversampling(float p_oversampling) {
_THREAD_SAFE_METHOD_
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
@ -2904,7 +2928,7 @@ TextServer::Direction TextServerAdvanced::shaped_text_get_direction(RID p_shaped
return sd->direction;
}
void TextServerAdvanced::shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) {
void TextServerAdvanced::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@ -2912,7 +2936,10 @@ void TextServerAdvanced::shaped_text_set_bidi_override(RID p_shaped, const Vecto
if (sd->parent != RID()) {
full_copy(sd);
}
sd->bidi_override = p_override;
sd->bidi_override.clear();
for (int i = 0; i < p_override.size(); i++) {
sd->bidi_override.push_back(p_override[i]);
}
invalidate(sd);
}
@ -3096,8 +3123,7 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key,
} else if (sd->preserve_invalid || (sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f));
sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f));
sd->ascent = MAX(sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y);
} else {
sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
@ -3108,8 +3134,8 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key,
}
// Align embedded objects to baseline.
real_t full_ascent = sd->ascent;
real_t full_descent = sd->descent;
float full_ascent = sd->ascent;
float full_descent = sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@ -3283,8 +3309,7 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng
} else if (new_sd->preserve_invalid || (new_sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
if (new_sd->orientation == ORIENTATION_HORIZONTAL) {
new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f));
new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f));
new_sd->ascent = MAX(new_sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y);
} else {
new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
@ -3299,8 +3324,8 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng
}
// Align embedded objects to baseline.
real_t full_ascent = new_sd->ascent;
real_t full_descent = new_sd->descent;
float full_ascent = new_sd->ascent;
float full_descent = new_sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) {
if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@ -3378,7 +3403,7 @@ RID TextServerAdvanced::shaped_text_get_parent(RID p_shaped) const {
return sd->parent;
}
real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags) {
float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -3419,7 +3444,7 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width
}
}
real_t justification_width;
float justification_width;
if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) == JUSTIFICATION_CONSTRAIN_ELLIPSIS) {
if (sd->overrun_trim_data.trim_pos >= 0) {
start_pos = sd->overrun_trim_data.trim_pos;
@ -3459,7 +3484,7 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width
}
if ((elongation_count > 0) && ((p_jst_flags & JUSTIFICATION_KASHIDA) == JUSTIFICATION_KASHIDA)) {
real_t delta_width_per_kashida = (p_width - justification_width) / elongation_count;
float delta_width_per_kashida = (p_width - justification_width) / elongation_count;
for (int i = start_pos; i <= end_pos; i++) {
Glyph &gl = sd->glyphs.write[i];
if (gl.count > 0) {
@ -3474,15 +3499,15 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width
}
}
}
real_t adv_remain = 0;
float adv_remain = 0;
if ((space_count > 0) && ((p_jst_flags & JUSTIFICATION_WORD_BOUND) == JUSTIFICATION_WORD_BOUND)) {
real_t delta_width_per_space = (p_width - justification_width) / space_count;
float delta_width_per_space = (p_width - justification_width) / space_count;
for (int i = start_pos; i <= end_pos; i++) {
Glyph &gl = sd->glyphs.write[i];
if (gl.count > 0) {
if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) {
real_t old_adv = gl.advance;
real_t new_advance;
float old_adv = gl.advance;
float new_advance;
if ((gl.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) {
new_advance = MAX(gl.advance + delta_width_per_space, 0.f);
} else {
@ -3514,7 +3539,7 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width
return sd->width;
}
real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) {
float TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -3527,7 +3552,7 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real
}
int tab_index = 0;
real_t off = 0.f;
float off = 0.f;
int start, end, delta;
if (sd->para_direction == DIRECTION_LTR) {
@ -3544,7 +3569,7 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real
for (int i = start; i != end; i += delta) {
if ((gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB) {
real_t tab_off = 0.f;
float tab_off = 0.f;
while (tab_off <= off) {
tab_off += p_tab_stops[tab_index];
tab_index++;
@ -3552,7 +3577,7 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real
tab_index = 0;
}
}
real_t old_adv = gl[i].advance;
float old_adv = gl[i].advance;
gl[i].advance = tab_off - off;
sd->width += gl[i].advance - old_adv;
off = 0;
@ -3564,7 +3589,7 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real
return 0.f;
}
void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, real_t p_width, uint8_t p_trim_flags) {
void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataAdvanced invalid.");
@ -3607,7 +3632,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
}
int ell_min_characters = 6;
real_t width = sd->width;
float width = sd->width;
bool is_rtl = sd->direction == DIRECTION_RTL || (sd->direction == DIRECTION_AUTO && sd->para_direction == DIRECTION_RTL);
@ -3663,7 +3688,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
if (add_ellipsis && (ellipsis_pos > 0 || enforce_ellipsis)) {
// Insert an additional space when cutting word bound for aesthetics.
if (cut_per_word && (ellipsis_pos > 0)) {
TextServer::Glyph gl;
Glyph gl;
gl.count = 1;
gl.advance = whitespace_adv.x;
gl.index = whitespace_gl_idx;
@ -3674,7 +3699,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
sd->overrun_trim_data.ellipsis_glyph_buf.append(gl);
}
// Add ellipsis dots.
TextServer::Glyph gl;
Glyph gl;
gl.count = 1;
gl.repeat = 3;
gl.advance = dot_adv.x;
@ -3691,12 +3716,36 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
}
}
TextServer::TrimData TextServerAdvanced::shaped_text_get_trim_data(RID p_shaped) const {
int TextServerAdvanced::shaped_text_get_trim_pos(RID p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, TrimData(), "ShapedTextDataAdvanced invalid.");
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data;
return sd->overrun_trim_data.trim_pos;
}
int TextServerAdvanced::shaped_text_get_ellipsis_pos(RID p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_pos;
}
const Glyph *TextServerAdvanced::shaped_text_get_ellipsis_glyphs(RID p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextDataAdvanced invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_glyph_buf.ptr();
}
int TextServerAdvanced::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextDataAdvanced invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_glyph_buf.size();
}
bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
@ -3783,7 +3832,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
if (is_whitespace(c)) {
sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT;
} else {
TextServer::Glyph gl;
Glyph gl;
gl.start = sd_glyphs[i].start;
gl.end = sd_glyphs[i].end;
gl.count = 1;
@ -3964,7 +4013,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) {
sd->glyphs.write[i].flags |= GRAPHEME_IS_ELONGATION;
} else {
if (sd->glyphs[i].font_rid != RID()) {
TextServer::Glyph gl = _shape_single_glyph(sd, 0x0640, HB_SCRIPT_ARABIC, HB_DIRECTION_RTL, sd->glyphs[i].font_rid, sd->glyphs[i].font_size);
Glyph gl = _shape_single_glyph(sd, 0x0640, HB_SCRIPT_ARABIC, HB_DIRECTION_RTL, sd->glyphs[i].font_rid, sd->glyphs[i].font_size);
if ((gl.flags & GRAPHEME_IS_VALID) == GRAPHEME_IS_VALID) {
gl.start = sd->glyphs[i].start;
gl.end = sd->glyphs[i].end;
@ -3982,7 +4031,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) {
}
}
} else if (!is_whitespace(c)) {
TextServer::Glyph gl;
Glyph gl;
gl.start = sd->glyphs[i].start;
gl.end = sd->glyphs[i].end;
gl.count = 1;
@ -4007,9 +4056,9 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) {
return sd->justification_ops_valid;
}
TextServer::Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size) {
Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size) {
hb_font_t *hb_font = _font_get_hb_handle(p_font, p_font_size);
ERR_FAIL_COND_V(hb_font == nullptr, TextServer::Glyph());
ERR_FAIL_COND_V(hb_font == nullptr, Glyph());
hb_buffer_clear_contents(p_sd->hb_buffer);
hb_buffer_set_direction(p_sd->hb_buffer, p_direction);
@ -4024,7 +4073,7 @@ TextServer::Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced
hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(p_sd->hb_buffer, &glyph_count);
// Process glyphs.
TextServer::Glyph gl;
Glyph gl;
if (p_direction == HB_DIRECTION_RTL || p_direction == HB_DIRECTION_BTT) {
gl.flags |= TextServer::GRAPHEME_IS_RTL;
@ -4034,7 +4083,7 @@ TextServer::Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced
gl.font_size = p_font_size;
if (glyph_count > 0) {
real_t scale = font_get_scale(p_font, p_font_size);
float scale = font_get_scale(p_font, p_font_size);
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale));
} else {
@ -4059,7 +4108,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
// Add fallback glyphs.
for (int i = p_start; i < p_end; i++) {
if (p_sd->preserve_invalid || (p_sd->preserve_control && is_control(p_sd->text[i]))) {
TextServer::Glyph gl;
Glyph gl;
gl.start = i;
gl.end = i + 1;
gl.count = 1;
@ -4071,8 +4120,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
}
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
gl.advance = get_hex_code_box_size(fs, gl.index).x;
p_sd->ascent = MAX(p_sd->ascent, Math::round(get_hex_code_box_size(fs, gl.index).y * 0.75f));
p_sd->descent = MAX(p_sd->descent, Math::round(get_hex_code_box_size(fs, gl.index).y * 0.25f));
p_sd->ascent = MAX(p_sd->ascent, get_hex_code_box_size(fs, gl.index).y);
} else {
gl.advance = get_hex_code_box_size(fs, gl.index).y;
p_sd->ascent = MAX(p_sd->ascent, Math::round(get_hex_code_box_size(fs, gl.index).x * 0.5f));
@ -4126,7 +4174,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
// Process glyphs.
if (glyph_count > 0) {
TextServer::Glyph *w = (TextServer::Glyph *)memalloc(glyph_count * sizeof(TextServer::Glyph));
Glyph *w = (Glyph *)memalloc(glyph_count * sizeof(Glyph));
int end = (p_direction == HB_DIRECTION_RTL || p_direction == HB_DIRECTION_BTT) ? p_end : 0;
uint32_t last_cluster_id = UINT32_MAX;
@ -4155,8 +4203,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
last_cluster_id = glyph_info[i].cluster;
TextServer::Glyph &gl = w[i];
gl = TextServer::Glyph();
Glyph &gl = w[i];
gl = Glyph();
gl.start = glyph_info[i].cluster;
gl.end = end;
@ -4171,7 +4219,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
gl.index = glyph_info[i].codepoint;
if (gl.index != 0) {
real_t scale = font_get_scale(f, fs);
float scale = font_get_scale(f, fs);
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale));
} else {
@ -4411,8 +4459,8 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) {
}
// Align embedded objects to baseline.
real_t full_ascent = sd->ascent;
real_t full_descent = sd->descent;
float full_ascent = sd->ascent;
float full_descent = sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
@ -4486,28 +4534,31 @@ bool TextServerAdvanced::shaped_text_is_ready(RID p_shaped) const {
return sd->valid;
}
Vector<TextServer::Glyph> TextServerAdvanced::shaped_text_get_glyphs(RID p_shaped) const {
const Glyph *TextServerAdvanced::shaped_text_get_glyphs(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>());
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
}
return sd->glyphs;
return sd->glyphs.ptr();
}
Vector2i TextServerAdvanced::shaped_text_get_range(RID p_shaped) const {
int TextServerAdvanced::shaped_text_get_glyph_count(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector2i());
ERR_FAIL_COND_V(!sd, 0);
MutexLock lock(sd->mutex);
return Vector2(sd->start, sd->end);
if (!sd->valid) {
const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
}
return sd->glyphs.size();
}
Vector<TextServer::Glyph> TextServerAdvanced::shaped_text_sort_logical(RID p_shaped) {
const Glyph *TextServerAdvanced::shaped_text_sort_logical(RID p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>());
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
@ -4516,11 +4567,19 @@ Vector<TextServer::Glyph> TextServerAdvanced::shaped_text_sort_logical(RID p_sha
if (!sd->sort_valid) {
sd->glyphs_logical = sd->glyphs;
sd->glyphs_logical.sort_custom<TextServer::GlyphCompare>();
sd->glyphs_logical.sort_custom<GlyphCompare>();
sd->sort_valid = true;
}
return sd->glyphs_logical;
return sd->glyphs_logical.ptr();
}
Vector2i TextServerAdvanced::shaped_text_get_range(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector2i());
MutexLock lock(sd->mutex);
return Vector2(sd->start, sd->end);
}
Array TextServerAdvanced::shaped_text_get_objects(RID p_shaped) const {
@ -4563,7 +4622,7 @@ Size2 TextServerAdvanced::shaped_text_get_size(RID p_shaped) const {
}
}
real_t TextServerAdvanced::shaped_text_get_ascent(RID p_shaped) const {
float TextServerAdvanced::shaped_text_get_ascent(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -4574,7 +4633,7 @@ real_t TextServerAdvanced::shaped_text_get_ascent(RID p_shaped) const {
return sd->ascent;
}
real_t TextServerAdvanced::shaped_text_get_descent(RID p_shaped) const {
float TextServerAdvanced::shaped_text_get_descent(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -4585,7 +4644,7 @@ real_t TextServerAdvanced::shaped_text_get_descent(RID p_shaped) const {
return sd->descent;
}
real_t TextServerAdvanced::shaped_text_get_width(RID p_shaped) const {
float TextServerAdvanced::shaped_text_get_width(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -4596,7 +4655,7 @@ real_t TextServerAdvanced::shaped_text_get_width(RID p_shaped) const {
return (sd->text_trimmed ? sd->width_trimmed : sd->width);
}
real_t TextServerAdvanced::shaped_text_get_underline_position(RID p_shaped) const {
float TextServerAdvanced::shaped_text_get_underline_position(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -4608,7 +4667,7 @@ real_t TextServerAdvanced::shaped_text_get_underline_position(RID p_shaped) cons
return sd->upos;
}
real_t TextServerAdvanced::shaped_text_get_underline_thickness(RID p_shaped) const {
float TextServerAdvanced::shaped_text_get_underline_thickness(RID p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -4752,15 +4811,6 @@ String TextServerAdvanced::percent_sign(const String &p_language) const {
return "%";
}
TextServer *TextServerAdvanced::create_func(Error &r_error, void *p_user_data) {
r_error = OK;
return memnew(TextServerAdvanced());
}
void TextServerAdvanced::register_server() {
TextServerManager::register_create_function(interface_name, interface_features, create_func, nullptr);
}
TextServerAdvanced::TextServerAdvanced() {
_insert_num_systems_lang();
_insert_feature_sets();

View File

@ -115,12 +115,12 @@ class TextServerAdvanced : public TextServer {
};
struct FontDataForSizeAdvanced {
real_t ascent = 0.f;
real_t descent = 0.f;
real_t underline_position = 0.f;
real_t underline_thickness = 0.f;
real_t scale = 1.f;
real_t oversampling = 1.f;
float ascent = 0.f;
float descent = 0.f;
float underline_position = 0.f;
float underline_thickness = 0.f;
float scale = 1.f;
float oversampling = 1.f;
int spacing_glyph = 0;
int spacing_space = 0;
@ -161,7 +161,7 @@ class TextServerAdvanced : public TextServer {
bool force_autohinter = false;
TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
Dictionary variation_coordinates;
real_t oversampling = 0.f;
float oversampling = 0.f;
Map<Vector2i, FontDataForSizeAdvanced *> cache;
@ -245,14 +245,14 @@ class TextServerAdvanced : public TextServer {
// Common data.
real_t oversampling = 1.f;
float oversampling = 1.f;
mutable RID_PtrOwner<FontDataAdvanced> font_owner;
mutable RID_PtrOwner<ShapedTextDataAdvanced> shaped_owner;
int _convert_pos(const ShapedTextDataAdvanced *p_sd, int p_pos) const;
int _convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int p_pos) const;
void _shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index);
TextServer::Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size);
Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size);
// HarfBuzz bitmap font interface.
@ -284,20 +284,19 @@ protected:
void invalidate(ShapedTextDataAdvanced *p_shaped);
public:
virtual bool has_feature(Feature p_feature) override;
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
virtual uint32_t get_features() const override;
virtual void free(RID p_rid) override;
virtual bool has(RID p_rid) override;
virtual bool load_support_data(const String &p_filename) override;
#ifdef TOOLS_ENABLED
virtual String get_support_data_filename() override { return _MKSTR(ICU_DATA_NAME); };
virtual String get_support_data_info() override { return String("ICU break iteration data (") + _MKSTR(ICU_DATA_NAME) + String(")."); };
virtual bool save_support_data(const String &p_filename) override;
#endif
virtual String get_support_data_filename() const override;
virtual String get_support_data_info() const override;
virtual bool save_support_data(const String &p_filename) const override;
virtual bool is_locale_right_to_left(const String &p_locale) override;
virtual bool is_locale_right_to_left(const String &p_locale) const override;
virtual int32_t name_to_tag(const String &p_name) const override;
virtual String tag_to_name(int32_t p_tag) const override;
@ -332,8 +331,8 @@ public:
virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override;
virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override;
virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) override;
virtual real_t font_get_oversampling(RID p_font_rid) const override;
virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override;
virtual float font_get_oversampling(RID p_font_rid) const override;
virtual Array font_get_size_cache_list(RID p_font_rid) const override;
virtual void font_clear_size_cache(RID p_font_rid) override;
@ -341,20 +340,20 @@ public:
hb_font_t *_font_get_hb_handle(RID p_font, int p_font_size) const;
virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) override;
virtual real_t font_get_ascent(RID p_font_rid, int p_size) const override;
virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override;
virtual float font_get_ascent(RID p_font_rid, int p_size) const override;
virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) override;
virtual real_t font_get_descent(RID p_font_rid, int p_size) const override;
virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override;
virtual float font_get_descent(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) override;
virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override;
virtual float font_get_underline_position(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) override;
virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override;
virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override;
virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) override;
virtual real_t font_get_scale(RID p_font_rid, int p_size) const override;
virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override;
virtual float font_get_scale(RID p_font_rid, int p_size) const override;
virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override;
virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override;
@ -388,7 +387,7 @@ public:
virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override;
virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override;
virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override;
virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override;
@ -423,8 +422,8 @@ public:
virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
virtual real_t font_get_global_oversampling() const override;
virtual void font_set_global_oversampling(real_t p_oversampling) override;
virtual float font_get_global_oversampling() const override;
virtual void font_set_global_oversampling(float p_oversampling) override;
/* Shaped text buffer interface */
@ -435,7 +434,7 @@ public:
virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override;
virtual Direction shaped_text_get_direction(RID p_shaped) const override;
virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) override;
virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override;
virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
virtual Orientation shaped_text_get_orientation(RID p_shaped) const override;
@ -453,41 +452,42 @@ public:
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) override;
virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override;
virtual bool shaped_text_shape(RID p_shaped) override;
virtual bool shaped_text_update_breaks(RID p_shaped) override;
virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) override;
virtual TrimData shaped_text_get_trim_data(RID p_shaped) const override;
virtual int shaped_text_get_trim_pos(RID p_shaped) const override;
virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override;
virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override;
virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override;
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override;
virtual bool shaped_text_is_ready(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override;
virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override;
virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override;
virtual int shaped_text_get_glyph_count(RID p_shaped) const override;
virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) override;
virtual Array shaped_text_get_objects(RID p_shaped) const override;
virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override;
virtual Size2 shaped_text_get_size(RID p_shaped) const override;
virtual real_t shaped_text_get_ascent(RID p_shaped) const override;
virtual real_t shaped_text_get_descent(RID p_shaped) const override;
virtual real_t shaped_text_get_width(RID p_shaped) const override;
virtual real_t shaped_text_get_underline_position(RID p_shaped) const override;
virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const override;
virtual float shaped_text_get_ascent(RID p_shaped) const override;
virtual float shaped_text_get_descent(RID p_shaped) const override;
virtual float shaped_text_get_width(RID p_shaped) const override;
virtual float shaped_text_get_underline_position(RID p_shaped) const override;
virtual float shaped_text_get_underline_thickness(RID p_shaped) const override;
virtual String format_number(const String &p_string, const String &p_language = "") const override;
virtual String parse_number(const String &p_string, const String &p_language = "") const override;
virtual String percent_sign(const String &p_language = "") const override;
static TextServer *create_func(Error &r_error, void *p_user_data);
static void register_server();
TextServerAdvanced();
~TextServerAdvanced();
};

View File

@ -9,3 +9,13 @@ def configure(env):
def is_enabled():
# The module is disabled by default. Use module_text_server_fb_enabled=yes to enable it.
return False
def get_doc_classes():
return [
"TextServerFallback",
]
def get_doc_path():
return "doc_classes"

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TextServerFallback" inherits="TextServer" version="4.0">
<brief_description>
Fallback implementation of the Text Server, without BiDi and complex text layout support.
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
</class>

View File

@ -33,7 +33,12 @@
#include "text_server_fb.h"
void preregister_text_server_fb_types() {
TextServerFallback::register_server();
GDREGISTER_CLASS(TextServerFallback);
if (TextServerManager::get_singleton()) {
Ref<TextServerFallback> ts;
ts.instantiate();
TextServerManager::get_singleton()->add_interface(ts);
}
}
void register_text_server_fb_types() {

View File

@ -69,7 +69,7 @@ _FORCE_INLINE_ bool is_underscore(char32_t p_char) {
String TextServerFallback::interface_name = "Fallback";
uint32_t TextServerFallback::interface_features = 0; // Nothing is supported.
bool TextServerFallback::has_feature(Feature p_feature) {
bool TextServerFallback::has_feature(Feature p_feature) const {
return (interface_features & p_feature) == p_feature;
}
@ -77,6 +77,10 @@ String TextServerFallback::get_name() const {
return interface_name;
}
uint32_t TextServerFallback::get_features() const {
return interface_features;
}
void TextServerFallback::free(RID p_rid) {
_THREAD_SAFE_METHOD_
if (font_owner.owns(p_rid)) {
@ -99,15 +103,11 @@ bool TextServerFallback::load_support_data(const String &p_filename) {
return false; // No extra data used.
}
#ifdef TOOLS_ENABLED
bool TextServerFallback::save_support_data(const String &p_filename) {
bool TextServerFallback::save_support_data(const String &p_filename) const {
return false; // No extra data used.
}
#endif
bool TextServerFallback::is_locale_right_to_left(const String &p_locale) {
bool TextServerFallback::is_locale_right_to_left(const String &p_locale) const {
return false; // No RTL support.
}
@ -420,7 +420,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(
FontTexture &tex = p_data->textures.write[tex_pos.index];
edgeColoringSimple(shape, 3.0); // Max. angle.
msdfgen::Bitmap<real_t, 4> image(w, h); // Texture size.
msdfgen::Bitmap<float, 4> image(w, h); // Texture size.
//msdfgen::generateMTSDF(image, shape, p_pixel_range, 1.0, msdfgen::Vector2(-bounds.l, -bounds.b)); // Range, scale, translation.
DistancePixelConversion distancePixelConversion(p_pixel_range);
@ -620,7 +620,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontDataFallback *p_font_d
int error = FT_Load_Glyph(fd->face, glyph_index, flags);
if (error) {
fd->glyph_map[p_glyph] = FontGlyph();
ERR_FAIL_V_MSG(false, "FreeType: Failed to load glyph.");
return false;
}
if (!outline) {
@ -714,7 +714,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback
fd->oversampling = 1.0f;
fd->size.x = p_font_data->msdf_source_size;
} else if (p_font_data->oversampling <= 0.0f) {
fd->oversampling = TS->font_get_global_oversampling();
fd->oversampling = font_get_global_oversampling();
} else {
fd->oversampling = p_font_data->oversampling;
}
@ -722,13 +722,13 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback
if (FT_HAS_COLOR(fd->face) && fd->face->num_fixed_sizes > 0) {
int best_match = 0;
int diff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[0].width));
fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width;
fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width;
for (int i = 1; i < fd->face->num_fixed_sizes; i++) {
int ndiff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[i].width));
if (ndiff < diff) {
best_match = i;
diff = ndiff;
fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width;
fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width;
}
}
FT_Select_Size(fd->face, best_match);
@ -769,7 +769,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback
for (FT_UInt i = 0; i < amaster->num_axis; i++) {
// Reset to default.
int32_t var_tag = amaster->axis[i].tag;
real_t var_value = (double)amaster->axis[i].def / 65536.f;
float var_value = (double)amaster->axis[i].def / 65536.f;
coords.write[i] = amaster->axis[i].def;
if (p_font_data->variation_coordinates.has(var_tag)) {
@ -983,7 +983,7 @@ Dictionary TextServerFallback::font_get_variation_coordinates(RID p_font_rid) co
return fd->variation_coordinates;
}
void TextServerFallback::font_set_oversampling(RID p_font_rid, real_t p_oversampling) {
void TextServerFallback::font_set_oversampling(RID p_font_rid, float p_oversampling) {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -994,7 +994,7 @@ void TextServerFallback::font_set_oversampling(RID p_font_rid, real_t p_oversamp
}
}
real_t TextServerFallback::font_get_oversampling(RID p_font_rid) const {
float TextServerFallback::font_get_oversampling(RID p_font_rid) const {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1036,7 +1036,7 @@ void TextServerFallback::font_remove_size_cache(RID p_font_rid, const Vector2i &
}
}
void TextServerFallback::font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) {
void TextServerFallback::font_set_ascent(RID p_font_rid, int p_size, float p_ascent) {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1047,7 +1047,7 @@ void TextServerFallback::font_set_ascent(RID p_font_rid, int p_size, real_t p_as
fd->cache[size]->ascent = p_ascent;
}
real_t TextServerFallback::font_get_ascent(RID p_font_rid, int p_size) const {
float TextServerFallback::font_get_ascent(RID p_font_rid, int p_size) const {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1057,13 +1057,13 @@ real_t TextServerFallback::font_get_ascent(RID p_font_rid, int p_size) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->ascent * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->ascent * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->ascent;
}
}
void TextServerFallback::font_set_descent(RID p_font_rid, int p_size, real_t p_descent) {
void TextServerFallback::font_set_descent(RID p_font_rid, int p_size, float p_descent) {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1073,7 +1073,7 @@ void TextServerFallback::font_set_descent(RID p_font_rid, int p_size, real_t p_d
fd->cache[size]->descent = p_descent;
}
real_t TextServerFallback::font_get_descent(RID p_font_rid, int p_size) const {
float TextServerFallback::font_get_descent(RID p_font_rid, int p_size) const {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1083,13 +1083,13 @@ real_t TextServerFallback::font_get_descent(RID p_font_rid, int p_size) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->descent * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->descent * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->descent;
}
}
void TextServerFallback::font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) {
void TextServerFallback::font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1100,7 +1100,7 @@ void TextServerFallback::font_set_underline_position(RID p_font_rid, int p_size,
fd->cache[size]->underline_position = p_underline_position;
}
real_t TextServerFallback::font_get_underline_position(RID p_font_rid, int p_size) const {
float TextServerFallback::font_get_underline_position(RID p_font_rid, int p_size) const {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1110,13 +1110,13 @@ real_t TextServerFallback::font_get_underline_position(RID p_font_rid, int p_siz
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->underline_position * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->underline_position * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->underline_position;
}
}
void TextServerFallback::font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) {
void TextServerFallback::font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1127,7 +1127,7 @@ void TextServerFallback::font_set_underline_thickness(RID p_font_rid, int p_size
fd->cache[size]->underline_thickness = p_underline_thickness;
}
real_t TextServerFallback::font_get_underline_thickness(RID p_font_rid, int p_size) const {
float TextServerFallback::font_get_underline_thickness(RID p_font_rid, int p_size) const {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1137,13 +1137,13 @@ real_t TextServerFallback::font_get_underline_thickness(RID p_font_rid, int p_si
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->underline_thickness * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->underline_thickness * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->underline_thickness;
}
}
void TextServerFallback::font_set_scale(RID p_font_rid, int p_size, real_t p_scale) {
void TextServerFallback::font_set_scale(RID p_font_rid, int p_size, float p_scale) {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@ -1154,7 +1154,7 @@ void TextServerFallback::font_set_scale(RID p_font_rid, int p_size, real_t p_sca
fd->cache[size]->scale = p_scale;
}
real_t TextServerFallback::font_get_scale(RID p_font_rid, int p_size) const {
float TextServerFallback::font_get_scale(RID p_font_rid, int p_size) const {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.f);
@ -1164,7 +1164,7 @@ real_t TextServerFallback::font_get_scale(RID p_font_rid, int p_size) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f);
if (fd->msdf) {
return fd->cache[size]->scale * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->scale * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->scale / fd->cache[size]->oversampling;
}
@ -1203,14 +1203,14 @@ int TextServerFallback::font_get_spacing(RID p_font_rid, int p_size, TextServer:
switch (p_spacing) {
case TextServer::SPACING_GLYPH: {
if (fd->msdf) {
return fd->cache[size]->spacing_glyph * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->spacing_glyph * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->spacing_glyph;
}
} break;
case TextServer::SPACING_SPACE: {
if (fd->msdf) {
return fd->cache[size]->spacing_space * (real_t)p_size / (real_t)fd->msdf_source_size;
return fd->cache[size]->spacing_space * (float)p_size / (float)fd->msdf_source_size;
} else {
return fd->cache[size]->spacing_space;
}
@ -1379,7 +1379,7 @@ Vector2 TextServerFallback::font_get_glyph_advance(RID p_font_rid, int p_size, i
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
if (fd->msdf) {
return gl[p_glyph].advance * (real_t)p_size / (real_t)fd->msdf_source_size;
return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size;
} else {
return gl[p_glyph].advance;
}
@ -1415,7 +1415,7 @@ Vector2 TextServerFallback::font_get_glyph_offset(RID p_font_rid, const Vector2i
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
if (fd->msdf) {
return gl[p_glyph].rect.position * (real_t)p_size.x / (real_t)fd->msdf_source_size;
return gl[p_glyph].rect.position * (float)p_size.x / (float)fd->msdf_source_size;
} else {
return gl[p_glyph].rect.position;
}
@ -1451,7 +1451,7 @@ Vector2 TextServerFallback::font_get_glyph_size(RID p_font_rid, const Vector2i &
const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map;
if (fd->msdf) {
return gl[p_glyph].rect.size * (real_t)p_size.x / (real_t)fd->msdf_source_size;
return gl[p_glyph].rect.size * (float)p_size.x / (float)fd->msdf_source_size;
} else {
return gl[p_glyph].rect.size;
}
@ -1534,38 +1534,46 @@ void TextServerFallback::font_set_glyph_texture_idx(RID p_font_rid, const Vector
gl[p_glyph].found = true;
}
bool TextServerFallback::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
Dictionary TextServerFallback::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index) const {
FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
Vector2i size = _get_size(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), false);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Dictionary());
Vector<Vector3> points;
Vector<int32_t> contours;
bool orientation;
#ifdef MODULE_FREETYPE_ENABLED
int error = FT_Load_Glyph(fd->cache[size]->face, FT_Get_Char_Index(fd->cache[size]->face, p_index), FT_LOAD_NO_BITMAP | (fd->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0));
ERR_FAIL_COND_V(error, false);
ERR_FAIL_COND_V(error, Dictionary());
r_points.clear();
r_contours.clear();
points.clear();
contours.clear();
real_t h = fd->cache[size]->ascent;
real_t scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale;
float h = fd->cache[size]->ascent;
float scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale;
if (fd->msdf) {
scale = scale * (real_t)p_size / (real_t)fd->msdf_source_size;
scale = scale * (float)p_size / (float)fd->msdf_source_size;
}
for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_points; i++) {
r_points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i])));
points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i])));
}
for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_contours; i++) {
r_contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]);
contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]);
}
r_orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
#else
return false;
return Dictionary();
#endif
return true;
Dictionary out;
out["points"] = points;
out["contours"] = contours;
out["orientation"] = orientation;
return out;
}
Array TextServerFallback::font_get_kerning_list(RID p_font_rid, int p_size) const {
@ -1630,7 +1638,7 @@ Vector2 TextServerFallback::font_get_kerning(RID p_font_rid, int p_size, const V
if (kern.has(p_glyph_pair)) {
if (fd->msdf) {
return kern[p_glyph_pair] * (real_t)p_size / (real_t)fd->msdf_source_size;
return kern[p_glyph_pair] * (float)p_size / (float)fd->msdf_source_size;
} else {
return kern[p_glyph_pair];
}
@ -1642,7 +1650,7 @@ Vector2 TextServerFallback::font_get_kerning(RID p_font_rid, int p_size, const V
int32_t glyph_b = FT_Get_Char_Index(fd->cache[size]->face, p_glyph_pair.y);
FT_Get_Kerning(fd->cache[size]->face, glyph_a, glyph_b, FT_KERNING_DEFAULT, &delta);
if (fd->msdf) {
return Vector2(delta.x, delta.y) * (real_t)p_size / (real_t)fd->msdf_source_size;
return Vector2(delta.x, delta.y) * (float)p_size / (float)fd->msdf_source_size;
} else {
return Vector2(delta.x, delta.y);
}
@ -1756,8 +1764,8 @@ void TextServerFallback::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz
RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid();
if (fd->msdf) {
Point2 cpos = p_pos;
cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size;
Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size;
cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size;
Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size;
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range);
} else {
Point2i cpos = p_pos;
@ -1796,8 +1804,8 @@ void TextServerFallback::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i
RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid();
if (fd->msdf) {
Point2 cpos = p_pos;
cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size;
Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size;
cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size;
Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size;
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range);
} else {
Point2i cpos = p_pos;
@ -1922,11 +1930,11 @@ Dictionary TextServerFallback::font_supported_variation_list(RID p_font_rid) con
return fd->supported_varaitions;
}
real_t TextServerFallback::font_get_global_oversampling() const {
float TextServerFallback::font_get_global_oversampling() const {
return oversampling;
}
void TextServerFallback::font_set_global_oversampling(real_t p_oversampling) {
void TextServerFallback::font_set_global_oversampling(float p_oversampling) {
_THREAD_SAFE_METHOD_
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
@ -2037,7 +2045,7 @@ void TextServerFallback::shaped_text_set_orientation(RID p_shaped, TextServer::O
}
}
void TextServerFallback::shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) {
void TextServerFallback::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) {
// No BiDi support, ignore.
}
@ -2223,8 +2231,7 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key,
} else if (sd->preserve_invalid || (sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f));
sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f));
sd->ascent = MAX(sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y);
} else {
sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
@ -2235,8 +2242,8 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key,
}
// Align embedded objects to baseline.
real_t full_ascent = sd->ascent;
real_t full_descent = sd->descent;
float full_ascent = sd->ascent;
float full_descent = sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@ -2373,8 +2380,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
} else if (new_sd->preserve_invalid || (new_sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
if (new_sd->orientation == ORIENTATION_HORIZONTAL) {
new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f));
new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f));
new_sd->ascent = MAX(new_sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y);
} else {
new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
@ -2387,8 +2393,8 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
}
// Align embedded objects to baseline.
real_t full_ascent = new_sd->ascent;
real_t full_descent = new_sd->descent;
float full_ascent = new_sd->ascent;
float full_descent = new_sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) {
if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@ -2466,7 +2472,7 @@ RID TextServerFallback::shaped_text_get_parent(RID p_shaped) const {
return sd->parent;
}
real_t TextServerFallback::shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags) {
float TextServerFallback::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags) {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -2530,12 +2536,12 @@ real_t TextServerFallback::shaped_text_fit_to_width(RID p_shaped, real_t p_width
}
if ((space_count > 0) && ((p_jst_flags & JUSTIFICATION_WORD_BOUND) == JUSTIFICATION_WORD_BOUND)) {
real_t delta_width_per_space = (p_width - sd->width) / space_count;
float delta_width_per_space = (p_width - sd->width) / space_count;
for (int i = start_pos; i <= end_pos; i++) {
Glyph &gl = sd->glyphs.write[i];
if (gl.count > 0) {
if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) {
real_t old_adv = gl.advance;
float old_adv = gl.advance;
gl.advance = MAX(gl.advance + delta_width_per_space, Math::round(0.1 * gl.font_size));
sd->width += (gl.advance - old_adv);
}
@ -2546,7 +2552,7 @@ real_t TextServerFallback::shaped_text_fit_to_width(RID p_shaped, real_t p_width
return sd->width;
}
real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) {
float TextServerFallback::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -2559,7 +2565,7 @@ real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real
}
int tab_index = 0;
real_t off = 0.f;
float off = 0.f;
int start, end, delta;
if (sd->para_direction == DIRECTION_LTR) {
@ -2576,7 +2582,7 @@ real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real
for (int i = start; i != end; i += delta) {
if ((gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB) {
real_t tab_off = 0.f;
float tab_off = 0.f;
while (tab_off <= off) {
tab_off += p_tab_stops[tab_index];
tab_index++;
@ -2584,7 +2590,7 @@ real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real
tab_index = 0;
}
}
real_t old_adv = gl[i].advance;
float old_adv = gl[i].advance;
gl[i].advance = tab_off - off;
sd->width += gl[i].advance - old_adv;
off = 0;
@ -2653,7 +2659,7 @@ bool TextServerFallback::shaped_text_update_justification_ops(RID p_shaped) {
return true;
}
void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, real_t p_width, uint8_t p_trim_flags) {
void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataFallback invalid.");
@ -2696,7 +2702,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
}
int ell_min_characters = 6;
real_t width = sd->width;
float width = sd->width;
int trim_pos = 0;
int ellipsis_pos = (enforce_ellipsis) ? 0 : -1;
@ -2742,7 +2748,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
if (add_ellipsis && (ellipsis_pos > 0 || enforce_ellipsis)) {
// Insert an additional space when cutting word bound for aesthetics.
if (cut_per_word && (ellipsis_pos > 0)) {
TextServer::Glyph gl;
Glyph gl;
gl.count = 1;
gl.advance = whitespace_adv.x;
gl.index = whitespace_gl_idx;
@ -2753,7 +2759,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
sd->overrun_trim_data.ellipsis_glyph_buf.append(gl);
}
// Add ellipsis dots.
TextServer::Glyph gl;
Glyph gl;
gl.count = 1;
gl.repeat = 3;
gl.advance = dot_adv.x;
@ -2770,12 +2776,36 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re
}
}
TextServer::TrimData TextServerFallback::shaped_text_get_trim_data(RID p_shaped) const {
int TextServerFallback::shaped_text_get_trim_pos(RID p_shaped) const {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, TrimData(), "ShapedTextDataFallback invalid.");
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextData invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data;
return sd->overrun_trim_data.trim_pos;
}
int TextServerFallback::shaped_text_get_ellipsis_pos(RID p_shaped) const {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextData invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_pos;
}
const Glyph *TextServerFallback::shaped_text_get_ellipsis_glyphs(RID p_shaped) const {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextData invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_glyph_buf.ptr();
}
int TextServerFallback::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const {
ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextData invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_glyph_buf.size();
}
bool TextServerFallback::shaped_text_shape(RID p_shaped) {
@ -2890,8 +2920,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
// Glyph not found, replace with hex code box.
if (sd->orientation == ORIENTATION_HORIZONTAL) {
gl.advance = get_hex_code_box_size(gl.font_size, gl.index).x;
sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f));
sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f));
sd->ascent = MAX(sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y);
} else {
gl.advance = get_hex_code_box_size(gl.font_size, gl.index).y;
sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f));
@ -2905,8 +2934,8 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
}
// Align embedded objects to baseline.
real_t full_ascent = sd->ascent;
real_t full_descent = sd->descent;
float full_ascent = sd->ascent;
float full_descent = sd->descent;
for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) {
@ -2980,15 +3009,38 @@ bool TextServerFallback::shaped_text_is_ready(RID p_shaped) const {
return sd->valid;
}
Vector<TextServer::Glyph> TextServerFallback::shaped_text_get_glyphs(RID p_shaped) const {
const Glyph *TextServerFallback::shaped_text_get_glyphs(RID p_shaped) const {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>());
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
}
return sd->glyphs;
return sd->glyphs.ptr();
}
int TextServerFallback::shaped_text_get_glyph_count(RID p_shaped) const {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
}
return sd->glyphs.size();
}
const Glyph *TextServerFallback::shaped_text_sort_logical(RID p_shaped) {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
}
return sd->glyphs.ptr(); // Already in the logical order, return as is.
}
Vector2i TextServerFallback::shaped_text_get_range(RID p_shaped) const {
@ -2999,18 +3051,6 @@ Vector2i TextServerFallback::shaped_text_get_range(RID p_shaped) const {
return Vector2(sd->start, sd->end);
}
Vector<TextServer::Glyph> TextServerFallback::shaped_text_sort_logical(RID p_shaped) {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>());
MutexLock lock(sd->mutex);
if (!sd->valid) {
const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
}
return sd->glyphs; // Already in the logical order, return as is.
}
Array TextServerFallback::shaped_text_get_objects(RID p_shaped) const {
Array ret;
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
@ -3051,7 +3091,7 @@ Size2 TextServerFallback::shaped_text_get_size(RID p_shaped) const {
}
}
real_t TextServerFallback::shaped_text_get_ascent(RID p_shaped) const {
float TextServerFallback::shaped_text_get_ascent(RID p_shaped) const {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -3062,7 +3102,7 @@ real_t TextServerFallback::shaped_text_get_ascent(RID p_shaped) const {
return sd->ascent;
}
real_t TextServerFallback::shaped_text_get_descent(RID p_shaped) const {
float TextServerFallback::shaped_text_get_descent(RID p_shaped) const {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -3073,7 +3113,7 @@ real_t TextServerFallback::shaped_text_get_descent(RID p_shaped) const {
return sd->descent;
}
real_t TextServerFallback::shaped_text_get_width(RID p_shaped) const {
float TextServerFallback::shaped_text_get_width(RID p_shaped) const {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -3084,7 +3124,7 @@ real_t TextServerFallback::shaped_text_get_width(RID p_shaped) const {
return sd->width;
}
real_t TextServerFallback::shaped_text_get_underline_position(RID p_shaped) const {
float TextServerFallback::shaped_text_get_underline_position(RID p_shaped) const {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -3096,7 +3136,7 @@ real_t TextServerFallback::shaped_text_get_underline_position(RID p_shaped) cons
return sd->upos;
}
real_t TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) const {
float TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) const {
const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
@ -3108,15 +3148,6 @@ real_t TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) con
return sd->uthk;
}
TextServer *TextServerFallback::create_func(Error &r_error, void *p_user_data) {
r_error = OK;
return memnew(TextServerFallback());
}
void TextServerFallback::register_server() {
TextServerManager::register_create_function(interface_name, interface_features, create_func, nullptr);
}
TextServerFallback::TextServerFallback(){};
TextServerFallback::~TextServerFallback() {

View File

@ -93,12 +93,12 @@ class TextServerFallback : public TextServer {
};
struct FontDataForSizeFallback {
real_t ascent = 0.f;
real_t descent = 0.f;
real_t underline_position = 0.f;
real_t underline_thickness = 0.f;
real_t scale = 1.f;
real_t oversampling = 1.f;
float ascent = 0.f;
float descent = 0.f;
float underline_position = 0.f;
float underline_thickness = 0.f;
float scale = 1.f;
float oversampling = 1.f;
int spacing_glyph = 0;
int spacing_space = 0;
@ -134,7 +134,7 @@ class TextServerFallback : public TextServer {
bool force_autohinter = false;
TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
Dictionary variation_coordinates;
real_t oversampling = 0.f;
float oversampling = 0.f;
Map<Vector2i, FontDataForSizeFallback *> cache;
@ -194,7 +194,7 @@ class TextServerFallback : public TextServer {
// Common data.
real_t oversampling = 1.f;
float oversampling = 1.f;
mutable RID_PtrOwner<FontDataFallback> font_owner;
mutable RID_PtrOwner<ShapedTextData> shaped_owner;
@ -205,20 +205,19 @@ protected:
void invalidate(ShapedTextData *p_shaped);
public:
virtual bool has_feature(Feature p_feature) override;
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
virtual uint32_t get_features() const override;
virtual void free(RID p_rid) override;
virtual bool has(RID p_rid) override;
virtual bool load_support_data(const String &p_filename) override;
#ifdef TOOLS_ENABLED
virtual String get_support_data_filename() override { return ""; };
virtual String get_support_data_info() override { return "Not supported"; };
virtual bool save_support_data(const String &p_filename) override;
#endif
virtual String get_support_data_filename() const override { return ""; };
virtual String get_support_data_info() const override { return "Not supported"; };
virtual bool save_support_data(const String &p_filename) const override;
virtual bool is_locale_right_to_left(const String &p_locale) override;
virtual bool is_locale_right_to_left(const String &p_locale) const override;
virtual int32_t name_to_tag(const String &p_name) const override;
virtual String tag_to_name(int32_t p_tag) const override;
@ -253,27 +252,27 @@ public:
virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override;
virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override;
virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) override;
virtual real_t font_get_oversampling(RID p_font_rid) const override;
virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override;
virtual float font_get_oversampling(RID p_font_rid) const override;
virtual Array font_get_size_cache_list(RID p_font_rid) const override;
virtual void font_clear_size_cache(RID p_font_rid) override;
virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override;
virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) override;
virtual real_t font_get_ascent(RID p_font_rid, int p_size) const override;
virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override;
virtual float font_get_ascent(RID p_font_rid, int p_size) const override;
virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) override;
virtual real_t font_get_descent(RID p_font_rid, int p_size) const override;
virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override;
virtual float font_get_descent(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) override;
virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override;
virtual float font_get_underline_position(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) override;
virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const override;
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override;
virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override;
virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) override;
virtual real_t font_get_scale(RID p_font_rid, int p_size) const override;
virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override;
virtual float font_get_scale(RID p_font_rid, int p_size) const override;
virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override;
virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override;
@ -307,7 +306,7 @@ public:
virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override;
virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override;
virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override;
virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override;
@ -342,8 +341,8 @@ public:
virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
virtual real_t font_get_global_oversampling() const override;
virtual void font_set_global_oversampling(real_t p_oversampling) override;
virtual float font_get_global_oversampling() const override;
virtual void font_set_global_oversampling(float p_oversampling) override;
/* Shaped text buffer interface */
@ -354,7 +353,7 @@ public:
virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override;
virtual Direction shaped_text_get_direction(RID p_shaped) const override;
virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) override;
virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override;
virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
virtual Orientation shaped_text_get_orientation(RID p_shaped) const override;
@ -372,36 +371,37 @@ public:
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) override;
virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override;
virtual bool shaped_text_shape(RID p_shaped) override;
virtual bool shaped_text_update_breaks(RID p_shaped) override;
virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) override;
virtual TrimData shaped_text_get_trim_data(RID p_shaped) const override;
virtual int shaped_text_get_trim_pos(RID p_shaped) const override;
virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override;
virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override;
virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override;
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override;
virtual bool shaped_text_is_ready(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override;
virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override;
virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override;
virtual int shaped_text_get_glyph_count(RID p_shaped) const override;
virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) override;
virtual Array shaped_text_get_objects(RID p_shaped) const override;
virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override;
virtual Size2 shaped_text_get_size(RID p_shaped) const override;
virtual real_t shaped_text_get_ascent(RID p_shaped) const override;
virtual real_t shaped_text_get_descent(RID p_shaped) const override;
virtual real_t shaped_text_get_width(RID p_shaped) const override;
virtual real_t shaped_text_get_underline_position(RID p_shaped) const override;
virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const override;
static TextServer *create_func(Error &r_error, void *p_user_data);
static void register_server();
virtual float shaped_text_get_ascent(RID p_shaped) const override;
virtual float shaped_text_get_descent(RID p_shaped) const override;
virtual float shaped_text_get_width(RID p_shaped) const override;
virtual float shaped_text_get_underline_position(RID p_shaped) const override;
virtual float shaped_text_get_underline_thickness(RID p_shaped) const override;
TextServerFallback();
~TextServerFallback();

View File

@ -314,17 +314,27 @@ String OS_OSX::get_name() const {
return "macOS";
}
_FORCE_INLINE_ String _get_framework_executable(const String p_path) {
// Append framework executable name, or return as is if p_path is not a framework.
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) {
return p_path.plus_file(p_path.get_file().get_basename());
} else {
return p_path;
}
}
Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
String path = p_path;
String path = _get_framework_executable(p_path);
if (!FileAccess::exists(path)) {
//this code exists so gdnative can load .dylib files from within the executable path
path = get_executable_path().get_base_dir().plus_file(p_path.get_file());
// This code exists so gdnative can load .dylib files from within the executable path.
path = _get_framework_executable(get_executable_path().get_base_dir().plus_file(p_path.get_file()));
}
if (!FileAccess::exists(path)) {
//this code exists so gdnative can load .dylib files from a standard macOS location
path = get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file());
// This code exists so gdnative can load .dylib files from a standard macOS location.
path = _get_framework_executable(get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file()));
}
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);

View File

@ -2449,8 +2449,8 @@ bool Control::is_text_field() const {
return false;
}
Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const {
Vector<Vector2i> ret;
Array Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const {
Array ret;
switch (p_theme_type) {
case STRUCTURED_TEXT_URI: {
int prev = 0;

View File

@ -283,7 +283,7 @@ protected:
//virtual void _window_gui_input(InputEvent p_event);
virtual Vector<Vector2i> structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const;
virtual Array structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const;
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;

View File

@ -108,7 +108,7 @@ void Label::_shape() {
}
lines_rid.clear();
uint8_t autowrap_flags = TextServer::BREAK_MANDATORY;
uint16_t autowrap_flags = TextServer::BREAK_MANDATORY;
switch (autowrap_mode) {
case AUTOWRAP_WORD_SMART:
autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
@ -122,10 +122,10 @@ void Label::_shape() {
case AUTOWRAP_OFF:
break;
}
Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags);
PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags);
for (int i = 0; i < line_breaks.size(); i++) {
RID line = TS->shaped_text_substr(text_rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x);
for (int i = 0; i < line_breaks.size(); i = i + 2) {
RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]);
lines_rid.push_back(line);
}
}
@ -145,7 +145,7 @@ void Label::_shape() {
}
if (lines_dirty) {
uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING;
uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING;
switch (overrun_behavior) {
case OVERRUN_TRIM_WORD_ELLIPSIS:
overrun_flags |= TextServer::OVERRUN_TRIM;
@ -231,7 +231,7 @@ void Label::_update_visible() {
}
}
inline void draw_glyph(const TextServer::Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) {
inline void draw_glyph(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) {
if (p_gl.font_rid != RID()) {
TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off), p_gl.index, p_font_color);
} else {
@ -239,7 +239,7 @@ inline void draw_glyph(const TextServer::Glyph &p_gl, const RID &p_canvas, const
}
}
inline void draw_glyph_outline(const TextServer::Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Color &p_font_shadow_color, const Color &p_font_outline_color, const int &p_shadow_outline_size, const int &p_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) {
inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Color &p_font_shadow_color, const Color &p_font_outline_color, const int &p_shadow_outline_size, const int &p_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) {
if (p_gl.font_rid != RID()) {
if (p_font_shadow_color.a > 0) {
TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off) + shadow_ofs, p_gl.index, p_font_shadow_color);
@ -387,21 +387,25 @@ void Label::_notification(int p_what) {
} break;
}
const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(lines_rid[i]);
const TextServer::Glyph *glyphs = visual.ptr();
int gl_size = visual.size();
TextServer::TrimData trim_data = TS->shaped_text_get_trim_data(lines_rid[i]);
const Glyph *glyphs = TS->shaped_text_get_glyphs(lines_rid[i]);
int gl_size = TS->shaped_text_get_glyph_count(lines_rid[i]);
int ellipsis_pos = TS->shaped_text_get_ellipsis_pos(lines_rid[i]);
int trim_pos = TS->shaped_text_get_trim_pos(lines_rid[i]);
const Glyph *ellipsis_glyphs = TS->shaped_text_get_ellipsis_glyphs(lines_rid[i]);
int ellipsis_gl_size = TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]);
// Draw outline. Note: Do not merge this into the single loop with the main text, to prevent overlaps.
if (font_shadow_color.a > 0 || (font_outline_color.a != 0.0 && outline_size > 0)) {
Vector2 offset = ofs;
// Draw RTL ellipsis string when necessary.
if (rtl && trim_data.ellipsis_pos >= 0) {
for (int gl_idx = trim_data.ellipsis_glyph_buf.size() - 1; gl_idx >= 0; gl_idx--) {
for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) {
if (rtl && ellipsis_pos >= 0) {
for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) {
for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) {
//Draw glyph outlines and shadow.
draw_glyph_outline(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs);
offset.x += trim_data.ellipsis_glyph_buf[gl_idx].advance;
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs);
offset.x += ellipsis_glyphs[gl_idx].advance;
}
}
}
@ -410,13 +414,13 @@ void Label::_notification(int p_what) {
for (int j = 0; j < gl_size; j++) {
for (int k = 0; k < glyphs[j].repeat; k++) {
// Trim when necessary.
if (trim_data.trim_pos >= 0) {
if (trim_pos >= 0) {
if (rtl) {
if (j < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
continue;
}
} else {
if (j >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
break;
}
}
@ -428,12 +432,12 @@ void Label::_notification(int p_what) {
}
}
// Draw LTR ellipsis string when necessary.
if (!rtl && trim_data.ellipsis_pos >= 0) {
for (int gl_idx = 0; gl_idx < trim_data.ellipsis_glyph_buf.size(); gl_idx++) {
for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) {
if (!rtl && ellipsis_pos >= 0) {
for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) {
for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) {
//Draw glyph outlines and shadow.
draw_glyph_outline(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs);
offset.x += trim_data.ellipsis_glyph_buf[gl_idx].advance;
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs);
offset.x += ellipsis_glyphs[gl_idx].advance;
}
}
}
@ -442,12 +446,12 @@ void Label::_notification(int p_what) {
// Draw main text. Note: Do not merge this into the single loop with the outline, to prevent overlaps.
// Draw RTL ellipsis string when necessary.
if (rtl && trim_data.ellipsis_pos >= 0) {
for (int gl_idx = trim_data.ellipsis_glyph_buf.size() - 1; gl_idx >= 0; gl_idx--) {
for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) {
if (rtl && ellipsis_pos >= 0) {
for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) {
for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) {
//Draw glyph outlines and shadow.
draw_glyph(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, ofs);
ofs.x += trim_data.ellipsis_glyph_buf[gl_idx].advance;
draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs);
ofs.x += ellipsis_glyphs[gl_idx].advance;
}
}
}
@ -456,13 +460,13 @@ void Label::_notification(int p_what) {
for (int j = 0; j < gl_size; j++) {
for (int k = 0; k < glyphs[j].repeat; k++) {
// Trim when necessary.
if (trim_data.trim_pos >= 0) {
if (trim_pos >= 0) {
if (rtl) {
if (j < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
continue;
}
} else {
if (j >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
break;
}
}
@ -474,12 +478,12 @@ void Label::_notification(int p_what) {
}
}
// Draw LTR ellipsis string when necessary.
if (!rtl && trim_data.ellipsis_pos >= 0) {
for (int gl_idx = 0; gl_idx < trim_data.ellipsis_glyph_buf.size(); gl_idx++) {
for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) {
if (!rtl && ellipsis_pos >= 0) {
for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) {
for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) {
//Draw glyph outlines and shadow.
draw_glyph(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, ofs);
ofs.x += trim_data.ellipsis_glyph_buf[gl_idx].advance;
draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs);
ofs.x += ellipsis_glyphs[gl_idx].advance;
}
}
}

View File

@ -67,10 +67,10 @@ void LineEdit::_move_caret_left(bool p_select, bool p_move_by_word) {
if (p_move_by_word) {
int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 1; i >= 0; i--) {
if (words[i].x < cc) {
cc = words[i].x;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < cc) {
cc = words[i];
break;
}
}
@ -99,10 +99,10 @@ void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) {
if (p_move_by_word) {
int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 0; i < words.size(); i++) {
if (words[i].y > cc) {
cc = words[i].y;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > cc) {
cc = words[i];
break;
}
}
@ -151,10 +151,10 @@ void LineEdit::_backspace(bool p_word, bool p_all_to_left) {
if (p_word) {
int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 1; i >= 0; i--) {
if (words[i].x < cc) {
cc = words[i].x;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < cc) {
cc = words[i];
break;
}
}
@ -194,10 +194,10 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) {
if (p_word) {
int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 0; i < words.size(); i++) {
if (words[i].y > cc) {
cc = words[i].y;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > cc) {
cc = words[i];
break;
}
}
@ -276,12 +276,12 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
// Double-click select word.
last_dblclk = OS::get_singleton()->get_ticks_msec();
last_dblclk_pos = b->get_position();
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 0; i < words.size(); i++) {
if ((words[i].x < caret_column && words[i].y > caret_column) || (i == words.size() - 1 && caret_column == words[i].y)) {
PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 0; i < words.size(); i = i + 2) {
if ((words[i] < caret_column && words[i + 1] > caret_column) || (i == words.size() - 2 && caret_column == words[i + 1])) {
selection.enabled = true;
selection.begin = words[i].x;
selection.end = words[i].y;
selection.begin = words[i];
selection.end = words[i + 1];
selection.double_click = true;
caret_column = selection.end;
break;
@ -737,9 +737,8 @@ void LineEdit::_notification(int p_what) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, selection_color);
}
}
const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(text_rid);
const TextServer::Glyph *glyphs = visual.ptr();
int gl_size = visual.size();
const Glyph *glyphs = TS->shaped_text_get_glyphs(text_rid);
int gl_size = TS->shaped_text_get_glyph_count(text_rid);
// Draw text.
ofs.y += TS->shaped_text_get_ascent(text_rid);
@ -783,38 +782,36 @@ void LineEdit::_notification(int p_what) {
if (draw_caret) {
if (ime_text.length() == 0) {
// Normal caret.
Rect2 l_caret, t_caret;
TextServer::Direction l_dir, t_dir;
TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir);
CaretInfo caret = TS->shaped_text_get_carets(text_rid, caret_column);
if (l_caret == Rect2() && t_caret == Rect2()) {
if (caret.l_caret == Rect2() && caret.t_caret == Rect2()) {
// No carets, add one at the start.
int h = get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size")));
int y = style->get_offset().y + (y_area - h) / 2;
if (rtl) {
l_dir = TextServer::DIRECTION_RTL;
l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h));
caret.l_dir = TextServer::DIRECTION_RTL;
caret.l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h));
} else {
l_dir = TextServer::DIRECTION_LTR;
l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h));
caret.l_dir = TextServer::DIRECTION_LTR;
caret.l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h));
}
RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color);
} else {
if (l_caret != Rect2() && l_dir == TextServer::DIRECTION_AUTO) {
if (caret.l_caret != Rect2() && caret.l_dir == TextServer::DIRECTION_AUTO) {
// Draw extra marker on top of mid caret.
Rect2 trect = Rect2(l_caret.position.x - 3 * caret_width, l_caret.position.y, 6 * caret_width, caret_width);
Rect2 trect = Rect2(caret.l_caret.position.x - 3 * caret_width, caret.l_caret.position.y, 6 * caret_width, caret_width);
trect.position += ofs;
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
}
l_caret.position += ofs;
l_caret.size.x = caret_width;
RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color);
caret.l_caret.position += ofs;
caret.l_caret.size.x = caret_width;
RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color);
t_caret.position += ofs;
t_caret.size.x = caret_width;
caret.t_caret.position += ofs;
caret.t_caret.size.x = caret_width;
RenderingServer::get_singleton()->canvas_item_add_rect(ci, t_caret, caret_color);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.t_caret, caret_color);
}
} else {
{
@ -1114,32 +1111,31 @@ Vector2i LineEdit::get_caret_pixel_pos() {
}
Vector2i ret;
Rect2 l_caret, t_caret;
TextServer::Direction l_dir, t_dir;
CaretInfo caret;
// Get position of the start of caret.
if (ime_text.length() != 0 && ime_selection.x != 0) {
TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x, l_caret, l_dir, t_caret, t_dir);
caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x);
} else {
TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir);
caret = TS->shaped_text_get_carets(text_rid, caret_column);
}
if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) {
ret.x = x_ofs + l_caret.position.x + scroll_offset;
if ((caret.l_caret != Rect2() && (caret.l_dir == TextServer::DIRECTION_AUTO || caret.l_dir == (TextServer::Direction)input_direction)) || (caret.t_caret == Rect2())) {
ret.x = x_ofs + caret.l_caret.position.x + scroll_offset;
} else {
ret.x = x_ofs + t_caret.position.x + scroll_offset;
ret.x = x_ofs + caret.t_caret.position.x + scroll_offset;
}
// Get position of the end of caret.
if (ime_text.length() != 0) {
if (ime_selection.y != 0) {
TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x + ime_selection.y, l_caret, l_dir, t_caret, t_dir);
caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x + ime_selection.y);
} else {
TS->shaped_text_get_carets(text_rid, caret_column + ime_text.size(), l_caret, l_dir, t_caret, t_dir);
caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_text.size());
}
if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) {
ret.y = x_ofs + l_caret.position.x + scroll_offset;
if ((caret.l_caret != Rect2() && (caret.l_dir == TextServer::DIRECTION_AUTO || caret.l_dir == (TextServer::Direction)input_direction)) || (caret.t_caret == Rect2())) {
ret.y = x_ofs + caret.l_caret.position.x + scroll_offset;
} else {
ret.y = x_ofs + t_caret.position.x + scroll_offset;
ret.y = x_ofs + caret.t_caret.position.x + scroll_offset;
}
} else {
ret.y = ret.x;
@ -1502,7 +1498,7 @@ void LineEdit::insert_text_at_caret(String p_text) {
String post = text.substr(caret_column, text.length() - caret_column);
text = pre + p_text + post;
_shape();
TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length());
TextServer::Direction dir = TS->shaped_text_get_dominant_direction_in_range(text_rid, caret_column, caret_column + p_text.length());
if (dir != TextServer::DIRECTION_AUTO) {
input_direction = (TextDirection)dir;
}

View File

@ -819,9 +819,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
}
}
const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid);
const TextServer::Glyph *glyphs = visual.ptr();
int gl_size = visual.size();
const Glyph *glyphs = TS->shaped_text_get_glyphs(rid);
int gl_size = TS->shaped_text_get_glyph_count(rid);
Vector2 gloff = off;
// Draw oulines and shadow.
@ -1593,18 +1592,18 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
if (c_frame) {
const Line &l = c_frame->lines[c_line];
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(l.text_buf->get_rid());
for (int i = 0; i < words.size(); i++) {
if (c_index >= words[i].x && c_index < words[i].y) {
PackedInt32Array words = TS->shaped_text_get_word_breaks(l.text_buf->get_rid());
for (int i = 0; i < words.size(); i = i + 2) {
if (c_index >= words[i] && c_index < words[i + 1]) {
selection.from_frame = c_frame;
selection.from_line = c_line;
selection.from_item = c_item;
selection.from_char = words[i].x;
selection.from_char = words[i];
selection.to_frame = c_frame;
selection.to_line = c_line;
selection.to_item = c_item;
selection.to_char = words[i].y;
selection.to_char = words[i + 1];
selection.active = true;
update();

View File

@ -186,7 +186,7 @@ void TextEdit::Text::_calculate_max_line_width() {
max_width = width;
}
void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Vector<Vector2i> &p_bidi_override) {
void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Array &p_bidi_override) {
ERR_FAIL_INDEX(p_line, text.size());
if (font.is_null() || font_size <= 0) {
@ -278,14 +278,14 @@ void TextEdit::Text::invalidate_all() {
void TextEdit::Text::clear() {
text.clear();
insert(0, "", Vector<Vector2i>());
insert(0, "", Array());
}
int TextEdit::Text::get_max_width() const {
return max_width;
}
void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override) {
void TextEdit::Text::set(int p_line, const String &p_text, const Array &p_bidi_override) {
ERR_FAIL_INDEX(p_line, text.size());
text.write[p_line].data = p_text;
@ -293,7 +293,7 @@ void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i
invalidate_cache(p_line);
}
void TextEdit::Text::insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override) {
void TextEdit::Text::insert(int p_at, const String &p_text, const Array &p_bidi_override) {
Line line;
line.gutters.resize(gutter_count);
line.hidden = false;
@ -1076,9 +1076,8 @@ void TextEdit::_notification(int p_what) {
ofs_y += (row_height - text_height) / 2;
const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid);
const TextServer::Glyph *glyphs = visual.ptr();
int gl_size = visual.size();
const Glyph *glyphs = TS->shaped_text_get_glyphs(rid);
int gl_size = TS->shaped_text_get_glyph_count(rid);
ofs_y += ldata->get_line_ascent(line_wrap_index);
int char_ofs = 0;
@ -1185,27 +1184,26 @@ void TextEdit::_notification(int p_what) {
caret.draw_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index);
if (ime_text.length() == 0) {
Rect2 l_caret, t_caret;
TextServer::Direction l_dir, t_dir;
CaretInfo ts_caret;
if (str.length() != 0) {
// Get carets.
TS->shaped_text_get_carets(rid, caret.column, l_caret, l_dir, t_caret, t_dir);
ts_caret = TS->shaped_text_get_carets(rid, caret.column);
} else {
// No carets, add one at the start.
int h = font->get_height(font_size);
if (rtl) {
l_dir = TextServer::DIRECTION_RTL;
l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h));
ts_caret.l_dir = TextServer::DIRECTION_RTL;
ts_caret.l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h));
} else {
l_dir = TextServer::DIRECTION_LTR;
l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h));
ts_caret.l_dir = TextServer::DIRECTION_LTR;
ts_caret.l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h));
}
}
if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) {
caret.draw_pos.x = char_margin + ofs_x + l_caret.position.x;
if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) {
caret.draw_pos.x = char_margin + ofs_x + ts_caret.l_caret.position.x;
} else {
caret.draw_pos.x = char_margin + ofs_x + t_caret.position.x;
caret.draw_pos.x = char_margin + ofs_x + ts_caret.t_caret.position.x;
}
if (caret.draw_pos.x >= xmargin_beg && caret.draw_pos.x < xmargin_end) {
@ -1215,64 +1213,64 @@ void TextEdit::_notification(int p_what) {
//Block or underline caret, draw trailing carets at full height.
int h = font->get_height(font_size);
if (t_caret != Rect2()) {
if (ts_caret.t_caret != Rect2()) {
if (overtype_mode) {
t_caret.position.y = TS->shaped_text_get_descent(rid);
t_caret.size.y = caret_width;
ts_caret.t_caret.position.y = TS->shaped_text_get_descent(rid);
ts_caret.t_caret.size.y = caret_width;
} else {
t_caret.position.y = -TS->shaped_text_get_ascent(rid);
t_caret.size.y = h;
ts_caret.t_caret.position.y = -TS->shaped_text_get_ascent(rid);
ts_caret.t_caret.size.y = h;
}
t_caret.position += Vector2(char_margin + ofs_x, ofs_y);
draw_rect(t_caret, caret_color, overtype_mode);
ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y);
draw_rect(ts_caret.t_caret, caret_color, overtype_mode);
if (l_caret != Rect2() && l_dir != t_dir) {
l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
l_caret.size.x = caret_width;
draw_rect(l_caret, caret_color * Color(1, 1, 1, 0.5));
if (ts_caret.l_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) {
ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
ts_caret.l_caret.size.x = caret_width;
draw_rect(ts_caret.l_caret, caret_color * Color(1, 1, 1, 0.5));
}
} else { // End of the line.
if (gl_size > 0) {
// Adjust for actual line dimensions.
if (overtype_mode) {
l_caret.position.y = TS->shaped_text_get_descent(rid);
l_caret.size.y = caret_width;
ts_caret.l_caret.position.y = TS->shaped_text_get_descent(rid);
ts_caret.l_caret.size.y = caret_width;
} else {
l_caret.position.y = -TS->shaped_text_get_ascent(rid);
l_caret.size.y = h;
ts_caret.l_caret.position.y = -TS->shaped_text_get_ascent(rid);
ts_caret.l_caret.size.y = h;
}
} else if (overtype_mode) {
l_caret.position.y += l_caret.size.y;
l_caret.size.y = caret_width;
ts_caret.l_caret.position.y += ts_caret.l_caret.size.y;
ts_caret.l_caret.size.y = caret_width;
}
if (l_caret.position.x >= TS->shaped_text_get_size(rid).x) {
l_caret.size.x = font->get_char_size('m', 0, font_size).x;
if (ts_caret.l_caret.position.x >= TS->shaped_text_get_size(rid).x) {
ts_caret.l_caret.size.x = font->get_char_size('m', 0, font_size).x;
} else {
l_caret.size.x = 3 * caret_width;
ts_caret.l_caret.size.x = 3 * caret_width;
}
l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
if (l_dir == TextServer::DIRECTION_RTL) {
l_caret.position.x -= l_caret.size.x;
ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
if (ts_caret.l_dir == TextServer::DIRECTION_RTL) {
ts_caret.l_caret.position.x -= ts_caret.l_caret.size.x;
}
draw_rect(l_caret, caret_color, overtype_mode);
draw_rect(ts_caret.l_caret, caret_color, overtype_mode);
}
} else {
// Normal caret.
if (l_caret != Rect2() && l_dir == TextServer::DIRECTION_AUTO) {
if (ts_caret.l_caret != Rect2() && ts_caret.l_dir == TextServer::DIRECTION_AUTO) {
// Draw extra marker on top of mid caret.
Rect2 trect = Rect2(l_caret.position.x - 3 * caret_width, l_caret.position.y, 6 * caret_width, caret_width);
Rect2 trect = Rect2(ts_caret.l_caret.position.x - 3 * caret_width, ts_caret.l_caret.position.y, 6 * caret_width, caret_width);
trect.position += Vector2(char_margin + ofs_x, ofs_y);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
}
l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
l_caret.size.x = caret_width;
ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
ts_caret.l_caret.size.x = caret_width;
draw_rect(l_caret, caret_color);
draw_rect(ts_caret.l_caret, caret_color);
t_caret.position += Vector2(char_margin + ofs_x, ofs_y);
t_caret.size.x = caret_width;
ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y);
ts_caret.t_caret.size.x = caret_width;
draw_rect(t_caret, caret_color);
draw_rect(ts_caret.t_caret, caret_color);
}
}
}
@ -1968,10 +1966,10 @@ void TextEdit::_move_caret_left(bool p_select, bool p_move_by_word) {
set_caret_line(caret.line - 1);
set_caret_column(text[caret.line].length());
} else {
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = words.size() - 1; i >= 0; i--) {
if (words[i].x < cc) {
cc = words[i].x;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < cc) {
cc = words[i];
break;
}
}
@ -2019,10 +2017,10 @@ void TextEdit::_move_caret_right(bool p_select, bool p_move_by_word) {
set_caret_line(caret.line + 1);
set_caret_column(0);
} else {
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = 0; i < words.size(); i++) {
if (words[i].y > cc) {
cc = words[i].y;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > cc) {
cc = words[i];
break;
}
}
@ -2214,10 +2212,10 @@ void TextEdit::_do_backspace(bool p_word, bool p_all_to_left) {
int line = caret.line;
int column = caret.column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
for (int i = words.size() - 1; i >= 0; i--) {
if (words[i].x < column) {
column = words[i].x;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
for (int i = words.size() - 2; i >= 0; i = i - 2) {
if (words[i] < column) {
column = words[i];
break;
}
}
@ -2257,10 +2255,10 @@ void TextEdit::_delete(bool p_word, bool p_all_to_right) {
int line = caret.line;
int column = caret.column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
for (int i = 0; i < words.size(); i++) {
if (words[i].y > column) {
column = words[i].y;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
for (int i = 1; i < words.size(); i = i + 2) {
if (words[i] > column) {
column = words[i];
break;
}
}
@ -3631,10 +3629,10 @@ int TextEdit::get_caret_wrap_index() const {
}
String TextEdit::get_word_under_caret() const {
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = 0; i < words.size(); i++) {
if (words[i].x <= caret.column && words[i].y > caret.column) {
return text[caret.line].substr(words[i].x, words[i].y - words[i].x);
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = 0; i < words.size(); i = i + 2) {
if (words[i] <= caret.column && words[i + 1] > caret.column) {
return text[caret.line].substr(words[i], words[i + 1] - words[i]);
}
}
return "";
@ -3718,11 +3716,11 @@ void TextEdit::select_word_under_caret() {
int begin = 0;
int end = 0;
const Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = 0; i < words.size(); i++) {
if ((words[i].x < caret.column && words[i].y > caret.column) || (i == words.size() - 1 && caret.column == words[i].y)) {
begin = words[i].x;
end = words[i].y;
const PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid());
for (int i = 0; i < words.size(); i = i + 2) {
if ((words[i] < caret.column && words[i + 1] > caret.column) || (i == words.size() - 2 && caret.column == words[i + 1])) {
begin = words[i];
end = words[i + 1];
break;
}
}
@ -5376,14 +5374,12 @@ int TextEdit::_get_column_x_offset_for_line(int p_char, int p_line) const {
}
}
Rect2 l_caret, t_caret;
TextServer::Direction l_dir, t_dir;
RID text_rid = text.get_line_data(p_line)->get_line_rid(row);
TS->shaped_text_get_carets(text_rid, caret.column, l_caret, l_dir, t_caret, t_dir);
if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) {
return l_caret.position.x;
CaretInfo ts_caret = TS->shaped_text_get_carets(text_rid, caret.column);
if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) {
return ts_caret.l_caret.position.x;
} else {
return t_caret.position.x;
return ts_caret.t_caret.position.x;
}
}
@ -5440,11 +5436,11 @@ void TextEdit::_update_selection_mode_word() {
int caret_pos = CLAMP(col, 0, text[line].length());
int beg = caret_pos;
int end = beg;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
for (int i = 0; i < words.size(); i++) {
if ((words[i].x < caret_pos && words[i].y > caret_pos) || (i == words.size() - 1 && caret_pos == words[i].y)) {
beg = words[i].x;
end = words[i].y;
PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
for (int i = 0; i < words.size(); i = i + 2) {
if ((words[i] < caret_pos && words[i + 1] > caret_pos) || (i == words.size() - 2 && caret_pos == words[i + 1])) {
beg = words[i];
end = words[i + 1];
break;
}
}
@ -6032,7 +6028,7 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
r_end_line = p_line + substrings.size() - 1;
r_end_column = text[r_end_line].length() - postinsert_text.length();
TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text.get_line_data(r_end_line)->get_rid(), (r_end_line == p_line) ? caret.column : 0, r_end_column);
TextServer::Direction dir = TS->shaped_text_get_dominant_direction_in_range(text.get_line_data(r_end_line)->get_rid(), (r_end_line == p_line) ? caret.column : 0, r_end_column);
if (dir != TextServer::DIRECTION_AUTO) {
input_direction = (TextDirection)dir;
}

View File

@ -139,7 +139,7 @@ private:
Vector<Gutter> gutters;
String data;
Vector<Vector2i> bidi_override;
Array bidi_override;
Ref<TextParagraph> data_buf;
Color background_color = Color(0, 0, 0, 0);
@ -194,7 +194,7 @@ private:
Vector<Vector2i> get_line_wrap_ranges(int p_line) const;
const Ref<TextParagraph> get_line_data(int p_line) const;
void set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override);
void set(int p_line, const String &p_text, const Array &p_bidi_override);
void set_hidden(int p_line, bool p_hidden) {
text.write[p_line].hidden = p_hidden;
if (!p_hidden && text[p_line].width > max_width) {
@ -204,12 +204,12 @@ private:
}
}
bool is_hidden(int p_line) const { return text[p_line].hidden; }
void insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override);
void insert(int p_at, const String &p_text, const Array &p_bidi_override);
void remove(int p_at);
int size() const { return text.size(); }
void clear();
void invalidate_cache(int p_line, int p_column = -1, const String &p_ime_text = String(), const Vector<Vector2i> &p_bidi_override = Vector<Vector2i>());
void invalidate_cache(int p_line, int p_column = -1, const String &p_ime_text = String(), const Array &p_bidi_override = Array());
void invalidate_all();
void invalidate_all_lines();

View File

@ -647,13 +647,13 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid);
}
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
p_font->draw_string(canvas_item, p_pos, p_text, p_align, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
}
void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_align, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);

View File

@ -235,8 +235,8 @@ public:
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture);
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));

View File

@ -1404,7 +1404,7 @@ real_t Font::get_underline_thickness(int p_size) const {
return ret;
}
Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, real_t p_width, uint8_t p_flags) const {
Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, real_t p_width, uint16_t p_flags) const {
ERR_FAIL_COND_V(data.is_empty(), Size2());
int size = (p_size <= 0) ? base_size : p_size;
@ -1431,7 +1431,7 @@ Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, re
return buffer->get_size();
}
Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int p_size, uint8_t p_flags) const {
Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int p_size, uint16_t p_flags) const {
ERR_FAIL_COND_V(data.is_empty(), Size2());
int size = (p_size <= 0) ? base_size : p_size;
@ -1470,7 +1470,7 @@ Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int
return ret;
}
void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND(data.is_empty());
int size = (p_size <= 0) ? base_size : p_size;
@ -1512,7 +1512,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t
buffer->draw(p_canvas_item, ofs, p_modulate);
}
void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
ERR_FAIL_COND(data.is_empty());
int size = (p_size <= 0) ? base_size : p_size;

View File

@ -266,11 +266,11 @@ public:
virtual real_t get_underline_thickness(int p_size = -1) const;
// Drawing string.
virtual Size2 get_string_size(const String &p_text, int p_size = -1, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, uint8_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
virtual Size2 get_multiline_string_size(const String &p_text, real_t p_width = -1, int p_size = -1, uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const;
virtual Size2 get_string_size(const String &p_text, int p_size = -1, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
virtual Size2 get_multiline_string_size(const String &p_text, real_t p_width = -1, int p_size = -1, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const;
virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
// Helper functions.
virtual bool has_char(char32_t p_char) const;

View File

@ -53,7 +53,7 @@ void TextLine::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "preserve_control"), "set_preserve_control", "get_preserve_control");
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::_set_bidi_override);
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::set_bidi_override);
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL(""));
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
@ -112,7 +112,7 @@ void TextLine::_shape() {
TS->shaped_text_tab_align(rid, tab_stops);
}
uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING;
uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING;
if (overrun_behavior != OVERRUN_NO_TRIMMING) {
switch (overrun_behavior) {
case OVERRUN_TRIM_WORD_ELLIPSIS:
@ -195,15 +195,7 @@ TextServer::Orientation TextLine::get_orientation() const {
return TS->shaped_text_get_orientation(rid);
}
void TextLine::_set_bidi_override(const Array &p_override) {
Vector<Vector2i> overrides;
for (int i = 0; i < p_override.size(); i++) {
overrides.push_back(p_override[i]);
}
set_bidi_override(overrides);
}
void TextLine::set_bidi_override(const Vector<Vector2i> &p_override) {
void TextLine::set_bidi_override(const Array &p_override) {
TS->shaped_text_set_bidi_override(rid, p_override);
dirty = true;
}
@ -256,14 +248,14 @@ void TextLine::tab_align(const Vector<float> &p_tab_stops) {
dirty = true;
}
void TextLine::set_flags(uint8_t p_flags) {
void TextLine::set_flags(uint16_t p_flags) {
if (flags != p_flags) {
flags = p_flags;
dirty = true;
}
}
uint8_t TextLine::get_flags() const {
uint16_t TextLine::get_flags() const {
return flags;
}

View File

@ -56,7 +56,7 @@ private:
bool dirty = true;
float width = -1.0;
uint8_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
uint16_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
HAlign align = HALIGN_LEFT;
OverrunBehavior overrun_behavior = OVERRUN_TRIM_ELLIPSIS;
@ -75,7 +75,7 @@ public:
void set_direction(TextServer::Direction p_direction);
TextServer::Direction get_direction() const;
void set_bidi_override(const Vector<Vector2i> &p_override);
void set_bidi_override(const Array &p_override);
void set_orientation(TextServer::Orientation p_orientation);
TextServer::Orientation get_orientation() const;
@ -95,8 +95,8 @@ public:
void tab_align(const Vector<float> &p_tab_stops);
void set_flags(uint8_t p_flags);
uint8_t get_flags() const;
void set_flags(uint16_t p_flags);
uint16_t get_flags() const;
void set_text_overrun_behavior(OverrunBehavior p_behavior);
OverrunBehavior get_text_overrun_behavior() const;
@ -120,8 +120,6 @@ public:
int hit_test(float p_coords) const;
void _set_bidi_override(const Array &p_override);
TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
TextLine();
~TextLine();

View File

@ -53,7 +53,7 @@ void TextParagraph::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "preserve_control"), "set_preserve_control", "get_preserve_control");
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextParagraph::_set_bidi_override);
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextParagraph::set_bidi_override);
ClassDB::bind_method(D_METHOD("set_dropcap", "text", "fonts", "size", "dropcap_margins", "opentype_features", "language"), &TextParagraph::set_dropcap, DEFVAL(Rect2()), DEFVAL(Dictionary()), DEFVAL(""));
ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap);
@ -158,9 +158,9 @@ void TextParagraph::_shape_lines() {
if (h_offset > 0) {
// Dropcap, flow around.
Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(rid, width - h_offset, 0, flags);
for (int i = 0; i < line_breaks.size(); i++) {
RID line = TS->shaped_text_substr(rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x);
PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width - h_offset, 0, flags);
for (int i = 0; i < line_breaks.size(); i = i + 2) {
RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]);
float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x;
if (v_offset < h) {
TS->free(line);
@ -171,21 +171,21 @@ void TextParagraph::_shape_lines() {
}
dropcap_lines++;
v_offset -= h;
start = line_breaks[i].y;
start = line_breaks[i + 1];
lines_rid.push_back(line);
}
}
// Use fixed for the rest of lines.
Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(rid, width, start, flags);
for (int i = 0; i < line_breaks.size(); i++) {
RID line = TS->shaped_text_substr(rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x);
PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width, start, flags);
for (int i = 0; i < line_breaks.size(); i = i + 2) {
RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]);
if (!tab_stops.is_empty()) {
TS->shaped_text_tab_align(line, tab_stops);
}
lines_rid.push_back(line);
}
uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING;
uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING;
if (overrun_behavior != OVERRUN_NO_TRIMMING) {
switch (overrun_behavior) {
case OVERRUN_TRIM_WORD_ELLIPSIS:
@ -347,15 +347,7 @@ int TextParagraph::get_spacing_bottom() const {
return spacing_bottom;
}
void TextParagraph::_set_bidi_override(const Array &p_override) {
Vector<Vector2i> overrides;
for (int i = 0; i < p_override.size(); i++) {
overrides.push_back(p_override[i]);
}
set_bidi_override(overrides);
}
void TextParagraph::set_bidi_override(const Vector<Vector2i> &p_override) {
void TextParagraph::set_bidi_override(const Array &p_override) {
TS->shaped_text_set_bidi_override(rid, p_override);
lines_dirty = true;
}
@ -392,14 +384,14 @@ void TextParagraph::tab_align(const Vector<float> &p_tab_stops) {
lines_dirty = true;
}
void TextParagraph::set_flags(uint8_t p_flags) {
void TextParagraph::set_flags(uint16_t p_flags) {
if (flags != p_flags) {
flags = p_flags;
lines_dirty = true;
}
}
uint8_t TextParagraph::get_flags() const {
uint16_t TextParagraph::get_flags() const {
return flags;
}

View File

@ -63,7 +63,7 @@ private:
float width = -1.0;
int max_lines_visible = -1;
uint8_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
uint16_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
OverrunBehavior overrun_behavior = OVERRUN_NO_TRIMMING;
HAlign align = HALIGN_LEFT;
@ -94,7 +94,7 @@ public:
void set_preserve_control(bool p_enabled);
bool get_preserve_control() const;
void set_bidi_override(const Vector<Vector2i> &p_override);
void set_bidi_override(const Array &p_override);
bool set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
void clear_dropcap();
@ -108,8 +108,8 @@ public:
void tab_align(const Vector<float> &p_tab_stops);
void set_flags(uint8_t p_flags);
uint8_t get_flags() const;
void set_flags(uint16_t p_flags);
uint16_t get_flags() const;
void set_text_overrun_behavior(OverrunBehavior p_behavior);
OverrunBehavior get_text_overrun_behavior() const;
@ -153,8 +153,6 @@ public:
int hit_test(const Point2 &p_coords) const;
void _set_bidi_override(const Array &p_override);
TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
TextParagraph();
~TextParagraph();

View File

@ -11,6 +11,7 @@ SConscript("physics_3d/SCsub")
SConscript("physics_2d/SCsub")
SConscript("rendering/SCsub")
SConscript("audio/SCsub")
SConscript("text/SCsub")
lib = env.add_library("servers", env.servers_sources)

View File

@ -70,6 +70,7 @@
#include "rendering/rendering_device_binds.h"
#include "rendering_server.h"
#include "servers/rendering/shader_types.h"
#include "text/text_server_extension.h"
#include "text_server.h"
#include "xr/xr_interface.h"
#include "xr/xr_interface_extension.h"
@ -107,15 +108,11 @@ static bool has_server_feature_callback(const String &p_feature) {
void preregister_server_types() {
shader_types = memnew(ShaderTypes);
GLOBAL_DEF("internationalization/rendering/text_driver", "");
String text_driver_options;
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
if (i > 0) {
text_driver_options += ",";
}
text_driver_options += TextServerManager::get_interface_name(i);
}
ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options));
GDREGISTER_CLASS(TextServerManager);
GDREGISTER_VIRTUAL_CLASS(TextServer);
GDREGISTER_CLASS(TextServerExtension);
Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager"));
}
void register_server_types() {
@ -125,8 +122,6 @@ void register_server_types() {
GDREGISTER_VIRTUAL_CLASS(RenderingServer);
GDREGISTER_CLASS(AudioServer);
GDREGISTER_CLASS(TextServerManager);
GDREGISTER_VIRTUAL_CLASS(TextServer);
TextServer::initialize_hex_code_box_fonts();
GDREGISTER_VIRTUAL_CLASS(PhysicsServer2D);
@ -255,7 +250,6 @@ void register_server_singletons() {
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton(), "PhysicsServer3D"));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton_mut(), "NavigationServer2D"));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton_mut(), "NavigationServer3D"));
Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager"));
Engine::get_singleton()->add_singleton(Engine::Singleton("XRServer", XRServer::get_singleton(), "XRServer"));
Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton(), "CameraServer"));
}

View File

@ -2539,6 +2539,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &RenderingServer::canvas_item_add_rect);
ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &RenderingServer::canvas_item_add_circle);
ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect", "item", "rect", "texture", "tile", "modulate", "transpose"), &RenderingServer::canvas_item_add_texture_rect, DEFVAL(false), DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("canvas_item_add_msdf_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "outline_size", "px_range"), &RenderingServer::canvas_item_add_msdf_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "transpose", "clip_uv"), &RenderingServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true));
ClassDB::bind_method(D_METHOD("canvas_item_add_nine_patch", "item", "rect", "source", "texture", "topleft", "bottomright", "x_axis_mode", "y_axis_mode", "draw_center", "modulate"), &RenderingServer::canvas_item_add_nine_patch, DEFVAL(NINE_PATCH_STRETCH), DEFVAL(NINE_PATCH_STRETCH), DEFVAL(true), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("canvas_item_add_primitive", "item", "points", "colors", "uvs", "texture", "width"), &RenderingServer::canvas_item_add_primitive, DEFVAL(1.0));

5
servers/text/SCsub Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env python
Import("env")
env.add_source_files(env.servers_sources, "*.cpp")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,426 @@
/*************************************************************************/
/* text_server_extension.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEXT_SERVER_EXTENSION_H
#define TEXT_SERVER_EXTENSION_H
#include "core/object/gdvirtual.gen.inc"
#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
#include "servers/text_server.h"
class TextServerExtension : public TextServer {
GDCLASS(TextServerExtension, TextServer);
protected:
_THREAD_SAFE_CLASS_
static void _bind_methods();
public:
virtual bool has_feature(Feature p_feature) const override;
virtual String get_name() const override;
virtual uint32_t get_features() const override;
GDVIRTUAL1RC(bool, _has_feature, Feature);
GDVIRTUAL0RC(String, _get_name);
GDVIRTUAL0RC(uint32_t, _get_features);
virtual void free(RID p_rid) override;
virtual bool has(RID p_rid) override;
virtual bool load_support_data(const String &p_filename) override;
GDVIRTUAL1(_free, RID);
GDVIRTUAL1R(bool, _has, RID);
GDVIRTUAL1R(bool, _load_support_data, const String &);
virtual String get_support_data_filename() const override;
virtual String get_support_data_info() const override;
virtual bool save_support_data(const String &p_filename) const override;
GDVIRTUAL0RC(String, _get_support_data_filename);
GDVIRTUAL0RC(String, _get_support_data_info);
GDVIRTUAL1RC(bool, _save_support_data, const String &);
virtual bool is_locale_right_to_left(const String &p_locale) const override;
GDVIRTUAL1RC(bool, _is_locale_right_to_left, const String &);
virtual int32_t name_to_tag(const String &p_name) const override;
virtual String tag_to_name(int32_t p_tag) const override;
GDVIRTUAL1RC(int32_t, _name_to_tag, const String &);
GDVIRTUAL1RC(String, _tag_to_name, int32_t);
/* Font interface */
virtual RID create_font() override;
GDVIRTUAL0R(RID, _create_font);
virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override;
virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override;
GDVIRTUAL2(_font_set_data, RID, const PackedByteArray &);
GDVIRTUAL3(_font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, uint64_t);
virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override;
virtual bool font_is_antialiased(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_antialiased, RID, bool);
GDVIRTUAL1RC(bool, _font_is_antialiased, RID);
virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) override;
virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_multichannel_signed_distance_field, RID, bool);
GDVIRTUAL1RC(bool, _font_is_multichannel_signed_distance_field, RID);
virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) override;
virtual int font_get_msdf_pixel_range(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_msdf_pixel_range, RID, int);
GDVIRTUAL1RC(int, _font_get_msdf_pixel_range, RID);
virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) override;
virtual int font_get_msdf_size(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_msdf_size, RID, int);
GDVIRTUAL1RC(int, _font_get_msdf_size, RID);
virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) override;
virtual int font_get_fixed_size(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_fixed_size, RID, int);
GDVIRTUAL1RC(int, _font_get_fixed_size, RID);
virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) override;
virtual bool font_is_force_autohinter(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_force_autohinter, RID, bool);
GDVIRTUAL1RC(bool, _font_is_force_autohinter, RID);
virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) override;
virtual Hinting font_get_hinting(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_hinting, RID, Hinting);
GDVIRTUAL1RC(/*Hinting*/ int, _font_get_hinting, RID);
virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override;
virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_variation_coordinates, RID, Dictionary);
GDVIRTUAL1RC(Dictionary, _font_get_variation_coordinates, RID);
virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override;
virtual float font_get_oversampling(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_oversampling, RID, float);
GDVIRTUAL1RC(float, _font_get_oversampling, RID);
virtual Array font_get_size_cache_list(RID p_font_rid) const override;
virtual void font_clear_size_cache(RID p_font_rid) override;
virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override;
GDVIRTUAL1RC(Array, _font_get_size_cache_list, RID);
GDVIRTUAL1(_font_clear_size_cache, RID);
GDVIRTUAL2(_font_remove_size_cache, RID, const Vector2i &);
virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override;
virtual float font_get_ascent(RID p_font_rid, int p_size) const override;
GDVIRTUAL3(_font_set_ascent, RID, int, float);
GDVIRTUAL2RC(float, _font_get_ascent, RID, int);
virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override;
virtual float font_get_descent(RID p_font_rid, int p_size) const override;
GDVIRTUAL3(_font_set_descent, RID, int, float);
GDVIRTUAL2RC(float, _font_get_descent, RID, int);
virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override;
virtual float font_get_underline_position(RID p_font_rid, int p_size) const override;
GDVIRTUAL3(_font_set_underline_position, RID, int, float);
GDVIRTUAL2RC(float, _font_get_underline_position, RID, int);
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override;
virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override;
GDVIRTUAL3(_font_set_underline_thickness, RID, int, float);
GDVIRTUAL2RC(float, _font_get_underline_thickness, RID, int);
virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override;
virtual float font_get_scale(RID p_font_rid, int p_size) const override;
GDVIRTUAL3(_font_set_scale, RID, int, float);
GDVIRTUAL2RC(float, _font_get_scale, RID, int);
virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override;
virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override;
GDVIRTUAL4(_font_set_spacing, RID, int, SpacingType, int);
GDVIRTUAL3RC(int, _font_get_spacing, RID, int, SpacingType);
virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) override;
GDVIRTUAL2RC(int, _font_get_texture_count, RID, const Vector2i &);
GDVIRTUAL2(_font_clear_textures, RID, const Vector2i &);
GDVIRTUAL3(_font_remove_texture, RID, const Vector2i &, int);
virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) override;
virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override;
GDVIRTUAL4(_font_set_texture_image, RID, const Vector2i &, int, const Ref<Image> &);
GDVIRTUAL3RC(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int);
virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) override;
virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override;
GDVIRTUAL4(_font_set_texture_offsets, RID, const Vector2i &, int, const PackedInt32Array &);
GDVIRTUAL3RC(PackedInt32Array, _font_get_texture_offsets, RID, const Vector2i &, int);
virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) override;
GDVIRTUAL2RC(Array, _font_get_glyph_list, RID, const Vector2i &);
GDVIRTUAL2(_font_clear_glyphs, RID, const Vector2i &);
GDVIRTUAL3(_font_remove_glyph, RID, const Vector2i &, int32_t);
virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) override;
GDVIRTUAL3RC(Vector2, _font_get_glyph_advance, RID, int, int32_t);
GDVIRTUAL4(_font_set_glyph_advance, RID, int, int32_t, const Vector2 &);
virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) override;
GDVIRTUAL3RC(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int32_t);
GDVIRTUAL4(_font_set_glyph_offset, RID, const Vector2i &, int32_t, const Vector2 &);
virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) override;
GDVIRTUAL3RC(Vector2, _font_get_glyph_size, RID, const Vector2i &, int32_t);
GDVIRTUAL4(_font_set_glyph_size, RID, const Vector2i &, int32_t, const Vector2 &);
virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) override;
GDVIRTUAL3RC(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int32_t);
GDVIRTUAL4(_font_set_glyph_uv_rect, RID, const Vector2i &, int32_t, const Rect2 &);
virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override;
GDVIRTUAL3RC(int, _font_get_glyph_texture_idx, RID, const Vector2i &, int32_t);
GDVIRTUAL4(_font_set_glyph_texture_idx, RID, const Vector2i &, int32_t, int);
virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override;
GDVIRTUAL3RC(Dictionary, _font_get_glyph_contours, RID, int, int32_t);
virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override;
virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override;
virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) override;
GDVIRTUAL2RC(Array, _font_get_kerning_list, RID, int);
GDVIRTUAL2(_font_clear_kerning_map, RID, int);
GDVIRTUAL3(_font_remove_kerning, RID, int, const Vector2i &);
virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override;
virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const override;
GDVIRTUAL4(_font_set_kerning, RID, int, const Vector2i &, const Vector2 &);
GDVIRTUAL3RC(Vector2, _font_get_kerning, RID, int, const Vector2i &);
virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector = 0) const override;
GDVIRTUAL4RC(int32_t, _font_get_glyph_index, RID, int, char32_t, char32_t);
virtual bool font_has_char(RID p_font_rid, char32_t p_char) const override;
virtual String font_get_supported_chars(RID p_font_rid) const override;
GDVIRTUAL2RC(bool, _font_has_char, RID, char32_t);
GDVIRTUAL1RC(String, _font_get_supported_chars, RID);
virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) override;
virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) override;
GDVIRTUAL4(_font_render_range, RID, const Vector2i &, char32_t, char32_t);
GDVIRTUAL3(_font_render_glyph, RID, const Vector2i &, int32_t);
virtual void font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual void font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
GDVIRTUAL6C(_font_draw_glyph, RID, RID, int, const Vector2 &, int32_t, const Color &);
GDVIRTUAL7C(_font_draw_glyph_outline, RID, RID, int, int, const Vector2 &, int32_t, const Color &);
virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const override;
virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) override;
virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) override;
virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) override;
virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) override;
GDVIRTUAL2RC(bool, _font_is_language_supported, RID, const String &);
GDVIRTUAL3(_font_set_language_support_override, RID, const String &, bool);
GDVIRTUAL2R(bool, _font_get_language_support_override, RID, const String &);
GDVIRTUAL2(_font_remove_language_support_override, RID, const String &);
GDVIRTUAL1R(Vector<String>, _font_get_language_support_overrides, RID);
virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const override;
virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) override;
virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) override;
virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override;
virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override;
GDVIRTUAL2RC(bool, _font_is_script_supported, RID, const String &);
GDVIRTUAL3(_font_set_script_support_override, RID, const String &, bool);
GDVIRTUAL2R(bool, _font_get_script_support_override, RID, const String &);
GDVIRTUAL2(_font_remove_script_support_override, RID, const String &);
GDVIRTUAL1R(Vector<String>, _font_get_script_support_overrides, RID);
virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
GDVIRTUAL1RC(Dictionary, _font_supported_feature_list, RID);
GDVIRTUAL1RC(Dictionary, _font_supported_variation_list, RID);
virtual float font_get_global_oversampling() const override;
virtual void font_set_global_oversampling(float p_oversampling) override;
GDVIRTUAL0RC(float, _font_get_global_oversampling);
GDVIRTUAL1(_font_set_global_oversampling, float);
virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const override;
virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const override;
GDVIRTUAL2RC(Vector2, _get_hex_code_box_size, int, char32_t);
GDVIRTUAL5C(_draw_hex_code_box, RID, int, const Vector2 &, char32_t, const Color &);
/* Shaped text buffer interface */
virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
GDVIRTUAL2R(RID, _create_shaped_text, Direction, Orientation);
virtual void shaped_text_clear(RID p_shaped) override;
GDVIRTUAL1(_shaped_text_clear, RID);
virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override;
virtual Direction shaped_text_get_direction(RID p_shaped) const override;
GDVIRTUAL2(_shaped_text_set_direction, RID, Direction);
GDVIRTUAL1RC(/*Direction*/ int, _shaped_text_get_direction, RID);
virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override;
GDVIRTUAL2(_shaped_text_set_bidi_override, RID, const Array &);
virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
virtual Orientation shaped_text_get_orientation(RID p_shaped) const override;
GDVIRTUAL2(_shaped_text_set_orientation, RID, Orientation);
GDVIRTUAL1RC(/*Orientation*/ int, _shaped_text_get_orientation, RID);
virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const override;
GDVIRTUAL2(_shaped_text_set_preserve_invalid, RID, bool);
GDVIRTUAL1RC(bool, _shaped_text_get_preserve_invalid, RID);
virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_control(RID p_shaped) const override;
GDVIRTUAL2(_shaped_text_set_preserve_control, RID, bool);
GDVIRTUAL1RC(bool, _shaped_text_get_preserve_control, RID);
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override;
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override;
GDVIRTUAL6R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &);
GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlign, int);
GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlign);
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
GDVIRTUAL3RC(RID, _shaped_text_substr, RID, int, int);
GDVIRTUAL1RC(RID, _shaped_text_get_parent, RID);
virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override;
GDVIRTUAL3R(float, _shaped_text_fit_to_width, RID, float, uint16_t);
GDVIRTUAL2R(float, _shaped_text_tab_align, RID, const PackedFloat32Array &);
virtual bool shaped_text_shape(RID p_shaped) override;
virtual bool shaped_text_update_breaks(RID p_shaped) override;
virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
GDVIRTUAL1R(bool, _shaped_text_shape, RID);
GDVIRTUAL1R(bool, _shaped_text_update_breaks, RID);
GDVIRTUAL1R(bool, _shaped_text_update_justification_ops, RID);
virtual bool shaped_text_is_ready(RID p_shaped) const override;
GDVIRTUAL1RC(bool, _shaped_text_is_ready, RID);
virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override;
virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override;
virtual int shaped_text_get_glyph_count(RID p_shaped) const override;
GDVIRTUAL2C(_shaped_text_get_glyphs, RID, GDNativePtr<const Glyph *>);
GDVIRTUAL2(_shaped_text_sort_logical, RID, GDNativePtr<const Glyph *>);
GDVIRTUAL1RC(int, _shaped_text_get_glyph_count, RID);
virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
GDVIRTUAL1RC(Vector2i, _shaped_text_get_range, RID);
virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override;
GDVIRTUAL5RC(PackedInt32Array, _shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int, bool, uint16_t);
GDVIRTUAL4RC(PackedInt32Array, _shaped_text_get_line_breaks, RID, float, int, uint16_t);
GDVIRTUAL2RC(PackedInt32Array, _shaped_text_get_word_breaks, RID, int);
virtual int shaped_text_get_trim_pos(RID p_shaped) const override;
virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override;
virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override;
virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override;
GDVIRTUAL1RC(int, _shaped_text_get_trim_pos, RID);
GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_pos, RID);
GDVIRTUAL2C(_shaped_text_get_ellipsis_glyphs, RID, GDNativePtr<const Glyph *>);
GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_glyph_count, RID);
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override;
GDVIRTUAL3(_shaped_text_overrun_trim_to_width, RID, float, uint16_t);
virtual Array shaped_text_get_objects(RID p_shaped) const override;
virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override;
GDVIRTUAL1RC(Array, _shaped_text_get_objects, RID);
GDVIRTUAL2RC(Rect2, _shaped_text_get_object_rect, RID, Variant);
virtual Size2 shaped_text_get_size(RID p_shaped) const override;
virtual float shaped_text_get_ascent(RID p_shaped) const override;
virtual float shaped_text_get_descent(RID p_shaped) const override;
virtual float shaped_text_get_width(RID p_shaped) const override;
virtual float shaped_text_get_underline_position(RID p_shaped) const override;
virtual float shaped_text_get_underline_thickness(RID p_shaped) const override;
GDVIRTUAL1RC(Size2, _shaped_text_get_size, RID);
GDVIRTUAL1RC(float, _shaped_text_get_ascent, RID);
GDVIRTUAL1RC(float, _shaped_text_get_descent, RID);
GDVIRTUAL1RC(float, _shaped_text_get_width, RID);
GDVIRTUAL1RC(float, _shaped_text_get_underline_position, RID);
GDVIRTUAL1RC(float, _shaped_text_get_underline_thickness, RID);
virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const override;
GDVIRTUAL3RC(int, _shaped_text_get_dominant_direction_in_range, RID, int, int);
virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const override;
virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const override;
GDVIRTUAL3C(_shaped_text_get_carets, RID, int, GDNativePtr<CaretInfo>);
GDVIRTUAL3RC(Vector<Vector2>, _shaped_text_get_selection, RID, int, int);
virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const override;
virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const override;
GDVIRTUAL2RC(int, _shaped_text_hit_test_grapheme, RID, float);
GDVIRTUAL2RC(int, _shaped_text_hit_test_position, RID, float);
virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const override;
virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const override;
GDVIRTUAL6C(_shaped_text_draw, RID, RID, const Vector2 &, float, float, const Color &);
GDVIRTUAL7C(_shaped_text_draw_outline, RID, RID, const Vector2 &, float, float, int, const Color &);
virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const override;
virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const override;
GDVIRTUAL2RC(int, _shaped_text_next_grapheme_pos, RID, int);
GDVIRTUAL2RC(int, _shaped_text_prev_grapheme_pos, RID, int);
virtual String format_number(const String &p_string, const String &p_language = "") const override;
virtual String parse_number(const String &p_string, const String &p_language = "") const override;
virtual String percent_sign(const String &p_language = "") const override;
GDVIRTUAL2RC(String, _format_number, const String &, const String &);
GDVIRTUAL2RC(String, _parse_number, const String &, const String &);
GDVIRTUAL1RC(String, _percent_sign, const String &);
TextServerExtension();
~TextServerExtension();
};
#endif // TEXT_SERVER_EXTENSION_H

File diff suppressed because it is too large Load Diff

View File

@ -34,13 +34,17 @@
#include "core/object/ref_counted.h"
#include "core/os/os.h"
#include "core/templates/rid.h"
#include "core/variant/native_ptr.h"
#include "core/variant/variant.h"
#include "scene/resources/texture.h"
class CanvasTexture;
class TextServer : public Object {
GDCLASS(TextServer, Object);
struct Glyph;
struct CaretInfo;
class TextServer : public RefCounted {
GDCLASS(TextServer, RefCounted);
public:
enum Direction {
@ -63,12 +67,12 @@ public:
JUSTIFICATION_CONSTRAIN_ELLIPSIS = 1 << 4,
};
enum LineBreakFlag {
enum LineBreakFlag { // LineBreakFlag can be passed in the same value as the JustificationFlag, do not use the same values.
BREAK_NONE = 0,
BREAK_MANDATORY = 1 << 4,
BREAK_WORD_BOUND = 1 << 5,
BREAK_GRAPHEME_BOUND = 1 << 6,
BREAK_WORD_BOUND_ADAPTIVE = 1 << 5 | 1 << 7,
BREAK_MANDATORY = 1 << 5,
BREAK_WORD_BOUND = 1 << 6,
BREAK_GRAPHEME_BOUND = 1 << 7,
BREAK_WORD_BOUND_ADAPTIVE = 1 << 6 | 1 << 8,
};
enum TextOverrunFlag {
@ -124,50 +128,11 @@ public:
SPACING_BOTTOM,
};
struct Glyph {
int start = -1; // Start offset in the source string.
int end = -1; // End offset in the source string.
uint8_t count = 0; // Number of glyphs in the grapheme, set in the first glyph only.
uint8_t repeat = 1; // Draw multiple times in the row.
uint16_t flags = 0; // Grapheme flags (valid, rtl, virtual), set in the first glyph only.
real_t x_off = 0.f; // Offset from the origin of the glyph on baseline.
real_t y_off = 0.f;
real_t advance = 0.f; // Advance to the next glyph along baseline(x for horizontal layout, y for vertical).
RID font_rid; // Font resource.
int font_size = 0; // Font size;
int32_t index = 0; // Glyph index (font specific) or UTF-32 codepoint (for the invalid glyphs).
bool operator==(const Glyph &p_a) const;
bool operator!=(const Glyph &p_a) const;
bool operator<(const Glyph &p_a) const;
bool operator>(const Glyph &p_a) const;
};
struct GlyphCompare { // For line breaking reordering.
_FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const {
if (l.start == r.start) {
if (l.count == r.count) {
if ((l.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) {
return false;
} else {
return true;
}
}
return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant.
} else {
return l.start < r.start;
}
}
};
protected:
struct TrimData {
int trim_pos = -1;
int ellipsis_pos = -1;
Vector<TextServer::Glyph> ellipsis_glyph_buf;
Vector<Glyph> ellipsis_glyph_buf;
};
struct ShapedTextData {
@ -215,22 +180,21 @@ public:
bool preserve_invalid = true; // Draw hex code box instead of missing characters.
bool preserve_control = false; // Draw control characters.
real_t ascent = 0.f; // Ascent for horizontal layout, 1/2 of width for vertical.
real_t descent = 0.f; // Descent for horizontal layout, 1/2 of width for vertical.
real_t width = 0.f; // Width for horizontal layout, height for vertical.
real_t width_trimmed = 0.f;
float ascent = 0.f; // Ascent for horizontal layout, 1/2 of width for vertical.
float descent = 0.f; // Descent for horizontal layout, 1/2 of width for vertical.
float width = 0.f; // Width for horizontal layout, height for vertical.
float width_trimmed = 0.f;
real_t upos = 0.f;
real_t uthk = 0.f;
float upos = 0.f;
float uthk = 0.f;
TrimData overrun_trim_data;
bool fit_width_minimum_reached = false;
Vector<TextServer::Glyph> glyphs;
Vector<TextServer::Glyph> glyphs_logical;
Vector<Glyph> glyphs;
Vector<Glyph> glyphs_logical;
};
protected:
static void _bind_methods();
static Vector3 hex_code_box_font_size[2];
@ -240,20 +204,19 @@ public:
static void initialize_hex_code_box_fonts();
static void finish_hex_code_box_fonts();
virtual bool has_feature(Feature p_feature) = 0;
virtual bool has_feature(Feature p_feature) const = 0;
virtual String get_name() const = 0;
virtual uint32_t get_features() const = 0;
virtual void free(RID p_rid) = 0;
virtual bool has(RID p_rid) = 0;
virtual bool load_support_data(const String &p_filename) = 0;
#ifdef TOOLS_ENABLED
virtual String get_support_data_filename() = 0;
virtual String get_support_data_info() = 0;
virtual bool save_support_data(const String &p_filename) = 0;
#endif
virtual String get_support_data_filename() const = 0;
virtual String get_support_data_info() const = 0;
virtual bool save_support_data(const String &p_filename) const = 0;
virtual bool is_locale_right_to_left(const String &p_locale) = 0;
virtual bool is_locale_right_to_left(const String &p_locale) const = 0;
virtual int32_t name_to_tag(const String &p_name) const { return 0; };
virtual String tag_to_name(int32_t p_tag) const { return ""; };
@ -282,33 +245,33 @@ public:
virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) = 0;
virtual bool font_is_force_autohinter(RID p_font_rid) const = 0;
virtual void font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) = 0;
virtual TextServer::Hinting font_get_hinting(RID p_font_rid) const = 0;
virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) = 0;
virtual Hinting font_get_hinting(RID p_font_rid) const = 0;
virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) = 0;
virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const = 0;
virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) = 0;
virtual real_t font_get_oversampling(RID p_font_rid) const = 0;
virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) = 0;
virtual float font_get_oversampling(RID p_font_rid) const = 0;
virtual Array font_get_size_cache_list(RID p_font_rid) const = 0;
virtual void font_clear_size_cache(RID p_font_rid) = 0;
virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) = 0;
virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) = 0;
virtual real_t font_get_ascent(RID p_font_rid, int p_size) const = 0;
virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) = 0;
virtual float font_get_ascent(RID p_font_rid, int p_size) const = 0;
virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) = 0;
virtual real_t font_get_descent(RID p_font_rid, int p_size) const = 0;
virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) = 0;
virtual float font_get_descent(RID p_font_rid, int p_size) const = 0;
virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) = 0;
virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const = 0;
virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) = 0;
virtual float font_get_underline_position(RID p_font_rid, int p_size) const = 0;
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) = 0;
virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const = 0;
virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) = 0;
virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const = 0;
virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) = 0;
virtual real_t font_get_scale(RID p_font_rid, int p_size) const = 0;
virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) = 0;
virtual float font_get_scale(RID p_font_rid, int p_size) const = 0;
virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) = 0;
virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const = 0;
@ -342,7 +305,7 @@ public:
virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0;
virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) = 0;
virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const = 0;
virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const = 0;
virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const = 0;
virtual void font_clear_kerning_map(RID p_font_rid, int p_size) = 0;
@ -377,11 +340,11 @@ public:
virtual Dictionary font_supported_feature_list(RID p_font_rid) const = 0;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const = 0;
virtual real_t font_get_global_oversampling() const = 0;
virtual void font_set_global_oversampling(real_t p_oversampling) = 0;
virtual float font_get_global_oversampling() const = 0;
virtual void font_set_global_oversampling(float p_oversampling) = 0;
Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const;
void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const;
virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const;
virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const;
/* Shaped text buffer interface */
@ -392,7 +355,7 @@ public:
virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) = 0;
virtual Direction shaped_text_get_direction(RID p_shaped) const = 0;
virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) = 0;
virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) = 0;
virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0;
virtual Orientation shaped_text_get_orientation(RID p_shaped) const = 0;
@ -410,8 +373,8 @@ public:
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
virtual RID shaped_text_get_parent(RID p_shaped) const = 0;
virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0;
virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) = 0;
virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0;
virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) = 0;
virtual bool shaped_text_shape(RID p_shaped) = 0;
virtual bool shaped_text_update_breaks(RID p_shaped) = 0;
@ -419,119 +382,142 @@ public:
virtual bool shaped_text_is_ready(RID p_shaped) const = 0;
virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const = 0;
virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const = 0;
Array _shaped_text_get_glyphs_wrapper(RID p_shaped) const;
virtual const Glyph *shaped_text_sort_logical(RID p_shaped) = 0;
Array _shaped_text_sort_logical_wrapper(RID p_shaped);
virtual int shaped_text_get_glyph_count(RID p_shaped) const = 0;
virtual Vector2i shaped_text_get_range(RID p_shaped) const = 0;
virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) = 0;
virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
virtual Vector<Vector2i> shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start = 0, bool p_once = true, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
virtual Vector<Vector2i> shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start = 0, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
virtual int shaped_text_get_trim_pos(RID p_shaped) const = 0;
virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const = 0;
virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const = 0;
Array _shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const;
virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const = 0;
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) = 0;
virtual TrimData shaped_text_get_trim_data(RID p_shaped) const;
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) = 0;
virtual Array shaped_text_get_objects(RID p_shaped) const = 0;
virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const = 0;
virtual Size2 shaped_text_get_size(RID p_shaped) const = 0;
virtual real_t shaped_text_get_ascent(RID p_shaped) const = 0;
virtual real_t shaped_text_get_descent(RID p_shaped) const = 0;
virtual real_t shaped_text_get_width(RID p_shaped) const = 0;
virtual real_t shaped_text_get_underline_position(RID p_shaped) const = 0;
virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const = 0;
virtual float shaped_text_get_ascent(RID p_shaped) const = 0;
virtual float shaped_text_get_descent(RID p_shaped) const = 0;
virtual float shaped_text_get_width(RID p_shaped) const = 0;
virtual float shaped_text_get_underline_position(RID p_shaped) const = 0;
virtual float shaped_text_get_underline_thickness(RID p_shaped) const = 0;
virtual Direction shaped_text_get_dominant_direciton_in_range(RID p_shaped, int p_start, int p_end) const;
virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const;
virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const;
Dictionary _shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const;
virtual void shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_leading_caret, Direction &p_leading_dir, Rect2 &p_trailing_caret, Direction &p_trailing_dir) const;
virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const;
virtual int shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) const; // Return grapheme index.
virtual int shaped_text_hit_test_position(RID p_shaped, real_t p_coords) const; // Return caret/selection position.
virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const; // Return grapheme index.
virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const; // Return caret/selection position.
virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos);
virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos);
virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const;
virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const;
// The pen position is always placed on the baseline and moveing left to right.
virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l = -1.f, real_t p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const;
virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l = -1.f, real_t p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const;
virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
// Number conversion.
virtual String format_number(const String &p_string, const String &p_language = "") const { return p_string; };
virtual String parse_number(const String &p_string, const String &p_language = "") const { return p_string; };
virtual String percent_sign(const String &p_language = "") const { return "%"; };
/* GDScript wrappers */
RID _create_font_memory(const PackedByteArray &p_data, int p_base_size = 16);
Dictionary _font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const;
Array _shaped_text_get_glyphs(RID p_shaped) const;
Dictionary _shaped_text_get_carets(RID p_shaped, int p_position) const;
void _shaped_text_set_bidi_override(RID p_shaped, const Array &p_override);
Array _shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint8_t p_break_flags) const;
Array _shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t p_break_flags) const;
Array _shaped_text_get_word_breaks(RID p_shaped) const;
Array _shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const;
TextServer();
~TextServer();
};
/*************************************************************************/
struct Glyph {
int start = -1; // Start offset in the source string.
int end = -1; // End offset in the source string.
uint8_t count = 0; // Number of glyphs in the grapheme, set in the first glyph only.
uint8_t repeat = 1; // Draw multiple times in the row.
uint16_t flags = 0; // Grapheme flags (valid, rtl, virtual), set in the first glyph only.
float x_off = 0.f; // Offset from the origin of the glyph on baseline.
float y_off = 0.f;
float advance = 0.f; // Advance to the next glyph along baseline(x for horizontal layout, y for vertical).
RID font_rid; // Font resource.
int font_size = 0; // Font size;
int32_t index = 0; // Glyph index (font specific) or UTF-32 codepoint (for the invalid glyphs).
bool operator==(const Glyph &p_a) const;
bool operator!=(const Glyph &p_a) const;
bool operator<(const Glyph &p_a) const;
bool operator>(const Glyph &p_a) const;
};
struct CaretInfo {
Rect2 l_caret;
Rect2 t_caret;
TextServer::Direction l_dir;
TextServer::Direction t_dir;
};
struct GlyphCompare { // For line breaking reordering.
_FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const {
if (l.start == r.start) {
if (l.count == r.count) {
if ((l.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) {
return false;
} else {
return true;
}
}
return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant.
} else {
return l.start < r.start;
}
}
};
/*************************************************************************/
class TextServerManager : public Object {
GDCLASS(TextServerManager, Object);
public:
typedef TextServer *(*CreateFunction)(Error &r_error, void *p_user_data);
protected:
static void _bind_methods();
private:
static TextServerManager *singleton;
static TextServer *server;
enum {
MAX_SERVERS = 64
};
struct TextServerCreate {
String name;
CreateFunction create_function = nullptr;
uint32_t features = 0;
TextServer *instance = nullptr;
void *user_data = nullptr;
};
static TextServerCreate server_create_functions[MAX_SERVERS];
static int server_create_count;
Ref<TextServer> primary_interface;
Vector<Ref<TextServer>> interfaces;
public:
_FORCE_INLINE_ static TextServerManager *get_singleton() {
return singleton;
}
static void register_create_function(const String &p_name, uint32_t p_features, CreateFunction p_function, void *p_user_data);
static int get_interface_count();
static String get_interface_name(int p_index);
static uint32_t get_interface_features(int p_index);
static TextServer *initialize(int p_index, Error &r_error);
static TextServer *get_primary_interface();
void add_interface(const Ref<TextServer> &p_interface);
void remove_interface(const Ref<TextServer> &p_interface);
int get_interface_count() const;
Ref<TextServer> get_interface(int p_index) const;
Ref<TextServer> find_interface(const String &p_name) const;
Array get_interfaces() const;
/* GDScript wrappers */
int _get_interface_count() const;
String _get_interface_name(int p_index) const;
uint32_t _get_interface_features(int p_index) const;
TextServer *_get_interface(int p_index) const;
Array _get_interfaces() const;
TextServer *_find_interface(const String &p_name) const;
bool _set_primary_interface(int p_index);
TextServer *_get_primary_interface() const;
_FORCE_INLINE_ Ref<TextServer> get_primary_interface() const {
return primary_interface;
}
Ref<TextServer> _get_primary_interface() const;
void set_primary_interface(const Ref<TextServer> &p_primary_interface);
TextServerManager();
~TextServerManager();
@ -539,7 +525,7 @@ public:
/*************************************************************************/
#define TS TextServerManager::get_primary_interface()
#define TS TextServerManager::get_singleton()->get_primary_interface()
VARIANT_ENUM_CAST(TextServer::Direction);
VARIANT_ENUM_CAST(TextServer::Orientation);
@ -552,4 +538,8 @@ VARIANT_ENUM_CAST(TextServer::Feature);
VARIANT_ENUM_CAST(TextServer::ContourPointTag);
VARIANT_ENUM_CAST(TextServer::SpacingType);
GDVIRTUAL_NATIVE_PTR(Glyph);
GDVIRTUAL_NATIVE_PTR(Glyph *);
GDVIRTUAL_NATIVE_PTR(CaretInfo);
#endif // TEXT_SERVER_H

View File

@ -174,10 +174,8 @@ struct GodotTestCaseListener : public doctest::IReporter {
memnew(MessageQueue);
GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false);
memnew(TextServerManager);
Error err = OK;
TextServerManager::initialize(0, err);
Error err = OK;
OS::get_singleton()->set_has_server_feature_callback(nullptr);
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
if (String("headless") == DisplayServer::get_create_function_name(i)) {
@ -224,10 +222,6 @@ struct GodotTestCaseListener : public doctest::IReporter {
clear_default_theme();
if (TextServerManager::get_singleton()) {
memdelete(TextServerManager::get_singleton());
}
if (navigation_3d_server) {
memdelete(navigation_3d_server);
navigation_3d_server = nullptr;

View File

@ -41,19 +41,10 @@ namespace TestTextServer {
TEST_SUITE("[[TextServer]") {
TEST_CASE("[TextServer] Init, font loading and shaping") {
TextServerManager *tsman = memnew(TextServerManager);
Error err = OK;
SUBCASE("[TextServer] Init") {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
TextServer *ts = TextServerManager::initialize(i, err);
TEST_FAIL_COND((err != OK || ts == nullptr), "Text server ", TextServerManager::get_interface_name(i), " init failed.");
}
}
SUBCASE("[TextServer] Loading fonts") {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
TextServer *ts = TextServerManager::initialize(i, err);
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
RID font = ts->create_font();
ts->font_set_data_ptr(font, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
@ -63,8 +54,9 @@ TEST_SUITE("[[TextServer]") {
}
SUBCASE("[TextServer] Text layout: Font fallback") {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
TextServer *ts = TextServerManager::initialize(i, err);
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
RID font1 = ts->create_font();
ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
@ -83,9 +75,10 @@ TEST_SUITE("[[TextServer]") {
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
Vector<TextServer::Glyph> glyphs = ts->shaped_text_get_glyphs(ctx);
TEST_FAIL_COND(glyphs.size() == 0, "Shaping failed");
for (int j = 0; j < glyphs.size(); j++) {
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size == 0, "Shaping failed");
for (int j = 0; j < gl_size; j++) {
if (glyphs[j].start < 6) {
TEST_FAIL_COND(glyphs[j].font_rid != font[1], "Incorrect font selected.");
}
@ -110,8 +103,9 @@ TEST_SUITE("[[TextServer]") {
}
SUBCASE("[TextServer] Text layout: BiDi") {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
TextServer *ts = TextServerManager::initialize(i, err);
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
if (!ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) {
continue;
@ -134,9 +128,10 @@ TEST_SUITE("[[TextServer]") {
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
Vector<TextServer::Glyph> glyphs = ts->shaped_text_get_glyphs(ctx);
TEST_FAIL_COND(glyphs.size() == 0, "Shaping failed");
for (int j = 0; j < glyphs.size(); j++) {
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size == 0, "Shaping failed");
for (int j = 0; j < gl_size; j++) {
if (glyphs[j].count > 0) {
if (glyphs[j].start < 7) {
TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction.");
@ -160,8 +155,9 @@ TEST_SUITE("[[TextServer]") {
}
SUBCASE("[TextServer] Text layout: Line breaking") {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
TextServer *ts = TextServerManager::initialize(i, err);
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
String test_1 = U"test test test";
// 5^ 10^
@ -180,12 +176,17 @@ TEST_SUITE("[[TextServer]") {
bool ok = ts->shaped_text_add_string(ctx, test_1, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
Vector<Vector2i> brks = ts->shaped_text_get_line_breaks(ctx, 1);
TEST_FAIL_COND(brks.size() != 3, "Invalid line breaks number.");
if (brks.size() == 3) {
TEST_FAIL_COND(brks[0] != Vector2i(0, 5), "Invalid line break position.");
TEST_FAIL_COND(brks[1] != Vector2i(5, 10), "Invalid line break position.");
TEST_FAIL_COND(brks[2] != Vector2i(10, 14), "Invalid line break position.");
PackedInt32Array brks = ts->shaped_text_get_line_breaks(ctx, 1);
TEST_FAIL_COND(brks.size() != 6, "Invalid line breaks number.");
if (brks.size() == 6) {
TEST_FAIL_COND(brks[0] != 0, "Invalid line break position.");
TEST_FAIL_COND(brks[1] != 5, "Invalid line break position.");
TEST_FAIL_COND(brks[2] != 5, "Invalid line break position.");
TEST_FAIL_COND(brks[3] != 10, "Invalid line break position.");
TEST_FAIL_COND(brks[4] != 10, "Invalid line break position.");
TEST_FAIL_COND(brks[5] != 14, "Invalid line break position.");
}
ts->free(ctx);
@ -198,8 +199,9 @@ TEST_SUITE("[[TextServer]") {
}
SUBCASE("[TextServer] Text layout: Justification") {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
TextServer *ts = TextServerManager::initialize(i, err);
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
RID font1 = ts->create_font();
ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
@ -263,7 +265,6 @@ TEST_SUITE("[[TextServer]") {
font.clear();
}
}
memdelete(tsman);
}
}
}; // namespace TestTextServer