dwrite: Use [0,~0u) as initial text range.
This commit is contained in:
parent
b513e07c55
commit
496aec11e5
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue