Nikolay Sivov : dwrite: Implement CreateNumberSubstitution().

Alexandre Julliard julliard at wine.codeweavers.com
Thu Oct 2 16:29:23 CDT 2014


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Oct  1 16:14:41 2014 +0400

dwrite: Implement CreateNumberSubstitution().

---

 dlls/dwrite/analyzer.c       | 93 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/dwrite/dwrite_private.h |  1 +
 dlls/dwrite/main.c           |  4 +-
 dlls/dwrite/tests/analyzer.c | 36 +++++++++++++++++
 include/winnls.h             |  3 +-
 5 files changed, 134 insertions(+), 3 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index 2470fa2..7c32e6b 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -165,6 +165,20 @@ static const struct dwritescript_properties dwritescripts_properties[Script_Last
     { /* Yiii */ { 0x69696959, 460,  1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, TRUE }
 };
 
+struct dwrite_numbersubstitution {
+    IDWriteNumberSubstitution IDWriteNumberSubstitution_iface;
+    LONG ref;
+
+    DWRITE_NUMBER_SUBSTITUTION_METHOD method;
+    WCHAR *locale;
+    BOOL ignore_user_override;
+};
+
+static inline struct dwrite_numbersubstitution *impl_from_IDWriteNumberSubstitution(IDWriteNumberSubstitution *iface)
+{
+    return CONTAINING_RECORD(iface, struct dwrite_numbersubstitution, IDWriteNumberSubstitution_iface);
+}
+
 static inline UINT16 get_char_script(WCHAR c)
 {
     UINT16 script = get_table_entry(wine_scripts_table, c);
@@ -1044,3 +1058,82 @@ HRESULT get_textanalyzer(IDWriteTextAnalyzer **ret)
     *ret = (IDWriteTextAnalyzer*)&textanalyzer;
     return S_OK;
 }
+
+static HRESULT WINAPI dwritenumbersubstitution_QueryInterface(IDWriteNumberSubstitution *iface, REFIID riid, void **obj)
+{
+    struct dwrite_numbersubstitution *This = impl_from_IDWriteNumberSubstitution(iface);
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
+
+    if (IsEqualIID(riid, &IID_IDWriteNumberSubstitution) ||
+        IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IDWriteNumberSubstitution_AddRef(iface);
+        return S_OK;
+    }
+
+    *obj = NULL;
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dwritenumbersubstitution_AddRef(IDWriteNumberSubstitution *iface)
+{
+    struct dwrite_numbersubstitution *This = impl_from_IDWriteNumberSubstitution(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+    TRACE("(%p)->(%d)\n", This, ref);
+    return ref;
+}
+
+static ULONG WINAPI dwritenumbersubstitution_Release(IDWriteNumberSubstitution *iface)
+{
+    struct dwrite_numbersubstitution *This = impl_from_IDWriteNumberSubstitution(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->(%d)\n", This, ref);
+
+    if (!ref) {
+        heap_free(This->locale);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static const struct IDWriteNumberSubstitutionVtbl numbersubstitutionvtbl = {
+    dwritenumbersubstitution_QueryInterface,
+    dwritenumbersubstitution_AddRef,
+    dwritenumbersubstitution_Release
+};
+
+HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD method, const WCHAR *locale,
+    BOOL ignore_user_override, IDWriteNumberSubstitution **ret)
+{
+    struct dwrite_numbersubstitution *substitution;
+
+    *ret = NULL;
+
+    if (method < DWRITE_NUMBER_SUBSTITUTION_METHOD_FROM_CULTURE || method > DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL)
+        return E_INVALIDARG;
+
+    if (method != DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE && !IsValidLocaleName(locale))
+        return E_INVALIDARG;
+
+    substitution = heap_alloc(sizeof(*substitution));
+    if (!substitution)
+        return E_OUTOFMEMORY;
+
+    substitution->IDWriteNumberSubstitution_iface.lpVtbl = &numbersubstitutionvtbl;
+    substitution->ref = 1;
+    substitution->ignore_user_override = ignore_user_override;
+    substitution->method = method;
+    substitution->locale = heap_strdupW(locale);
+    if (locale && !substitution->locale) {
+        heap_free(substitution);
+        return E_OUTOFMEMORY;
+    }
+
+    *ret = &substitution->IDWriteNumberSubstitution_iface;
+    return S_OK;
+}
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index ccad5a8..3ca7114 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -89,6 +89,7 @@ static inline unsigned short get_table_entry(const unsigned short *table, WCHAR
 
 extern HRESULT create_font_from_logfont(const LOGFONTW*, IDWriteFont**) DECLSPEC_HIDDEN;
 extern HRESULT convert_fontface_to_logfont(IDWriteFontFace*, LOGFONTW*) DECLSPEC_HIDDEN;
+extern HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD,const WCHAR *locale,BOOL,IDWriteNumberSubstitution**) DECLSPEC_HIDDEN;
 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;
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 7d62871..033e89a 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -749,8 +749,8 @@ static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory *ifa
     WCHAR const* locale, BOOL ignore_user_override, IDWriteNumberSubstitution **substitution)
 {
     struct dwritefactory *This = impl_from_IDWriteFactory(iface);
-    FIXME("(%p)->(%d %s %d %p): stub\n", This, method, debugstr_w(locale), ignore_user_override, substitution);
-    return E_NOTIMPL;
+    TRACE("(%p)->(%d %s %d %p)\n", This, method, debugstr_w(locale), ignore_user_override, substitution);
+    return create_numbersubstitution(method, locale, ignore_user_override, substitution);
 }
 
 static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory *iface, DWRITE_GLYPH_RUN const *glyph_run,
diff --git a/dlls/dwrite/tests/analyzer.c b/dlls/dwrite/tests/analyzer.c
index 45e2e07..31532ca 100644
--- a/dlls/dwrite/tests/analyzer.c
+++ b/dlls/dwrite/tests/analyzer.c
@@ -1046,11 +1046,46 @@ if (0) { /* crashes on native */
            ok(indices[0] == 0, "%d: got %d\n", i, indices[0]);
     }
 
+    IDWriteFont_Release(font);
     IDWriteFontFace_Release(fontface);
     IDWriteGdiInterop_Release(interop);
     IDWriteTextAnalyzer1_Release(analyzer1);
 }
 
+static void test_numbersubstitution(void)
+{
+    static const WCHAR dummyW[] = {'d','u','m','m','y',0};
+    IDWriteNumberSubstitution *substitution;
+    HRESULT hr;
+
+    hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, NULL, FALSE, &substitution);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IDWriteNumberSubstitution_Release(substitution);
+
+    /* invalid method */
+    hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL+1, NULL, FALSE, &substitution);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    /* invalid method */
+    hr = IDWriteFactory_CreateNumberSubstitution(factory, -1, NULL, FALSE, &substitution);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    /* invalid locale */
+    hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL, dummyW, FALSE, &substitution);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL, dummyW, FALSE, &substitution);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL, dummyW, FALSE, &substitution);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    /* invalid locale, but it's not needed for this method */
+    hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, dummyW, FALSE, &substitution);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IDWriteNumberSubstitution_Release(substitution);
+}
+
 START_TEST(analyzer)
 {
     HRESULT hr;
@@ -1070,6 +1105,7 @@ START_TEST(analyzer)
     test_AnalyzeLineBreakpoints();
     test_GetScriptProperties();
     test_GetTextComplexity();
+    test_numbersubstitution();
 
     IDWriteFactory_Release(factory);
 }
diff --git a/include/winnls.h b/include/winnls.h
index 9b353cb..13274be 100644
--- a/include/winnls.h
+++ b/include/winnls.h
@@ -863,8 +863,9 @@ WINBASEAPI BOOL        WINAPI IsDBCSLeadByte(BYTE);
 WINBASEAPI BOOL        WINAPI IsDBCSLeadByteEx(UINT,BYTE);
 WINNORMALIZEAPI BOOL   WINAPI IsNormalizedString(NORM_FORM,LPCWSTR,INT);
 WINBASEAPI BOOL        WINAPI IsValidCodePage(UINT);
-WINBASEAPI BOOL        WINAPI IsValidLocale(LCID,DWORD);
 WINBASEAPI BOOL        WINAPI IsValidLanguageGroup(LGRPID,DWORD);
+WINBASEAPI BOOL        WINAPI IsValidLocale(LCID,DWORD);
+WINBASEAPI BOOL        WINAPI IsValidLocaleName(LPCWSTR);
 WINBASEAPI INT         WINAPI LCIDToLocaleName(LCID,LPWSTR,INT,DWORD);
 WINBASEAPI INT         WINAPI LCMapStringA(LCID,DWORD,LPCSTR,INT,LPSTR,INT);
 WINBASEAPI INT         WINAPI LCMapStringW(LCID,DWORD,LPCWSTR,INT,LPWSTR,INT);




More information about the wine-cvs mailing list