From e7947359fee54a75035ff9b8c3e6d48e0d623d65 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 26 Dec 2014 14:14:20 +0300 Subject: [PATCH] dwrite: Cleanup layout instance creation, handle memory allocation failures. --- dlls/dwrite/layout.c | 143 +++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 8717f631a85..2025b84b283 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; + hr = IDWriteTextFormat_GetTrimming(format, &layout->format.trimming, &layout->format.trimmingsign); + if (FAILED(hr)) + return hr; - 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 */ + len = IDWriteTextFormat_GetLocaleNameLength(format); + layout->format.locale = heap_alloc((len+1)*sizeof(WCHAR)); + if (!layout->format.locale) + return E_OUTOFMEMORY; - /* 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; + hr = IDWriteTextFormat_GetLocaleName(format, layout->format.locale, len+1); + if (FAILED(hr)) + return hr; + layout->format.locale_len = 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; - } + /* 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; - 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); + 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)); - 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)