[Text Server] Improve object (image/table) inline alignment.
This commit is contained in:
parent
e010e05b3d
commit
7c3c5603d0
|
@ -133,6 +133,19 @@ void register_global_constants() {
|
|||
BIND_CORE_ENUM_CONSTANT(VALIGN_CENTER);
|
||||
BIND_CORE_ENUM_CONSTANT(VALIGN_BOTTOM);
|
||||
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TOP_TO);
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_CENTER_TO);
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_BOTTOM_TO);
|
||||
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_TOP);
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_CENTER);
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_BASELINE);
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_BOTTOM);
|
||||
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TOP);
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_CENTER);
|
||||
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_BOTTOM);
|
||||
|
||||
// huge list of keys
|
||||
BIND_CORE_CONSTANT(SPKEY);
|
||||
|
||||
|
|
|
@ -81,6 +81,26 @@ enum VAlign {
|
|||
VALIGN_BOTTOM
|
||||
};
|
||||
|
||||
enum InlineAlign {
|
||||
// Image alignment points.
|
||||
INLINE_ALIGN_TOP_TO = 0b0000,
|
||||
INLINE_ALIGN_CENTER_TO = 0b0001,
|
||||
INLINE_ALIGN_BOTTOM_TO = 0b0010,
|
||||
INLINE_ALIGN_IMAGE_MASK = 0b0011,
|
||||
|
||||
// Text alignment points.
|
||||
INLINE_ALIGN_TO_TOP = 0b0000,
|
||||
INLINE_ALIGN_TO_CENTER = 0b0100,
|
||||
INLINE_ALIGN_TO_BASELINE = 0b1000,
|
||||
INLINE_ALIGN_TO_BOTTOM = 0b1100,
|
||||
INLINE_ALIGN_TEXT_MASK = 0b1100,
|
||||
|
||||
// Presets.
|
||||
INLINE_ALIGN_TOP = INLINE_ALIGN_TOP_TO | INLINE_ALIGN_TO_TOP,
|
||||
INLINE_ALIGN_CENTER = INLINE_ALIGN_CENTER_TO | INLINE_ALIGN_TO_CENTER,
|
||||
INLINE_ALIGN_BOTTOM = INLINE_ALIGN_BOTTOM_TO | INLINE_ALIGN_TO_BOTTOM
|
||||
};
|
||||
|
||||
enum Side {
|
||||
SIDE_LEFT,
|
||||
SIDE_TOP,
|
||||
|
|
|
@ -101,6 +101,7 @@ VARIANT_ENUM_CAST(MouseButton);
|
|||
VARIANT_ENUM_CAST(Orientation);
|
||||
VARIANT_ENUM_CAST(HAlign);
|
||||
VARIANT_ENUM_CAST(VAlign);
|
||||
VARIANT_ENUM_CAST(InlineAlign);
|
||||
VARIANT_ENUM_CAST(PropertyHint);
|
||||
VARIANT_ENUM_CAST(PropertyUsageFlags);
|
||||
VARIANT_ENUM_CAST(Variant::Type);
|
||||
|
|
|
@ -1128,6 +1128,36 @@
|
|||
<constant name="VALIGN_BOTTOM" value="2" enum="VAlign">
|
||||
Vertical bottom alignment, usually for text-derived classes.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_TOP_TO" value="0" enum="InlineAlign">
|
||||
Aligns the top of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGN_TO_*[/code] constant.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_CENTER_TO" value="1" enum="InlineAlign">
|
||||
Aligns the center of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGN_TO_*[/code] constant.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_BOTTOM_TO" value="2" enum="InlineAlign">
|
||||
Aligns the bottom of the inline object (e.g. image, table) to the position of the text specified by [code]INLINE_ALIGN_TO_*[/code] constant.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_TO_TOP" value="0" enum="InlineAlign">
|
||||
Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGN_*_TO[/code] constant to the top of the text.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_TO_CENTER" value="4" enum="InlineAlign">
|
||||
Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGN_*_TO[/code] constant to the center of the text.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_TO_BASELINE" value="8" enum="InlineAlign">
|
||||
Aligns the position of the inline object (e.g. image, table) specified by [code]INLINE_ALIGN_*_TO[/code] constant to the baseline of the text.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_TO_BOTTOM" value="12" enum="InlineAlign">
|
||||
Aligns inline object (e.g. image, table) to the bottom of the text.
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_TOP" value="0" enum="InlineAlign">
|
||||
Aligns top of the inline object (e.g. image, table) to the top of the text. Equvalent to [code]INLINE_ALIGN_TOP_TO | INLINE_ALIGN_TO_TOP[/code].
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_CENTER" value="5" enum="InlineAlign">
|
||||
Aligns center of the inline object (e.g. image, table) to the center of the text. Equvalent to [code]INLINE_ALIGN_CENTER_TO | INLINE_ALIGN_TO_CENTER[/code].
|
||||
</constant>
|
||||
<constant name="INLINE_ALIGN_BOTTOM" value="14" enum="InlineAlign">
|
||||
Aligns bottom of the inline object (e.g. image, table) to the bottom of the text. Equvalent to [code]INLINE_ALIGN_BOTTOM_TO | INLINE_ALIGN_TO_BOTTOM[/code].
|
||||
</constant>
|
||||
<constant name="SPKEY" value="16777216">
|
||||
Keycodes with this bit applied are non-printable.
|
||||
</constant>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<argument index="1" name="width" type="int" default="0" />
|
||||
<argument index="2" name="height" type="int" default="0" />
|
||||
<argument index="3" name="color" type="Color" default="Color(1, 1, 1, 1)" />
|
||||
<argument index="4" name="inline_align" type="int" enum="VAlign" default="0" />
|
||||
<argument index="4" name="inline_align" type="int" enum="InlineAlign" default="5" />
|
||||
<description>
|
||||
Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image and a [code]color[/code] to tint the image.
|
||||
If [code]width[/code] or [code]height[/code] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.
|
||||
|
@ -288,7 +288,7 @@
|
|||
<method name="push_table">
|
||||
<return type="void" />
|
||||
<argument index="0" name="columns" type="int" />
|
||||
<argument index="1" name="inline_align" type="int" enum="VAlign" default="0" />
|
||||
<argument index="1" name="inline_align" type="int" enum="InlineAlign" default="0" />
|
||||
<description>
|
||||
Adds a [code][table=columns,inline_align][/code] tag to the tag stack.
|
||||
</description>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<return type="bool" />
|
||||
<argument index="0" name="key" type="Variant" />
|
||||
<argument index="1" name="size" type="Vector2" />
|
||||
<argument index="2" name="inline_align" type="int" enum="VAlign" default="1" />
|
||||
<argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
|
||||
<argument index="3" name="length" type="int" default="1" />
|
||||
<description>
|
||||
Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters.
|
||||
|
@ -122,7 +122,7 @@
|
|||
<return type="bool" />
|
||||
<argument index="0" name="key" type="Variant" />
|
||||
<argument index="1" name="size" type="Vector2" />
|
||||
<argument index="2" name="inline_align" type="int" enum="VAlign" default="1" />
|
||||
<argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
|
||||
<description>
|
||||
Sets new size and alignment of embedded object.
|
||||
</description>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<return type="bool" />
|
||||
<argument index="0" name="key" type="Variant" />
|
||||
<argument index="1" name="size" type="Vector2" />
|
||||
<argument index="2" name="inline_align" type="int" enum="VAlign" default="1" />
|
||||
<argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
|
||||
<argument index="3" name="length" type="int" default="1" />
|
||||
<description>
|
||||
Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters.
|
||||
|
@ -240,7 +240,7 @@
|
|||
<return type="bool" />
|
||||
<argument index="0" name="key" type="Variant" />
|
||||
<argument index="1" name="size" type="Vector2" />
|
||||
<argument index="2" name="inline_align" type="int" enum="VAlign" default="1" />
|
||||
<argument index="2" name="inline_align" type="int" enum="InlineAlign" default="5" />
|
||||
<description>
|
||||
Sets new size and alignment of embedded object.
|
||||
</description>
|
||||
|
|
|
@ -541,7 +541,7 @@
|
|||
<argument index="0" name="shaped" type="RID" />
|
||||
<argument index="1" name="key" type="Variant" />
|
||||
<argument index="2" name="size" type="Vector2" />
|
||||
<argument index="3" name="inline_align" type="int" enum="VAlign" default="1" />
|
||||
<argument index="3" name="inline_align" type="int" enum="InlineAlign" default="5" />
|
||||
<argument index="4" name="length" type="int" default="1" />
|
||||
<description>
|
||||
Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters.
|
||||
|
@ -817,7 +817,7 @@
|
|||
<argument index="0" name="shaped" type="RID" />
|
||||
<argument index="1" name="key" type="Variant" />
|
||||
<argument index="2" name="size" type="Vector2" />
|
||||
<argument index="3" name="inline_align" type="int" enum="VAlign" default="1" />
|
||||
<argument index="3" name="inline_align" type="int" enum="InlineAlign" default="5" />
|
||||
<description>
|
||||
Sets new size and alignment of embedded object.
|
||||
</description>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 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 VALIGN_BOTTOM: {
|
||||
E->get().rect.position.x = 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 = 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 VALIGN_BOTTOM: {
|
||||
E->get().rect.position.y = new_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 = 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 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 VALIGN_BOTTOM: {
|
||||
E->get().rect.position.x = 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 = 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 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 VALIGN_BOTTOM: {
|
||||
E->get().rect.position.x = 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 = 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 VALIGN_BOTTOM: {
|
||||
E->get().rect.position.y = new_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 = 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 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;
|
||||
|
||||
|
@ -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 VALIGN_BOTTOM: {
|
||||
E->get().rect.position.x = 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 = 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2289,7 +2289,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, VAlign p_align) {
|
||||
void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlign p_align) {
|
||||
if (current->type == ITEM_TABLE) {
|
||||
return;
|
||||
}
|
||||
|
@ -2534,7 +2534,7 @@ void RichTextLabel::push_meta(const Variant &p_meta) {
|
|||
_add_item(item, true);
|
||||
}
|
||||
|
||||
void RichTextLabel::push_table(int p_columns, VAlign p_align) {
|
||||
void RichTextLabel::push_table(int p_columns, InlineAlign p_align) {
|
||||
ERR_FAIL_COND(p_columns < 1);
|
||||
ItemTable *item = memnew(ItemTable);
|
||||
|
||||
|
@ -2897,18 +2897,35 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
|
|||
columns = 1;
|
||||
}
|
||||
|
||||
VAlign align = VALIGN_TOP;
|
||||
if (subtag.size() > 1) {
|
||||
int align = INLINE_ALIGN_TOP;
|
||||
if (subtag.size() > 2) {
|
||||
if (subtag[1] == "top" || subtag[1] == "t") {
|
||||
align = VALIGN_TOP;
|
||||
align = INLINE_ALIGN_TOP_TO;
|
||||
} else if (subtag[1] == "center" || subtag[1] == "c") {
|
||||
align = VALIGN_CENTER;
|
||||
align = INLINE_ALIGN_CENTER_TO;
|
||||
} else if (subtag[1] == "bottom" || subtag[1] == "b") {
|
||||
align = VALIGN_BOTTOM;
|
||||
align = INLINE_ALIGN_BOTTOM_TO;
|
||||
}
|
||||
if (subtag[2] == "top" || subtag[2] == "t") {
|
||||
align |= INLINE_ALIGN_TO_TOP;
|
||||
} else if (subtag[2] == "center" || subtag[2] == "c") {
|
||||
align |= INLINE_ALIGN_TO_CENTER;
|
||||
} else if (subtag[2] == "baseline" || subtag[2] == "l") {
|
||||
align |= INLINE_ALIGN_TO_BASELINE;
|
||||
} else if (subtag[2] == "bottom" || subtag[2] == "b") {
|
||||
align |= INLINE_ALIGN_TO_BOTTOM;
|
||||
}
|
||||
} else if (subtag.size() > 1) {
|
||||
if (subtag[1] == "top" || subtag[1] == "t") {
|
||||
align = INLINE_ALIGN_TOP;
|
||||
} else if (subtag[1] == "center" || subtag[1] == "c") {
|
||||
align = INLINE_ALIGN_CENTER;
|
||||
} else if (subtag[1] == "bottom" || subtag[1] == "b") {
|
||||
align = INLINE_ALIGN_BOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
push_table(columns, align);
|
||||
push_table(columns, (InlineAlign)align);
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("table");
|
||||
} else if (tag == "cell") {
|
||||
|
@ -3187,15 +3204,34 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
|
|||
pos = end;
|
||||
tag_stack.push_front(bbcode_name);
|
||||
} else if (tag.begins_with("img")) {
|
||||
VAlign align = VALIGN_TOP;
|
||||
int align = INLINE_ALIGN_CENTER;
|
||||
if (tag.begins_with("img=")) {
|
||||
String al = tag.substr(4, tag.length());
|
||||
if (al == "top" || al == "t") {
|
||||
align = VALIGN_TOP;
|
||||
} else if (al == "center" || al == "c") {
|
||||
align = VALIGN_CENTER;
|
||||
} else if (al == "bottom" || al == "b") {
|
||||
align = VALIGN_BOTTOM;
|
||||
Vector<String> subtag = tag.substr(4, tag.length()).split(",");
|
||||
if (subtag.size() > 1) {
|
||||
if (subtag[0] == "top" || subtag[0] == "t") {
|
||||
align = INLINE_ALIGN_TOP_TO;
|
||||
} else if (subtag[0] == "center" || subtag[0] == "c") {
|
||||
align = INLINE_ALIGN_CENTER_TO;
|
||||
} else if (subtag[0] == "bottom" || subtag[0] == "b") {
|
||||
align = INLINE_ALIGN_BOTTOM_TO;
|
||||
}
|
||||
if (subtag[1] == "top" || subtag[1] == "t") {
|
||||
align |= INLINE_ALIGN_TO_TOP;
|
||||
} else if (subtag[1] == "center" || subtag[1] == "c") {
|
||||
align |= INLINE_ALIGN_TO_CENTER;
|
||||
} else if (subtag[1] == "baseline" || subtag[1] == "l") {
|
||||
align |= INLINE_ALIGN_TO_BASELINE;
|
||||
} else if (subtag[1] == "bottom" || subtag[1] == "b") {
|
||||
align |= INLINE_ALIGN_TO_BOTTOM;
|
||||
}
|
||||
} else if (subtag.size() > 0) {
|
||||
if (subtag[0] == "top" || subtag[0] == "t") {
|
||||
align = INLINE_ALIGN_TOP;
|
||||
} else if (subtag[0] == "center" || subtag[0] == "c") {
|
||||
align = INLINE_ALIGN_CENTER;
|
||||
} else if (subtag[0] == "bottom" || subtag[0] == "b") {
|
||||
align = INLINE_ALIGN_BOTTOM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3236,7 +3272,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
|
|||
}
|
||||
}
|
||||
|
||||
add_image(texture, width, height, color, align);
|
||||
add_image(texture, width, height, color, (InlineAlign)align);
|
||||
}
|
||||
|
||||
pos = end;
|
||||
|
@ -3961,7 +3997,7 @@ void RichTextLabel::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
|
||||
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
|
||||
ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text);
|
||||
ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(VALIGN_TOP));
|
||||
ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGN_CENTER));
|
||||
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
|
||||
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
|
||||
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
|
||||
|
@ -3981,7 +4017,7 @@ void RichTextLabel::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta);
|
||||
ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline);
|
||||
ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough);
|
||||
ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(VALIGN_TOP));
|
||||
ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGN_TOP));
|
||||
ClassDB::bind_method(D_METHOD("push_dropcap", "string", "font", "size", "dropcap_margins", "color", "outline_size", "outline_color"), &RichTextLabel::push_dropcap, DEFVAL(Rect2()), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(0, 0, 0, 0)));
|
||||
ClassDB::bind_method(D_METHOD("set_table_column_expand", "column", "expand", "ratio"), &RichTextLabel::set_table_column_expand);
|
||||
ClassDB::bind_method(D_METHOD("set_cell_row_background_color", "odd_row_bg", "even_row_bg"), &RichTextLabel::set_cell_row_background_color);
|
||||
|
|
|
@ -161,7 +161,7 @@ private:
|
|||
|
||||
struct ItemImage : public Item {
|
||||
Ref<Texture2D> image;
|
||||
VAlign inline_align = VALIGN_TOP;
|
||||
InlineAlign inline_align = INLINE_ALIGN_CENTER;
|
||||
Size2 size;
|
||||
Color color;
|
||||
ItemImage() { type = ITEM_IMAGE; }
|
||||
|
@ -248,7 +248,7 @@ private:
|
|||
|
||||
int total_width = 0;
|
||||
int total_height = 0;
|
||||
VAlign inline_align = VALIGN_TOP;
|
||||
InlineAlign inline_align = INLINE_ALIGN_TOP;
|
||||
ItemTable() { type = ITEM_TABLE; }
|
||||
};
|
||||
|
||||
|
@ -463,7 +463,7 @@ private:
|
|||
public:
|
||||
String get_text();
|
||||
void add_text(const String &p_text);
|
||||
void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), VAlign p_align = VALIGN_TOP);
|
||||
void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), InlineAlign p_align = INLINE_ALIGN_CENTER);
|
||||
void add_newline();
|
||||
bool remove_line(const int p_line);
|
||||
void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));
|
||||
|
@ -484,7 +484,7 @@ public:
|
|||
void push_indent(int p_level);
|
||||
void push_list(int p_level, ListType p_list, bool p_capitalize);
|
||||
void push_meta(const Variant &p_meta);
|
||||
void push_table(int p_columns, VAlign p_align = VALIGN_TOP);
|
||||
void push_table(int p_columns, InlineAlign p_align = INLINE_ALIGN_TOP);
|
||||
void push_fade(int p_start_index, int p_length);
|
||||
void push_shake(int p_strength, float p_rate);
|
||||
void push_wave(float p_frequency, float p_amplitude);
|
||||
|
|
|
@ -56,8 +56,8 @@ void TextLine::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::_set_bidi_override);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL(""));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(VALIGN_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(VALIGN_CENTER));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(INLINE_ALIGN_CENTER));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_width", "width"), &TextLine::set_width);
|
||||
ClassDB::bind_method(D_METHOD("get_width"), &TextLine::get_width);
|
||||
|
@ -175,13 +175,13 @@ bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_
|
|||
return res;
|
||||
}
|
||||
|
||||
bool TextLine::add_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align, int p_length) {
|
||||
bool TextLine::add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
|
||||
bool res = TS->shaped_text_add_object(rid, p_key, p_size, p_inline_align, p_length);
|
||||
dirty = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool TextLine::resize_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align) {
|
||||
bool TextLine::resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
|
||||
const_cast<TextLine *>(this)->_shape();
|
||||
return TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align);
|
||||
}
|
||||
|
|
|
@ -76,8 +76,8 @@ public:
|
|||
bool get_preserve_control() const;
|
||||
|
||||
bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
|
||||
bool add_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER, int p_length = 1);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER);
|
||||
bool add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER);
|
||||
|
||||
void set_align(HAlign p_align);
|
||||
HAlign get_align() const;
|
||||
|
|
|
@ -59,8 +59,8 @@ void TextParagraph::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextParagraph::add_string, DEFVAL(Dictionary()), DEFVAL(""));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(VALIGN_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(VALIGN_CENTER));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGN_CENTER));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_align", "align"), &TextParagraph::set_align);
|
||||
ClassDB::bind_method(D_METHOD("get_align"), &TextParagraph::get_align);
|
||||
|
@ -290,13 +290,13 @@ void TextParagraph::set_bidi_override(const Vector<Vector2i> &p_override) {
|
|||
dirty_lines = true;
|
||||
}
|
||||
|
||||
bool TextParagraph::add_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align, int p_length) {
|
||||
bool TextParagraph::add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
|
||||
bool res = TS->shaped_text_add_object(rid, p_key, p_size, p_inline_align, p_length);
|
||||
dirty_lines = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align) {
|
||||
bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
|
||||
bool res = TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align);
|
||||
dirty_lines = true;
|
||||
return res;
|
||||
|
|
|
@ -86,8 +86,8 @@ public:
|
|||
void clear_dropcap();
|
||||
|
||||
bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
|
||||
bool add_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER, int p_length = 1);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER);
|
||||
bool add_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER);
|
||||
|
||||
void set_align(HAlign p_align);
|
||||
HAlign get_align() const;
|
||||
|
|
|
@ -314,8 +314,8 @@ void TextServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("shaped_text_get_preserve_control", "shaped"), &TextServer::shaped_text_get_preserve_control);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(VALIGN_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(VALIGN_CENTER));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGN_CENTER));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_substr", "shaped", "start", "length"), &TextServer::shaped_text_substr);
|
||||
ClassDB::bind_method(D_METHOD("shaped_text_get_parent", "shaped"), &TextServer::shaped_text_get_parent);
|
||||
|
|
|
@ -181,7 +181,7 @@ public:
|
|||
|
||||
struct EmbeddedObject {
|
||||
int pos = 0;
|
||||
VAlign inline_align = VALIGN_TOP;
|
||||
InlineAlign inline_align = INLINE_ALIGN_CENTER;
|
||||
Rect2 rect;
|
||||
};
|
||||
Map<Variant, EmbeddedObject> objects;
|
||||
|
@ -332,8 +332,8 @@ public:
|
|||
virtual bool shaped_text_get_preserve_control(RID p_shaped) const = 0;
|
||||
|
||||
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 = "") = 0;
|
||||
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) = 0;
|
||||
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER) = 0;
|
||||
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) = 0;
|
||||
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) = 0;
|
||||
|
||||
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
|
||||
virtual RID shaped_text_get_parent(RID p_shaped) const = 0;
|
||||
|
|
Loading…
Reference in New Issue