Re: [PATCH] d3dx9: Correctly handle whitespace character in D3DXCreateText. (try 2)
2015-08-02 22:29 GMT+02:00 Józef Kucia <joseph.kucia(a)gmail.com>:
Fixes bug 38976.
Try 2: Remove useless hr assignments. --- dlls/d3dx9_36/mesh.c | 4 ++ dlls/d3dx9_36/tests/mesh.c | 168 ++++++++++++++++++++++++--------------------- 2 files changed, 94 insertions(+), 78 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index d0459da..39d279d 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -5847,6 +5847,10 @@ static HRESULT triangulate(struct triangulation_array *triangulations) int i; struct point2d_index *idx_ptr;
+ /* Glyphs without outlines do not generate any vertices. */ + if (!glyph->outlines.count) + return D3D_OK; + for (i = 0; i < glyph->outlines.count; i++) nb_vertices += glyph->outlines.items[i].count;
diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index 0243a61..16c79ea 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -3617,57 +3617,17 @@ static HRESULT create_outline(struct glyphinfo *glyph, void *raw_outline, int da return S_OK; }
-static BOOL compute_text_mesh(struct mesh *mesh, HDC hdc, const char *text, - float deviation, float extrusion, float otmEMSquare) +static BOOL compute_text_mesh(struct mesh *mesh, const char *text, + float deviation, float extrusion, float otmEMSquare, const struct glyphinfo *glyphs) { - HRESULT hr = E_FAIL; DWORD nb_vertices, nb_faces; DWORD nb_corners, nb_outline_points; int textlen = 0; - float offset_x; - char *raw_outline = NULL; - struct glyphinfo *glyphs = NULL; - GLYPHMETRICS gm; int i; struct vertex *vertex_ptr; face *face_ptr;
- if (deviation == 0.0f) - deviation = 1.0f / otmEMSquare; - textlen = strlen(text); - glyphs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, textlen * sizeof(*glyphs)); - if (!glyphs) { - hr = E_OUTOFMEMORY; - goto error; - } - - offset_x = 0.0f; - for (i = 0; i < textlen; i++) - { - /* get outline points from data returned from GetGlyphOutline */ - const MAT2 identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; - int datasize; - - glyphs[i].offset_x = offset_x; - - datasize = GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, 0, NULL, &identity); - if (datasize < 0) { - hr = E_FAIL; - goto error; - } - HeapFree(GetProcessHeap(), 0, raw_outline); - raw_outline = HeapAlloc(GetProcessHeap(), 0, datasize); - if (!raw_outline) { - hr = E_OUTOFMEMORY; - goto error; - } - datasize = GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, datasize, raw_outline, &identity); - - create_outline(&glyphs[i], raw_outline, datasize, deviation, otmEMSquare); - - offset_x += gm.gmCellIncX / (float)otmEMSquare; - }
/* corner points need an extra vertex for the different side faces normals */ nb_corners = 0; @@ -3691,7 +3651,7 @@ static BOOL compute_text_mesh(struct mesh *mesh, HDC hdc, const char *text, nb_faces = nb_outline_points * 2;
if (!new_mesh(mesh, nb_vertices, nb_faces)) - goto error; + return FALSE;
/* convert 2D vertices and faces into 3D mesh */ vertex_ptr = mesh->vertices; @@ -3801,24 +3761,11 @@ static BOOL compute_text_mesh(struct mesh *mesh, HDC hdc, const char *text, vertex_ptr++; }
- hr = D3D_OK; -error: - if (glyphs) { - for (i = 0; i < textlen; i++) - { - int j; - for (j = 0; j < glyphs[i].outlines.count; j++) - HeapFree(GetProcessHeap(), 0, glyphs[i].outlines.items[j].items); - HeapFree(GetProcessHeap(), 0, glyphs[i].outlines.items); - } - HeapFree(GetProcessHeap(), 0, glyphs); - } - HeapFree(GetProcessHeap(), 0, raw_outline); - - return hr == D3D_OK; + return TRUE; }
-static void compare_text_outline_mesh(const char *name, ID3DXMesh *d3dxmesh, struct mesh *mesh, int textlen, float extrusion) +static void compare_text_outline_mesh(const char *name, ID3DXMesh *d3dxmesh, struct mesh *mesh, + size_t textlen, float extrusion, const struct glyphinfo *glyphs) { HRESULT hr; DWORD number_of_vertices, number_of_faces; @@ -3936,13 +3883,20 @@ static void compare_text_outline_mesh(const char *name, ID3DXMesh *d3dxmesh, str
first_vtx1 = vtx_idx1; first_vtx2 = vtx_idx2; - for (; vtx_idx1 < number_of_vertices; vtx_idx1++) { - if (vertices[vtx_idx1].normal.z != 0) - break; - } - for (; vtx_idx2 < mesh->number_of_vertices; vtx_idx2++) { - if (mesh->vertices[vtx_idx2].normal.z != 0) - break; + /* Glyphs without outlines do not generate any vertices. */ + if (glyphs[i].outlines.count > 0) + { + for (; vtx_idx1 < number_of_vertices; vtx_idx1++) + { + if (vertices[vtx_idx1].normal.z != 0) + break; + } + + for (; vtx_idx2 < mesh->number_of_vertices; vtx_idx2++) + { + if (mesh->vertices[vtx_idx2].normal.z != 0) + break; + } } nb_outline_vertices1 = vtx_idx1 - first_vtx1; nb_outline_vertices2 = vtx_idx2 - first_vtx2; @@ -4124,15 +4078,19 @@ error: static void test_createtext(IDirect3DDevice9 *device, HDC hdc, const char *text, float deviation, float extrusion) { HRESULT hr; - ID3DXMesh *d3dxmesh; - struct mesh mesh; + ID3DXMesh *d3dxmesh = NULL; + struct mesh mesh = {0}; char name[256]; OUTLINETEXTMETRICA otm; GLYPHMETRICS gm; + struct glyphinfo *glyphs = NULL; GLYPHMETRICSFLOAT *glyphmetrics_float = HeapAlloc(GetProcessHeap(), 0, sizeof(GLYPHMETRICSFLOAT) * strlen(text)); int i; LOGFONTA lf; + float offset_x; + size_t textlen; HFONT font = NULL, oldfont = NULL; + char *raw_outline = NULL;
sprintf(name, "text ('%s', %f, %f)", text, deviation, extrusion);
@@ -4141,7 +4099,7 @@ static void test_createtext(IDirect3DDevice9 *device, HDC hdc, const char *text, if (hr != D3D_OK) { skip("Couldn't create text with D3DXCreateText\n"); - return; + goto error; }
/* must select a modified font having lfHeight = otm.otmEMSquare before @@ -4149,21 +4107,25 @@ static void test_createtext(IDirect3DDevice9 *device, HDC hdc, const char *text, if (!GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf) || !GetOutlineTextMetricsA(hdc, sizeof(otm), &otm)) { - d3dxmesh->lpVtbl->Release(d3dxmesh); skip("Couldn't get text outline\n"); - return; + goto error; } lf.lfHeight = otm.otmEMSquare; lf.lfWidth = 0; if (!(font = CreateFontIndirectA(&lf))) { - d3dxmesh->lpVtbl->Release(d3dxmesh); skip("Couldn't create the modified font\n"); - return; + goto error; } + + textlen = strlen(text); + glyphs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, textlen * sizeof(*glyphs)); + if (!glyphs) + goto error; + oldfont = SelectObject(hdc, font);
- for (i = 0; i < strlen(text); i++) + for (i = 0; i < textlen; i++) { const MAT2 identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, 0, NULL, &identity); @@ -4175,8 +4137,42 @@ static void test_createtext(IDirect3DDevice9 *device, HDC hdc, const char *text, compare_float(glyphmetrics_float[i].gmfCellIncY, gm.gmCellIncY / (float)otm.otmEMSquare); }
+ if (deviation == 0.0f) + deviation = 1.0f / otm.otmEMSquare; + + offset_x = 0.0f; + for (i = 0; i < textlen; i++) + { + /* get outline points from data returned from GetGlyphOutline */ + const MAT2 identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; + int datasize; + + glyphs[i].offset_x = offset_x; + + datasize = GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, 0, NULL, &identity); + if (datasize < 0) + { + SelectObject(hdc, oldfont); + goto error; + } + HeapFree(GetProcessHeap(), 0, raw_outline); + raw_outline = HeapAlloc(GetProcessHeap(), 0, datasize); + if (!raw_outline) + { + SelectObject(hdc, oldfont); + goto error; + } + datasize = GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, datasize, raw_outline, &identity); + + create_outline(&glyphs[i], raw_outline, datasize, deviation, otm.otmEMSquare); + + offset_x += gm.gmCellIncX / (float)otm.otmEMSquare; + } + + SelectObject(hdc, oldfont); + ZeroMemory(&mesh, sizeof(mesh)); - if (!compute_text_mesh(&mesh, hdc, text, deviation, extrusion, otm.otmEMSquare)) + if (!compute_text_mesh(&mesh, text, deviation, extrusion, otm.otmEMSquare, glyphs)) { skip("Couldn't create mesh\n"); d3dxmesh->lpVtbl->Release(d3dxmesh); @@ -4184,13 +4180,26 @@ static void test_createtext(IDirect3DDevice9 *device, HDC hdc, const char *text, } mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
- compare_text_outline_mesh(name, d3dxmesh, &mesh, strlen(text), extrusion); + compare_text_outline_mesh(name, d3dxmesh, &mesh, textlen, extrusion, glyphs);
+error: free_mesh(&mesh);
- d3dxmesh->lpVtbl->Release(d3dxmesh); - SelectObject(hdc, oldfont); + if (d3dxmesh) d3dxmesh->lpVtbl->Release(d3dxmesh); HeapFree(GetProcessHeap(), 0, glyphmetrics_float); + + if (glyphs) + { + for (i = 0; i < textlen; i++) + { + int j; + for (j = 0; j < glyphs[i].outlines.count; j++) + HeapFree(GetProcessHeap(), 0, glyphs[i].outlines.items[j].items); + HeapFree(GetProcessHeap(), 0, glyphs[i].outlines.items); + } + HeapFree(GetProcessHeap(), 0, glyphs); + } + HeapFree(GetProcessHeap(), 0, raw_outline); }
It looks like there is a minor (preexisting) issue here, the font is not deleted. Maybe fix that in a followup patch, while you're at it? The patch itself is fine to me though.
participants (1)
-
Matteo Bruni