summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2021-06-14 10:11:37 +0300
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2021-08-08 22:35:47 +0300
commit7c3c5603d0a3208d6bee186f50857b15a02419d6 (patch)
tree8cb3e7dba7f9218988dcd02f31a21adf83c630f5 /modules
parente010e05b3dd842ba86a68dee60e0d7be6f9aae50 (diff)
[Text Server] Improve object (image/table) inline alignment.
Diffstat (limited to 'modules')
-rw-r--r--modules/gdnative/text/text_server_gdnative.cpp4
-rw-r--r--modules/gdnative/text/text_server_gdnative.h4
-rw-r--r--modules/text_server_adv/text_server_adv.cpp258
-rw-r--r--modules/text_server_adv/text_server_adv.h4
-rw-r--r--modules/text_server_fb/text_server_fb.cpp258
-rw-r--r--modules/text_server_fb/text_server_fb.h4
6 files changed, 301 insertions, 231 deletions
diff --git a/modules/gdnative/text/text_server_gdnative.cpp b/modules/gdnative/text/text_server_gdnative.cpp
index 81dd570bcb..d54b1a47df 100644
--- a/modules/gdnative/text/text_server_gdnative.cpp
+++ b/modules/gdnative/text/text_server_gdnative.cpp
@@ -449,12 +449,12 @@ bool TextServerGDNative::shaped_text_add_string(RID p_shaped, const String &p_te
return interface->shaped_text_add_string(data, (godot_rid *)&p_shaped, (const godot_string *)&p_text, (const godot_rid **)p_fonts.ptr(), p_size, (const godot_dictionary *)&p_opentype_features, (const godot_string *)&p_language);
}
-bool TextServerGDNative::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align, int p_length) {
+bool TextServerGDNative::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
ERR_FAIL_COND_V(interface == nullptr, false);
return interface->shaped_text_add_object(data, (godot_rid *)&p_shaped, (const godot_variant *)&p_key, (const godot_vector2 *)&p_size, (godot_int)p_inline_align, p_length);
}
-bool TextServerGDNative::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align) {
+bool TextServerGDNative::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
ERR_FAIL_COND_V(interface == nullptr, false);
return interface->shaped_text_resize_object(data, (godot_rid *)&p_shaped, (const godot_variant *)&p_key, (const godot_vector2 *)&p_size, (godot_int)p_inline_align);
}
diff --git a/modules/gdnative/text/text_server_gdnative.h b/modules/gdnative/text/text_server_gdnative.h
index 7a0725f3d9..a2eb944499 100644
--- a/modules/gdnative/text/text_server_gdnative.h
+++ b/modules/gdnative/text/text_server_gdnative.h
@@ -154,8 +154,8 @@ public:
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, VAlign p_inline_align = VALIGN_CENTER, int p_length = 1) override;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER) 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;
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index fa4888f843..66816f32d1 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -1161,7 +1161,7 @@ bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_te
return true;
}
-bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align, int p_length) {
+bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -1191,7 +1191,7 @@ bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, con
return true;
}
-bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align) {
+bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
_THREAD_SAFE_METHOD_
ShapedTextData *sd = shaped_owner.getornull(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -1222,34 +1222,10 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key,
if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->objects[key].rect.position.x = sd->width;
sd->width += sd->objects[key].rect.size.x;
- switch (sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[key].rect.size.y);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[key].rect.size.y / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[key].rect.size.y / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[key].rect.size.y);
- } break;
- }
sd->glyphs.write[i].advance = sd->objects[key].rect.size.x;
} else {
sd->objects[key].rect.position.y = sd->width;
sd->width += sd->objects[key].rect.size.y;
- switch (sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[key].rect.size.x);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[key].rect.size.x / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[key].rect.size.x / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[key].rect.size.x);
- } break;
- }
sd->glyphs.write[i].advance = sd->objects[key].rect.size.y;
}
} else {
@@ -1279,35 +1255,71 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key,
}
// Align embedded objects to baseline.
+ float full_ascent = sd->ascent;
+ float full_descent = sd->descent;
for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) {
if ((E->get().pos >= sd->start) && (E->get().pos < sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.y = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.y = -(E->get().rect.size.y / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.y = (-sd->ascent + sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.y = 0;
+ } break;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.y = sd->descent;
+ } break;
+ }
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y / 2;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.y = sd->descent - E->get().rect.size.y;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
} break;
}
+ full_ascent = MAX(full_ascent, -E->get().rect.position.y);
+ full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y);
} else {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.x = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.x = -(E->get().rect.size.x / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.x = (-sd->ascent + sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.x = 0;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.x = sd->descent - E->get().rect.size.x;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.x = sd->descent;
} break;
}
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E->get().rect.position.x);
+ full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x);
}
}
}
+ sd->ascent = full_ascent;
+ sd->descent = full_descent;
}
return true;
}
@@ -1404,33 +1416,9 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng
if (new_sd->orientation == ORIENTATION_HORIZONTAL) {
new_sd->objects[key].rect.position.x = new_sd->width;
new_sd->width += new_sd->objects[key].rect.size.x;
- switch (new_sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- new_sd->ascent = MAX(new_sd->ascent, new_sd->objects[key].rect.size.y);
- } break;
- case VALIGN_CENTER: {
- new_sd->ascent = MAX(new_sd->ascent, Math::round(new_sd->objects[key].rect.size.y / 2));
- new_sd->descent = MAX(new_sd->descent, Math::round(new_sd->objects[key].rect.size.y / 2));
- } break;
- case VALIGN_BOTTOM: {
- new_sd->descent = MAX(new_sd->descent, new_sd->objects[key].rect.size.y);
- } break;
- }
} else {
new_sd->objects[key].rect.position.y = new_sd->width;
new_sd->width += new_sd->objects[key].rect.size.y;
- switch (new_sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- new_sd->ascent = MAX(new_sd->ascent, new_sd->objects[key].rect.size.x);
- } break;
- case VALIGN_CENTER: {
- new_sd->ascent = MAX(new_sd->ascent, Math::round(new_sd->objects[key].rect.size.x / 2));
- new_sd->descent = MAX(new_sd->descent, Math::round(new_sd->objects[key].rect.size.x / 2));
- } break;
- case VALIGN_BOTTOM: {
- new_sd->descent = MAX(new_sd->descent, new_sd->objects[key].rect.size.x);
- } break;
- }
}
} else {
if (prev_rid != gl.font_rid) {
@@ -1464,37 +1452,72 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng
}
// Align embedded objects to baseline.
+ float full_ascent = new_sd->ascent;
+ float full_descent = new_sd->descent;
for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = new_sd->objects.front(); E; E = E->next()) {
if ((E->get().pos >= new_sd->start) && (E->get().pos < new_sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.y = -new_sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.y = -(E->get().rect.size.y / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.y = (-new_sd->ascent + new_sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.y = 0;
+ } break;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.y = new_sd->descent;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.y = new_sd->descent - E->get().rect.size.y;
+ }
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
} break;
}
+ full_ascent = MAX(full_ascent, -E->get().rect.position.y);
+ full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y);
} else {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.x = -new_sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.x = -(E->get().rect.size.x / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.x = (-new_sd->ascent + new_sd->descent) / 2;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.x = new_sd->descent - E->get().rect.size.x;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.x = 0;
+ } break;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.x = new_sd->descent;
} break;
}
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E->get().rect.position.x);
+ full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x);
}
}
}
+ new_sd->ascent = full_ascent;
+ new_sd->descent = full_descent;
}
-
new_sd->valid = true;
return shaped_owner.make_rid(new_sd);
@@ -2473,33 +2496,9 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->objects[span.embedded_key].rect.position.x = sd->width;
sd->width += sd->objects[span.embedded_key].rect.size.x;
- switch (sd->objects[span.embedded_key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[span.embedded_key].rect.size.y);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[span.embedded_key].rect.size.y / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[span.embedded_key].rect.size.y / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[span.embedded_key].rect.size.y);
- } break;
- }
} else {
sd->objects[span.embedded_key].rect.position.y = sd->width;
sd->width += sd->objects[span.embedded_key].rect.size.y;
- switch (sd->objects[span.embedded_key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[span.embedded_key].rect.size.x);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[span.embedded_key].rect.size.x / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[span.embedded_key].rect.size.x / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[span.embedded_key].rect.size.x);
- } break;
- }
}
Glyph gl;
gl.start = span.start;
@@ -2539,34 +2538,69 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) {
}
// Align embedded objects to baseline.
+ float full_ascent = sd->ascent;
+ float full_descent = sd->descent;
for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.y = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.y = -(E->get().rect.size.y / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.y = (-sd->ascent + sd->descent) / 2;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.y = sd->descent - E->get().rect.size.y;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.y = 0;
+ } break;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.y = sd->descent;
+ } break;
+ }
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
} break;
}
+ full_ascent = MAX(full_ascent, -E->get().rect.position.y);
+ full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y);
} else {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.x = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.x = -(E->get().rect.size.x / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.x = (-sd->ascent + sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.x = 0;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.x = sd->descent - E->get().rect.size.x;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.x = sd->descent;
} break;
}
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E->get().rect.position.x);
+ full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x);
}
}
-
+ sd->ascent = full_ascent;
+ sd->descent = full_descent;
sd->valid = true;
return sd->valid;
}
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 3c4f840bfd..c54686c114 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -216,8 +216,8 @@ public:
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, VAlign p_inline_align = VALIGN_CENTER, int p_length = 1) override;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER) 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;
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index 004cbc2bb3..b60bf8e8d3 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -661,7 +661,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te
return true;
}
-bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align, int p_length) {
+bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
_THREAD_SAFE_METHOD_
ShapedTextData *sd = shaped_owner.getornull(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -691,7 +691,7 @@ bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, con
return true;
}
-bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align) {
+bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
_THREAD_SAFE_METHOD_
ShapedTextData *sd = shaped_owner.getornull(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -724,34 +724,10 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key,
if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->objects[key].rect.position.x = sd->width;
sd->width += sd->objects[key].rect.size.x;
- switch (sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[key].rect.size.y);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[key].rect.size.y / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[key].rect.size.y / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[key].rect.size.y);
- } break;
- }
sd->glyphs.write[i].advance = sd->objects[key].rect.size.x;
} else {
sd->objects[key].rect.position.y = sd->width;
sd->width += sd->objects[key].rect.size.y;
- switch (sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[key].rect.size.x);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[key].rect.size.x / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[key].rect.size.x / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[key].rect.size.x);
- } break;
- }
sd->glyphs.write[i].advance = sd->objects[key].rect.size.y;
}
} else {
@@ -784,35 +760,71 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key,
}
// Align embedded objects to baseline.
+ float full_ascent = sd->ascent;
+ float full_descent = sd->descent;
for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) {
if ((E->get().pos >= sd->start) && (E->get().pos < sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.y = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.y = -(E->get().rect.size.y / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.y = (-sd->ascent + sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.y = 0;
+ } break;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.y = sd->descent;
+ } break;
+ }
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y / 2;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.y = sd->descent - E->get().rect.size.y;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
} break;
}
+ full_ascent = MAX(full_ascent, -E->get().rect.position.y);
+ full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y);
} else {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.x = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.x = -(E->get().rect.size.x / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.x = (-sd->ascent + sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.x = 0;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.x = sd->descent - E->get().rect.size.x;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.x = sd->descent;
} break;
}
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E->get().rect.position.x);
+ full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x);
}
}
}
+ sd->ascent = full_ascent;
+ sd->descent = full_descent;
}
return true;
}
@@ -869,33 +881,9 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
if (new_sd->orientation == ORIENTATION_HORIZONTAL) {
new_sd->objects[key].rect.position.x = new_sd->width;
new_sd->width += new_sd->objects[key].rect.size.x;
- switch (new_sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- new_sd->ascent = MAX(new_sd->ascent, new_sd->objects[key].rect.size.y);
- } break;
- case VALIGN_CENTER: {
- new_sd->ascent = MAX(new_sd->ascent, Math::round(new_sd->objects[key].rect.size.y / 2));
- new_sd->descent = MAX(new_sd->descent, Math::round(new_sd->objects[key].rect.size.y / 2));
- } break;
- case VALIGN_BOTTOM: {
- new_sd->descent = MAX(new_sd->descent, new_sd->objects[key].rect.size.y);
- } break;
- }
} else {
new_sd->objects[key].rect.position.y = new_sd->width;
new_sd->width += new_sd->objects[key].rect.size.y;
- switch (new_sd->objects[key].inline_align) {
- case VALIGN_TOP: {
- new_sd->ascent = MAX(new_sd->ascent, new_sd->objects[key].rect.size.x);
- } break;
- case VALIGN_CENTER: {
- new_sd->ascent = MAX(new_sd->ascent, Math::round(new_sd->objects[key].rect.size.x / 2));
- new_sd->descent = MAX(new_sd->descent, Math::round(new_sd->objects[key].rect.size.x / 2));
- } break;
- case VALIGN_BOTTOM: {
- new_sd->descent = MAX(new_sd->descent, new_sd->objects[key].rect.size.x);
- } break;
- }
}
} else {
const FontDataFallback *fd = font_owner.getornull(gl.font_rid);
@@ -923,35 +911,72 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
}
}
+ // Align embedded objects to baseline.
+ float full_ascent = new_sd->ascent;
+ float full_descent = new_sd->descent;
for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = new_sd->objects.front(); E; E = E->next()) {
if ((E->get().pos >= new_sd->start) && (E->get().pos < new_sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.y = -new_sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.y = -(E->get().rect.size.y / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.y = (-new_sd->ascent + new_sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.y = 0;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.y = new_sd->descent - E->get().rect.size.y;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.y = new_sd->descent;
} break;
}
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E->get().rect.position.y);
+ full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y);
} else {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.x = -new_sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.x = -(E->get().rect.size.x / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.x = (-new_sd->ascent + new_sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.x = 0;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.x = new_sd->descent - E->get().rect.size.x;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.x = new_sd->descent;
} break;
}
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E->get().rect.position.x);
+ full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x);
}
}
}
+ new_sd->ascent = full_ascent;
+ new_sd->descent = full_descent;
}
new_sd->valid = true;
@@ -1336,33 +1361,9 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->objects[span.embedded_key].rect.position.x = sd->width;
sd->width += sd->objects[span.embedded_key].rect.size.x;
- switch (sd->objects[span.embedded_key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[span.embedded_key].rect.size.y);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[span.embedded_key].rect.size.y / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[span.embedded_key].rect.size.y / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[span.embedded_key].rect.size.y);
- } break;
- }
} else {
sd->objects[span.embedded_key].rect.position.y = sd->width;
sd->width += sd->objects[span.embedded_key].rect.size.y;
- switch (sd->objects[span.embedded_key].inline_align) {
- case VALIGN_TOP: {
- sd->ascent = MAX(sd->ascent, sd->objects[span.embedded_key].rect.size.x);
- } break;
- case VALIGN_CENTER: {
- sd->ascent = MAX(sd->ascent, Math::round(sd->objects[span.embedded_key].rect.size.x / 2));
- sd->descent = MAX(sd->descent, Math::round(sd->objects[span.embedded_key].rect.size.x / 2));
- } break;
- case VALIGN_BOTTOM: {
- sd->descent = MAX(sd->descent, sd->objects[span.embedded_key].rect.size.x);
- } break;
- }
}
Glyph gl;
gl.start = span.start;
@@ -1456,34 +1457,69 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
}
// Align embedded objects to baseline.
+ float full_ascent = sd->ascent;
+ float full_descent = sd->descent;
for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.y = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.y = -(E->get().rect.size.y / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.y = (-sd->ascent + sd->descent) / 2;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.y = sd->descent - E->get().rect.size.y;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.y = 0;
+ } break;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.y = sd->descent;
+ } break;
+ }
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.y -= E->get().rect.size.y / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
} break;
}
+ full_ascent = MAX(full_ascent, -E->get().rect.position.y);
+ full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y);
} else {
- switch (E->get().inline_align) {
- case VALIGN_TOP: {
+ switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) {
+ case INLINE_ALIGN_TO_TOP: {
E->get().rect.position.x = -sd->ascent;
} break;
- case VALIGN_CENTER: {
- E->get().rect.position.x = -(E->get().rect.size.x / 2);
+ case INLINE_ALIGN_TO_CENTER: {
+ E->get().rect.position.x = (-sd->ascent + sd->descent) / 2;
+ } break;
+ case INLINE_ALIGN_TO_BASELINE: {
+ E->get().rect.position.x = 0;
} break;
- case VALIGN_BOTTOM: {
- E->get().rect.position.x = sd->descent - E->get().rect.size.x;
+ case INLINE_ALIGN_TO_BOTTOM: {
+ E->get().rect.position.x = sd->descent;
} break;
}
+ switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) {
+ case INLINE_ALIGN_BOTTOM_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x;
+ } break;
+ case INLINE_ALIGN_CENTER_TO: {
+ E->get().rect.position.x -= E->get().rect.size.x / 2;
+ } break;
+ case INLINE_ALIGN_TOP_TO: {
+ //NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E->get().rect.position.x);
+ full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x);
}
}
-
+ sd->ascent = full_ascent;
+ sd->descent = full_descent;
sd->valid = true;
return sd->valid;
}
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index b70c8f4ec0..e3bbde76d4 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -165,8 +165,8 @@ public:
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, VAlign p_inline_align = VALIGN_CENTER, int p_length = 1) override;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER) 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;