Nikolay Sivov : dwrite: Update overhangs rectangle on alignment changes.
Alexandre Julliard
julliard at winehq.org
Tue Apr 25 16:22:34 CDT 2017
Module: wine
Branch: master
Commit: ace830625d09dbb384cff19ff9723265357990a8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ace830625d09dbb384cff19ff9723265357990a8
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue Apr 25 08:54:43 2017 +0300
dwrite: Update overhangs rectangle on alignment changes.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dwrite/layout.c | 51 +++++++++++++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index c988c75..ab68ecf 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -188,6 +188,7 @@ struct layout_effective_run {
UINT16 *clustermap; /* effective clustermap, allocated separately, is not reused from nominal map */
UINT32 line; /* 0-based line index in line metrics array */
BOOL underlined; /* set if this run is underlined */
+ D2D1_RECT_F bbox; /* ink run box, top == bottom means it wasn't estimated yet */
};
struct layout_effective_inline {
@@ -1249,6 +1250,7 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
run->start = start = layout->clusters[first_cluster].position;
run->length = length;
run->width = get_cluster_range_width(layout, first_cluster, first_cluster + cluster_count);
+ memset(&run->bbox, 0, sizeof(run->bbox));
/* Check if run direction matches paragraph direction, if it doesn't adjust by
run width */
@@ -3581,25 +3583,28 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout
D2D1_POINT_2F origin = { 0 };
UINT32 i;
- IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics);
+ if (run->bbox.top == run->bbox.bottom) {
+ IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics);
- origin.x = run->origin.x + run->align_dx;
- origin.y = run->origin.y;
- for (i = 0; i < run->glyphcount; i++) {
- D2D1_RECT_F glyph_bbox;
- RECT design_bbox;
+ for (i = 0; i < run->glyphcount; i++) {
+ D2D1_RECT_F glyph_bbox;
+ RECT design_bbox;
- freetype_get_design_glyph_bbox((IDWriteFontFace4 *)glyph_run->fontFace, font_metrics.designUnitsPerEm,
- glyph_run->glyphIndices[i + start_glyph], &design_bbox);
+ freetype_get_design_glyph_bbox((IDWriteFontFace4 *)glyph_run->fontFace, font_metrics.designUnitsPerEm,
+ glyph_run->glyphIndices[i + start_glyph], &design_bbox);
- scale_glyph_bbox(&design_bbox, glyph_run->fontEmSize, font_metrics.designUnitsPerEm, &glyph_bbox);
- d2d_rect_offset(&glyph_bbox, origin.x + glyph_run->glyphOffsets[i + start_glyph].advanceOffset,
- origin.y + glyph_run->glyphOffsets[i + start_glyph].ascenderOffset);
- d2d_rect_union(bbox, &glyph_bbox);
+ scale_glyph_bbox(&design_bbox, glyph_run->fontEmSize, font_metrics.designUnitsPerEm, &glyph_bbox);
+ d2d_rect_offset(&glyph_bbox, origin.x + glyph_run->glyphOffsets[i + start_glyph].advanceOffset,
+ origin.y + glyph_run->glyphOffsets[i + start_glyph].ascenderOffset);
+ d2d_rect_union(&run->bbox, &glyph_bbox);
- /* FIXME: take care of vertical/rtl */
- origin.x += glyph_run->glyphAdvances[i + start_glyph];
+ /* FIXME: take care of vertical/rtl */
+ origin.x += glyph_run->glyphAdvances[i + start_glyph];
+ }
}
+
+ *bbox = run->bbox;
+ d2d_rect_offset(bbox, run->origin.x + run->align_dx, run->origin.y);
}
static HRESULT WINAPI dwritetextlayout_GetOverhangMetrics(IDWriteTextLayout3 *iface,
@@ -4091,9 +4096,12 @@ static HRESULT WINAPI dwritetextformat_layout_SetTextAlignment(IDWriteTextFormat
if (FAILED(hr))
return hr;
- /* if layout is not ready there's nothing to align */
- if (changed && !(This->recompute & RECOMPUTE_LINES))
- layout_apply_text_alignment(This);
+ if (changed) {
+ /* if layout is not ready there's nothing to align */
+ if (!(This->recompute & RECOMPUTE_LINES))
+ layout_apply_text_alignment(This);
+ This->recompute |= RECOMPUTE_OVERHANGS;
+ }
return S_OK;
}
@@ -4110,9 +4118,12 @@ static HRESULT WINAPI dwritetextformat_layout_SetParagraphAlignment(IDWriteTextF
if (FAILED(hr))
return hr;
- /* if layout is not ready there's nothing to align */
- if (changed && !(This->recompute & RECOMPUTE_LINES))
- layout_apply_par_alignment(This);
+ if (changed) {
+ /* if layout is not ready there's nothing to align */
+ if (!(This->recompute & RECOMPUTE_LINES))
+ layout_apply_par_alignment(This);
+ This->recompute |= RECOMPUTE_OVERHANGS;
+ }
return S_OK;
}
More information about the wine-cvs
mailing list