Commit e7947359 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

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

parent 6d009b98
...@@ -1833,92 +1833,103 @@ static const IDWriteTextAnalysisSourceVtbl dwritetextlayoutsourcevtbl = { ...@@ -1833,92 +1833,103 @@ static const IDWriteTextAnalysisSourceVtbl dwritetextlayoutsourcevtbl = {
dwritetextlayout_source_GetNumberSubstitution 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))) hr = IDWriteTextFormat_GetTrimming(format, &layout->format.trimming, &layout->format.trimmingsign);
{ if (FAILED(hr))
layout->format = f->format; return hr;
layout->format.locale = heap_strdupW(f->format.locale);
layout->format.family_name = heap_strdupW(f->format.family_name); /* locale name and length */
if (layout->format.trimmingsign) len = IDWriteTextFormat_GetLocaleNameLength(format);
IDWriteInlineObject_AddRef(layout->format.trimmingsign); layout->format.locale = heap_alloc((len+1)*sizeof(WCHAR));
} if (!layout->format.locale)
else return E_OUTOFMEMORY;
{
UINT32 locale_len, family_len; hr = IDWriteTextFormat_GetLocaleName(format, layout->format.locale, len+1);
if (FAILED(hr))
layout->format.weight = IDWriteTextFormat_GetFontWeight(format); return hr;
layout->format.style = IDWriteTextFormat_GetFontStyle(format); layout->format.locale_len = len;
layout->format.stretch = IDWriteTextFormat_GetFontStretch(format);
layout->format.fontsize= IDWriteTextFormat_GetFontSize(format); /* font family name and length */
layout->format.textalignment = IDWriteTextFormat_GetTextAlignment(format); len = IDWriteTextFormat_GetFontFamilyNameLength(format);
layout->format.paralign = IDWriteTextFormat_GetParagraphAlignment(format); layout->format.family_name = heap_alloc((len+1)*sizeof(WCHAR));
layout->format.wrapping = IDWriteTextFormat_GetWordWrapping(format); if (!layout->format.family_name)
layout->format.readingdir = IDWriteTextFormat_GetReadingDirection(format); return E_OUTOFMEMORY;
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;
}
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; struct layout_range *range;
DWRITE_TEXT_RANGE r = { 0, len }; DWRITE_TEXT_RANGE r = { 0, len };
HRESULT hr;
*layout = NULL; *ret = NULL;
This = heap_alloc(sizeof(struct dwrite_textlayout)); layout = heap_alloc(sizeof(struct dwrite_textlayout));
if (!This) return E_OUTOFMEMORY; 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; layout->str = heap_strdupnW(str, len);
This->IDWriteTextAnalysisSink_iface.lpVtbl = &dwritetextlayoutsinkvtbl; if (len && !layout->str) {
This->IDWriteTextAnalysisSource_iface.lpVtbl = &dwritetextlayoutsourcevtbl; hr = E_OUTOFMEMORY;
This->ref = 1; goto fail;
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;
} }
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; return S_OK;
fail:
IDWriteTextLayout2_Release(&layout->IDWriteTextLayout2_iface);
return hr;
} }
static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *iface, REFIID riid, void **obj) static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *iface, REFIID riid, void **obj)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment