dwrite: Initial layout GetMetrics() implementation.
This commit is contained in:
parent
8d85da757a
commit
a940c9b970
|
@ -248,6 +248,8 @@ struct dwrite_textlayout {
|
||||||
UINT32 line_count;
|
UINT32 line_count;
|
||||||
UINT32 line_alloc;
|
UINT32 line_alloc;
|
||||||
|
|
||||||
|
DWRITE_TEXT_METRICS1 metrics;
|
||||||
|
|
||||||
/* gdi-compatible layout specifics */
|
/* gdi-compatible layout specifics */
|
||||||
BOOL gdicompatible;
|
BOOL gdicompatible;
|
||||||
FLOAT pixels_per_dip;
|
FLOAT pixels_per_dip;
|
||||||
|
@ -1125,7 +1127,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
i == layout->cluster_count - 1) /* end of the text */ {
|
i == layout->cluster_count - 1) /* end of the text */ {
|
||||||
|
|
||||||
UINT32 strlength, last_cluster = i, index;
|
UINT32 strlength, last_cluster = i, index;
|
||||||
FLOAT descent;
|
FLOAT descent, trailingspacewidth;
|
||||||
|
|
||||||
if (!overflow) {
|
if (!overflow) {
|
||||||
metrics.length += layout->clustermetrics[i].length;
|
metrics.length += layout->clustermetrics[i].length;
|
||||||
|
@ -1145,6 +1147,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
trailing properties for current line */
|
trailing properties for current line */
|
||||||
strlength = metrics.length;
|
strlength = metrics.length;
|
||||||
index = last_cluster;
|
index = last_cluster;
|
||||||
|
trailingspacewidth = 0.0;
|
||||||
while (strlength) {
|
while (strlength) {
|
||||||
DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index];
|
DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index];
|
||||||
|
|
||||||
|
@ -1156,8 +1159,10 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
metrics.newlineLength += cluster->length;
|
metrics.newlineLength += cluster->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cluster->isWhitespace)
|
if (cluster->isWhitespace) {
|
||||||
metrics.trailingWhitespaceLength += cluster->length;
|
metrics.trailingWhitespaceLength += cluster->length;
|
||||||
|
trailingspacewidth += cluster->width;
|
||||||
|
}
|
||||||
|
|
||||||
strlength -= cluster->length;
|
strlength -= cluster->length;
|
||||||
index--;
|
index--;
|
||||||
|
@ -1184,6 +1189,11 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
}
|
}
|
||||||
metrics.height = descent + metrics.baseline;
|
metrics.height = descent + metrics.baseline;
|
||||||
|
|
||||||
|
if (width > layout->metrics.widthIncludingTrailingWhitespace)
|
||||||
|
layout->metrics.widthIncludingTrailingWhitespace = width;
|
||||||
|
if (width - trailingspacewidth > layout->metrics.width)
|
||||||
|
layout->metrics.width = width - trailingspacewidth;
|
||||||
|
|
||||||
metrics.isTrimmed = width > layout->maxwidth;
|
metrics.isTrimmed = width > layout->maxwidth;
|
||||||
hr = layout_set_line_metrics(layout, &metrics, &line);
|
hr = layout_set_line_metrics(layout, &metrics, &line);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -1203,6 +1213,12 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
textpos += layout->clustermetrics[i].length;
|
textpos += layout->clustermetrics[i].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layout->metrics.left = layout->metrics.top = 0.0;
|
||||||
|
layout->metrics.layoutWidth = layout->maxwidth;
|
||||||
|
layout->metrics.layoutHeight = layout->maxheight;
|
||||||
|
layout->metrics.maxBidiReorderingDepth = 1; /* FIXME */
|
||||||
|
layout->metrics.lineCount = layout->line_count;
|
||||||
|
|
||||||
/* Now all line info is here, update effective runs positions in flow direction */
|
/* Now all line info is here, update effective runs positions in flow direction */
|
||||||
erun = layout_get_next_erun(layout, NULL);
|
erun = layout_get_next_erun(layout, NULL);
|
||||||
inrun = layout_get_next_inline_run(layout, NULL);
|
inrun = layout_get_next_inline_run(layout, NULL);
|
||||||
|
@ -1227,8 +1243,12 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
if (!inrun)
|
if (!inrun)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layout->metrics.height += layout->lines[line].height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layout->metrics.heightIncludingTrailingWhitespace = layout->metrics.height; /* FIXME: not true for vertical text */
|
||||||
|
|
||||||
layout->recompute &= ~RECOMPUTE_EFFECTIVE_RUNS;
|
layout->recompute &= ~RECOMPUTE_EFFECTIVE_RUNS;
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -2775,8 +2795,16 @@ static HRESULT WINAPI dwritetextlayout1_GetCharacterSpacing(IDWriteTextLayout2 *
|
||||||
static HRESULT WINAPI dwritetextlayout2_GetMetrics(IDWriteTextLayout2 *iface, DWRITE_TEXT_METRICS1 *metrics)
|
static HRESULT WINAPI dwritetextlayout2_GetMetrics(IDWriteTextLayout2 *iface, DWRITE_TEXT_METRICS1 *metrics)
|
||||||
{
|
{
|
||||||
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface);
|
||||||
FIXME("(%p)->(%p): stub\n", This, metrics);
|
HRESULT hr;
|
||||||
return E_NOTIMPL;
|
|
||||||
|
TRACE("(%p)->(%p)\n", This, metrics);
|
||||||
|
|
||||||
|
hr = layout_compute_effective_runs(This);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
*metrics = This->metrics;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI dwritetextlayout2_SetVerticalGlyphOrientation(IDWriteTextLayout2 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
|
static HRESULT WINAPI dwritetextlayout2_SetVerticalGlyphOrientation(IDWriteTextLayout2 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation)
|
||||||
|
@ -3542,6 +3570,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
|
||||||
list_init(&layout->effects);
|
list_init(&layout->effects);
|
||||||
list_init(&layout->spacing);
|
list_init(&layout->spacing);
|
||||||
memset(&layout->format, 0, sizeof(layout->format));
|
memset(&layout->format, 0, sizeof(layout->format));
|
||||||
|
memset(&layout->metrics, 0, sizeof(layout->metrics));
|
||||||
|
|
||||||
layout->gdicompatible = FALSE;
|
layout->gdicompatible = FALSE;
|
||||||
layout->pixels_per_dip = 0.0;
|
layout->pixels_per_dip = 0.0;
|
||||||
|
|
|
@ -2485,7 +2485,6 @@ static void test_GetMetrics(void)
|
||||||
|
|
||||||
memset(&metrics, 0xcc, sizeof(metrics));
|
memset(&metrics, 0xcc, sizeof(metrics));
|
||||||
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
|
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
|
||||||
todo_wine {
|
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
|
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
|
||||||
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
|
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
|
||||||
|
@ -2496,7 +2495,7 @@ todo_wine {
|
||||||
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
|
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
|
||||||
ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
|
ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
|
||||||
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
|
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
|
||||||
}
|
|
||||||
IDWriteTextLayout_Release(layout);
|
IDWriteTextLayout_Release(layout);
|
||||||
|
|
||||||
/* a string with more complex bidi sequence */
|
/* a string with more complex bidi sequence */
|
||||||
|
@ -2506,7 +2505,6 @@ todo_wine {
|
||||||
memset(&metrics, 0xcc, sizeof(metrics));
|
memset(&metrics, 0xcc, sizeof(metrics));
|
||||||
metrics.maxBidiReorderingDepth = 0;
|
metrics.maxBidiReorderingDepth = 0;
|
||||||
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
|
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
|
||||||
todo_wine {
|
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
|
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
|
||||||
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
|
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
|
||||||
|
@ -2515,9 +2513,10 @@ todo_wine {
|
||||||
ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
|
ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
|
||||||
ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth);
|
ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth);
|
||||||
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
|
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
|
||||||
|
todo_wine
|
||||||
ok(metrics.maxBidiReorderingDepth > 1, "got %u\n", metrics.maxBidiReorderingDepth);
|
ok(metrics.maxBidiReorderingDepth > 1, "got %u\n", metrics.maxBidiReorderingDepth);
|
||||||
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
|
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
|
||||||
}
|
|
||||||
IDWriteTextLayout_Release(layout);
|
IDWriteTextLayout_Release(layout);
|
||||||
|
|
||||||
IDWriteTextFormat_Release(format);
|
IDWriteTextFormat_Release(format);
|
||||||
|
|
Loading…
Reference in New Issue