Nikolay Sivov : dwrite: Cleanup layout instance creation, handle memory allocation failures.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 30 16:48:13 CST 2014


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Dec 26 14:14:20 2014 +0300

dwrite: Cleanup layout instance creation, handle memory allocation failures.

---

 dlls/dwrite/layout.c | 151 +++++++++++++++++++++++++++------------------------
 1 file changed, 81 insertions(+), 70 deletions(-)

diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 8717f63..2025b84 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -1833,92 +1833,103 @@ static const IDWriteTextAnalysisSourceVtbl dwritetextlayoutsourcevtbl = {
     dwritetextlayout_source_GetNumberSubstitution
 };
 
-static void layout_format_from_textformat(struct dwrite_textlayout *layout, IDWriteTextFormat *format)
+static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, IDWriteTextFormat *format)
 {
-    struct dwrite_textformat *f;
+    UINT32 len;
+    HRESULT hr;
 
-    memset(&layout->format, 0, sizeof(layout->format));
+    layout->format.weight  = IDWriteTextFormat_GetFontWeight(format);
+    layout->format.style   = IDWriteTextFormat_GetFontStyle(format);
+    layout->format.stretch = IDWriteTextFormat_GetFontStretch(format);
+    layout->format.fontsize= IDWriteTextFormat_GetFontSize(format);
+    layout->format.textalignment = IDWriteTextFormat_GetTextAlignment(format);
+    layout->format.paralign = IDWriteTextFormat_GetParagraphAlignment(format);
+    layout->format.wrapping = IDWriteTextFormat_GetWordWrapping(format);
+    layout->format.readingdir = IDWriteTextFormat_GetReadingDirection(format);
+    layout->format.flow = IDWriteTextFormat_GetFlowDirection(format);
+    hr = IDWriteTextFormat_GetLineSpacing(format, &layout->format.spacingmethod,
+        &layout->format.spacing, &layout->format.baseline);
+    if (FAILED(hr))
+        return hr;
 
-    if ((f = unsafe_impl_from_IDWriteTextFormat1((IDWriteTextFormat1*)format)))
-    {
-        layout->format = f->format;
-        layout->format.locale = heap_strdupW(f->format.locale);
-        layout->format.family_name = heap_strdupW(f->format.family_name);
-        if (layout->format.trimmingsign)
-            IDWriteInlineObject_AddRef(layout->format.trimmingsign);
-    }
-    else
-    {
-        UINT32 locale_len, family_len;
-
-        layout->format.weight  = IDWriteTextFormat_GetFontWeight(format);
-        layout->format.style   = IDWriteTextFormat_GetFontStyle(format);
-        layout->format.stretch = IDWriteTextFormat_GetFontStretch(format);
-        layout->format.fontsize= IDWriteTextFormat_GetFontSize(format);
-        layout->format.textalignment = IDWriteTextFormat_GetTextAlignment(format);
-        layout->format.paralign = IDWriteTextFormat_GetParagraphAlignment(format);
-        layout->format.wrapping = IDWriteTextFormat_GetWordWrapping(format);
-        layout->format.readingdir = IDWriteTextFormat_GetReadingDirection(format);
-        layout->format.flow = IDWriteTextFormat_GetFlowDirection(format);
-        IDWriteTextFormat_GetLineSpacing(format,
-            &layout->format.spacingmethod,
-            &layout->format.spacing,
-            &layout->format.baseline
-        );
-        IDWriteTextFormat_GetTrimming(format, &layout->format.trimming, &layout->format.trimmingsign);
-
-        /* locale name and length */
-        locale_len = IDWriteTextFormat_GetLocaleNameLength(format);
-        layout->format.locale  = heap_alloc((locale_len+1)*sizeof(WCHAR));
-        IDWriteTextFormat_GetLocaleName(format, layout->format.locale, locale_len+1);
-        layout->format.locale_len = locale_len;
-
-        /* font family name and length */
-        family_len = IDWriteTextFormat_GetFontFamilyNameLength(format);
-        layout->format.family_name = heap_alloc((family_len+1)*sizeof(WCHAR));
-        IDWriteTextFormat_GetFontFamilyName(format, layout->format.family_name, family_len+1);
-        layout->format.family_len = family_len;
-    }
+    hr = IDWriteTextFormat_GetTrimming(format, &layout->format.trimming, &layout->format.trimmingsign);
+    if (FAILED(hr))
+        return hr;
+
+    /* locale name and length */
+    len = IDWriteTextFormat_GetLocaleNameLength(format);
+    layout->format.locale = heap_alloc((len+1)*sizeof(WCHAR));
+    if (!layout->format.locale)
+        return E_OUTOFMEMORY;
+
+    hr = IDWriteTextFormat_GetLocaleName(format, layout->format.locale, len+1);
+    if (FAILED(hr))
+        return hr;
+    layout->format.locale_len = len;
+
+    /* font family name and length */
+    len = IDWriteTextFormat_GetFontFamilyNameLength(format);
+    layout->format.family_name = heap_alloc((len+1)*sizeof(WCHAR));
+    if (!layout->format.family_name)
+        return E_OUTOFMEMORY;
 
-    IDWriteTextFormat_GetFontCollection(format, &layout->format.collection);
+    hr = IDWriteTextFormat_GetFontFamilyName(format, layout->format.family_name, len+1);
+    if (FAILED(hr))
+        return hr;
+    layout->format.family_len = len;
+
+    return IDWriteTextFormat_GetFontCollection(format, &layout->format.collection);
 }
 
-HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, IDWriteTextLayout **layout)
+HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, IDWriteTextLayout **ret)
 {
-    struct dwrite_textlayout *This;
+    struct dwrite_textlayout *layout;
     struct layout_range *range;
     DWRITE_TEXT_RANGE r = { 0, len };
+    HRESULT hr;
 
-    *layout = NULL;
+    *ret = NULL;
 
-    This = heap_alloc(sizeof(struct dwrite_textlayout));
-    if (!This) return E_OUTOFMEMORY;
+    layout = heap_alloc(sizeof(struct dwrite_textlayout));
+    if (!layout) return E_OUTOFMEMORY;
+
+    layout->IDWriteTextLayout2_iface.lpVtbl = &dwritetextlayoutvtbl;
+    layout->IDWriteTextAnalysisSink_iface.lpVtbl = &dwritetextlayoutsinkvtbl;
+    layout->IDWriteTextAnalysisSource_iface.lpVtbl = &dwritetextlayoutsourcevtbl;
+    layout->ref = 1;
+    layout->len = len;
+    layout->maxwidth = maxwidth;
+    layout->maxheight = maxheight;
+    layout->recompute = TRUE;
+    layout->nominal_breakpoints = NULL;
+    layout->actual_breakpoints = NULL;
+    list_init(&layout->runs);
+    list_init(&layout->ranges);
+    memset(&layout->format, 0, sizeof(layout->format));
 
-    This->IDWriteTextLayout2_iface.lpVtbl = &dwritetextlayoutvtbl;
-    This->IDWriteTextAnalysisSink_iface.lpVtbl = &dwritetextlayoutsinkvtbl;
-    This->IDWriteTextAnalysisSource_iface.lpVtbl = &dwritetextlayoutsourcevtbl;
-    This->ref = 1;
-    This->str = heap_strdupnW(str, len);
-    This->len = len;
-    This->maxwidth = maxwidth;
-    This->maxheight = maxheight;
-    This->recompute = TRUE;
-    This->nominal_breakpoints = NULL;
-    This->actual_breakpoints = NULL;
-    layout_format_from_textformat(This, format);
-
-    list_init(&This->runs);
-    list_init(&This->ranges);
-    range = alloc_layout_range(This, &r);
-    if (!range) {
-        IDWriteTextLayout2_Release(&This->IDWriteTextLayout2_iface);
-        return E_OUTOFMEMORY;
+    layout->str = heap_strdupnW(str, len);
+    if (len && !layout->str) {
+        hr = E_OUTOFMEMORY;
+        goto fail;
     }
-    list_add_head(&This->ranges, &range->entry);
 
-    *layout = (IDWriteTextLayout*)&This->IDWriteTextLayout2_iface;
+    hr = layout_format_from_textformat(layout, format);
+    if (FAILED(hr))
+        goto fail;
+
+    range = alloc_layout_range(layout, &r);
+    if (!range) {
+        hr = E_OUTOFMEMORY;
+        goto fail;
+    }
+    list_add_head(&layout->ranges, &range->entry);
 
+    *ret = (IDWriteTextLayout*)&layout->IDWriteTextLayout2_iface;
     return S_OK;
+
+fail:
+    IDWriteTextLayout2_Release(&layout->IDWriteTextLayout2_iface);
+    return hr;
 }
 
 static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *iface, REFIID riid, void **obj)




More information about the wine-cvs mailing list