dwrite: Don't bother to free memory at process exit.
[wine.git] / dlls / dwrite / main.c
blobd253c42c5b3d87bc3a01e7f392dbd15878fceaf3
1 /*
2 * DWrite
4 * Copyright 2012 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
29 #include "initguid.h"
30 #include "dwrite.h"
32 #include "dwrite_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
37 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
39 switch (reason)
41 case DLL_WINE_PREATTACH:
42 return FALSE; /* prefer native version */
43 case DLL_PROCESS_ATTACH:
44 DisableThreadLibraryCalls( hinstDLL );
45 break;
46 case DLL_PROCESS_DETACH:
47 if (reserved) break;
48 release_system_fontcollection();
49 break;
51 return TRUE;
54 struct renderingparams {
55 IDWriteRenderingParams IDWriteRenderingParams_iface;
56 LONG ref;
58 FLOAT gamma;
59 FLOAT enh_contrast;
60 FLOAT cleartype_level;
61 DWRITE_PIXEL_GEOMETRY geometry;
62 DWRITE_RENDERING_MODE mode;
65 static inline struct renderingparams *impl_from_IDWriteRenderingParams(IDWriteRenderingParams *iface)
67 return CONTAINING_RECORD(iface, struct renderingparams, IDWriteRenderingParams_iface);
70 static HRESULT WINAPI renderingparams_QueryInterface(IDWriteRenderingParams *iface, REFIID riid, void **obj)
72 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
74 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
76 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteRenderingParams))
78 *obj = iface;
79 IDWriteRenderingParams_AddRef(iface);
80 return S_OK;
83 *obj = NULL;
85 return E_NOINTERFACE;
88 static ULONG WINAPI renderingparams_AddRef(IDWriteRenderingParams *iface)
90 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
91 ULONG ref = InterlockedIncrement(&This->ref);
92 TRACE("(%p)->(%d)\n", This, ref);
93 return ref;
96 static ULONG WINAPI renderingparams_Release(IDWriteRenderingParams *iface)
98 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
99 ULONG ref = InterlockedDecrement(&This->ref);
101 TRACE("(%p)->(%d)\n", This, ref);
103 if (!ref)
104 heap_free(This);
106 return ref;
109 static FLOAT WINAPI renderingparams_GetGamma(IDWriteRenderingParams *iface)
111 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
112 TRACE("(%p)\n", This);
113 return This->gamma;
116 static FLOAT WINAPI renderingparams_GetEnhancedContrast(IDWriteRenderingParams *iface)
118 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
119 TRACE("(%p)\n", This);
120 return This->enh_contrast;
123 static FLOAT WINAPI renderingparams_GetClearTypeLevel(IDWriteRenderingParams *iface)
125 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
126 TRACE("(%p)\n", This);
127 return This->cleartype_level;
130 static DWRITE_PIXEL_GEOMETRY WINAPI renderingparams_GetPixelGeometry(IDWriteRenderingParams *iface)
132 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
133 TRACE("(%p)\n", This);
134 return This->geometry;
137 static DWRITE_RENDERING_MODE WINAPI renderingparams_GetRenderingMode(IDWriteRenderingParams *iface)
139 struct renderingparams *This = impl_from_IDWriteRenderingParams(iface);
140 TRACE("(%p)\n", This);
141 return This->mode;
144 static const struct IDWriteRenderingParamsVtbl renderingparamsvtbl = {
145 renderingparams_QueryInterface,
146 renderingparams_AddRef,
147 renderingparams_Release,
148 renderingparams_GetGamma,
149 renderingparams_GetEnhancedContrast,
150 renderingparams_GetClearTypeLevel,
151 renderingparams_GetPixelGeometry,
152 renderingparams_GetRenderingMode
155 static HRESULT create_renderingparams(FLOAT gamma, FLOAT enhancedContrast, FLOAT cleartype_level,
156 DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, IDWriteRenderingParams **params)
158 struct renderingparams *This;
160 *params = NULL;
162 This = heap_alloc(sizeof(struct renderingparams));
163 if (!This) return E_OUTOFMEMORY;
165 This->IDWriteRenderingParams_iface.lpVtbl = &renderingparamsvtbl;
166 This->ref = 1;
168 This->gamma = gamma;
169 This->enh_contrast = enhancedContrast;
170 This->cleartype_level = cleartype_level;
171 This->geometry = geometry;
172 This->mode = mode;
174 *params = &This->IDWriteRenderingParams_iface;
176 return S_OK;
179 struct localizedpair {
180 WCHAR *locale;
181 WCHAR *string;
184 struct localizedstrings {
185 IDWriteLocalizedStrings IDWriteLocalizedStrings_iface;
186 LONG ref;
188 struct localizedpair *data;
189 UINT32 count;
190 UINT32 alloc;
193 static inline struct localizedstrings *impl_from_IDWriteLocalizedStrings(IDWriteLocalizedStrings *iface)
195 return CONTAINING_RECORD(iface, struct localizedstrings, IDWriteLocalizedStrings_iface);
198 static HRESULT WINAPI localizedstrings_QueryInterface(IDWriteLocalizedStrings *iface, REFIID riid, void **obj)
200 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
202 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
204 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteLocalizedStrings))
206 *obj = iface;
207 IDWriteLocalizedStrings_AddRef(iface);
208 return S_OK;
211 *obj = NULL;
213 return E_NOINTERFACE;
216 static ULONG WINAPI localizedstrings_AddRef(IDWriteLocalizedStrings *iface)
218 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
219 ULONG ref = InterlockedIncrement(&This->ref);
220 TRACE("(%p)->(%d)\n", This, ref);
221 return ref;
224 static ULONG WINAPI localizedstrings_Release(IDWriteLocalizedStrings *iface)
226 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
227 ULONG ref = InterlockedDecrement(&This->ref);
229 TRACE("(%p)->(%d)\n", This, ref);
231 if (!ref) {
232 unsigned int i;
234 for (i = 0; i < This->count; i++) {
235 heap_free(This->data[i].locale);
236 heap_free(This->data[i].string);
239 heap_free(This->data);
240 heap_free(This);
243 return ref;
246 static UINT32 WINAPI localizedstrings_GetCount(IDWriteLocalizedStrings *iface)
248 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
249 TRACE("(%p)\n", This);
250 return This->count;
253 static HRESULT WINAPI localizedstrings_FindLocaleName(IDWriteLocalizedStrings *iface,
254 WCHAR const *locale_name, UINT32 *index, BOOL *exists)
256 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
257 FIXME("(%p)->(%s %p %p): stub\n", This, debugstr_w(locale_name), index, exists);
258 return E_NOTIMPL;
261 static HRESULT WINAPI localizedstrings_GetLocaleNameLength(IDWriteLocalizedStrings *iface, UINT32 index, UINT32 *length)
263 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
264 FIXME("(%p)->(%u %p): stub\n", This, index, length);
265 return E_NOTIMPL;
268 static HRESULT WINAPI localizedstrings_GetLocaleName(IDWriteLocalizedStrings *iface, UINT32 index, WCHAR *locale_name, UINT32 size)
270 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
271 FIXME("(%p)->(%u %p %u): stub\n", This, index, locale_name, size);
272 return E_NOTIMPL;
275 static HRESULT WINAPI localizedstrings_GetStringLength(IDWriteLocalizedStrings *iface, UINT32 index, UINT32 *length)
277 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
279 TRACE("(%p)->(%u %p)\n", This, index, length);
281 if (index >= This->count) {
282 *length = (UINT32)-1;
283 return E_FAIL;
286 *length = strlenW(This->data[index].string);
287 return S_OK;
290 static HRESULT WINAPI localizedstrings_GetString(IDWriteLocalizedStrings *iface, UINT32 index, WCHAR *buffer, UINT32 size)
292 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
294 TRACE("(%p)->(%u %p %u)\n", This, index, buffer, size);
296 if (index >= This->count) {
297 if (buffer) *buffer = 0;
298 return E_FAIL;
301 if (size < strlenW(This->data[index].string)+1) {
302 if (buffer) *buffer = 0;
303 return E_NOT_SUFFICIENT_BUFFER;
306 strcpyW(buffer, This->data[index].string);
307 return S_OK;
310 static const IDWriteLocalizedStringsVtbl localizedstringsvtbl = {
311 localizedstrings_QueryInterface,
312 localizedstrings_AddRef,
313 localizedstrings_Release,
314 localizedstrings_GetCount,
315 localizedstrings_FindLocaleName,
316 localizedstrings_GetLocaleNameLength,
317 localizedstrings_GetLocaleName,
318 localizedstrings_GetStringLength,
319 localizedstrings_GetString
322 HRESULT create_localizedstrings(IDWriteLocalizedStrings **strings)
324 struct localizedstrings *This;
326 *strings = NULL;
328 This = heap_alloc(sizeof(struct localizedstrings));
329 if (!This) return E_OUTOFMEMORY;
331 This->IDWriteLocalizedStrings_iface.lpVtbl = &localizedstringsvtbl;
332 This->ref = 1;
333 This->count = 0;
334 This->data = heap_alloc_zero(sizeof(struct localizedpair));
335 if (!This->data) {
336 heap_free(This);
337 return E_OUTOFMEMORY;
339 This->alloc = 1;
341 *strings = &This->IDWriteLocalizedStrings_iface;
343 return S_OK;
346 HRESULT add_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *locale, const WCHAR *string)
348 struct localizedstrings *This = impl_from_IDWriteLocalizedStrings(iface);
350 if (This->count == This->alloc) {
351 This->alloc *= 2;
352 This->data = heap_realloc(This->data, This->alloc*sizeof(struct localizedpair));
355 This->data[This->count].locale = heap_strdupW(locale);
356 This->data[This->count].string = heap_strdupW(string);
357 This->count++;
359 return S_OK;
362 static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory *iface, REFIID riid, void **obj)
364 TRACE("(%s %p)\n", debugstr_guid(riid), obj);
366 if (IsEqualIID(riid, &IID_IUnknown) ||
367 IsEqualIID(riid, &IID_IDWriteFactory))
369 *obj = iface;
370 return S_OK;
373 *obj = NULL;
375 return E_NOINTERFACE;
378 static ULONG WINAPI dwritefactory_AddRef(IDWriteFactory *iface)
380 return 2;
383 static ULONG WINAPI dwritefactory_Release(IDWriteFactory *iface)
385 return 1;
388 static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory *iface,
389 IDWriteFontCollection **collection, BOOL check_for_updates)
391 TRACE("(%p %d)\n", collection, check_for_updates);
393 if (check_for_updates)
394 FIXME("checking for system font updates not implemented\n");
396 return get_system_fontcollection(collection);
399 static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory *iface,
400 IDWriteFontCollectionLoader *loader, void const *key, UINT32 key_size, IDWriteFontCollection **collection)
402 FIXME("(%p %p %u %p): stub\n", loader, key, key_size, collection);
403 return E_NOTIMPL;
406 static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory *iface,
407 IDWriteFontCollectionLoader *loader)
409 FIXME("(%p): stub\n", loader);
410 return E_NOTIMPL;
413 static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory *iface,
414 IDWriteFontCollectionLoader *loader)
416 FIXME("(%p): stub\n", loader);
417 return E_NOTIMPL;
420 static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory *iface,
421 WCHAR const *path, FILETIME const *writetime, IDWriteFontFile **font_file)
423 FIXME("(%s %p %p): stub\n", debugstr_w(path), writetime, font_file);
424 return E_NOTIMPL;
427 static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory *iface,
428 void const *reference_key, UINT32 key_size, IDWriteFontFileLoader *loader, IDWriteFontFile **font_file)
430 FIXME("(%p %u %p %p): stub\n", reference_key, key_size, loader, font_file);
431 return E_NOTIMPL;
434 static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory *iface,
435 DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files,
436 UINT32 index, DWRITE_FONT_SIMULATIONS sim_flags, IDWriteFontFace **font_face)
438 FIXME("(%d %u %p %u 0x%x %p): stub\n", facetype, files_number, font_files, index, sim_flags, font_face);
439 return E_NOTIMPL;
442 static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory *iface, IDWriteRenderingParams **params)
444 HMONITOR monitor;
445 POINT pt;
447 TRACE("(%p)\n", params);
449 pt.x = pt.y = 0;
450 monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
451 return IDWriteFactory_CreateMonitorRenderingParams(iface, monitor, params);
454 static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory *iface, HMONITOR monitor,
455 IDWriteRenderingParams **params)
457 static int fixme_once = 0;
459 TRACE("(%p %p)\n", monitor, params);
461 if (!fixme_once++)
462 FIXME("(%p): monitor setting ignored\n", monitor);
463 return IDWriteFactory_CreateCustomRenderingParams(iface, 0.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT,
464 DWRITE_RENDERING_MODE_DEFAULT, params);
467 static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory *iface, FLOAT gamma, FLOAT enhancedContrast,
468 FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode, IDWriteRenderingParams **params)
470 TRACE("(%f %f %f %d %d %p)\n", gamma, enhancedContrast, cleartype_level, geometry, mode, params);
471 return create_renderingparams(gamma, enhancedContrast, cleartype_level, geometry, mode, params);
474 static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory *iface, IDWriteFontFileLoader *loader)
476 FIXME("(%p): stub\n", loader);
477 return E_NOTIMPL;
480 static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory *iface, IDWriteFontFileLoader *loader)
482 FIXME("(%p): stub\n", loader);
483 return E_NOTIMPL;
486 static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory *iface, WCHAR const* family_name,
487 IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style,
488 DWRITE_FONT_STRETCH stretch, FLOAT size, WCHAR const *locale, IDWriteTextFormat **format)
490 TRACE("(%s %p %d %d %d %f %s %p)\n", debugstr_w(family_name), collection, weight, style, stretch,
491 size, debugstr_w(locale), format);
492 return create_textformat(family_name, collection, weight, style, stretch, size, locale, format);
495 static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory *iface, IDWriteTypography **typography)
497 FIXME("(%p): stub\n", typography);
498 return E_NOTIMPL;
501 static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory *iface, IDWriteGdiInterop **gdi_interop)
503 TRACE("(%p)\n", gdi_interop);
504 return get_gdiinterop(gdi_interop);
507 static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory *iface, WCHAR const* string,
508 UINT32 len, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, IDWriteTextLayout **layout)
510 TRACE("(%s %u %p %f %f %p)\n", debugstr_w(string), len, format, max_width, max_height, layout);
512 if (!format) return E_INVALIDARG;
513 return create_textlayout(string, len, format, layout);
516 static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory *iface, WCHAR const* string,
517 UINT32 len, IDWriteTextFormat *format, FLOAT layout_width, FLOAT layout_height, FLOAT pixels_per_dip,
518 DWRITE_MATRIX const* transform, BOOL use_gdi_natural, IDWriteTextLayout **layout)
520 FIXME("(%s:%u %p %f %f %f %p %d %p): semi-stub\n", debugstr_wn(string, len), len, format, layout_width, layout_height,
521 pixels_per_dip, transform, use_gdi_natural, layout);
523 if (!format) return E_INVALIDARG;
524 return create_textlayout(string, len, format, layout);
527 static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory *iface, IDWriteTextFormat *format,
528 IDWriteInlineObject **trimming_sign)
530 FIXME("(%p %p): stub\n", format, trimming_sign);
531 return E_NOTIMPL;
534 static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory *iface, IDWriteTextAnalyzer **analyzer)
536 TRACE("(%p)\n", analyzer);
537 return get_textanalyzer(analyzer);
540 static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory *iface, DWRITE_NUMBER_SUBSTITUTION_METHOD method,
541 WCHAR const* locale, BOOL ignore_user_override, IDWriteNumberSubstitution **substitution)
543 FIXME("(%d %s %d %p): stub\n", method, debugstr_w(locale), ignore_user_override, substitution);
544 return E_NOTIMPL;
547 static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory *iface, DWRITE_GLYPH_RUN const *glyph_run,
548 FLOAT pixels_per_dip, DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE rendering_mode,
549 DWRITE_MEASURING_MODE measuring_mode, FLOAT baseline_x, FLOAT baseline_y, IDWriteGlyphRunAnalysis **analysis)
551 FIXME("(%p %f %p %d %d %f %f %p): stub\n", glyph_run, pixels_per_dip, transform, rendering_mode,
552 measuring_mode, baseline_x, baseline_y, analysis);
553 return E_NOTIMPL;
556 static const struct IDWriteFactoryVtbl dwritefactoryvtbl = {
557 dwritefactory_QueryInterface,
558 dwritefactory_AddRef,
559 dwritefactory_Release,
560 dwritefactory_GetSystemFontCollection,
561 dwritefactory_CreateCustomFontCollection,
562 dwritefactory_RegisterFontCollectionLoader,
563 dwritefactory_UnregisterFontCollectionLoader,
564 dwritefactory_CreateFontFileReference,
565 dwritefactory_CreateCustomFontFileReference,
566 dwritefactory_CreateFontFace,
567 dwritefactory_CreateRenderingParams,
568 dwritefactory_CreateMonitorRenderingParams,
569 dwritefactory_CreateCustomRenderingParams,
570 dwritefactory_RegisterFontFileLoader,
571 dwritefactory_UnregisterFontFileLoader,
572 dwritefactory_CreateTextFormat,
573 dwritefactory_CreateTypography,
574 dwritefactory_GetGdiInterop,
575 dwritefactory_CreateTextLayout,
576 dwritefactory_CreateGdiCompatibleTextLayout,
577 dwritefactory_CreateEllipsisTrimmingSign,
578 dwritefactory_CreateTextAnalyzer,
579 dwritefactory_CreateNumberSubstitution,
580 dwritefactory_CreateGlyphRunAnalysis
583 static IDWriteFactory dwritefactory = { &dwritefactoryvtbl };
585 HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **factory)
587 TRACE("(%d, %s, %p)\n", type, debugstr_guid(riid), factory);
589 if (!IsEqualIID(riid, &IID_IDWriteFactory)) return E_FAIL;
591 *factory = (IUnknown*)&dwritefactory;
593 return S_OK;