dwrite: Set line baseline/height from font metrics.
This commit is contained in:
parent
9c9f8c0bb9
commit
8adc6679e9
|
@ -168,6 +168,8 @@ struct layout_run {
|
||||||
struct inline_object_run object;
|
struct inline_object_run object;
|
||||||
struct regular_layout_run regular;
|
struct regular_layout_run regular;
|
||||||
} u;
|
} u;
|
||||||
|
FLOAT baseline;
|
||||||
|
FLOAT height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct layout_effective_run {
|
struct layout_effective_run {
|
||||||
|
@ -573,6 +575,11 @@ static inline UINT32 get_clipped_range_length(const struct dwrite_textlayout *la
|
||||||
return layout->len - range->h.range.startPosition;
|
return layout->len - range->h.range.startPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline FLOAT get_scaled_font_metric(UINT32 metric, FLOAT emSize, const DWRITE_FONT_METRICS *metrics)
|
||||||
|
{
|
||||||
|
return (FLOAT)metric * emSize / (FLOAT)metrics->designUnitsPerEm;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
{
|
{
|
||||||
IDWriteTextAnalyzer *analyzer;
|
IDWriteTextAnalyzer *analyzer;
|
||||||
|
@ -639,6 +646,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props = NULL;
|
DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props = NULL;
|
||||||
DWRITE_SHAPING_TEXT_PROPERTIES *text_props = NULL;
|
DWRITE_SHAPING_TEXT_PROPERTIES *text_props = NULL;
|
||||||
struct regular_layout_run *run = &r->u.regular;
|
struct regular_layout_run *run = &r->u.regular;
|
||||||
|
DWRITE_FONT_METRICS fontmetrics = { 0 };
|
||||||
IDWriteFontFamily *family;
|
IDWriteFontFamily *family;
|
||||||
UINT32 index, max_count;
|
UINT32 index, max_count;
|
||||||
IDWriteFont *font;
|
IDWriteFont *font;
|
||||||
|
@ -669,6 +677,8 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
}
|
}
|
||||||
metrics->width = inlinemetrics.width;
|
metrics->width = inlinemetrics.width;
|
||||||
|
r->baseline = inlinemetrics.baseline;
|
||||||
|
r->height = inlinemetrics.height;
|
||||||
|
|
||||||
/* FIXME: use resolved breakpoints in this case too */
|
/* FIXME: use resolved breakpoints in this case too */
|
||||||
|
|
||||||
|
@ -778,6 +788,22 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
run->run.glyphCount = 0;
|
run->run.glyphCount = 0;
|
||||||
else
|
else
|
||||||
run->run.glyphCount = run->glyphcount;
|
run->run.glyphCount = run->glyphcount;
|
||||||
|
|
||||||
|
/* baseline derived from font metrics */
|
||||||
|
if (layout->gdicompatible) {
|
||||||
|
/* FIXME: check return value when it's actually implemented */
|
||||||
|
IDWriteFontFace_GetGdiCompatibleMetrics(run->run.fontFace,
|
||||||
|
run->run.fontEmSize,
|
||||||
|
layout->pixels_per_dip,
|
||||||
|
&layout->transform,
|
||||||
|
&fontmetrics);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IDWriteFontFace_GetMetrics(run->run.fontFace, &fontmetrics);
|
||||||
|
|
||||||
|
r->baseline = get_scaled_font_metric(fontmetrics.ascent, run->run.fontEmSize, &fontmetrics);
|
||||||
|
r->height = get_scaled_font_metric(fontmetrics.ascent + fontmetrics.descent, run->run.fontEmSize, &fontmetrics);
|
||||||
|
|
||||||
layout_set_cluster_metrics(layout, r, &cluster);
|
layout_set_cluster_metrics(layout, r, &cluster);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -1059,11 +1085,15 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
layout->clustermetrics[i].isNewline || /* always wrap on new line */
|
layout->clustermetrics[i].isNewline || /* always wrap on new line */
|
||||||
i == layout->cluster_count - 1) /* end of the text */ {
|
i == layout->cluster_count - 1) /* end of the text */ {
|
||||||
|
|
||||||
UINT32 strlength, index = i;
|
UINT32 strlength, last_cluster = i, index;
|
||||||
|
FLOAT descent;
|
||||||
|
|
||||||
if (!overflow)
|
if (!overflow) {
|
||||||
metrics.length += layout->clustermetrics[i].length;
|
metrics.length += layout->clustermetrics[i].length;
|
||||||
strlength = metrics.length;
|
last_cluster = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
last_cluster = i ? i - 1 : i;
|
||||||
|
|
||||||
if (i >= start) {
|
if (i >= start) {
|
||||||
hr = layout_add_effective_run(layout, run, start, i - start + 1, origin_x, s[0]);
|
hr = layout_add_effective_run(layout, run, start, i - start + 1, origin_x, s[0]);
|
||||||
|
@ -1074,6 +1104,8 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
|
|
||||||
/* take a look at clusters we got for this line in reverse order to set
|
/* take a look at clusters we got for this line in reverse order to set
|
||||||
trailing properties for current line */
|
trailing properties for current line */
|
||||||
|
strlength = metrics.length;
|
||||||
|
index = last_cluster;
|
||||||
while (strlength) {
|
while (strlength) {
|
||||||
DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index];
|
DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index];
|
||||||
|
|
||||||
|
@ -1092,8 +1124,27 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics.height = 0.0; /* FIXME */
|
/* look for max baseline and descent for this line */
|
||||||
metrics.baseline = 0.0; /* FIXME */
|
strlength = metrics.length;
|
||||||
|
index = last_cluster;
|
||||||
|
metrics.baseline = 0.0;
|
||||||
|
descent = 0.0;
|
||||||
|
while (strlength) {
|
||||||
|
DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index];
|
||||||
|
const struct layout_run *cur = layout->clusters[index].run;
|
||||||
|
FLOAT cur_descent = cur->height - cur->baseline;
|
||||||
|
|
||||||
|
if (cur->baseline > metrics.baseline)
|
||||||
|
metrics.baseline = cur->baseline;
|
||||||
|
|
||||||
|
if (cur_descent > descent)
|
||||||
|
descent = cur_descent;
|
||||||
|
|
||||||
|
strlength -= cluster->length;
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
metrics.height = descent + metrics.baseline;
|
||||||
|
|
||||||
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))
|
||||||
|
|
|
@ -2767,12 +2767,11 @@ static void test_GetLineMetrics(void)
|
||||||
ok(fontface != NULL, "got %p\n", fontface);
|
ok(fontface != NULL, "got %p\n", fontface);
|
||||||
IDWriteFontFace_GetMetrics(fontface, &fontmetrics);
|
IDWriteFontFace_GetMetrics(fontface, &fontmetrics);
|
||||||
|
|
||||||
todo_wine {
|
|
||||||
ok(metrics.baseline == fontmetrics.ascent, "got %.2f, expected %d\n", metrics.baseline,
|
ok(metrics.baseline == fontmetrics.ascent, "got %.2f, expected %d\n", metrics.baseline,
|
||||||
fontmetrics.ascent);
|
fontmetrics.ascent);
|
||||||
ok(metrics.height == fontmetrics.ascent + fontmetrics.descent, "got %.2f, expected %d\n",
|
ok(metrics.height == fontmetrics.ascent + fontmetrics.descent, "got %.2f, expected %d\n",
|
||||||
metrics.height, fontmetrics.ascent + fontmetrics.descent);
|
metrics.height, fontmetrics.ascent + fontmetrics.descent);
|
||||||
}
|
|
||||||
IDWriteFontFace_Release(fontface);
|
IDWriteFontFace_Release(fontface);
|
||||||
IDWriteTextLayout_Release(layout);
|
IDWriteTextLayout_Release(layout);
|
||||||
IDWriteTextFormat_Release(format);
|
IDWriteTextFormat_Release(format);
|
||||||
|
|
Loading…
Reference in New Issue