Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RTL] Use "visible characters" property for inline object visibility #89395

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions doc/classes/TextServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,22 @@
Breaks text to the lines and columns. Returns character ranges for each segment.
</description>
</method>
<method name="shaped_text_get_object_glyph" qualifiers="const">
<return type="int" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="key" type="Variant" />
<description>
Returns the glyph index of the inline object.
</description>
</method>
<method name="shaped_text_get_object_range" qualifiers="const">
<return type="Vector2i" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="key" type="Variant" />
<description>
Returns the character range of the inline object.
</description>
</method>
<method name="shaped_text_get_object_rect" qualifiers="const">
<return type="Rect2" />
<param index="0" name="shaped" type="RID" />
Expand Down
14 changes: 14 additions & 0 deletions doc/classes/TextServerExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,20 @@
<description>
</description>
</method>
<method name="_shaped_text_get_object_glyph" qualifiers="virtual const">
<return type="int" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="key" type="Variant" />
<description>
</description>
</method>
<method name="_shaped_text_get_object_range" qualifiers="virtual const">
<return type="Vector2i" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="key" type="Variant" />
<description>
</description>
</method>
<method name="_shaped_text_get_object_rect" qualifiers="virtual const">
<return type="Rect2" />
<param index="0" name="shaped" type="RID" />
Expand Down
40 changes: 35 additions & 5 deletions modules/text_server_adv/text_server_adv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4000,7 +4000,7 @@ void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) {
ShapedTextDataAdvanced *parent = shaped_owner.get_or_null(p_shaped->parent);

for (const KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : parent->objects) {
if (E.value.pos >= p_shaped->start && E.value.pos < p_shaped->end) {
if (E.value.start >= p_shaped->start && E.value.start < p_shaped->end) {
p_shaped->objects[E.key] = E.value;
}
}
Expand Down Expand Up @@ -4300,7 +4300,8 @@ bool TextServerAdvanced::_shaped_text_add_object(const RID &p_shaped, const Vari
ShapedTextDataAdvanced::EmbeddedObject obj;
obj.inline_align = p_inline_align;
obj.rect.size = p_size;
obj.pos = span.start;
obj.start = span.start;
obj.end = span.end;
obj.baseline = p_baseline;

sd->spans.push_back(span);
Expand Down Expand Up @@ -4335,7 +4336,7 @@ bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const V
Variant key;
if (gl.count == 1) {
for (const KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : sd->objects) {
if (E.value.pos == gl.start) {
if (E.value.start == gl.start) {
key = E.key;
break;
}
Expand Down Expand Up @@ -4386,7 +4387,7 @@ void TextServerAdvanced::_realign(ShapedTextDataAdvanced *p_sd) const {
double full_ascent = p_sd->ascent;
double full_descent = p_sd->descent;
for (KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : p_sd->objects) {
if ((E.value.pos >= p_sd->start) && (E.value.pos < p_sd->end)) {
if ((E.value.start >= p_sd->start) && (E.value.start < p_sd->end)) {
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
case INLINE_ALIGNMENT_TO_TOP: {
Expand Down Expand Up @@ -4598,7 +4599,7 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
bool find_embedded = false;
if (gl.count == 1) {
for (const KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : p_sd->objects) {
if (E.value.pos == gl.start) {
if (E.value.start == gl.start) {
find_embedded = true;
key = E.key;
p_new_sd->objects[key] = E.value;
Expand Down Expand Up @@ -6437,6 +6438,35 @@ Rect2 TextServerAdvanced::_shaped_text_get_object_rect(const RID &p_shaped, cons
return sd->objects[p_key].rect;
}

Vector2i TextServerAdvanced::_shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, Vector2i());

MutexLock lock(sd->mutex);
ERR_FAIL_COND_V(!sd->objects.has(p_key), Vector2i());
return Vector2i(sd->objects[p_key].start, sd->objects[p_key].end);
}

int64_t TextServerAdvanced::_shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, -1);

MutexLock lock(sd->mutex);
ERR_FAIL_COND_V(!sd->objects.has(p_key), -1);
if (!sd->valid) {
const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
const ShapedTextDataAdvanced::EmbeddedObject &obj = sd->objects[p_key];
int sd_size = sd->glyphs.size();
const Glyph *sd_glyphs = sd->glyphs.ptr();
for (int i = 0; i < sd_size; i++) {
if (obj.start == sd_glyphs[i].start) {
return i;
}
}
return -1;
}

Size2 TextServerAdvanced::_shaped_text_get_size(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, Size2());
Expand Down
5 changes: 4 additions & 1 deletion modules/text_server_adv/text_server_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,8 @@ class TextServerAdvanced : public TextServerExtension {
Vector<Span> spans;

struct EmbeddedObject {
int pos = 0;
int start = -1;
int end = -1;
InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
Rect2 rect;
double baseline = 0;
Expand Down Expand Up @@ -957,6 +958,8 @@ class TextServerAdvanced : public TextServerExtension {

MODBIND1RC(Array, shaped_text_get_objects, const RID &);
MODBIND2RC(Rect2, shaped_text_get_object_rect, const RID &, const Variant &);
MODBIND2RC(Vector2i, shaped_text_get_object_range, const RID &, const Variant &);
MODBIND2RC(int64_t, shaped_text_get_object_glyph, const RID &, const Variant &);

MODBIND1RC(Size2, shaped_text_get_size, const RID &);
MODBIND1RC(double, shaped_text_get_ascent, const RID &);
Expand Down
37 changes: 32 additions & 5 deletions modules/text_server_fb/text_server_fb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2874,7 +2874,7 @@ void TextServerFallback::full_copy(ShapedTextDataFallback *p_shaped) {
ShapedTextDataFallback *parent = shaped_owner.get_or_null(p_shaped->parent);

for (const KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : parent->objects) {
if (E.value.pos >= p_shaped->start && E.value.pos < p_shaped->end) {
if (E.value.start >= p_shaped->start && E.value.start < p_shaped->end) {
p_shaped->objects[E.key] = E.value;
}
}
Expand Down Expand Up @@ -3170,7 +3170,8 @@ bool TextServerFallback::_shaped_text_add_object(const RID &p_shaped, const Vari
ShapedTextDataFallback::EmbeddedObject obj;
obj.inline_align = p_inline_align;
obj.rect.size = p_size;
obj.pos = span.start;
obj.start = span.start;
obj.end = span.end;
obj.baseline = p_baseline;

sd->spans.push_back(span);
Expand Down Expand Up @@ -3205,7 +3206,7 @@ bool TextServerFallback::_shaped_text_resize_object(const RID &p_shaped, const V
Variant key;
if (gl.count == 1) {
for (const KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : sd->objects) {
if (E.value.pos == gl.start) {
if (E.value.start == gl.start) {
key = E.key;
break;
}
Expand Down Expand Up @@ -3254,7 +3255,7 @@ void TextServerFallback::_realign(ShapedTextDataFallback *p_sd) const {
double full_ascent = p_sd->ascent;
double full_descent = p_sd->descent;
for (KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : p_sd->objects) {
if ((E.value.pos >= p_sd->start) && (E.value.pos < p_sd->end)) {
if ((E.value.start >= p_sd->start) && (E.value.start < p_sd->end)) {
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
case INLINE_ALIGNMENT_TO_TOP: {
Expand Down Expand Up @@ -3375,7 +3376,7 @@ RID TextServerFallback::_shaped_text_substr(const RID &p_shaped, int64_t p_start
bool find_embedded = false;
if (gl.count == 1) {
for (const KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : sd->objects) {
if (E.value.pos == gl.start) {
if (E.value.start == gl.start) {
find_embedded = true;
key = E.key;
new_sd->objects[key] = E.value;
Expand Down Expand Up @@ -4288,6 +4289,32 @@ Rect2 TextServerFallback::_shaped_text_get_object_rect(const RID &p_shaped, cons
return sd->objects[p_key].rect;
}

Vector2i TextServerFallback::_shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, Vector2i());

MutexLock lock(sd->mutex);
ERR_FAIL_COND_V(!sd->objects.has(p_key), Vector2i());
return Vector2i(sd->objects[p_key].start, sd->objects[p_key].end);
}

int64_t TextServerFallback::_shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, -1);

MutexLock lock(sd->mutex);
ERR_FAIL_COND_V(!sd->objects.has(p_key), -1);
const ShapedTextDataFallback::EmbeddedObject &obj = sd->objects[p_key];
int sd_size = sd->glyphs.size();
const Glyph *sd_glyphs = sd->glyphs.ptr();
for (int i = 0; i < sd_size; i++) {
if (obj.start == sd_glyphs[i].start) {
return i;
}
}
return -1;
}

Size2 TextServerFallback::_shaped_text_get_size(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_NULL_V(sd, Size2());
Expand Down
5 changes: 4 additions & 1 deletion modules/text_server_fb/text_server_fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ class TextServerFallback : public TextServerExtension {
Vector<Span> spans;

struct EmbeddedObject {
int pos = 0;
int start = -1;
int end = -1;
InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
Rect2 rect;
double baseline = 0;
Expand Down Expand Up @@ -825,6 +826,8 @@ class TextServerFallback : public TextServerExtension {

MODBIND1RC(Array, shaped_text_get_objects, const RID &);
MODBIND2RC(Rect2, shaped_text_get_object_rect, const RID &, const Variant &);
MODBIND2RC(Vector2i, shaped_text_get_object_range, const RID &, const Variant &);
MODBIND2RC(int64_t, shaped_text_get_object_glyph, const RID &, const Variant &);

MODBIND1RC(Size2, shaped_text_get_size, const RID &);
MODBIND1RC(double, shaped_text_get_ascent, const RID &);
Expand Down
10 changes: 10 additions & 0 deletions scene/gui/rich_text_label.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,16 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
for (int i = 0; i < objects.size(); i++) {
Item *it = items.get_or_null(objects[i]);
if (it != nullptr) {
Vector2i obj_range = TS->shaped_text_get_object_range(rid, objects[i]);
if (trim_chars && l.char_offset + obj_range.y > visible_characters) {
continue;
}
if (trim_glyphs_ltr || trim_glyphs_rtl) {
int obj_glyph = r_processed_glyphs + TS->shaped_text_get_object_glyph(rid, objects[i]);
if ((trim_glyphs_ltr && (obj_glyph >= visible_glyphs)) || (trim_glyphs_rtl && (obj_glyph < total_glyphs - visible_glyphs))) {
continue;
}
}
Rect2 rect = TS->shaped_text_get_object_rect(rid, objects[i]);
//draw_rect(rect, Color(1,0,0), false, 2); //DEBUG_RECTS
switch (it->type) {
Expand Down
14 changes: 14 additions & 0 deletions servers/text/text_server_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ void TextServerExtension::_bind_methods() {

GDVIRTUAL_BIND(_shaped_text_get_objects, "shaped");
GDVIRTUAL_BIND(_shaped_text_get_object_rect, "shaped", "key");
GDVIRTUAL_BIND(_shaped_text_get_object_range, "shaped", "key");
GDVIRTUAL_BIND(_shaped_text_get_object_glyph, "shaped", "key");

GDVIRTUAL_BIND(_shaped_text_get_size, "shaped");
GDVIRTUAL_BIND(_shaped_text_get_ascent, "shaped");
Expand Down Expand Up @@ -1284,6 +1286,18 @@ Rect2 TextServerExtension::shaped_text_get_object_rect(const RID &p_shaped, cons
return ret;
}

Vector2i TextServerExtension::shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const {
Vector2i ret;
GDVIRTUAL_CALL(_shaped_text_get_object_range, p_shaped, p_key, ret);
return ret;
}

int64_t TextServerExtension::shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const {
int64_t ret = -1;
GDVIRTUAL_CALL(_shaped_text_get_object_glyph, p_shaped, p_key, ret);
return ret;
}

Size2 TextServerExtension::shaped_text_get_size(const RID &p_shaped) const {
Size2 ret;
GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret);
Expand Down
4 changes: 4 additions & 0 deletions servers/text/text_server_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,12 @@ class TextServerExtension : public TextServer {

virtual Array shaped_text_get_objects(const RID &p_shaped) const override;
virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override;
virtual Vector2i shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const override;
virtual int64_t shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const override;
GDVIRTUAL1RC(Array, _shaped_text_get_objects, RID);
GDVIRTUAL2RC(Rect2, _shaped_text_get_object_rect, RID, const Variant &);
GDVIRTUAL2RC(Vector2i, _shaped_text_get_object_range, RID, const Variant &);
GDVIRTUAL2RC(int64_t, _shaped_text_get_object_glyph, RID, const Variant &);

virtual Size2 shaped_text_get_size(const RID &p_shaped) const override;
virtual double shaped_text_get_ascent(const RID &p_shaped) const override;
Expand Down
2 changes: 2 additions & 0 deletions servers/text_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ void TextServer::_bind_methods() {

ClassDB::bind_method(D_METHOD("shaped_text_get_objects", "shaped"), &TextServer::shaped_text_get_objects);
ClassDB::bind_method(D_METHOD("shaped_text_get_object_rect", "shaped", "key"), &TextServer::shaped_text_get_object_rect);
ClassDB::bind_method(D_METHOD("shaped_text_get_object_range", "shaped", "key"), &TextServer::shaped_text_get_object_range);
ClassDB::bind_method(D_METHOD("shaped_text_get_object_glyph", "shaped", "key"), &TextServer::shaped_text_get_object_glyph);

ClassDB::bind_method(D_METHOD("shaped_text_get_size", "shaped"), &TextServer::shaped_text_get_size);
ClassDB::bind_method(D_METHOD("shaped_text_get_ascent", "shaped"), &TextServer::shaped_text_get_ascent);
Expand Down
2 changes: 2 additions & 0 deletions servers/text_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ class TextServer : public RefCounted {

virtual Array shaped_text_get_objects(const RID &p_shaped) const = 0;
virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const = 0;
virtual Vector2i shaped_text_get_object_range(const RID &p_shaped, const Variant &p_key) const = 0;
virtual int64_t shaped_text_get_object_glyph(const RID &p_shaped, const Variant &p_key) const = 0;

virtual Size2 shaped_text_get_size(const RID &p_shaped) const = 0;
virtual double shaped_text_get_ascent(const RID &p_shaped) const = 0;
Expand Down
Loading