mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 11:32:13 +00:00
Implement TextServer GDExtension interface, remove TextServer GDNative interface.
This commit is contained in:
parent
06c1b40b84
commit
0c0b5c84b0
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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].
|
||||
|
@ -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">
|
||||
|
@ -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" />
|
||||
|
@ -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">
|
||||
|
@ -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>
|
||||
|
1262
doc/classes/TextServerExtension.xml
Normal file
1262
doc/classes/TextServerExtension.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -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>
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
130
main/main.cpp
130
main/main.cpp
@ -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);
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ Export("env_gdnative")
|
||||
|
||||
SConscript("pluginscript/SCsub")
|
||||
SConscript("videodecoder/SCsub")
|
||||
SConscript("text/SCsub")
|
||||
|
||||
|
||||
import gdnative_builders
|
||||
|
@ -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"
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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" {',
|
||||
|
@ -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 */
|
@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
Import("env_gdnative")
|
||||
|
||||
env_gdnative.add_source_files(env.modules_sources, "*.cpp")
|
@ -1,6 +0,0 @@
|
||||
def can_build(env, platform):
|
||||
return True
|
||||
|
||||
|
||||
def configure(env):
|
||||
pass
|
@ -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() {}
|
@ -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
@ -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
|
@ -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"
|
||||
|
10
modules/text_server_adv/doc_classes/TextServerAdvanced.xml
Normal file
10
modules/text_server_adv/doc_classes/TextServerAdvanced.xml
Normal 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>
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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"
|
||||
|
10
modules/text_server_fb/doc_classes/TextServerFallback.xml
Normal file
10
modules/text_server_fb/doc_classes/TextServerFallback.xml
Normal 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>
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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"));
|
||||
}
|
||||
|
@ -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
5
servers/text/SCsub
Normal file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
|
||||
env.add_source_files(env.servers_sources, "*.cpp")
|
1281
servers/text/text_server_extension.cpp
Normal file
1281
servers/text/text_server_extension.cpp
Normal file
File diff suppressed because it is too large
Load Diff
426
servers/text/text_server_extension.h
Normal file
426
servers/text/text_server_extension.h
Normal 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
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user