mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
[RTL] Use separate paragraph copy for the partially visible paragraphs.
This commit is contained in:
parent
019889d1da
commit
0d19e18b00
19 changed files with 346 additions and 51 deletions
|
|
@ -58,6 +58,12 @@
|
|||
Draw text into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
|
||||
</description>
|
||||
</method>
|
||||
<method name="duplicate" qualifiers="const">
|
||||
<return type="TextLine" />
|
||||
<description>
|
||||
Duplicates this [TextLine].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_inferred_direction" qualifiers="const">
|
||||
<return type="int" enum="TextServer.Direction" />
|
||||
<description>
|
||||
|
|
@ -119,6 +125,13 @@
|
|||
Returns size of the bounding box of the text.
|
||||
</description>
|
||||
</method>
|
||||
<method name="has_object" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="key" type="Variant" />
|
||||
<description>
|
||||
Returns [code]true[/code] if an object with [param key] is embedded in this line.
|
||||
</description>
|
||||
</method>
|
||||
<method name="hit_test" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="coords" type="float" />
|
||||
|
|
|
|||
|
|
@ -110,6 +110,12 @@
|
|||
Draw outlines of all lines of the text and drop cap into a canvas item at a given position, with [param color]. [param pos] specifies the top left corner of the bounding box. If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
|
||||
</description>
|
||||
</method>
|
||||
<method name="duplicate" qualifiers="const">
|
||||
<return type="TextParagraph" />
|
||||
<description>
|
||||
Duplicates this [TextParagraph].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_dropcap_lines" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
|
|
@ -235,6 +241,13 @@
|
|||
Returns the size of the bounding box of the paragraph.
|
||||
</description>
|
||||
</method>
|
||||
<method name="has_object" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="key" type="Variant" />
|
||||
<description>
|
||||
Returns [code]true[/code] if an object with [param key] is embedded in this shaped text buffer.
|
||||
</description>
|
||||
</method>
|
||||
<method name="hit_test" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="coords" type="Vector2" />
|
||||
|
|
|
|||
|
|
@ -1418,6 +1418,13 @@
|
|||
[param clip_l] and [param clip_r] are offsets relative to [param pos], going to the right in horizontal layout and downward in vertical layout. If [param clip_l] is not negative, glyphs starting before the offset are clipped. If [param clip_r] is not negative, glyphs ending after the offset are clipped.
|
||||
</description>
|
||||
</method>
|
||||
<method name="shaped_text_duplicate">
|
||||
<return type="RID" />
|
||||
<param index="0" name="rid" type="RID" />
|
||||
<description>
|
||||
Duplicates shaped text buffer.
|
||||
</description>
|
||||
</method>
|
||||
<method name="shaped_text_fit_to_width">
|
||||
<return type="float" />
|
||||
<param index="0" name="shaped" type="RID" />
|
||||
|
|
@ -1687,6 +1694,14 @@
|
|||
Breaks text into words and returns array of character ranges. Use [param grapheme_flags] to set what characters are used for breaking.
|
||||
</description>
|
||||
</method>
|
||||
<method name="shaped_text_has_object" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="shaped" type="RID" />
|
||||
<param index="1" name="key" type="Variant" />
|
||||
<description>
|
||||
Returns [code]true[/code] if an object with [param key] is embedded in this shaped text buffer.
|
||||
</description>
|
||||
</method>
|
||||
<method name="shaped_text_has_visible_chars" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="shaped" type="RID" />
|
||||
|
|
|
|||
|
|
@ -1388,6 +1388,13 @@
|
|||
Draw the outline of the shaped text into a canvas item at a given position, with [param color]. [param pos] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). If [param oversampling] is greater than zero, it is used as font oversampling factor, otherwise viewport oversampling settings are used.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_shaped_text_duplicate" qualifiers="virtual required">
|
||||
<return type="RID" />
|
||||
<param index="0" name="shaped" type="RID" />
|
||||
<description>
|
||||
Duplicates shaped text buffer.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_shaped_text_fit_to_width" qualifiers="virtual">
|
||||
<return type="float" />
|
||||
<param index="0" name="shaped" type="RID" />
|
||||
|
|
@ -1655,6 +1662,14 @@
|
|||
Breaks text into words and returns array of character ranges. Use [param grapheme_flags] to set what characters are used for breaking.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_shaped_text_has_object" qualifiers="virtual required const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="shaped" type="RID" />
|
||||
<param index="1" name="key" type="Variant" />
|
||||
<description>
|
||||
Returns [code]true[/code] if an object with [param key] is embedded in this shaped text buffer.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_shaped_text_hit_test_grapheme" qualifiers="virtual const">
|
||||
<return type="int" />
|
||||
<param index="0" name="shaped" type="RID" />
|
||||
|
|
|
|||
|
|
@ -4446,7 +4446,7 @@ void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = p_shaped->first_span; i <= p_shaped->last_span; i++) {
|
||||
for (int i = MAX(0, p_shaped->first_span); i <= MIN(p_shaped->last_span, parent->spans.size() - 1); i++) {
|
||||
ShapedTextDataAdvanced::Span span = parent->spans[i];
|
||||
span.start = MAX(p_shaped->start, span.start);
|
||||
span.end = MIN(p_shaped->end, span.end);
|
||||
|
|
@ -4486,6 +4486,43 @@ void TextServerAdvanced::_shaped_text_clear(const RID &p_shaped) {
|
|||
invalidate(sd, true);
|
||||
}
|
||||
|
||||
RID TextServerAdvanced::_shaped_text_duplicate(const RID &p_shaped) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, RID());
|
||||
|
||||
MutexLock lock(sd->mutex);
|
||||
|
||||
ShapedTextDataAdvanced *new_sd = memnew(ShapedTextDataAdvanced);
|
||||
new_sd->parent = p_shaped;
|
||||
new_sd->start = sd->start;
|
||||
new_sd->end = sd->end;
|
||||
new_sd->text = sd->text;
|
||||
new_sd->hb_buffer = hb_buffer_create();
|
||||
new_sd->utf16 = new_sd->text.utf16();
|
||||
new_sd->script_iter = memnew(ScriptIterator(new_sd->text, 0, new_sd->text.length()));
|
||||
new_sd->orientation = sd->orientation;
|
||||
new_sd->direction = sd->direction;
|
||||
new_sd->custom_punct = sd->custom_punct;
|
||||
new_sd->para_direction = sd->para_direction;
|
||||
new_sd->base_para_direction = sd->base_para_direction;
|
||||
new_sd->line_breaks_valid = sd->line_breaks_valid;
|
||||
new_sd->justification_ops_valid = sd->justification_ops_valid;
|
||||
new_sd->sort_valid = false;
|
||||
new_sd->upos = sd->upos;
|
||||
new_sd->uthk = sd->uthk;
|
||||
new_sd->runs.clear();
|
||||
new_sd->runs_dirty = true;
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
new_sd->extra_spacing[i] = sd->extra_spacing[i];
|
||||
}
|
||||
full_copy(new_sd);
|
||||
new_sd->valid.clear();
|
||||
|
||||
return shaped_owner.make_rid(new_sd);
|
||||
}
|
||||
|
||||
void TextServerAdvanced::_shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
|
||||
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_COND_MSG(p_direction == DIRECTION_INHERITED, "Invalid text direction.");
|
||||
|
|
@ -4998,6 +5035,14 @@ String TextServerAdvanced::_shaped_get_text(const RID &p_shaped) const {
|
|||
return sd->text;
|
||||
}
|
||||
|
||||
bool TextServerAdvanced::_shaped_text_has_object(const RID &p_shaped, const Variant &p_key) const {
|
||||
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, false);
|
||||
|
||||
MutexLock lock(sd->mutex);
|
||||
return sd->objects.has(p_key);
|
||||
}
|
||||
|
||||
bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, double p_baseline) {
|
||||
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, false);
|
||||
|
|
|
|||
|
|
@ -1032,6 +1032,7 @@ public:
|
|||
MODBIND2R(RID, create_shaped_text, Direction, Orientation);
|
||||
|
||||
MODBIND1(shaped_text_clear, const RID &);
|
||||
MODBIND1R(RID, shaped_text_duplicate, const RID &);
|
||||
|
||||
MODBIND2(shaped_text_set_direction, const RID &, Direction);
|
||||
MODBIND1RC(Direction, shaped_text_get_direction, const RID &);
|
||||
|
|
@ -1060,6 +1061,7 @@ public:
|
|||
MODBIND7R(bool, shaped_text_add_string, const RID &, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
|
||||
MODBIND6R(bool, shaped_text_add_object, const RID &, const Variant &, const Size2 &, InlineAlignment, int64_t, double);
|
||||
MODBIND5R(bool, shaped_text_resize_object, const RID &, const Variant &, const Size2 &, InlineAlignment, double);
|
||||
MODBIND2RC(bool, shaped_text_has_object, const RID &, const Variant &);
|
||||
MODBIND1RC(String, shaped_get_text, const RID &);
|
||||
|
||||
MODBIND1RC(int64_t, shaped_get_span_count, const RID &);
|
||||
|
|
|
|||
|
|
@ -3285,7 +3285,7 @@ void TextServerFallback::full_copy(ShapedTextDataFallback *p_shaped) {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = p_shaped->first_span; i <= p_shaped->last_span; i++) {
|
||||
for (int i = MAX(0, p_shaped->first_span); i <= MIN(p_shaped->last_span, parent->spans.size() - 1); i++) {
|
||||
ShapedTextDataFallback::Span span = parent->spans[i];
|
||||
span.start = MAX(p_shaped->start, span.start);
|
||||
span.end = MIN(p_shaped->end, span.end);
|
||||
|
|
@ -3324,6 +3324,39 @@ void TextServerFallback::_shaped_text_clear(const RID &p_shaped) {
|
|||
invalidate(sd);
|
||||
}
|
||||
|
||||
RID TextServerFallback::_shaped_text_duplicate(const RID &p_shaped) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, RID());
|
||||
|
||||
MutexLock lock(sd->mutex);
|
||||
|
||||
ShapedTextDataFallback *new_sd = memnew(ShapedTextDataFallback);
|
||||
new_sd->parent = p_shaped;
|
||||
new_sd->start = sd->start;
|
||||
new_sd->end = sd->end;
|
||||
new_sd->text = sd->text;
|
||||
new_sd->orientation = sd->orientation;
|
||||
new_sd->direction = sd->direction;
|
||||
new_sd->custom_punct = sd->custom_punct;
|
||||
new_sd->para_direction = sd->para_direction;
|
||||
new_sd->line_breaks_valid = sd->line_breaks_valid;
|
||||
new_sd->justification_ops_valid = sd->justification_ops_valid;
|
||||
new_sd->sort_valid = false;
|
||||
new_sd->upos = sd->upos;
|
||||
new_sd->uthk = sd->uthk;
|
||||
new_sd->runs.clear();
|
||||
new_sd->runs_dirty = true;
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
new_sd->extra_spacing[i] = sd->extra_spacing[i];
|
||||
}
|
||||
full_copy(new_sd);
|
||||
new_sd->valid.clear();
|
||||
|
||||
return shaped_owner.make_rid(new_sd);
|
||||
}
|
||||
|
||||
void TextServerFallback::_shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
|
||||
ERR_FAIL_COND_MSG(p_direction == DIRECTION_INHERITED, "Invalid text direction.");
|
||||
if (p_direction == DIRECTION_RTL) {
|
||||
|
|
@ -3832,6 +3865,14 @@ String TextServerFallback::_shaped_get_text(const RID &p_shaped) const {
|
|||
return sd->text;
|
||||
}
|
||||
|
||||
bool TextServerFallback::_shaped_text_has_object(const RID &p_shaped, const Variant &p_key) const {
|
||||
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, false);
|
||||
|
||||
MutexLock lock(sd->mutex);
|
||||
return sd->objects.has(p_key);
|
||||
}
|
||||
|
||||
bool TextServerFallback::_shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, double p_baseline) {
|
||||
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_NULL_V(sd, false);
|
||||
|
|
|
|||
|
|
@ -811,6 +811,7 @@ public:
|
|||
MODBIND2R(RID, create_shaped_text, Direction, Orientation);
|
||||
|
||||
MODBIND1(shaped_text_clear, const RID &);
|
||||
MODBIND1R(RID, shaped_text_duplicate, const RID &);
|
||||
|
||||
MODBIND2(shaped_text_set_direction, const RID &, Direction);
|
||||
MODBIND1RC(Direction, shaped_text_get_direction, const RID &);
|
||||
|
|
@ -839,6 +840,7 @@ public:
|
|||
MODBIND7R(bool, shaped_text_add_string, const RID &, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
|
||||
MODBIND6R(bool, shaped_text_add_object, const RID &, const Variant &, const Size2 &, InlineAlignment, int64_t, double);
|
||||
MODBIND5R(bool, shaped_text_resize_object, const RID &, const Variant &, const Size2 &, InlineAlignment, double);
|
||||
MODBIND2RC(bool, shaped_text_has_object, const RID &, const Variant &);
|
||||
MODBIND1RC(String, shaped_get_text, const RID &);
|
||||
|
||||
MODBIND1RC(int64_t, shaped_get_span_count, const RID &);
|
||||
|
|
|
|||
|
|
@ -381,31 +381,62 @@ void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref<
|
|||
// List.
|
||||
_add_list_prefixes(p_frame, p_line, l);
|
||||
|
||||
RID t = l.text_buf->get_rid();
|
||||
int spans = TS->shaped_get_span_count(t);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
Item *it_span = items.get_or_null(TS->shaped_get_span_meta(t, i));
|
||||
ItemText *it = reinterpret_cast<ItemText *>(it_span);
|
||||
if (it) {
|
||||
Ref<Font> font = p_base_font;
|
||||
int font_size = p_base_font_size;
|
||||
{
|
||||
RID t = l.text_buf->get_rid();
|
||||
int spans = TS->shaped_get_span_count(t);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
Item *it_span = items.get_or_null(TS->shaped_get_span_meta(t, i));
|
||||
ItemText *it = reinterpret_cast<ItemText *>(it_span);
|
||||
if (it) {
|
||||
Ref<Font> font = p_base_font;
|
||||
int font_size = p_base_font_size;
|
||||
|
||||
ItemFont *font_it = _find_font(it);
|
||||
if (font_it) {
|
||||
if (font_it->font.is_valid()) {
|
||||
font = font_it->font;
|
||||
ItemFont *font_it = _find_font(it);
|
||||
if (font_it) {
|
||||
if (font_it->font.is_valid()) {
|
||||
font = font_it->font;
|
||||
}
|
||||
if (font_it->font_size > 0) {
|
||||
font_size = font_it->font_size;
|
||||
}
|
||||
}
|
||||
if (font_it->font_size > 0) {
|
||||
font_size = font_it->font_size;
|
||||
ItemFontSize *font_size_it = _find_font_size(it);
|
||||
if (font_size_it && font_size_it->font_size > 0) {
|
||||
font_size = font_size_it->font_size;
|
||||
}
|
||||
TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
} else {
|
||||
TS->shaped_set_span_update_font(t, i, p_base_font->get_rids(), p_base_font_size, p_base_font->get_opentype_features());
|
||||
}
|
||||
ItemFontSize *font_size_it = _find_font_size(it);
|
||||
if (font_size_it && font_size_it->font_size > 0) {
|
||||
font_size = font_size_it->font_size;
|
||||
}
|
||||
}
|
||||
if (l.text_buf_disp.is_valid()) {
|
||||
RID t = l.text_buf_disp->get_rid();
|
||||
int spans = TS->shaped_get_span_count(t);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
Item *it_span = items.get_or_null(TS->shaped_get_span_meta(t, i));
|
||||
ItemText *it = reinterpret_cast<ItemText *>(it_span);
|
||||
if (it) {
|
||||
Ref<Font> font = p_base_font;
|
||||
int font_size = p_base_font_size;
|
||||
|
||||
ItemFont *font_it = _find_font(it);
|
||||
if (font_it) {
|
||||
if (font_it->font.is_valid()) {
|
||||
font = font_it->font;
|
||||
}
|
||||
if (font_it->font_size > 0) {
|
||||
font_size = font_it->font_size;
|
||||
}
|
||||
}
|
||||
ItemFontSize *font_size_it = _find_font_size(it);
|
||||
if (font_size_it && font_size_it->font_size > 0) {
|
||||
font_size = font_size_it->font_size;
|
||||
}
|
||||
TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
} else {
|
||||
TS->shaped_set_span_update_font(t, i, p_base_font->get_rids(), p_base_font_size, p_base_font->get_opentype_features());
|
||||
}
|
||||
TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
} else {
|
||||
TS->shaped_set_span_update_font(t, i, p_base_font->get_rids(), p_base_font_size, p_base_font->get_opentype_features());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -449,6 +480,17 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font
|
|||
l.text_buf->tab_align(tabs);
|
||||
}
|
||||
|
||||
if (l.text_buf_disp.is_valid()) {
|
||||
l.text_buf_disp->set_width(p_width - l.offset.x);
|
||||
if (!tab_stops.is_empty()) {
|
||||
l.text_buf_disp->tab_align(tab_stops);
|
||||
} else if (tab_size > 0) { // Align inline tabs.
|
||||
Vector<float> tabs;
|
||||
tabs.push_back(tab_size * p_base_font->get_char_size(' ', p_base_font_size).width);
|
||||
l.text_buf_disp->tab_align(tabs);
|
||||
}
|
||||
}
|
||||
|
||||
Item *it_to = (p_line + 1 < (int)p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
|
||||
for (Item *it = l.from; it && it != it_to; it = _get_next_item(it)) {
|
||||
switch (it->type) {
|
||||
|
|
@ -458,6 +500,9 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font
|
|||
if (img->width_in_percent || img->height_in_percent) {
|
||||
img_size = _get_image_size(img->image, img->width_in_percent ? (p_width * img->rq_size.width / 100.f) : img->rq_size.width, img->height_in_percent ? (p_width * img->rq_size.height / 100.f) : img->rq_size.height, img->region);
|
||||
l.text_buf->resize_object(it->rid, img_size, img->inline_align);
|
||||
if (l.text_buf_disp.is_valid() && l.text_buf_disp->has_object(it->rid)) {
|
||||
l.text_buf_disp->resize_object(it->rid, img_size, img->inline_align);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case ITEM_TABLE: {
|
||||
|
|
@ -489,8 +534,14 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font
|
|||
int row_idx = (table->align_to_row < 0) ? table->rows_baseline.size() - 1 : table->align_to_row;
|
||||
if (table->rows_baseline.size() != 0 && row_idx < (int)table->rows_baseline.size()) {
|
||||
l.text_buf->resize_object(it->rid, Size2(table->total_width, table->total_height), table->inline_align, Math::round(table->rows_baseline[row_idx]));
|
||||
if (l.text_buf_disp.is_valid() && l.text_buf_disp->has_object(it->rid)) {
|
||||
l.text_buf_disp->resize_object(it->rid, Size2(table->total_width, table->total_height), table->inline_align, Math::round(table->rows_baseline[row_idx]));
|
||||
}
|
||||
} else {
|
||||
l.text_buf->resize_object(it->rid, Size2(table->total_width, table->total_height), table->inline_align);
|
||||
if (l.text_buf_disp.is_valid() && l.text_buf_disp->has_object(it->rid)) {
|
||||
l.text_buf_disp->resize_object(it->rid, Size2(table->total_width, table->total_height), table->inline_align);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
|
|
@ -528,6 +579,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
|
||||
// Clear cache.
|
||||
l.dc_item = nullptr;
|
||||
l.text_buf_disp = Ref<TextParagraph>();
|
||||
l.text_buf->clear();
|
||||
l.text_buf->set_break_flags(autowrap_flags);
|
||||
l.text_buf->set_justification_flags(_find_jst_flags(l.from));
|
||||
|
|
@ -555,6 +607,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
|
||||
// Shape current paragraph.
|
||||
String txt;
|
||||
String txt_sub;
|
||||
Item *it_to = (p_line + 1 < (int)p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
|
||||
int remaining_characters = visible_characters - l.char_offset;
|
||||
for (Item *it = l.from; it && it != it_to; it = _get_next_item(it)) {
|
||||
|
|
@ -610,14 +663,13 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
}
|
||||
String lang = _find_language(it);
|
||||
String tx = t->text;
|
||||
if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING && visible_characters >= 0 && remaining_characters >= 0 && tx.length() > remaining_characters) {
|
||||
String first = tx.substr(0, remaining_characters);
|
||||
String second = tx.substr(remaining_characters, -1);
|
||||
l.text_buf->add_string(first, font, font_size, lang, it->rid);
|
||||
l.text_buf->add_string(second, font, font_size, lang, it->rid);
|
||||
} else {
|
||||
l.text_buf->add_string(tx, font, font_size, lang, it->rid);
|
||||
if (l.text_buf_disp.is_null() && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING && visible_characters >= 0 && remaining_characters >= 0 && tx.length() > remaining_characters) {
|
||||
String sub = tx.substr(0, remaining_characters);
|
||||
l.text_buf_disp = l.text_buf->duplicate();
|
||||
l.text_buf_disp->add_string(sub, font, font_size, lang, it->rid);
|
||||
txt_sub = txt + sub;
|
||||
}
|
||||
l.text_buf->add_string(tx, font, font_size, lang, it->rid);
|
||||
remaining_characters -= tx.length();
|
||||
|
||||
txt += tx;
|
||||
|
|
@ -698,7 +750,11 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
}
|
||||
|
||||
// Apply BiDi override.
|
||||
l.text_buf->set_bidi_override(structured_text_parser(_find_stt(l.from), st_args, txt));
|
||||
TextServer::StructuredTextParser stt = _find_stt(l.from);
|
||||
l.text_buf->set_bidi_override(structured_text_parser(stt, st_args, txt));
|
||||
if (l.text_buf_disp.is_valid()) {
|
||||
l.text_buf_disp->set_bidi_override(structured_text_parser(stt, st_args, txt_sub));
|
||||
}
|
||||
|
||||
*r_char_offset = l.char_offset + l.char_count;
|
||||
|
||||
|
|
@ -898,13 +954,15 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
|
|||
l.text_buf->draw_dropcap(ci, p_ofs + ((rtl) ? Vector2() : Vector2(l.offset.x, 0)), l.dc_color);
|
||||
}
|
||||
|
||||
const Ref<TextParagraph> &text_buf = l.text_buf_disp.is_valid() ? l.text_buf_disp : l.text_buf;
|
||||
|
||||
int line_count = 0;
|
||||
bool has_visible_chars = false;
|
||||
// Bottom margin for text clipping.
|
||||
float v_limit = theme_cache.normal_style->get_margin(SIDE_BOTTOM);
|
||||
Size2 ctrl_size = get_size();
|
||||
// Draw text.
|
||||
for (int line = 0; line < l.text_buf->get_line_count(); line++) {
|
||||
for (int line = 0; line < text_buf->get_line_count(); line++) {
|
||||
if (line > 0) {
|
||||
off.y += (theme_cache.line_separation + p_vsep);
|
||||
}
|
||||
|
|
@ -913,14 +971,14 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
|
|||
break;
|
||||
}
|
||||
|
||||
double l_height = l.text_buf->get_line_ascent(line) + l.text_buf->get_line_descent(line);
|
||||
double l_height = text_buf->get_line_ascent(line) + text_buf->get_line_descent(line);
|
||||
if (p_ofs.y + off.y + l_height <= 0) {
|
||||
off.y += l_height;
|
||||
continue;
|
||||
}
|
||||
|
||||
float width = l.text_buf->get_width();
|
||||
float length = l.text_buf->get_line_size(line).x;
|
||||
float width = text_buf->get_width();
|
||||
float length = text_buf->get_line_size(line).x;
|
||||
|
||||
// Draw line.
|
||||
if (rtl) {
|
||||
|
|
@ -936,7 +994,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
|
|||
}
|
||||
|
||||
// Draw text.
|
||||
switch (l.text_buf->get_alignment()) {
|
||||
switch (text_buf->get_alignment()) {
|
||||
case HORIZONTAL_ALIGNMENT_FILL:
|
||||
case HORIZONTAL_ALIGNMENT_LEFT: {
|
||||
if (rtl) {
|
||||
|
|
@ -986,7 +1044,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
|
|||
}
|
||||
}
|
||||
|
||||
RID rid = l.text_buf->get_line_rid(line);
|
||||
RID rid = text_buf->get_line_rid(line);
|
||||
double l_ascent = TS->shaped_text_get_ascent(rid);
|
||||
Size2 l_size = TS->shaped_text_get_size(rid);
|
||||
double upos = TS->shaped_text_get_underline_position(rid);
|
||||
|
|
@ -1627,10 +1685,12 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
|
|||
Item *table_click_item = nullptr;
|
||||
int table_click_char = -1;
|
||||
|
||||
for (int line = 0; line < l.text_buf->get_line_count(); line++) {
|
||||
RID rid = l.text_buf->get_line_rid(line);
|
||||
const Ref<TextParagraph> &text_buf = l.text_buf_disp.is_valid() ? l.text_buf_disp : l.text_buf;
|
||||
|
||||
float width = l.text_buf->get_width();
|
||||
for (int line = 0; line < text_buf->get_line_count(); line++) {
|
||||
RID rid = text_buf->get_line_rid(line);
|
||||
|
||||
float width = text_buf->get_width();
|
||||
float length = TS->shaped_text_get_width(rid);
|
||||
|
||||
if (rtl) {
|
||||
|
|
@ -1645,7 +1705,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
|
|||
}
|
||||
}
|
||||
|
||||
switch (l.text_buf->get_alignment()) {
|
||||
switch (text_buf->get_alignment()) {
|
||||
case HORIZONTAL_ALIGNMENT_FILL:
|
||||
case HORIZONTAL_ALIGNMENT_LEFT: {
|
||||
if (rtl) {
|
||||
|
|
@ -1662,8 +1722,8 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
|
|||
} break;
|
||||
}
|
||||
// Adjust for dropcap.
|
||||
int dc_lines = l.text_buf->get_dropcap_lines();
|
||||
float h_off = l.text_buf->get_dropcap_size().x;
|
||||
int dc_lines = text_buf->get_dropcap_lines();
|
||||
float h_off = text_buf->get_dropcap_size().x;
|
||||
if (line <= dc_lines) {
|
||||
if (rtl) {
|
||||
off.x -= h_off;
|
||||
|
|
@ -1824,7 +1884,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
|
|||
return table_offy;
|
||||
}
|
||||
|
||||
if (line == l.text_buf->get_line_count() - 1) {
|
||||
if (line == text_buf->get_line_count() - 1) {
|
||||
off.y += TS->shaped_text_get_descent(rid) + theme_cache.paragraph_separation + p_vsep;
|
||||
} else {
|
||||
off.y += TS->shaped_text_get_descent(rid) + theme_cache.line_separation + p_vsep;
|
||||
|
|
@ -2016,7 +2076,8 @@ void RichTextLabel::_accessibility_update_line(RID p_id, ItemFrame *p_frame, int
|
|||
float h_off = l.text_buf->get_dropcap_size().x;
|
||||
|
||||
// Process text.
|
||||
const RID ¶_rid = l.text_buf->get_rid();
|
||||
const Ref<TextParagraph> &text_buf = l.text_buf_disp.is_valid() ? l.text_buf_disp : l.text_buf;
|
||||
const RID ¶_rid = text_buf->get_rid();
|
||||
|
||||
String l_text = TS->shaped_get_text(para_rid).remove_char(0xfffc).strip_edges();
|
||||
if (l.dc_item) {
|
||||
|
|
@ -2026,7 +2087,7 @@ void RichTextLabel::_accessibility_update_line(RID p_id, ItemFrame *p_frame, int
|
|||
if (!l_text.is_empty()) {
|
||||
Vector2 off;
|
||||
if (rtl) {
|
||||
off.x = p_width - l.offset.x - l.text_buf->get_width();
|
||||
off.x = p_width - l.offset.x - text_buf->get_width();
|
||||
if (!lrtl && p_frame == main) { // Skip Scrollbar.
|
||||
off.x -= scroll_w;
|
||||
}
|
||||
|
|
@ -2039,7 +2100,7 @@ void RichTextLabel::_accessibility_update_line(RID p_id, ItemFrame *p_frame, int
|
|||
|
||||
l.accessibility_text_element = DisplayServer::get_singleton()->accessibility_create_sub_element(line_ae, DisplayServer::AccessibilityRole::ROLE_STATIC_TEXT);
|
||||
DisplayServer::get_singleton()->accessibility_update_set_value(l.accessibility_text_element, l_text);
|
||||
ae_rect = Rect2(p_ofs + off, l.text_buf->get_size());
|
||||
ae_rect = Rect2(p_ofs + off, text_buf->get_size());
|
||||
DisplayServer::get_singleton()->accessibility_update_set_bounds(l.accessibility_text_element, ae_rect);
|
||||
ac_element_bounds_cache[l.accessibility_text_element] = ae_rect;
|
||||
|
||||
|
|
@ -2049,14 +2110,14 @@ void RichTextLabel::_accessibility_update_line(RID p_id, ItemFrame *p_frame, int
|
|||
}
|
||||
|
||||
Vector2 off;
|
||||
for (int line = 0; line < l.text_buf->get_line_count(); line++) {
|
||||
for (int line = 0; line < text_buf->get_line_count(); line++) {
|
||||
if (line > 0) {
|
||||
off.y += (theme_cache.line_separation + p_vsep);
|
||||
}
|
||||
|
||||
const Size2 line_size = l.text_buf->get_line_size(line);
|
||||
const Size2 line_size = text_buf->get_line_size(line);
|
||||
|
||||
float width = l.text_buf->get_width();
|
||||
float width = text_buf->get_width();
|
||||
float length = line_size.x;
|
||||
|
||||
// Process line.
|
||||
|
|
@ -2074,7 +2135,7 @@ void RichTextLabel::_accessibility_update_line(RID p_id, ItemFrame *p_frame, int
|
|||
}
|
||||
|
||||
// Process text.
|
||||
switch (l.text_buf->get_alignment()) {
|
||||
switch (text_buf->get_alignment()) {
|
||||
case HORIZONTAL_ALIGNMENT_FILL:
|
||||
case HORIZONTAL_ALIGNMENT_LEFT: {
|
||||
if (rtl) {
|
||||
|
|
@ -2099,7 +2160,7 @@ void RichTextLabel::_accessibility_update_line(RID p_id, ItemFrame *p_frame, int
|
|||
}
|
||||
}
|
||||
|
||||
const RID &rid = l.text_buf->get_line_rid(line);
|
||||
const RID &rid = text_buf->get_line_rid(line);
|
||||
|
||||
Array objects = TS->shaped_text_get_objects(rid);
|
||||
for (int i = 0; i < objects.size(); i++) {
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ private:
|
|||
Color prefix_outline_color = Color(0, 0, 0, 0);
|
||||
float prefix_width = 0;
|
||||
Ref<TextParagraph> text_buf;
|
||||
Ref<TextParagraph> text_buf_disp;
|
||||
|
||||
RID accessibility_line_element;
|
||||
RID accessibility_text_element;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
void TextLine::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("clear"), &TextLine::clear);
|
||||
ClassDB::bind_method(D_METHOD("duplicate"), &TextLine::duplicate);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_direction", "direction"), &TextLine::set_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_direction"), &TextLine::get_direction);
|
||||
|
|
@ -64,6 +65,7 @@ void TextLine::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("add_string", "text", "font", "font_size", "language", "meta"), &TextLine::add_string, DEFVAL(""), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length", "baseline"), &TextLine::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1), DEFVAL(0.0));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align", "baseline"), &TextLine::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(0.0));
|
||||
ClassDB::bind_method(D_METHOD("has_object", "key"), &TextLine::has_object);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_width", "width"), &TextLine::set_width);
|
||||
ClassDB::bind_method(D_METHOD("get_width"), &TextLine::get_width);
|
||||
|
|
@ -149,6 +151,23 @@ void TextLine::clear() {
|
|||
TS->shaped_text_clear(rid);
|
||||
}
|
||||
|
||||
Ref<TextLine> TextLine::duplicate() const {
|
||||
Ref<TextLine> copy;
|
||||
copy.instantiate();
|
||||
if (rid.is_valid()) {
|
||||
copy->rid = TS->shaped_text_duplicate(rid);
|
||||
}
|
||||
copy->dirty = true;
|
||||
copy->width = width;
|
||||
copy->flags = flags;
|
||||
copy->alignment = alignment;
|
||||
copy->el_char = el_char;
|
||||
copy->overrun_behavior = overrun_behavior;
|
||||
copy->tab_stops = tab_stops;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void TextLine::set_preserve_invalid(bool p_enabled) {
|
||||
TS->shaped_text_set_preserve_invalid(rid, p_enabled);
|
||||
dirty = true;
|
||||
|
|
@ -212,6 +231,11 @@ bool TextLine::resize_object(Variant p_key, const Size2 &p_size, InlineAlignment
|
|||
return TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align, p_baseline);
|
||||
}
|
||||
|
||||
bool TextLine::has_object(Variant p_key) const {
|
||||
_shape();
|
||||
return TS->shaped_text_has_object(rid, p_key);
|
||||
}
|
||||
|
||||
Array TextLine::get_objects() const {
|
||||
return TS->shaped_text_get_objects(rid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ public:
|
|||
RID get_rid() const;
|
||||
|
||||
void clear();
|
||||
Ref<TextLine> duplicate() const;
|
||||
|
||||
void set_direction(TextServer::Direction p_direction);
|
||||
TextServer::Direction get_direction() const;
|
||||
|
|
@ -85,6 +86,7 @@ public:
|
|||
bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", const Variant &p_meta = Variant());
|
||||
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1, float p_baseline = 0.0);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, float p_baseline = 0.0);
|
||||
bool has_object(Variant p_key) const;
|
||||
|
||||
void set_horizontal_alignment(HorizontalAlignment p_alignment);
|
||||
HorizontalAlignment get_horizontal_alignment() const;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
void TextParagraph::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("clear"), &TextParagraph::clear);
|
||||
ClassDB::bind_method(D_METHOD("duplicate"), &TextParagraph::duplicate);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_direction", "direction"), &TextParagraph::set_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_direction"), &TextParagraph::get_direction);
|
||||
|
|
@ -72,6 +73,7 @@ void TextParagraph::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("add_string", "text", "font", "font_size", "language", "meta"), &TextParagraph::add_string, DEFVAL(""), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length", "baseline"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1), DEFVAL(0.0));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align", "baseline"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(0.0));
|
||||
ClassDB::bind_method(D_METHOD("has_object", "key"), &TextParagraph::has_object);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &TextParagraph::set_alignment);
|
||||
ClassDB::bind_method(D_METHOD("get_alignment"), &TextParagraph::get_alignment);
|
||||
|
|
@ -322,6 +324,31 @@ void TextParagraph::clear() {
|
|||
TS->shaped_text_clear(dropcap_rid);
|
||||
}
|
||||
|
||||
Ref<TextParagraph> TextParagraph::duplicate() const {
|
||||
Ref<TextParagraph> copy;
|
||||
copy.instantiate();
|
||||
if (dropcap_rid.is_valid()) {
|
||||
copy->dropcap_rid = TS->shaped_text_duplicate(dropcap_rid);
|
||||
}
|
||||
copy->dropcap_lines = dropcap_lines;
|
||||
copy->dropcap_margins = dropcap_margins;
|
||||
if (rid.is_valid()) {
|
||||
copy->rid = TS->shaped_text_duplicate(rid);
|
||||
}
|
||||
copy->lines_dirty = true;
|
||||
copy->line_spacing = line_spacing;
|
||||
copy->width = width;
|
||||
copy->max_lines_visible = max_lines_visible;
|
||||
copy->brk_flags = brk_flags;
|
||||
copy->jst_flags = jst_flags;
|
||||
copy->el_char = el_char;
|
||||
copy->overrun_behavior = overrun_behavior;
|
||||
copy->alignment = alignment;
|
||||
copy->tab_stops = tab_stops;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void TextParagraph::set_preserve_invalid(bool p_enabled) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -448,6 +475,12 @@ bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlig
|
|||
return res;
|
||||
}
|
||||
|
||||
bool TextParagraph::has_object(Variant p_key) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return TS->shaped_text_has_object(rid, p_key);
|
||||
}
|
||||
|
||||
void TextParagraph::set_alignment(HorizontalAlignment p_alignment) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ public:
|
|||
|
||||
void clear();
|
||||
|
||||
Ref<TextParagraph> duplicate() const;
|
||||
|
||||
void set_direction(TextServer::Direction p_direction);
|
||||
TextServer::Direction get_direction() const;
|
||||
TextServer::Direction get_inferred_direction() const;
|
||||
|
|
@ -109,6 +111,7 @@ public:
|
|||
bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", const Variant &p_meta = Variant());
|
||||
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1, float p_baseline = 0.0);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, float p_baseline = 0.0);
|
||||
bool has_object(Variant p_key) const;
|
||||
|
||||
void set_alignment(HorizontalAlignment p_alignment);
|
||||
HorizontalAlignment get_alignment() const;
|
||||
|
|
|
|||
|
|
@ -402,6 +402,7 @@ void TextServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("create_shaped_text", "direction", "orientation"), &TextServer::create_shaped_text, DEFVAL(DIRECTION_AUTO), DEFVAL(ORIENTATION_HORIZONTAL));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_clear", "rid"), &TextServer::shaped_text_clear);
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_duplicate", "rid"), &TextServer::shaped_text_duplicate);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_set_direction", "shaped", "direction"), &TextServer::shaped_text_set_direction, DEFVAL(DIRECTION_AUTO));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_get_direction", "shaped"), &TextServer::shaped_text_get_direction);
|
||||
|
|
@ -430,6 +431,7 @@ void TextServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length", "baseline"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1), DEFVAL(0.0));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align", "baseline"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(0.0));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_has_object", "shaped", "key"), &TextServer::shaped_text_has_object);
|
||||
ClassDB::bind_method(D_METHOD("shaped_get_text", "shaped"), &TextServer::shaped_get_text);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("shaped_get_span_count", "shaped"), &TextServer::shaped_get_span_count);
|
||||
|
|
|
|||
|
|
@ -463,6 +463,7 @@ public:
|
|||
virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0;
|
||||
|
||||
virtual void shaped_text_clear(const RID &p_shaped) = 0;
|
||||
virtual RID shaped_text_duplicate(const RID &p_shaped) = 0;
|
||||
|
||||
virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) = 0;
|
||||
virtual Direction shaped_text_get_direction(const RID &p_shaped) const = 0;
|
||||
|
|
@ -491,6 +492,7 @@ public:
|
|||
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0;
|
||||
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1, double p_baseline = 0.0) = 0;
|
||||
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, double p_baseline = 0.0) = 0;
|
||||
virtual bool shaped_text_has_object(const RID &p_shaped, const Variant &p_key) const = 0;
|
||||
virtual String shaped_get_text(const RID &p_shaped) const = 0;
|
||||
|
||||
virtual int64_t shaped_get_span_count(const RID &p_shaped) const = 0;
|
||||
|
|
|
|||
|
|
@ -94,9 +94,11 @@ public:
|
|||
|
||||
virtual RID create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) override { return RID(); }
|
||||
virtual void shaped_text_clear(const RID &p_shaped) override {}
|
||||
virtual RID shaped_text_duplicate(const RID &p_shaped) override { return RID(); }
|
||||
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) override { return false; }
|
||||
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length, double p_baseline) override { return false; }
|
||||
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, double p_baseline) override { return false; }
|
||||
virtual bool shaped_text_has_object(const RID &p_shaped, const Variant &p_key) const override { return false; }
|
||||
virtual int64_t shaped_get_span_count(const RID &p_shaped) const override { return 0; }
|
||||
virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override { return Variant(); }
|
||||
virtual Variant shaped_get_span_embedded_object(const RID &p_shaped, int64_t p_index) const override { return Variant(); }
|
||||
|
|
|
|||
|
|
@ -252,6 +252,7 @@ void TextServerExtension::_bind_methods() {
|
|||
GDVIRTUAL_BIND(_create_shaped_text, "direction", "orientation");
|
||||
|
||||
GDVIRTUAL_BIND(_shaped_text_clear, "shaped");
|
||||
GDVIRTUAL_BIND(_shaped_text_duplicate, "shaped");
|
||||
|
||||
GDVIRTUAL_BIND(_shaped_text_set_direction, "shaped", "direction");
|
||||
GDVIRTUAL_BIND(_shaped_text_get_direction, "shaped");
|
||||
|
|
@ -280,6 +281,7 @@ void TextServerExtension::_bind_methods() {
|
|||
GDVIRTUAL_BIND(_shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language", "meta");
|
||||
GDVIRTUAL_BIND(_shaped_text_add_object, "shaped", "key", "size", "inline_align", "length", "baseline");
|
||||
GDVIRTUAL_BIND(_shaped_text_resize_object, "shaped", "key", "size", "inline_align", "baseline");
|
||||
GDVIRTUAL_BIND(_shaped_text_has_object, "shaped", "key");
|
||||
GDVIRTUAL_BIND(_shaped_get_text, "shaped");
|
||||
|
||||
GDVIRTUAL_BIND(_shaped_get_span_count, "shaped");
|
||||
|
|
@ -1148,6 +1150,12 @@ void TextServerExtension::shaped_text_clear(const RID &p_shaped) {
|
|||
GDVIRTUAL_CALL(_shaped_text_clear, p_shaped);
|
||||
}
|
||||
|
||||
RID TextServerExtension::shaped_text_duplicate(const RID &p_shaped) {
|
||||
RID ret;
|
||||
GDVIRTUAL_CALL(_shaped_text_duplicate, p_shaped, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TextServerExtension::shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
|
||||
GDVIRTUAL_CALL(_shaped_text_set_direction, p_shaped, p_direction);
|
||||
}
|
||||
|
|
@ -1246,6 +1254,12 @@ bool TextServerExtension::shaped_text_resize_object(const RID &p_shaped, const V
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool TextServerExtension::shaped_text_has_object(const RID &p_shaped, const Variant &p_key) const {
|
||||
bool ret = false;
|
||||
GDVIRTUAL_CALL(_shaped_text_has_object, p_shaped, p_key, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String TextServerExtension::shaped_get_text(const RID &p_shaped) const {
|
||||
String ret;
|
||||
GDVIRTUAL_CALL(_shaped_get_text, p_shaped, ret);
|
||||
|
|
|
|||
|
|
@ -413,6 +413,9 @@ public:
|
|||
virtual void shaped_text_clear(const RID &p_shaped) override;
|
||||
GDVIRTUAL1_REQUIRED(_shaped_text_clear, RID);
|
||||
|
||||
virtual RID shaped_text_duplicate(const RID &p_shaped) override;
|
||||
GDVIRTUAL1R_REQUIRED(RID, _shaped_text_duplicate, RID);
|
||||
|
||||
virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override;
|
||||
virtual Direction shaped_text_get_direction(const RID &p_shaped) const override;
|
||||
virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const override;
|
||||
|
|
@ -456,9 +459,11 @@ public:
|
|||
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
|
||||
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1, double p_baseline = 0.0) override;
|
||||
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, double p_baseline = 0.0) override;
|
||||
virtual bool shaped_text_has_object(const RID &p_shaped, const Variant &p_key) const override;
|
||||
GDVIRTUAL7R_REQUIRED(bool, _shaped_text_add_string, RID, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
|
||||
GDVIRTUAL6R_REQUIRED(bool, _shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t, double);
|
||||
GDVIRTUAL5R_REQUIRED(bool, _shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment, double);
|
||||
GDVIRTUAL2RC_REQUIRED(bool, _shaped_text_has_object, RID, const Variant &);
|
||||
|
||||
virtual String shaped_get_text(const RID &p_shaped) const override;
|
||||
GDVIRTUAL1RC_REQUIRED(String, _shaped_get_text, RID);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue