From 2a06594ff272bab1c78124a301440114aa8bb032 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:38:22 +0200 Subject: [PATCH] [Text Mesh] Fix incorrectly cached glyph offsets. --- scene/resources/primitive_meshes.cpp | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index b3237107435..e9a806cb15d 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -2722,7 +2722,6 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph GlyphMeshData &gl_data = cache[p_key]; Dictionary d = TS->font_get_glyph_contours(p_gl.font_rid, p_gl.font_size, p_gl.index); - Vector2 origin = Vector2(p_gl.x_off, p_gl.y_off) * pixel_size; PackedVector3Array points = d["points"]; PackedInt32Array contours = d["contours"]; @@ -2742,7 +2741,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph for (int32_t j = start; j <= end; j++) { if (points[j].z == TextServer::CONTOUR_CURVE_TAG_ON) { // Point on the curve. - Vector2 p = Vector2(points[j].x, points[j].y) * pixel_size + origin; + Vector2 p = Vector2(points[j].x, points[j].y) * pixel_size; polygon.push_back(ContourPoint(p, true)); } else if (points[j].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { // Conic Bezier arc. @@ -2776,7 +2775,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph real_t t2 = t * t; Vector2 point = p1 + omt2 * (p0 - p1) + t2 * (p2 - p1); - Vector2 p = point * pixel_size + origin; + Vector2 p = point * pixel_size; polygon.push_back(ContourPoint(p, false)); t += step; } @@ -2810,7 +2809,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph real_t t = step; while (t < 1.0) { Vector2 point = p0.bezier_interpolate(p1, p2, p3, t); - Vector2 p = point * pixel_size + origin; + Vector2 p = point * pixel_size; polygon.push_back(ContourPoint(p, false)); t += step; } @@ -3045,6 +3044,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { GlyphMeshKey key = GlyphMeshKey(glyphs[j].font_rid.get_id(), glyphs[j].index); _generate_glyph_mesh_data(key, glyphs[j]); GlyphMeshData &gl_data = cache[key]; + const Vector2 gl_of = Vector2(glyphs[j].x_off, glyphs[j].y_off) * pixel_size; p_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); i_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); @@ -3057,10 +3057,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { } for (int r = 0; r < glyphs[j].repeat; r++) { - min_p.x = MIN(gl_data.min_p.x + offset.x, min_p.x); - min_p.y = MIN(gl_data.min_p.y - offset.y, min_p.y); - max_p.x = MAX(gl_data.max_p.x + offset.x, max_p.x); - max_p.y = MAX(gl_data.max_p.y - offset.y, max_p.y); + min_p.x = MIN(gl_data.min_p.x + offset.x + gl_of.x, min_p.x); + min_p.y = MIN(gl_data.min_p.y - offset.y + gl_of.y, min_p.y); + max_p.x = MAX(gl_data.max_p.x + offset.x + gl_of.x, max_p.x); + max_p.y = MAX(gl_data.max_p.y - offset.y + gl_of.y, max_p.y); offset.x += glyphs[j].advance * pixel_size; } @@ -3126,12 +3126,13 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { int64_t ts = gl_data.triangles.size(); const Vector2 *ts_ptr = gl_data.triangles.ptr(); + const Vector2 gl_of = Vector2(glyphs[j].x_off, glyphs[j].y_off) * pixel_size; for (int r = 0; r < glyphs[j].repeat; r++) { for (int k = 0; k < ts; k += 3) { // Add front face. for (int l = 0; l < 3; l++) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, depth / 2.0); + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x + gl_of.x, -ts_ptr[k + l].y + offset.y - gl_of.y, depth / 2.0); vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0); if (has_depth) { @@ -3149,7 +3150,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { if (has_depth) { // Add back face. for (int l = 2; l >= 0; l--) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, -depth / 2.0); + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x + gl_of.x, -ts_ptr[k + l].y + offset.y - gl_of.y, -depth / 2.0); vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, -1.0); uvs_ptr[p_idx] = Vector2(Math::remap(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(point.y, -max_p.y, -min_p.y, real_t(0.8), real_t(0.4))); @@ -3182,10 +3183,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { real_t seg_len = (ps_ptr[next].point - ps_ptr[l].point).length(); Vector3 quad_faces[4] = { - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, depth / 2.0), + Vector3(ps_ptr[l].point.x + offset.x + gl_of.x, -ps_ptr[l].point.y + offset.y - gl_of.y, -depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x + gl_of.x, -ps_ptr[next].point.y + offset.y - gl_of.y, -depth / 2.0), + Vector3(ps_ptr[l].point.x + offset.x + gl_of.x, -ps_ptr[l].point.y + offset.y - gl_of.y, depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x + gl_of.x, -ps_ptr[next].point.y + offset.y - gl_of.y, depth / 2.0), }; for (int m = 0; m < 4; m++) { const Vector2 &d = ((m % 2) == 0) ? d1 : d2;