Nikolay Sivov : dwrite: Store locale name for each text range.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jan 5 15:01:27 CST 2015


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Jan  1 21:50:59 2015 +0300

dwrite: Store locale name for each text range.

---

 dlls/dwrite/layout.c       | 74 ++++++++++++++++++++++++++++++++++++++--------
 dlls/dwrite/tests/layout.c | 67 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+), 13 deletions(-)

diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index ba35713..0ddb0b4 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -67,7 +67,8 @@ enum layout_range_attr_kind {
     LAYOUT_RANGE_ATTR_INLINE,
     LAYOUT_RANGE_ATTR_UNDERLINE,
     LAYOUT_RANGE_ATTR_STRIKETHROUGH,
-    LAYOUT_RANGE_ATTR_FONTCOLL
+    LAYOUT_RANGE_ATTR_FONTCOLL,
+    LAYOUT_RANGE_ATTR_LOCALE
 };
 
 struct layout_range_attr_value {
@@ -82,6 +83,7 @@ struct layout_range_attr_value {
         BOOL underline;
         BOOL strikethrough;
         IDWriteFontCollection *collection;
+        const WCHAR *locale;
     } u;
 };
 
@@ -97,6 +99,7 @@ struct layout_range {
     BOOL underline;
     BOOL strikethrough;
     IDWriteFontCollection *collection;
+    WCHAR locale[LOCALE_NAME_MAX_LENGTH];
 };
 
 struct layout_run {
@@ -402,6 +405,8 @@ static BOOL is_same_layout_attrvalue(struct layout_range const *range, enum layo
         return range->strikethrough == value->u.strikethrough;
     case LAYOUT_RANGE_ATTR_FONTCOLL:
         return range->collection == value->u.collection;
+    case LAYOUT_RANGE_ATTR_LOCALE:
+        return strcmpW(range->locale, value->u.locale) == 0;
     default:
         ;
     }
@@ -447,6 +452,7 @@ static struct layout_range *alloc_layout_range(struct dwrite_textlayout *layout,
     range->collection = layout->format.collection;
     if (range->collection)
         IDWriteFontCollection_AddRef(range->collection);
+    strcpyW(range->locale, layout->format.locale);
 
     return range;
 }
@@ -579,6 +585,11 @@ static BOOL set_layout_range_attrval(struct layout_range *dest, enum layout_rang
         if (dest->collection)
             IDWriteFontCollection_AddRef(dest->collection);
         break;
+    case LAYOUT_RANGE_ATTR_LOCALE:
+        changed = strcmpW(dest->locale, value->u.locale) != 0;
+        if (changed)
+            strcpyW(dest->locale, value->u.locale);
+        break;
     default:
         ;
     }
@@ -1127,17 +1138,17 @@ static HRESULT WINAPI dwritetextlayout_SetDrawingEffect(IDWriteTextLayout2 *ifac
     return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_EFFECT, &value);
 }
 
-static HRESULT WINAPI dwritetextlayout_SetInlineObject(IDWriteTextLayout2 *iface, IDWriteInlineObject *object, DWRITE_TEXT_RANGE r)
+static HRESULT WINAPI dwritetextlayout_SetInlineObject(IDWriteTextLayout2 *iface, IDWriteInlineObject *object, DWRITE_TEXT_RANGE range)
 {
     struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
     struct layout_range_attr_value attr;
 
-    TRACE("(%p)->(%p %s)\n", This, object, debugstr_range(&r));
+    TRACE("(%p)->(%p %s)\n", This, object, debugstr_range(&range));
 
-    if (!validate_text_range(This, &r))
+    if (!validate_text_range(This, &range))
         return S_OK;
 
-    attr.range = r;
+    attr.range = range;
     attr.u.object = object;
 
     return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_INLINE, &attr);
@@ -1153,8 +1164,20 @@ static HRESULT WINAPI dwritetextlayout_SetTypography(IDWriteTextLayout2 *iface,
 static HRESULT WINAPI dwritetextlayout_SetLocaleName(IDWriteTextLayout2 *iface, WCHAR const* locale, DWRITE_TEXT_RANGE range)
 {
     struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
-    FIXME("(%p)->(%s %s): stub\n", This, debugstr_w(locale), debugstr_range(&range));
-    return E_NOTIMPL;
+    struct layout_range_attr_value attr;
+
+    TRACE("(%p)->(%s %s)\n", This, debugstr_w(locale), debugstr_range(&range));
+
+    if (!locale || strlenW(locale) > LOCALE_NAME_MAX_LENGTH-1)
+        return E_INVALIDARG;
+
+    if (!validate_text_range(This, &range))
+        return S_OK;
+
+    attr.range = range;
+    attr.u.locale = locale;
+
+    return set_layout_range_attr(This, LAYOUT_RANGE_ATTR_LOCALE, &attr);
 }
 
 static FLOAT WINAPI dwritetextlayout_GetMaxWidth(IDWriteTextLayout2 *iface)
@@ -1349,19 +1372,44 @@ static HRESULT WINAPI dwritetextlayout_GetTypography(IDWriteTextLayout2 *iface,
 }
 
 static HRESULT WINAPI dwritetextlayout_layout_GetLocaleNameLength(IDWriteTextLayout2 *iface,
-    UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *range)
+    UINT32 position, UINT32* length, DWRITE_TEXT_RANGE *r)
 {
     struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
-    FIXME("(%p)->(%u %p %p): stub\n", This, position, length, range);
-    return E_NOTIMPL;
+    struct layout_range *range;
+
+    TRACE("(%p)->(%u %p %p)\n", This, position, length, r);
+
+    range = get_layout_range_by_pos(This, position);
+    if (!range) {
+        *length = 0;
+        return S_OK;
+    }
+
+    *length = strlenW(range->locale);
+    return return_range(range, r);
 }
 
 static HRESULT WINAPI dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout2 *iface,
-    UINT32 position, WCHAR* name, UINT32 name_size, DWRITE_TEXT_RANGE *range)
+    UINT32 position, WCHAR* locale, UINT32 length, DWRITE_TEXT_RANGE *r)
 {
     struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
-    FIXME("(%p)->(%u %p %u %p): stub\n", This, position, name, name_size, range);
-    return E_NOTIMPL;
+    struct layout_range *range;
+
+    TRACE("(%p)->(%u %p %u %p)\n", This, position, locale, length, r);
+
+    if (length == 0)
+        return E_INVALIDARG;
+
+    locale[0] = 0;
+    range = get_layout_range_by_pos(This, position);
+    if (!range)
+        return E_INVALIDARG;
+
+    if (length < strlenW(range->locale) + 1)
+        return E_NOT_SUFFICIENT_BUFFER;
+
+    strcpyW(locale, range->locale);
+    return return_range(range, r);
 }
 
 static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index de3e544..b90d7af 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -924,6 +924,72 @@ todo_wine {
     IDWriteTextFormat_Release(format);
 }
 
+static void test_SetLocaleName(void)
+{
+    static const WCHAR strW[] = {'a','b','c','d',0};
+    WCHAR buffW[LOCALE_NAME_MAX_LENGTH+5];
+    IDWriteTextFormat *format;
+    IDWriteTextLayout *layout;
+    DWRITE_TEXT_RANGE range;
+    HRESULT hr;
+
+    hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+        DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    range.startPosition = 0;
+    range.length = 1;
+    hr = IDWriteTextLayout_SetLocaleName(layout, enusW, range);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IDWriteTextLayout_SetLocaleName(layout, NULL, range);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    /* invalid locale name is allowed */
+    hr = IDWriteTextLayout_SetLocaleName(layout, strW, range);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IDWriteTextLayout_GetLocaleName(layout, 0, NULL, 0, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+if (0) /* crashes on native */
+    hr = IDWriteTextLayout_GetLocaleName(layout, 0, NULL, 1, NULL);
+
+    buffW[0] = 0;
+    hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, sizeof(buffW)/sizeof(WCHAR), NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(buffW, strW), "got %s\n", wine_dbgstr_w(buffW));
+
+    /* get with a shorter buffer */
+    buffW[0] = 0xa;
+    hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, 1, NULL);
+    ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
+    ok(buffW[0] == 0, "got %x\n", buffW[0]);
+
+    /* name is too long */
+    lstrcpyW(buffW, strW);
+    while (lstrlenW(buffW) < LOCALE_NAME_MAX_LENGTH) {
+        lstrcatW(buffW, strW);
+    }
+    lstrcatW(buffW, strW);
+
+    range.startPosition = 0;
+    range.length = 1;
+    hr = IDWriteTextLayout_SetLocaleName(layout, buffW, range);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    buffW[0] = 0;
+    hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, sizeof(buffW)/sizeof(WCHAR), NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(buffW, strW), "got %s\n", wine_dbgstr_w(buffW));
+
+    IDWriteTextLayout_Release(layout);
+    IDWriteTextFormat_Release(format);
+}
+
 START_TEST(layout)
 {
     HRESULT hr;
@@ -949,6 +1015,7 @@ START_TEST(layout)
     test_draw_sequence();
     test_typography();
     test_GetClusterMetrics();
+    test_SetLocaleName();
 
     IDWriteFactory_Release(factory);
 }




More information about the wine-cvs mailing list