Merge pull request #84180 from bruvzg/text_mesh_offset

[Text Mesh] Fix incorrectly cached glyph offsets.
This commit is contained in:
Rémi Verschelde 2023-10-30 10:20:32 +01:00
commit 2f1f1206a9
No known key found for this signature in database
GPG Key ID: C3336907360768E1

View File

@ -2726,7 +2726,6 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph
GlyphMeshData &gl_data = cache[p_key]; GlyphMeshData &gl_data = cache[p_key];
Dictionary d = TS->font_get_glyph_contours(p_gl.font_rid, p_gl.font_size, p_gl.index); 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"]; PackedVector3Array points = d["points"];
PackedInt32Array contours = d["contours"]; PackedInt32Array contours = d["contours"];
@ -2746,7 +2745,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph
for (int32_t j = start; j <= end; j++) { for (int32_t j = start; j <= end; j++) {
if (points[j].z == TextServer::CONTOUR_CURVE_TAG_ON) { if (points[j].z == TextServer::CONTOUR_CURVE_TAG_ON) {
// Point on the curve. // 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)); polygon.push_back(ContourPoint(p, true));
} else if (points[j].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { } else if (points[j].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) {
// Conic Bezier arc. // Conic Bezier arc.
@ -2780,7 +2779,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph
real_t t2 = t * t; real_t t2 = t * t;
Vector2 point = p1 + omt2 * (p0 - p1) + t2 * (p2 - p1); 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)); polygon.push_back(ContourPoint(p, false));
t += step; t += step;
} }
@ -2814,7 +2813,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph
real_t t = step; real_t t = step;
while (t < 1.0) { while (t < 1.0) {
Vector2 point = p0.bezier_interpolate(p1, p2, p3, t); 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)); polygon.push_back(ContourPoint(p, false));
t += step; t += step;
} }
@ -3049,6 +3048,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
GlyphMeshKey key = GlyphMeshKey(glyphs[j].font_rid.get_id(), glyphs[j].index); GlyphMeshKey key = GlyphMeshKey(glyphs[j].font_rid.get_id(), glyphs[j].index);
_generate_glyph_mesh_data(key, glyphs[j]); _generate_glyph_mesh_data(key, glyphs[j]);
GlyphMeshData &gl_data = cache[key]; 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); 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); i_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1);
@ -3061,10 +3061,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
} }
for (int r = 0; r < glyphs[j].repeat; r++) { 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.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, min_p.y); 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, max_p.x); 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, max_p.y); max_p.y = MAX(gl_data.max_p.y - offset.y + gl_of.y, max_p.y);
offset.x += glyphs[j].advance * pixel_size; offset.x += glyphs[j].advance * pixel_size;
} }
@ -3130,12 +3130,13 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
int64_t ts = gl_data.triangles.size(); int64_t ts = gl_data.triangles.size();
const Vector2 *ts_ptr = gl_data.triangles.ptr(); 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 r = 0; r < glyphs[j].repeat; r++) {
for (int k = 0; k < ts; k += 3) { for (int k = 0; k < ts; k += 3) {
// Add front face. // Add front face.
for (int l = 0; l < 3; l++) { 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; vertices_ptr[p_idx] = point;
normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0); normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0);
if (has_depth) { if (has_depth) {
@ -3153,7 +3154,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
if (has_depth) { if (has_depth) {
// Add back face. // Add back face.
for (int l = 2; l >= 0; l--) { 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; vertices_ptr[p_idx] = point;
normals_ptr[p_idx] = Vector3(0.0, 0.0, -1.0); 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))); 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)));
@ -3186,10 +3187,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
real_t seg_len = (ps_ptr[next].point - ps_ptr[l].point).length(); real_t seg_len = (ps_ptr[next].point - ps_ptr[l].point).length();
Vector3 quad_faces[4] = { 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[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, -ps_ptr[next].point.y + offset.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, -ps_ptr[l].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, -ps_ptr[next].point.y + offset.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++) { for (int m = 0; m < 4; m++) {
const Vector2 &d = ((m % 2) == 0) ? d1 : d2; const Vector2 &d = ((m % 2) == 0) ? d1 : d2;