dwrite/layout: Improve overhangs metrics computation.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-01-25 14:56:40 +03:00 committed by Alexandre Julliard
parent 27aef423d8
commit d933afc4a4
4 changed files with 41 additions and 31 deletions

View File

@ -252,13 +252,14 @@ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLS
extern WCHAR bidi_get_mirrored_char(WCHAR) DECLSPEC_HIDDEN;
/* FreeType integration */
struct dwrite_glyphbitmap {
struct dwrite_glyphbitmap
{
IDWriteFontFace4 *fontface;
DWORD simulations;
FLOAT emsize;
float emsize;
BOOL nohint;
BOOL aliased;
UINT16 index;
UINT16 glyph;
INT pitch;
RECT bbox;
BYTE *buf;
@ -276,7 +277,7 @@ extern UINT16 freetype_get_glyphcount(IDWriteFontFace4*) DECLSPEC_HIDDEN;
extern void freetype_get_glyphs(IDWriteFontFace4*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN;
extern BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) DECLSPEC_HIDDEN;
extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4*,UINT16,UINT16) DECLSPEC_HIDDEN;
extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN;
extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
extern INT freetype_get_charmap_index(IDWriteFontFace4*,BOOL*) DECLSPEC_HIDDEN;
extern INT32 freetype_get_glyph_advance(IDWriteFontFace4*,FLOAT,UINT16,DWRITE_MEASURING_MODE,BOOL*) DECLSPEC_HIDDEN;

View File

@ -5060,7 +5060,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
RECT *bbox = &glyph_bitmap.bbox;
UINT32 bitmap_size;
glyph_bitmap.index = analysis->run.glyphIndices[i];
glyph_bitmap.glyph = analysis->run.glyphIndices[i];
freetype_get_glyph_bbox(&glyph_bitmap);
bitmap_size = get_glyph_bitmap_pitch(analysis->rendering_mode, bbox->right - bbox->left) *
@ -5161,7 +5161,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis)
int x, y, width, height;
BOOL is_1bpp;
glyph_bitmap.index = analysis->run.glyphIndices[i];
glyph_bitmap.glyph = analysis->run.glyphIndices[i];
freetype_get_glyph_bbox(&glyph_bitmap);
if (IsRectEmpty(bbox))

View File

@ -686,7 +686,7 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
imagetype.height = bitmap->emsize;
imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT;
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) {
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->glyph, &glyph, NULL) == 0) {
if (needs_transform) {
FT_Glyph glyph_copy;
@ -844,7 +844,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
imagetype.height = bitmap->emsize;
imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT;
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) {
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->glyph, &glyph, NULL) == 0) {
FT_Glyph glyph_copy;
if (needs_transform) {

View File

@ -3604,16 +3604,6 @@ static HRESULT WINAPI dwritetextlayout_GetMetrics(IDWriteTextLayout3 *iface, DWR
return hr;
}
static void scale_glyph_bbox(RECT *bbox, FLOAT emSize, UINT16 units_per_em, D2D1_RECT_F *ret)
{
#define SCALE(x) ((FLOAT)x * emSize / (FLOAT)units_per_em)
ret->left = SCALE(bbox->left);
ret->right = SCALE(bbox->right);
ret->top = SCALE(bbox->top);
ret->bottom = SCALE(bbox->bottom);
#undef SCALE
}
static void d2d_rect_offset(D2D1_RECT_F *rect, FLOAT x, FLOAT y)
{
rect->left += x;
@ -3652,27 +3642,46 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout
const struct regular_layout_run *regular = &run->run->u.regular;
UINT32 start_glyph = regular->clustermap[run->start];
const DWRITE_GLYPH_RUN *glyph_run = &regular->run;
DWRITE_FONT_METRICS font_metrics;
D2D1_POINT_2F origin = { 0 };
float rtl_factor;
UINT32 i;
if (run->bbox.top == run->bbox.bottom) {
IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics);
if (run->bbox.top == run->bbox.bottom)
{
struct dwrite_glyphbitmap glyph_bitmap;
RECT *bbox;
memset(&glyph_bitmap, 0, sizeof(glyph_bitmap));
glyph_bitmap.fontface = (IDWriteFontFace4 *)glyph_run->fontFace;
glyph_bitmap.simulations = IDWriteFontFace_GetSimulations(glyph_run->fontFace);
glyph_bitmap.emsize = glyph_run->fontEmSize;
glyph_bitmap.nohint = layout->measuringmode == DWRITE_MEASURING_MODE_NATURAL;
bbox = &glyph_bitmap.bbox;
rtl_factor = glyph_run->bidiLevel & 1 ? -1.0f : 1.0f;
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);
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];
if (glyph_run->bidiLevel & 1)
origin.x -= glyph_run->glyphAdvances[i + start_glyph];
glyph_bitmap.glyph = glyph_run->glyphIndices[i + start_glyph];
freetype_get_glyph_bbox(&glyph_bitmap);
glyph_bbox.left = bbox->left;
glyph_bbox.top = bbox->top;
glyph_bbox.right = bbox->right;
glyph_bbox.bottom = bbox->bottom;
d2d_rect_offset(&glyph_bbox, origin.x + rtl_factor * glyph_run->glyphOffsets[i + start_glyph].advanceOffset,
origin.y - glyph_run->glyphOffsets[i + start_glyph].ascenderOffset);
d2d_rect_union(&run->bbox, &glyph_bbox);
if (!(glyph_run->bidiLevel & 1))
origin.x += glyph_run->glyphAdvances[i + start_glyph];
}
}