Commit 496aec11 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Use [0,~0u) as initial text range.

parent b513e07c
......@@ -546,6 +546,15 @@ static void layout_set_cluster_metrics(struct dwrite_textlayout *layout, const s
}
}
/* This helper should be used to get effective range length, in other words it returns number of text
positions from range starting point to the end of the range, limited by layout text length */
static inline UINT32 get_clipped_range_length(const struct dwrite_textlayout *layout, const struct layout_range *range)
{
if (range->h.range.startPosition + range->h.range.length <= layout->len)
return range->h.range.length;
return layout->len - range->h.range.startPosition;
}
static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
{
IDWriteTextAnalyzer *analyzer;
......@@ -574,6 +583,10 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
return hr;
LIST_FOR_EACH_ENTRY(range, &layout->ranges, struct layout_range, h.entry) {
/* we don't care about ranges that don't contain any text */
if (range->h.range.startPosition >= layout->len)
break;
/* inline objects override actual text in a range */
if (range->object) {
hr = layout_update_breakpoints_range(layout, range);
......@@ -585,7 +598,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
return E_OUTOFMEMORY;
r->u.object.object = range->object;
r->u.object.length = range->h.range.length;
r->u.object.length = get_clipped_range_length(layout, range);
r->effect = range->effect;
list_add_tail(&layout->runs, &r->entry);
continue;
......@@ -593,13 +606,13 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
/* initial splitting by script */
hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, &layout->IDWriteTextAnalysisSource_iface,
range->h.range.startPosition, range->h.range.length, &layout->IDWriteTextAnalysisSink_iface);
range->h.range.startPosition, get_clipped_range_length(layout, range), &layout->IDWriteTextAnalysisSink_iface);
if (FAILED(hr))
break;
/* this splits it further */
hr = IDWriteTextAnalyzer_AnalyzeBidi(analyzer, &layout->IDWriteTextAnalysisSource_iface,
range->h.range.startPosition, range->h.range.length, &layout->IDWriteTextAnalysisSink_iface);
range->h.range.startPosition, get_clipped_range_length(layout, range), &layout->IDWriteTextAnalysisSink_iface);
if (FAILED(hr))
break;
}
......@@ -1073,18 +1086,6 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
return hr;
}
/* To be used in IDWriteTextLayout methods to validate and fix passed range */
static inline BOOL validate_text_range(struct dwrite_textlayout *layout, DWRITE_TEXT_RANGE *r)
{
if (r->startPosition >= layout->len)
return FALSE;
if (r->startPosition + r->length > layout->len)
r->length = layout->len - r->startPosition;
return TRUE;
}
static BOOL is_same_layout_attrvalue(struct layout_range_header const *h, enum layout_range_attr_kind attr, struct layout_range_attr_value *value)
{
struct layout_range_bool const *range_bool = (struct layout_range_bool*)h;
......@@ -1430,9 +1431,6 @@ static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layo
struct list *ranges;
DWRITE_TEXT_RANGE r;
if (!validate_text_range(layout, &value->range))
return S_OK;
/* select from ranges lists */
switch (attr)
{
......@@ -2112,12 +2110,8 @@ static HRESULT WINAPI dwritetextlayout_layout_GetFontStyle(IDWriteTextLayout2 *i
TRACE("(%p)->(%u %p %p)\n", This, position, style, r);
if (position >= This->len)
return S_OK;
range = get_layout_range_by_pos(This, position);
*style = range->style;
return return_range(&range->h, r);
}
......@@ -2129,12 +2123,8 @@ static HRESULT WINAPI dwritetextlayout_layout_GetFontStretch(IDWriteTextLayout2
TRACE("(%p)->(%u %p %p)\n", This, position, stretch, r);
if (position >= This->len)
return S_OK;
range = get_layout_range_by_pos(This, position);
*stretch = range->stretch;
return return_range(&range->h, r);
}
......@@ -2146,12 +2136,8 @@ static HRESULT WINAPI dwritetextlayout_layout_GetFontSize(IDWriteTextLayout2 *if
TRACE("(%p)->(%u %p %p)\n", This, position, size, r);
if (position >= This->len)
return S_OK;
range = get_layout_range_by_pos(This, position);
*size = range->fontsize;
return return_range(&range->h, r);
}
......@@ -3257,7 +3243,7 @@ static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, I
static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, struct dwrite_textlayout *layout)
{
struct layout_range_header *range, *strike;
DWRITE_TEXT_RANGE r = { 0, len };
DWRITE_TEXT_RANGE r;
HRESULT hr;
layout->IDWriteTextLayout2_iface.lpVtbl = &dwritetextlayoutvtbl;
......@@ -3301,7 +3287,11 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
if (FAILED(hr))
goto fail;
r.startPosition = 0;
r.length = ~0u;
range = alloc_layout_range(layout, &r, LAYOUT_RANGE_REGULAR);
r.startPosition = 0;
r.length = len;
strike = alloc_layout_range(layout, &r, LAYOUT_RANGE_STRIKETHROUGH);
if (!range || !strike) {
free_layout_range(range);
......
......@@ -924,7 +924,6 @@ static void test_fontweight(void)
range.startPosition = range.length = 0;
hr = IDWriteTextLayout_GetFontWeight(layout, 0, &weight, &range);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(range.startPosition == 0 && range.length == ~0u, "got %u, %u\n", range.startPosition, range.length);
range.startPosition = 0;
......@@ -1838,7 +1837,6 @@ static void test_SetFontSize(void)
size = 0.0;
hr = IDWriteTextLayout_GetFontSize(layout, 0, &size, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(r.startPosition == 0 && r.length == ~0u, "got %u, %u\n", r.startPosition, r.length);
ok(size == 10.0, "got %.2f\n", size);
......@@ -1872,10 +1870,9 @@ todo_wine
r.startPosition = r.length = 0;
hr = IDWriteTextLayout_GetFontSize(layout, 20, &size, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine {
ok(r.startPosition == 4 && r.length == ~0u-4, "got %u, %u\n", r.startPosition, r.length);
ok(size == 10.0, "got %.2f\n", size);
}
r.startPosition = 100;
r.length = 4;
hr = IDWriteTextLayout_SetFontSize(layout, 25.0, r);
......@@ -1885,10 +1882,9 @@ todo_wine {
r.startPosition = r.length = 0;
hr = IDWriteTextLayout_GetFontSize(layout, 100, &size, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine {
ok(r.startPosition == 100 && r.length == 4, "got %u, %u\n", r.startPosition, r.length);
ok(size == 25.0, "got %.2f\n", size);
}
IDWriteTextLayout_Release(layout);
IDWriteTextFormat_Release(format);
}
......@@ -1918,7 +1914,6 @@ static void test_SetFontFamilyName(void)
nameW[0] = 0;
hr = IDWriteTextLayout_GetFontFamilyName(layout, 1, nameW, sizeof(nameW)/sizeof(WCHAR), &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(r.startPosition == 0 && r.length == ~0u, "got %u, %u\n", r.startPosition, r.length);
r.startPosition = 1;
......@@ -1970,7 +1965,6 @@ static void test_SetFontStyle(void)
r.length = 0;
hr = IDWriteTextLayout_GetFontStyle(layout, 0, &style, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(r.startPosition == 0 && r.length == ~0u, "got %u, %u\n", r.startPosition, r.length);
ok(style == DWRITE_FONT_STYLE_NORMAL, "got %d\n", style);
......@@ -2004,10 +1998,9 @@ todo_wine
r.startPosition = r.length = 0;
hr = IDWriteTextLayout_GetFontStyle(layout, 20, &style, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine {
ok(r.startPosition == 4 && r.length == ~0u-4, "got %u, %u\n", r.startPosition, r.length);
ok(style == DWRITE_FONT_STYLE_NORMAL, "got %d\n", style);
}
r.startPosition = 100;
r.length = 4;
hr = IDWriteTextLayout_SetFontStyle(layout, DWRITE_FONT_STYLE_OBLIQUE, r);
......@@ -2017,10 +2010,92 @@ todo_wine {
r.startPosition = r.length = 0;
hr = IDWriteTextLayout_GetFontStyle(layout, 100, &style, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine {
ok(r.startPosition == 100 && r.length == 4, "got %u, %u\n", r.startPosition, r.length);
ok(style == DWRITE_FONT_STYLE_OBLIQUE, "got %d\n", style);
IDWriteTextLayout_Release(layout);
IDWriteTextFormat_Release(format);
}
static void test_SetFontStretch(void)
{
static const WCHAR strW[] = {'a','b','c','d',0};
DWRITE_FONT_STRETCH stretch;
IDWriteTextFormat *format;
IDWriteTextLayout *layout;
IDWriteFactory *factory;
DWRITE_TEXT_RANGE r;
HRESULT hr;
factory = create_factory();
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);
r.startPosition = 1;
r.length = 0;
stretch = DWRITE_FONT_STRETCH_UNDEFINED;
hr = IDWriteTextLayout_GetFontStretch(layout, 0, &stretch, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(r.startPosition == 0 && r.length == ~0u, "got %u, %u\n", r.startPosition, r.length);
ok(stretch == DWRITE_FONT_STRETCH_NORMAL, "got %d\n", stretch);
r.startPosition = 1;
r.length = 1;
hr = IDWriteTextLayout_SetFontStretch(layout, DWRITE_FONT_STRETCH_CONDENSED, r);
ok(hr == S_OK, "got 0x%08x\n", hr);
stretch = DWRITE_FONT_STRETCH_UNDEFINED;
hr = IDWriteTextLayout_GetFontStretch(layout, 1, &stretch, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(stretch == DWRITE_FONT_STRETCH_CONDENSED, "got %d\n", stretch);
r.startPosition = 0;
r.length = 4;
hr = IDWriteTextLayout_SetFontStretch(layout, DWRITE_FONT_STRETCH_EXPANDED, r);
ok(hr == S_OK, "got 0x%08x\n", hr);
stretch = DWRITE_FONT_STRETCH_UNDEFINED;
hr = IDWriteTextLayout_GetFontStretch(layout, 1, &stretch, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(stretch == DWRITE_FONT_STRETCH_EXPANDED, "got %d\n", stretch);
stretch = DWRITE_FONT_STRETCH_UNDEFINED;
hr = IDWriteTextLayout_GetFontStretch(layout, 0, &stretch, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(r.startPosition == 0 && r.length == 4, "got %u, %u\n", r.startPosition, r.length);
ok(stretch == DWRITE_FONT_STRETCH_EXPANDED, "got %d\n", stretch);
stretch = DWRITE_FONT_STRETCH_UNDEFINED;
r.startPosition = r.length = 0;
hr = IDWriteTextLayout_GetFontStretch(layout, 20, &stretch, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(r.startPosition == 4 && r.length == ~0u-4, "got %u, %u\n", r.startPosition, r.length);
ok(stretch == DWRITE_FONT_STRETCH_NORMAL, "got %d\n", stretch);
r.startPosition = 100;
r.length = 4;
hr = IDWriteTextLayout_SetFontStretch(layout, DWRITE_FONT_STRETCH_EXPANDED, r);
ok(hr == S_OK, "got 0x%08x\n", hr);
stretch = DWRITE_FONT_STRETCH_UNDEFINED;
r.startPosition = r.length = 0;
hr = IDWriteTextLayout_GetFontStretch(layout, 100, &stretch, &r);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(r.startPosition == 100 && r.length == 4, "got %u, %u\n", r.startPosition, r.length);
ok(stretch == DWRITE_FONT_STRETCH_EXPANDED, "got %d\n", stretch);
/* trying to set undefined value */
r.startPosition = 0;
r.length = 2;
hr = IDWriteTextLayout_SetFontStretch(layout, DWRITE_FONT_STRETCH_UNDEFINED, r);
todo_wine
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
IDWriteTextLayout_Release(layout);
IDWriteTextFormat_Release(format);
}
......@@ -2059,6 +2134,7 @@ START_TEST(layout)
test_SetFontSize();
test_SetFontFamilyName();
test_SetFontStyle();
test_SetFontStretch();
IDWriteFactory_Release(factory);
}
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