Nikolay Sivov : dwrite: Improve error handling during font collection creation.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Feb 4 10:51:17 CST 2015


Module: wine
Branch: master
Commit: afd1911cd7430f24ffc3747df0dbf33e6888459f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=afd1911cd7430f24ffc3747df0dbf33e6888459f

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Feb  4 15:34:12 2015 +0300

dwrite: Improve error handling during font collection creation.

---

 dlls/dwrite/font.c | 83 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 51 insertions(+), 32 deletions(-)

diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 3dc5738..1f1f367 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -1551,7 +1551,6 @@ static HRESULT fontfamily_add_font(struct dwrite_fontfamily_data *family_data, s
     }
 
     family_data->fonts[family_data->font_count] = font_data;
-    InterlockedIncrement(&font_data->ref);
     family_data->font_count++;
     return S_OK;
 }
@@ -1617,17 +1616,25 @@ HRESULT get_filestream_from_file(IDWriteFontFile *file, IDWriteFontFileStream **
     return hr;
 }
 
-static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, UINT32 face_index, DWRITE_FONT_FACE_TYPE face_type, struct dwrite_font_data *data)
+static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, UINT32 face_index, DWRITE_FONT_FACE_TYPE face_type,
+    IDWriteFontFileStream **stream, struct dwrite_font_data **ret)
 {
     void *os2_context, *head_context;
     const void *tt_os2 = NULL, *tt_head = NULL;
-    IDWriteFontFileStream *stream;
+    struct dwrite_font_data *data;
     HRESULT hr;
 
-    hr = get_filestream_from_file(file, &stream);
-    if (FAILED(hr))
+    data = heap_alloc_zero(sizeof(*data));
+    if (!data)
+        return E_OUTOFMEMORY;
+
+    hr = get_filestream_from_file(file, stream);
+    if (FAILED(hr)) {
+        heap_free(data);
         return hr;
+    }
 
+    data->ref = 1;
     data->factory = factory;
     data->file = file;
     data->face_index = face_index;
@@ -1635,23 +1642,29 @@ static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, U
     IDWriteFontFile_AddRef(file);
     IDWriteFactory2_AddRef(factory);
 
-    opentype_get_font_table(stream, face_type, face_index, MS_OS2_TAG, &tt_os2, &os2_context, NULL, NULL);
-    opentype_get_font_table(stream, face_type, face_index, MS_HEAD_TAG, &tt_head, &head_context, NULL, NULL);
+    opentype_get_font_table(*stream, face_type, face_index, MS_OS2_TAG, &tt_os2, &os2_context, NULL, NULL);
+    opentype_get_font_table(*stream, face_type, face_index, MS_HEAD_TAG, &tt_head, &head_context, NULL, NULL);
 
-    opentype_get_font_properties(stream, face_type, face_index, &data->stretch, &data->weight, &data->style);
-    opentype_get_font_metrics(stream, face_type, face_index, &data->metrics, NULL);
+    opentype_get_font_properties(*stream, face_type, face_index, &data->stretch, &data->weight, &data->style);
+    opentype_get_font_metrics(*stream, face_type, face_index, &data->metrics, NULL);
 
     if (tt_os2)
-        IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context);
+        IDWriteFontFileStream_ReleaseFileFragment(*stream, os2_context);
     if (tt_head)
-        IDWriteFontFileStream_ReleaseFileFragment(stream, head_context);
-    IDWriteFontFileStream_Release(stream);
+        IDWriteFontFileStream_ReleaseFileFragment(*stream, head_context);
 
+    *ret = data;
     return S_OK;
 }
 
-static HRESULT init_fontfamily_data(IDWriteLocalizedStrings *familyname, struct dwrite_fontfamily_data *data)
+static HRESULT init_fontfamily_data(IDWriteLocalizedStrings *familyname, struct dwrite_fontfamily_data **ret)
 {
+    struct dwrite_fontfamily_data *data;
+
+    data = heap_alloc(sizeof(*data));
+    if (!data)
+        return E_OUTOFMEMORY;
+
     data->ref = 1;
     data->font_count = 0;
     data->font_alloc = 2;
@@ -1665,6 +1678,7 @@ static HRESULT init_fontfamily_data(IDWriteLocalizedStrings *familyname, struct
     data->familyname = familyname;
     IDWriteLocalizedStrings_AddRef(familyname);
 
+    *ret = data;
     return S_OK;
 }
 
@@ -1672,7 +1686,7 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat
 {
     struct dwrite_fontcollection *collection;
     BOOL current = FALSE;
-    HRESULT hr;
+    HRESULT hr = S_OK;
 
     *ret = NULL;
 
@@ -1689,7 +1703,7 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat
 
     TRACE("building font collection:\n");
 
-    while (1) {
+    while (hr == S_OK) {
         DWRITE_FONT_FACE_TYPE face_type;
         DWRITE_FONT_FILE_TYPE file_type;
         IDWriteFontFile *file;
@@ -1723,24 +1737,22 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat
             UINT32 index;
 
             /* alloc and init new font data structure */
-            font_data = heap_alloc_zero(sizeof(struct dwrite_font_data));
-            init_font_data(factory, file, i, face_type, font_data);
-
-            hr = get_filestream_from_file(file, &stream);
-            if (FAILED(hr)) {
-                heap_free (font_data);
-                return hr;
-            }
+            hr = init_font_data(factory, file, i, face_type, &stream, &font_data);
+            if (FAILED(hr))
+                break;
 
             /* get family name from font file */
             name_table = NULL;
             opentype_get_font_table(stream, face_type, i, MS_NAME_TAG, &name_table, &name_context, NULL, NULL);
-            if (name_table)
+            if (name_table) {
                 hr = opentype_get_font_strings_from_id(name_table, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &family_name);
+                IDWriteFontFileStream_ReleaseFileFragment(stream, name_context);
+            }
             IDWriteFontFileStream_Release(stream);
 
             if (FAILED(hr) || !family_name) {
                 WARN("unable to get family name from font\n");
+                release_font_data(font_data);
                 continue;
             }
 
@@ -1749,26 +1761,33 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat
 
             index = collection_find_family(collection, buffer);
             if (index != ~0u)
-                fontfamily_add_font(collection->family_data[index], font_data);
+                hr = fontfamily_add_font(collection->family_data[index], font_data);
             else {
                 struct dwrite_fontfamily_data *family_data;
 
                 /* create and init new family */
-                family_data = heap_alloc(sizeof(*family_data));
-                init_fontfamily_data(family_name, family_data);
-
-                /* add font to family, family - to collection */
-                fontfamily_add_font(family_data, font_data);
-                fontcollection_add_family(collection, family_data);
+                hr = init_fontfamily_data(family_name, &family_data);
+                if (hr == S_OK) {
+                    /* add font to family, family - to collection */
+                    hr = fontfamily_add_font(family_data, font_data);
+                    if (hr == S_OK)
+                        hr = fontcollection_add_family(collection, family_data);
+
+                    if (FAILED(hr))
+                        release_fontfamily_data(family_data);
+                }
             }
 
             IDWriteLocalizedStrings_Release(family_name);
+
+            if (FAILED(hr))
+                break;
         }
 
         IDWriteFontFile_Release(file);
     };
 
-    return S_OK;
+    return hr;
 }
 
 struct system_fontfile_enumerator




More information about the wine-cvs mailing list