[PATCH] d3dx9: Correctly handle whitespace character in D3DXCreateText. (try 2)

Matteo Bruni matteo.mystral at gmail.com
Tue Aug 4 16:14:25 CDT 2015


2015-08-02 22:29 GMT+02:00 Józef Kucia <joseph.kucia at 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.



More information about the wine-devel mailing list