On Wed, Jan 30, 2019 at 02:12:37AM +0900, Byeongsik Jeon wrote:
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net
dlls/gdi32/freetype.c | 250 ++++++++++++++++++++++++------------------ 1 file changed, 145 insertions(+), 105 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 7e07b22409..f996df62fe 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -6873,6 +6873,135 @@ static FT_Vector get_advance_metric(GdiFont *incoming_font, GdiFont *font, return adv; }
+static FT_BBox get_transformed_bbox( const FT_Glyph_Metrics *metrics,
BOOL needsTransform, const FT_Matrix *transMatTategaki )
Again, needs_transform. Let's pass the entries matrices array here for simpicity.
+{
- FT_BBox bbox = { 0, 0, 0, 0 };
- if (!needsTransform)
- {
bbox.xMin = (metrics->horiBearingX) & -64;
bbox.xMax = (metrics->horiBearingX + metrics->width + 63) & -64;
bbox.yMax = (metrics->horiBearingY + 63) & -64;
bbox.yMin = (metrics->horiBearingY - metrics->height) & -64;
- }
- else
- {
FT_Vector vec;
INT xc, yc;
for (xc = 0; xc < 2; xc++)
{
for (yc = 0; yc < 2; yc++)
{
vec.x = metrics->horiBearingX + xc * metrics->width;
vec.y = metrics->horiBearingY - yc * metrics->height;
TRACE( "Vec %ld,%ld\n", vec.x, vec.y );
Add a space after comma.
pFT_Vector_Transform( &vec, transMatTategaki );
if (xc == 0 && yc == 0)
{
bbox.xMin = bbox.xMax = vec.x;
bbox.yMin = bbox.yMax = vec.y;
}
else
{
if (vec.x < bbox.xMin) bbox.xMin = vec.x;
else if (vec.x > bbox.xMax) bbox.xMax = vec.x;
if (vec.y < bbox.yMin) bbox.yMin = vec.y;
else if (vec.y > bbox.yMax) bbox.yMax = vec.y;
}
}
}
bbox.xMin = bbox.xMin & -64;
bbox.xMax = (bbox.xMax + 63) & -64;
bbox.yMax = (bbox.yMax + 63) & -64;
bbox.yMin = bbox.yMin & -64;
TRACE( "transformed box: (%ld,%ld - %ld,%ld)\n", bbox.xMin, bbox.yMax, bbox.xMax, bbox.yMin );
Again, spaces after commas.
- }
- return bbox;
+}
+static void compute_gm_abc_metrics( GdiFont *incoming_font, GdiFont *font,
I think compute_metrics should be fine.
FT_BBox bbox, const FT_Glyph_Metrics *metrics,
BOOL tategaki, BOOL vertical_metrics, BOOL needsTransform,
takegaki -> vertical
const FT_Matrix *transMat,
const FT_Matrix *transMatTategaki,
const FT_Matrix *transMatUnrotated,
These three become the array.
GLYPHMETRICS *gm, ABC *abc )
+{
- FT_Vector adv, vec, origin;
- if (!needsTransform)
- {
adv = get_advance_metric( incoming_font, font, metrics, NULL, vertical_metrics );
gm->gmCellIncX = adv.x >> 6;
gm->gmCellIncY = 0;
origin.x = bbox.xMin;
origin.y = bbox.yMax;
abc->abcA = origin.x >> 6;
abc->abcB = (metrics->width + 63) >> 6;
- }
- else
- {
FT_Pos lsb;
if (tategaki && (font->potm || get_outline_text_metrics( font )))
{
if (vertical_metrics)
lsb = metrics->horiBearingY + metrics->vertBearingY;
else
lsb = metrics->vertAdvance + (font->potm->otmDescent << 6);
vec.x = lsb;
vec.y = font->potm->otmDescent << 6;
TRACE( "Vec %ld,%ld\n", vec.x>>6, vec.y>>6 );
pFT_Vector_Transform( &vec, transMat );
origin.x = (vec.x + bbox.xMin) & -64;
origin.y = (vec.y + bbox.yMax + 63) & -64;
lsb -= metrics->horiBearingY;
}
else
{
origin.x = bbox.xMin;
origin.y = bbox.yMax;
lsb = metrics->horiBearingX;
}
adv = get_advance_metric( incoming_font, font, metrics, transMat, vertical_metrics );
gm->gmCellIncX = adv.x >> 6;
gm->gmCellIncY = adv.y >> 6;
adv = get_advance_metric( incoming_font, font, metrics, transMatUnrotated, vertical_metrics );
adv.x = pFT_Vector_Length( &adv );
adv.y = 0;
vec.x = lsb;
vec.y = 0;
pFT_Vector_Transform( &vec, transMatUnrotated );
if (lsb > 0) abc->abcA = pFT_Vector_Length( &vec ) >> 6;
else abc->abcA = -((pFT_Vector_Length( &vec ) + 63) >> 6);
/* We use lsb again to avoid rounding errors */
vec.x = lsb + (tategaki ? metrics->height : metrics->width);
vec.y = 0;
pFT_Vector_Transform( &vec, transMatUnrotated );
abc->abcB = ((pFT_Vector_Length( &vec ) + 63) >> 6) - abc->abcA;
- }
- if (!abc->abcB) abc->abcB = 1;
- abc->abcC = (adv.x >> 6) - abc->abcA - abc->abcB;
- gm->gmptGlyphOrigin.x = origin.x >> 6;
- gm->gmptGlyphOrigin.y = origin.y >> 6;
- gm->gmBlackBoxX = (bbox.xMax - bbox.xMin) >> 6;
- gm->gmBlackBoxY = (bbox.yMax - bbox.yMin) >> 6;
- if (!gm->gmBlackBoxX) gm->gmBlackBoxX = 1;
- if (!gm->gmBlackBoxY) gm->gmBlackBoxY = 1;
- TRACE( "gm: %u,%u,%s,%d,%d\n", gm->gmBlackBoxX, gm->gmBlackBoxY,
wine_dbgstr_point(&gm->gmptGlyphOrigin), gm->gmCellIncX, gm->gmCellIncY );
- TRACE( "abc: %d,%u,%d\n", abc->abcA, abc->abcB, abc->abcC );
Use the same format here as in get_cached_metrics.
+}
static unsigned int get_native_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf) { TTPOLYGONHEADER *pph; @@ -7116,9 +7245,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, DWORD width, height, pitch, needed = 0; FT_Bitmap ft_bitmap; FT_Error err;
- INT left, right, top = 0, bottom = 0;
- FT_Vector adv;
- INT origin_x = 0, origin_y = 0;
- FT_BBox bbox; FT_Int load_flags = get_load_flags(format); FT_Matrix transMat = identityMat; FT_Matrix transMatUnrotated;
@@ -7191,8 +7318,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, if(incoming_font->potm || get_outline_text_metrics(incoming_font) || get_bitmap_text_metrics(incoming_font)) { TEXTMETRICW *ptm = &incoming_font->potm->otmTextMetrics;
top = min( metrics.horiBearingY, ptm->tmAscent << 6 );
bottom = max( metrics.horiBearingY - metrics.height, -(ptm->tmDescent << 6) );
INT top = min( metrics.horiBearingY, ptm->tmAscent << 6 );
INT bottom = max( metrics.horiBearingY - metrics.height, -(ptm->tmDescent << 6) ); metrics.horiBearingY = top; metrics.height = top - bottom;
@@ -7200,102 +7327,15 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, /* metrics.width = min( metrics.width, ptm->tmMaxCharWidth << 6 ); */ }
- if(!needsTransform) {
left = (INT)(metrics.horiBearingX) & -64;
right = (INT)((metrics.horiBearingX + metrics.width) + 63) & -64;
- top = (metrics.horiBearingY + 63) & -64;
- bottom = (metrics.horiBearingY - metrics.height) & -64;
- adv = get_advance_metric(incoming_font, font, &metrics, NULL, vertical_metrics);
- gm.gmCellIncX = adv.x >> 6;
- gm.gmCellIncY = 0;
origin_x = left;
origin_y = top;
abc->abcA = origin_x >> 6;
abc->abcB = (metrics.width + 63) >> 6;
- } else {
INT xc, yc;
- FT_Vector vec;
FT_Pos lsb;
left = right = 0;
- for(xc = 0; xc < 2; xc++) {
for(yc = 0; yc < 2; yc++) {
vec.x = metrics.horiBearingX + xc * metrics.width;
vec.y = metrics.horiBearingY - yc * metrics.height;
TRACE("Vec %ld,%ld\n", vec.x, vec.y);
pFT_Vector_Transform(&vec, &transMatTategaki);
if(xc == 0 && yc == 0) {
left = right = vec.x;
top = bottom = vec.y;
} else {
if(vec.x < left) left = vec.x;
else if(vec.x > right) right = vec.x;
if(vec.y < bottom) bottom = vec.y;
else if(vec.y > top) top = vec.y;
}
}
- }
- left = left & -64;
- right = (right + 63) & -64;
- bottom = bottom & -64;
- top = (top + 63) & -64;
if (tategaki && (font->potm || get_outline_text_metrics(font)))
{
if (vertical_metrics)
lsb = metrics.horiBearingY + metrics.vertBearingY;
else
lsb = metrics.vertAdvance + (font->potm->otmDescent << 6);
vec.x = lsb;
vec.y = font->potm->otmDescent << 6;
TRACE ("Vec %ld,%ld\n", vec.x>>6, vec.y>>6);
pFT_Vector_Transform(&vec, &transMat);
origin_x = (vec.x + left) & -64;
origin_y = (vec.y + top + 63) & -64;
lsb -= metrics.horiBearingY;
}
else
{
origin_x = left;
origin_y = top;
lsb = metrics.horiBearingX;
}
- bbox = get_transformed_bbox( &metrics, needsTransform, &transMatTategaki );
- TRACE("transformed box: (%d,%d - %d,%d)\n", left, top, right, bottom);
adv = get_advance_metric(incoming_font, font, &metrics, &transMat, vertical_metrics);
gm.gmCellIncX = adv.x >> 6;
gm.gmCellIncY = adv.y >> 6;
adv = get_advance_metric(incoming_font, font, &metrics, &transMatUnrotated, vertical_metrics);
adv.x = pFT_Vector_Length(&adv);
adv.y = 0;
vec.x = lsb;
vec.y = 0;
pFT_Vector_Transform(&vec, &transMatUnrotated);
if(lsb > 0) abc->abcA = pFT_Vector_Length(&vec) >> 6;
else abc->abcA = -((pFT_Vector_Length(&vec) + 63) >> 6);
/* We use lsb again to avoid rounding errors */
vec.x = lsb + (tategaki ? metrics.height : metrics.width);
vec.y = 0;
pFT_Vector_Transform(&vec, &transMatUnrotated);
abc->abcB = ((pFT_Vector_Length(&vec) + 63) >> 6) - abc->abcA;
- }
- width = (right - left) >> 6;
- height = (top - bottom) >> 6;
- gm.gmBlackBoxX = width ? width : 1;
- gm.gmBlackBoxY = height ? height : 1;
- gm.gmptGlyphOrigin.x = origin_x >> 6;
- gm.gmptGlyphOrigin.y = origin_y >> 6;
- if (!abc->abcB) abc->abcB = 1;
- abc->abcC = (adv.x >> 6) - abc->abcA - abc->abcB;
- compute_gm_abc_metrics( incoming_font, font, bbox, &metrics,
tategaki, vertical_metrics, needsTransform,
&transMat, &transMatTategaki, &transMatUnrotated,
&gm, abc );
- TRACE("%u,%u,%s,%d,%d\n", gm.gmBlackBoxX, gm.gmBlackBoxY,
wine_dbgstr_point(&gm.gmptGlyphOrigin),
gm.gmCellIncX, gm.gmCellIncY);
width = (bbox.xMax - bbox.xMin) >> 6;
height = (bbox.yMax - bbox.yMin) >> 6;
if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) && is_identity_MAT2(lpmat)) /* don't cache custom transforms */
@@ -7358,7 +7398,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, if(needsTransform) pFT_Outline_Transform(&ft_face->glyph->outline, &transMatTategaki);
pFT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
pFT_Outline_Translate(&ft_face->glyph->outline, -bbox.xMin, -bbox.yMin ); /* Note: FreeType will only set 'black' bits for us. */ memset(buf, 0, needed);
@@ -7419,7 +7459,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, if(needsTransform) pFT_Outline_Transform(&ft_face->glyph->outline, &transMatTategaki);
pFT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
pFT_Outline_Translate(&ft_face->glyph->outline, -bbox.xMin, -bbox.yMin ); memset(ft_bitmap.buffer, 0, buflen);
@@ -7510,13 +7550,13 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, { gm.gmBlackBoxX += 2; gm.gmptGlyphOrigin.x -= 1;
left -= (1 << 6);
bbox.xMin -= (1 << 6); } else { gm.gmBlackBoxY += 2; gm.gmptGlyphOrigin.y += 1;
top += (1 << 6);
bbox.yMax += (1 << 6); } width = gm.gmBlackBoxX;
@@ -7558,7 +7598,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, vmul = 3; }
x_shift = ft_face->glyph->bitmap_left - (left >> 6);
x_shift = ft_face->glyph->bitmap_left - (bbox.xMin >> 6); if ( x_shift < 0 ) { src += hmul * -x_shift;
@@ -7570,7 +7610,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format, width -= x_shift; }
y_shift = (top >> 6) - ft_face->glyph->bitmap_top;
y_shift = (bbox.yMax >> 6) - ft_face->glyph->bitmap_top; if ( y_shift < 0 ) { src += src_pitch * vmul * -y_shift;
-- 2.20.1