diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 522776207dd..f5c986e7c5f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -22,6 +22,13 @@ #include "wine/debug.h" #include "wine/unicode.h" +static const DWRITE_MATRIX identity = +{ + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 0.0f +}; + static inline void *heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); @@ -95,6 +102,7 @@ extern HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD,const extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH, FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN; extern HRESULT create_textlayout(const WCHAR*,UINT32,IDWriteTextFormat*,FLOAT,FLOAT,IDWriteTextLayout**) DECLSPEC_HIDDEN; +extern HRESULT create_gdicompat_textlayout(const WCHAR*,UINT32,IDWriteTextFormat*,FLOAT,FLOAT,FLOAT,const DWRITE_MATRIX*,BOOL,IDWriteTextLayout**) DECLSPEC_HIDDEN; extern HRESULT create_trimmingsign(IDWriteInlineObject**) DECLSPEC_HIDDEN; extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN; extern HRESULT create_gdiinterop(IDWriteFactory2*,IDWriteGdiInterop**) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c index 4e2870d3c26..bead01d778d 100644 --- a/dlls/dwrite/gdiinterop.c +++ b/dlls/dwrite/gdiinterop.c @@ -31,13 +31,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); -static const DWRITE_MATRIX identity = -{ - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f -}; - struct gdiinterop { IDWriteGdiInterop IDWriteGdiInterop_iface; IDWriteFactory2 *factory; diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index ea35bfab760..ad8ac446d24 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -133,6 +133,12 @@ struct dwrite_textlayout { DWRITE_LINE_BREAKPOINT *nominal_breakpoints; DWRITE_LINE_BREAKPOINT *actual_breakpoints; + + /* gdi-compatible layout specifics */ + BOOL gdicompatible; + FLOAT pixels_per_dip; + BOOL use_gdi_natural; + DWRITE_MATRIX transform; }; struct dwrite_textformat { @@ -2097,18 +2103,12 @@ static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, I return IDWriteTextFormat_GetFontCollection(format, &layout->format.collection); } -HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, IDWriteTextLayout **ret) +static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, struct dwrite_textlayout *layout) { - struct dwrite_textlayout *layout; - struct layout_range *range; DWRITE_TEXT_RANGE r = { 0, len }; + struct layout_range *range; HRESULT hr; - *ret = NULL; - - 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; @@ -2123,6 +2123,11 @@ HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *forma list_init(&layout->ranges); memset(&layout->format, 0, sizeof(layout->format)); + layout->gdicompatible = FALSE; + layout->pixels_per_dip = 0.0; + layout->use_gdi_natural = FALSE; + memset(&layout->transform, 0, sizeof(layout->transform)); + layout->str = heap_strdupnW(str, len); if (len && !layout->str) { hr = E_OUTOFMEMORY; @@ -2134,13 +2139,10 @@ HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *forma goto fail; range = alloc_layout_range(layout, &r); - if (!range) { - hr = E_OUTOFMEMORY; - goto fail; - } - list_add_head(&layout->ranges, &range->entry); + if (!range) + return E_OUTOFMEMORY; - *ret = (IDWriteTextLayout*)&layout->IDWriteTextLayout2_iface; + list_add_head(&layout->ranges, &range->entry); return S_OK; fail: @@ -2148,6 +2150,48 @@ fail: return hr; } +HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, IDWriteTextLayout **ret) +{ + struct dwrite_textlayout *layout; + HRESULT hr; + + *ret = NULL; + + layout = heap_alloc(sizeof(struct dwrite_textlayout)); + if (!layout) return E_OUTOFMEMORY; + + hr = init_textlayout(str, len, format, maxwidth, maxheight, layout); + if (hr == S_OK) + *ret = (IDWriteTextLayout*)&layout->IDWriteTextLayout2_iface; + + return hr; +} + +HRESULT create_gdicompat_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, + FLOAT pixels_per_dip, const DWRITE_MATRIX *transform, BOOL use_gdi_natural, IDWriteTextLayout **ret) +{ + struct dwrite_textlayout *layout; + HRESULT hr; + + *ret = NULL; + + layout = heap_alloc(sizeof(struct dwrite_textlayout)); + if (!layout) return E_OUTOFMEMORY; + + hr = init_textlayout(str, len, format, maxwidth, maxheight, layout); + if (hr == S_OK) { + /* set gdi-specific properties */ + layout->gdicompatible = TRUE; + layout->pixels_per_dip = pixels_per_dip; + layout->use_gdi_natural = use_gdi_natural; + layout->transform = transform ? *transform : identity; + + *ret = (IDWriteTextLayout*)&layout->IDWriteTextLayout2_iface; + } + + return hr; +} + static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *iface, REFIID riid, void **obj) { struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface); diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index a63f48f3593..58273fee12d 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -985,11 +985,13 @@ static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory DWRITE_MATRIX const* transform, BOOL use_gdi_natural, IDWriteTextLayout **layout) { struct dwritefactory *This = impl_from_IDWriteFactory2(iface); - FIXME("(%p)->(%s:%u %p %f %f %f %p %d %p): semi-stub\n", This, debugstr_wn(string, len), len, format, layout_width, layout_height, + + TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This, debugstr_wn(string, len), len, format, layout_width, layout_height, pixels_per_dip, transform, use_gdi_natural, layout); if (!format) return E_INVALIDARG; - return create_textlayout(string, len, format, layout_width, layout_height, layout); + return create_gdicompat_textlayout(string, len, format, layout_width, layout_height, pixels_per_dip, transform, + use_gdi_natural, layout); } static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory2 *iface, IDWriteTextFormat *format,