Commit 8adc6679 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Set line baseline/height from font metrics.

parent 9c9f8c0b
...@@ -168,6 +168,8 @@ struct layout_run { ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
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