Explorar o código

Fix `TextLine` and `TextParagraph` `get_*_object_rect` methods not accounting for alignment and drop cap.

bruvzg %!s(int64=2) %!d(string=hai) anos
pai
achega
4a6d39c6b9
Modificáronse 2 ficheiros con 122 adicións e 7 borrados
  1. 42 1
      scene/resources/text_line.cpp
  2. 80 6
      scene/resources/text_paragraph.cpp

+ 42 - 1
scene/resources/text_line.cpp

@@ -218,7 +218,48 @@ Array TextLine::get_objects() const {
 }
 
 Rect2 TextLine::get_object_rect(Variant p_key) const {
-	return TS->shaped_text_get_object_rect(rid, p_key);
+	Vector2 ofs;
+
+	float length = TS->shaped_text_get_width(rid);
+	if (width > 0) {
+		switch (alignment) {
+			case HORIZONTAL_ALIGNMENT_FILL:
+			case HORIZONTAL_ALIGNMENT_LEFT:
+				break;
+			case HORIZONTAL_ALIGNMENT_CENTER: {
+				if (length <= width) {
+					if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
+						ofs.x += Math::floor((width - length) / 2.0);
+					} else {
+						ofs.y += Math::floor((width - length) / 2.0);
+					}
+				} else if (TS->shaped_text_get_inferred_direction(rid) == TextServer::DIRECTION_RTL) {
+					if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
+						ofs.x += width - length;
+					} else {
+						ofs.y += width - length;
+					}
+				}
+			} break;
+			case HORIZONTAL_ALIGNMENT_RIGHT: {
+				if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
+					ofs.x += width - length;
+				} else {
+					ofs.y += width - length;
+				}
+			} break;
+		}
+	}
+	if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
+		ofs.y += TS->shaped_text_get_ascent(rid);
+	} else {
+		ofs.x += TS->shaped_text_get_ascent(rid);
+	}
+
+	Rect2 rect = TS->shaped_text_get_object_rect(rid, p_key);
+	rect.position += ofs;
+
+	return rect;
 }
 
 void TextLine::set_horizontal_alignment(HorizontalAlignment p_alignment) {

+ 80 - 6
scene/resources/text_paragraph.cpp

@@ -540,16 +540,90 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const {
 
 	const_cast<TextParagraph *>(this)->_shape_lines();
 	ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), Rect2());
-	Rect2 xrect = TS->shaped_text_get_object_rect(lines_rid[p_line], p_key);
-	for (int i = 0; i < p_line; i++) {
-		Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
+
+	Vector2 ofs;
+
+	float h_offset = 0.f;
+	if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+		h_offset = TS->shaped_text_get_size(dropcap_rid).x + dropcap_margins.size.x + dropcap_margins.position.x;
+	} else {
+		h_offset = TS->shaped_text_get_size(dropcap_rid).y + dropcap_margins.size.y + dropcap_margins.position.y;
+	}
+
+	for (int i = 0; i <= p_line; i++) {
+		float l_width = width;
 		if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
-			xrect.position.y += lsize.y;
+			ofs.x = 0.f;
+			ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
+			if (i <= dropcap_lines) {
+				if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+					ofs.x -= h_offset;
+				}
+				l_width -= h_offset;
+			}
 		} else {
-			xrect.position.x += lsize.x;
+			ofs.y = 0.f;
+			ofs.x += TS->shaped_text_get_ascent(lines_rid[i]);
+			if (i <= dropcap_lines) {
+				if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+					ofs.x -= h_offset;
+				}
+				l_width -= h_offset;
+			}
+		}
+		float length = TS->shaped_text_get_width(lines_rid[i]);
+		if (width > 0) {
+			switch (alignment) {
+				case HORIZONTAL_ALIGNMENT_FILL:
+					if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
+						if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
+							ofs.x += l_width - length;
+						} else {
+							ofs.y += l_width - length;
+						}
+					}
+					break;
+				case HORIZONTAL_ALIGNMENT_LEFT:
+					break;
+				case HORIZONTAL_ALIGNMENT_CENTER: {
+					if (length <= l_width) {
+						if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
+							ofs.x += Math::floor((l_width - length) / 2.0);
+						} else {
+							ofs.y += Math::floor((l_width - length) / 2.0);
+						}
+					} else if (TS->shaped_text_get_inferred_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
+						if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
+							ofs.x += l_width - length;
+						} else {
+							ofs.y += l_width - length;
+						}
+					}
+				} break;
+				case HORIZONTAL_ALIGNMENT_RIGHT: {
+					if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
+						ofs.x += l_width - length;
+					} else {
+						ofs.y += l_width - length;
+					}
+				} break;
+			}
+		}
+		if (i != p_line) {
+			if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
+				ofs.x = 0.f;
+				ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
+			} else {
+				ofs.y = 0.f;
+				ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
+			}
 		}
 	}
-	return xrect;
+
+	Rect2 rect = TS->shaped_text_get_object_rect(lines_rid[p_line], p_key);
+	rect.position += ofs;
+
+	return rect;
 }
 
 Size2 TextParagraph::get_line_size(int p_line) const {