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:
parent
27aef423d8
commit
d933afc4a4
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 = ®ular->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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue