From 4bcd7fb9752d11a1f16e4ef76278733ee871150b Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 16:04:54 +0900 Subject: [PATCH 01/24] [FONT][WIN32SS] Improve font coordinate transformation --- win32ss/gdi/ntgdi/freetype.c | 298 ++++++++++++++++------------------- 1 file changed, 140 insertions(+), 158 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index a74d223cd57..e9ad7042e5c 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -693,6 +693,16 @@ VOID FASTCALL IntEscapeMatrix(FT_Matrix *pmat, LONG lfEscapement) pmat->yy = pmat->xx; } +VOID FASTCALL IntViewportMatrix(FT_Matrix *pmat, PDC_ATTR pdcattr) +{ + ASSERT(pdcattr->szlWindowExt.cx != 0); + ASSERT(pdcattr->szlWindowExt.cy != 0); + pmat->xx = (1 << 16) * pdcattr->szlViewportExt.cx / pdcattr->szlWindowExt.cx; + pmat->yx = 0; + pmat->xy = 0; + pmat->yy = (1 << 16) * pdcattr->szlViewportExt.cy / pdcattr->szlWindowExt.cy; +} + VOID FASTCALL FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx) { @@ -5531,7 +5541,7 @@ GreExtTextOutW( FT_Face face; FT_GlyphSlot glyph; FT_BitmapGlyph realglyph; - LONGLONG TextLeft64, TextTop64, TextWidth64, RealXStart64; + LONGLONG TextLeft64, TextTop64, DeltaX64, DeltaY64, XStart64, YStart64; ULONG previous; FT_Bool use_kerning; RECTL DestRect, MaskRect; @@ -5555,10 +5565,8 @@ GreExtTextOutW( BOOL EmuBold, EmuItalic; int thickness; BOOL bResult; - INT DY1, DY2; - FT_Matrix mat1, mat2 = identityMat; + FT_Matrix mat = identityMat, matWidth, matEscape, matWorld, matViewport; FT_Vector vecs[9]; - POINT pts[9]; /* Check if String is valid */ if ((Count > 0xFFFF) || (Count > 0 && String == NULL)) @@ -5614,15 +5622,13 @@ GreExtTextOutW( { Start.x = pdcattr->ptlCurrent.x; Start.y = pdcattr->ptlCurrent.y; - } else { + } + else + { Start.x = XStart; Start.y = YStart; } - IntLPtoDP(dc, &Start, 1); - RealXStart64 = ((LONGLONG)Start.x + dc->ptlDCOrig.x) << 6; - YStart = Start.y + dc->ptlDCOrig.y; - SourcePoint.x = 0; SourcePoint.y = 0; MaskRect.left = 0; @@ -5723,43 +5729,29 @@ GreExtTextOutW( if (dc->pdcattr->iGraphicsMode == GM_ADVANCED) { pmxWorldToDevice = DC_pmxWorldToDevice(dc); - FtSetCoordinateTransform(face, pmxWorldToDevice); } else { pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault; - FtSetCoordinateTransform(face, pmxWorldToDevice); } - /* - * Process the vertical alignment and determine DY1 and DY2. - */ -#define VALIGN_MASK (TA_TOP | TA_BASELINE | TA_BOTTOM) - if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BASELINE) - { - DY1 = FontGDI->tmAscent; - DY2 = FontGDI->tmDescent; - } - else if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BOTTOM) - { - DY1 = FontGDI->tmHeight; - DY2 = 0; - } - else /* TA_TOP */ - { - DY1 = 0; - DY2 = FontGDI->tmHeight; - } -#undef VALIGN_MASK + IntWidthMatrix(face, &matWidth, lfWidth); + FT_Matrix_Multiply(&matWidth, &mat); + + IntEscapeMatrix(&matEscape, lfEscapement); + FT_Matrix_Multiply(&matEscape, &mat); + + FtMatrixFromMx(&matWorld, pmxWorldToDevice); + FT_Matrix_Multiply(&matWorld, &mat); - IntWidthMatrix(face, &mat1, lfWidth); - FT_Matrix_Multiply(&mat1, &mat2); - FT_Set_Transform(face, &mat2, NULL); + IntViewportMatrix(&matViewport, pdcattr); + FT_Matrix_Multiply(&matViewport, &mat); + + FT_Set_Transform(face, &mat, NULL); /* - * Calculate width of the text. + * Calculate extent of the text. */ - TextWidth64 = 0; DxShift = fuOptions & ETO_PDY ? 1 : 0; use_kerning = FT_HAS_KERNING(face); previous = 0; @@ -5767,8 +5759,7 @@ GreExtTextOutW( (pdcattr->lTextAlign & (TA_CENTER | TA_RIGHT)) || lfEscapement || plf->lfUnderline || plf->lfStrikeOut) { - TextLeft64 = RealXStart64; - TextTop64 = YStart << 6; + TextLeft64 = TextTop64 = 0; for (i = 0; i < Count; ++i) { glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); @@ -5803,11 +5794,13 @@ GreExtTextOutW( FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, 0, &delta); TextLeft64 += delta.x; + TextTop64 -= delta.y; } if (Dx == NULL) { TextLeft64 += realglyph->root.advance.x >> 10; + TextTop64 -= realglyph->root.advance.y >> 10; } else { @@ -5831,7 +5824,8 @@ GreExtTextOutW( FT_Done_Glyph((FT_Glyph)realglyph); } - TextWidth64 = TextLeft64 - RealXStart64; + DeltaX64 = TextLeft64; + DeltaY64 = TextTop64; } /* @@ -5839,13 +5833,17 @@ GreExtTextOutW( */ if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER) { - RealXStart64 -= TextWidth64 / 2; + XStart64 = -DeltaX64 / 2; + YStart64 = -DeltaY64 / 2; } else if ((pdcattr->lTextAlign & TA_RIGHT) == TA_RIGHT) { - RealXStart64 -= TextWidth64; - if (((RealXStart64 + TextWidth64 + 32) >> 6) <= Start.x + dc->ptlDCOrig.x) - RealXStart64 += 1 << 6; + XStart64 = -DeltaX64; + YStart64 = -DeltaY64; + } + else + { + XStart64 = YStart64 = 0; } psurf = dc->dclevel.pSurface; @@ -5866,23 +5864,30 @@ GreExtTextOutW( thickness = 1; } - IntEscapeMatrix(&mat1, lfEscapement); - FT_Matrix_Multiply(&mat1, &mat2); - FT_Set_Transform(face, &mat2, NULL); - - // background rectangle - vecs[0].x = 0; - vecs[0].y = (DY1 - FontGDI->tmHeight) << 16; // Top Left - vecs[1].x = TextWidth64 << 10; - vecs[1].y = (DY1 - FontGDI->tmHeight) << 16; // Top Right - vecs[2].x = TextWidth64 << 10; - vecs[2].y = DY1 << 16; // Bottom Right - vecs[3].x = 0; - vecs[3].y = DY1 << 16; // Bottom Left - - // the starting point - vecs[4].x = 0; - vecs[4].y = (DY1 - FontGDI->tmAscent) << 16; + /* Process the vertical alignment */ +#define VALIGN_MASK (TA_TOP | TA_BASELINE | TA_BOTTOM) + RtlZeroMemory(vecs, sizeof(vecs)); + if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BASELINE) + { + vecs[0].y = FontGDI->tmDescent << 16; // lower left + vecs[1].y = -FontGDI->tmAscent << 16; // upper left + vecs[4].y = 0; // baseline + } + else if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BOTTOM) + { + vecs[0].y = -FontGDI->tmHeight << 16; // lower left + vecs[1].y = 0; // upper left + vecs[4].y = -FontGDI->tmDescent << 16; // baseline + } + else /* TA_TOP */ + { + vecs[0].y = 0; // lower left + vecs[1].y = FontGDI->tmHeight << 16; // upper left + vecs[4].y = FontGDI->tmAscent << 16; // baseline + } + vecs[2] = vecs[1]; + vecs[3] = vecs[0]; +#undef VALIGN_MASK // underline if (plf->lfUnderline) @@ -5893,65 +5898,66 @@ GreExtTextOutW( position = face->underline_position * face->size->metrics.y_ppem / face->units_per_EM; } - vecs[5].x = 0; - vecs[5].y = (DY1 - FontGDI->tmAscent + position) << 16; - vecs[6].x = TextWidth64 << 10; - vecs[6].y = (DY1 - FontGDI->tmAscent + position) << 16; + vecs[5].y = vecs[6].y = vecs[4].y + (position << 16); } // strike through if (plf->lfStrikeOut) { - vecs[7].x = 0; - vecs[7].y = (DY1 - FontGDI->tmAscent + (FontGDI->tmAscent / 3)) << 16; - vecs[8].x = TextWidth64 << 10; - vecs[8].y = (DY1 - FontGDI->tmAscent + (FontGDI->tmAscent / 3)) << 16; + vecs[7].y = vecs[8].y = vecs[4].y - (((FontGDI->tmAscent * 2) / 3) << 16); } - // convert vecs to pts + IntEscapeMatrix(&matEscape, -lfEscapement); + matWorld.yx = -matWorld.yx; + matWorld.xy = -matWorld.xy; + + // convert vecs for (i = 0; i < 9; ++i) { - FT_Vector_Transform(&vecs[i], &mat1); - pts[i].x = (RealXStart64 >> 6) + (vecs[i].x >> 16); - pts[i].y = YStart - (vecs[i].y >> 16); - } + FT_Vector_Transform(&vecs[i], &matWidth); + FT_Vector_Transform(&vecs[i], &matEscape); + FT_Vector_Transform(&vecs[i], &matWorld); + vecs[i].x += FIX2LONG(pmxWorldToDevice->fxDx) * (1 << 16); + vecs[i].y += FIX2LONG(pmxWorldToDevice->fxDy) * (1 << 16); + vecs[i].x += (Start.x << 16) + (XStart64 << 10); + vecs[i].y += (Start.y << 16) + (YStart64 << 10); + vecs[i].x >>= 16; + vecs[i].y >>= 16; + vecs[i].x = (vecs[i].x - pdcattr->ptlWindowOrg.x) * pdcattr->szlViewportExt.cx / + pdcattr->szlWindowExt.cx + pdcattr->ptlViewportOrg.x; + vecs[i].y = (vecs[i].y - pdcattr->ptlWindowOrg.y) * pdcattr->szlViewportExt.cy / + pdcattr->szlWindowExt.cy + pdcattr->ptlViewportOrg.y; + vecs[i].x += dc->ptlDCOrig.x; + vecs[i].y += dc->ptlDCOrig.y; + } + vecs[2].x += DeltaX64 >> 6; + vecs[2].y += DeltaY64 >> 6; + vecs[3].x += DeltaX64 >> 6; + vecs[3].y += DeltaY64 >> 6; + vecs[6].x += DeltaX64 >> 6; + vecs[6].y += DeltaY64 >> 6; + vecs[8].x += DeltaX64 >> 6; + vecs[8].y += DeltaY64 >> 6; if (fuOptions & ETO_OPAQUE) { /* Draw background */ RECTL Rect; - INT X1 = ((RealXStart64 + 32) >> 6); + RtlZeroMemory(&Rect, sizeof(Rect)); - switch (lfEscapement) + if ((mat.xy == 0 && mat.yx == 0) || (mat.xx == 0 && mat.yy == 0)) { - case 0: - Rect.left = X1; - Rect.top = ((TextTop64 + 32) >> 6) - DY1; - Rect.right = (RealXStart64 + TextWidth64 + 32) >> 6; - Rect.bottom = ((TextTop64 + 32) >> 6) + DY2; - break; - case 90 * 10: - Rect.left = X1 - DY1; - Rect.top = ((TextTop64 - TextWidth64 + 32) >> 6); - Rect.right = X1 + DY2; - Rect.bottom = ((TextTop64 + 32) >> 6); - break; - case 180 * 10: - Rect.left = (RealXStart64 - TextWidth64 + 32) >> 6; - Rect.top = ((TextTop64 + 32) >> 6) - DY2; - Rect.right = X1; - Rect.bottom = ((TextTop64 + 32) >> 6) + DY1; - break; - case 270 * 10: - Rect.left = X1 - DY2; - Rect.top = ((TextTop64 + 32) >> 6); - Rect.right = X1 + DY1; - Rect.bottom = ((TextTop64 + TextWidth64 + 32) >> 6); - break; - default: - DPRINT1("FIXME: Not implemented lfEscapement\n"); - RtlZeroMemory(&Rect, sizeof(Rect)); - // FIXME: Use pts[0] ... pts[3] and EngFillPath + Rect.left = MAXLONG; + Rect.top = MAXLONG; + Rect.right = MINLONG; + Rect.bottom = MINLONG; + for (i = 0; i < 4; ++i) + { + Rect.left = min(Rect.left, vecs[i].x); + Rect.top = min(Rect.top, vecs[i].y); + Rect.right = max(Rect.right, vecs[i].x); + Rect.bottom = max(Rect.bottom, vecs[i].y); + } } if (dc->fs & (DC_ACCUM_APP | DC_ACCUM_WMGR)) @@ -5992,14 +5998,14 @@ GreExtTextOutW( * The main rendering loop. */ bResult = TRUE; - TextLeft64 = pts[4].x << 6; - TextTop64 = pts[4].y << 6; + TextLeft64 = vecs[4].x << 6; + TextTop64 = vecs[4].y << 6; previous = 0; for (i = 0; i < Count; ++i) { glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); realglyph = NULL; - if (!EmuBold && !EmuItalic && !lfEscapement) + if (!EmuBold && !EmuItalic && memcmp(&mat, &identityMat, sizeof(mat)) == 0) { realglyph = ftGdiGlyphCacheGet(face, glyph_index, plf->lfHeight, RenderMode, pmxWorldToDevice); @@ -6013,25 +6019,12 @@ GreExtTextOutW( bResult = FALSE; break; } - glyph = face->glyph; - if (EmuBold || EmuItalic || lfEscapement) - { - if (EmuBold) - FT_GlyphSlot_Embolden(glyph); - if (EmuItalic) - FT_GlyphSlot_Oblique(glyph); - realglyph = ftGdiGlyphSet(face, glyph, RenderMode); - } - else - { - realglyph = ftGdiGlyphCacheSet(face, - glyph_index, - plf->lfHeight, - pmxWorldToDevice, - glyph, - RenderMode); - } + if (EmuBold) + FT_GlyphSlot_Embolden(glyph); + if (EmuItalic) + FT_GlyphSlot_Oblique(glyph); + realglyph = ftGdiGlyphSet(face, glyph, RenderMode); if (!realglyph) { DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); @@ -6046,6 +6039,7 @@ GreExtTextOutW( FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, 0, &delta); TextLeft64 += delta.x; + TextTop64 -= delta.y; } DPRINT("TextLeft64: %I64d\n", TextLeft64); DPRINT("TextTop64: %I64d\n", TextTop64); @@ -6155,6 +6149,7 @@ GreExtTextOutW( TextLeft64 += realglyph->root.advance.x >> 10; TextTop64 -= realglyph->root.advance.y >> 10; DPRINT("New TextLeft64: %I64d\n", TextLeft64); + DPRINT("New TextTop64: %I64d\n", TextTop64); } else { @@ -6177,7 +6172,7 @@ GreExtTextOutW( previous = glyph_index; /* No cache, so clean up */ - if (EmuBold || EmuItalic || lfEscapement) + if (EmuBold || EmuItalic || memcmp(&mat, &identityMat, sizeof(mat)) != 0) { FT_Done_Glyph((FT_Glyph)realglyph); } @@ -6185,43 +6180,28 @@ GreExtTextOutW( if (plf->lfUnderline || plf->lfStrikeOut) { - INT x0, y0, x1, y1; - if (pts[0].x < pts[2].x) - { - x0 = pts[0].x; - x1 = pts[2].x; - } - else - { - x0 = pts[2].x; - x1 = pts[0].x; - } - if (pts[0].y < pts[2].y) - { - y0 = pts[0].y; - y1 = pts[2].y; - } - else - { - y0 = pts[2].y; - y1 = pts[0].y; - } + INT x0 = min(vecs[0].x, vecs[2].x); + INT y0 = min(vecs[0].y, vecs[2].y); + INT x1 = max(vecs[0].x, vecs[2].x); + INT y1 = max(vecs[0].y, vecs[2].y); if (dc->dctype == DCTYPE_DIRECT) MouseSafetyOnDrawStart(dc->ppdev, x0, y0, x1, y1); } if (plf->lfUnderline) { - INT i, nEscape = lfEscapement % (180 * 10); + INT i; for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) { - if (nEscape < 45 * 10 || nEscape > (180 - 45) * 10) + LONG dx = (LONG)(DeltaX64 >> 6); + LONG dy = (LONG)(DeltaY64 >> 6); + if (labs(dx) > labs(dy)) { // move vertical EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, &dc->eboText.BrushObject, - pts[5].x, pts[5].y + i, - pts[6].x, pts[6].y + i, + vecs[5].x, vecs[5].y + i, + vecs[6].x, vecs[6].y + i, NULL, ROP2_TO_MIX(R2_COPYPEN)); } else @@ -6229,8 +6209,8 @@ GreExtTextOutW( // move horizontal EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, &dc->eboText.BrushObject, - pts[5].x + i, pts[5].y, - pts[6].x + i, pts[6].y, + vecs[5].x + i, vecs[5].y, + vecs[6].x + i, vecs[6].y, NULL, ROP2_TO_MIX(R2_COPYPEN)); } } @@ -6238,16 +6218,18 @@ GreExtTextOutW( if (plf->lfStrikeOut) { - INT i, nEscape = lfEscapement % (180 * 10); + INT i; for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) { - if (nEscape < 45 * 10 || nEscape > (180 - 45) * 10) + LONG dx = (LONG)(DeltaX64 >> 6); + LONG dy = (LONG)(DeltaY64 >> 6); + if (labs(dx) > labs(dy)) { // move vertical EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, &dc->eboText.BrushObject, - pts[7].x, pts[7].y + i, - pts[8].x, pts[8].y + i, + vecs[7].x, vecs[7].y + i, + vecs[8].x, vecs[8].y + i, NULL, ROP2_TO_MIX(R2_COPYPEN)); } else @@ -6255,8 +6237,8 @@ GreExtTextOutW( // move horizontal EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, &dc->eboText.BrushObject, - pts[7].x + i, pts[7].y, - pts[8].x + i, pts[8].y, + vecs[7].x + i, vecs[7].y, + vecs[8].x + i, vecs[8].y, NULL, ROP2_TO_MIX(R2_COPYPEN)); } From d13bfba1c833bfa34f560145fa87e7189e0a31f9 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 16:36:26 +0900 Subject: [PATCH 02/24] add comments --- win32ss/gdi/ntgdi/freetype.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index e9ad7042e5c..64833e56d84 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5750,7 +5750,7 @@ GreExtTextOutW( FT_Set_Transform(face, &mat, NULL); /* - * Calculate extent of the text. + * Calculate displacement of the text. */ DxShift = fuOptions & ETO_PDY ? 1 : 0; use_kerning = FT_HAS_KERNING(face); @@ -5869,24 +5869,24 @@ GreExtTextOutW( RtlZeroMemory(vecs, sizeof(vecs)); if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BASELINE) { - vecs[0].y = FontGDI->tmDescent << 16; // lower left - vecs[1].y = -FontGDI->tmAscent << 16; // upper left + vecs[0].y = FontGDI->tmDescent << 16; // upper left vecs[4].y = 0; // baseline + vecs[1].y = -FontGDI->tmAscent << 16; // lower left } else if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BOTTOM) { - vecs[0].y = -FontGDI->tmHeight << 16; // lower left - vecs[1].y = 0; // upper left + vecs[0].y = -FontGDI->tmHeight << 16; // upper left vecs[4].y = -FontGDI->tmDescent << 16; // baseline + vecs[1].y = 0; // lower left } else /* TA_TOP */ { - vecs[0].y = 0; // lower left - vecs[1].y = FontGDI->tmHeight << 16; // upper left + vecs[0].y = 0; // upper left vecs[4].y = FontGDI->tmAscent << 16; // baseline + vecs[1].y = FontGDI->tmHeight << 16; // lower left } - vecs[2] = vecs[1]; - vecs[3] = vecs[0]; + vecs[3] = vecs[0]; // upper right + vecs[2] = vecs[1]; // lower right #undef VALIGN_MASK // underline @@ -5907,6 +5907,7 @@ GreExtTextOutW( vecs[7].y = vecs[8].y = vecs[4].y - (((FontGDI->tmAscent * 2) / 3) << 16); } + // invert y axis IntEscapeMatrix(&matEscape, -lfEscapement); matWorld.yx = -matWorld.yx; matWorld.xy = -matWorld.xy; @@ -5931,13 +5932,13 @@ GreExtTextOutW( vecs[i].y += dc->ptlDCOrig.y; } vecs[2].x += DeltaX64 >> 6; - vecs[2].y += DeltaY64 >> 6; + vecs[2].y += DeltaY64 >> 6; // lower right vecs[3].x += DeltaX64 >> 6; - vecs[3].y += DeltaY64 >> 6; + vecs[3].y += DeltaY64 >> 6; // upper right vecs[6].x += DeltaX64 >> 6; - vecs[6].y += DeltaY64 >> 6; + vecs[6].y += DeltaY64 >> 6; // underline right vecs[8].x += DeltaX64 >> 6; - vecs[8].y += DeltaY64 >> 6; + vecs[8].y += DeltaY64 >> 6; // strike through right if (fuOptions & ETO_OPAQUE) { From 95a1dd139f6141636dcc8c28b8624bc5bcd4fb24 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 16:41:54 +0900 Subject: [PATCH 03/24] fix comments --- win32ss/gdi/ntgdi/freetype.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 64833e56d84..3b4a0be8c6d 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5869,24 +5869,24 @@ GreExtTextOutW( RtlZeroMemory(vecs, sizeof(vecs)); if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BASELINE) { - vecs[0].y = FontGDI->tmDescent << 16; // upper left + vecs[1].y = -FontGDI->tmAscent << 16; // upper left vecs[4].y = 0; // baseline - vecs[1].y = -FontGDI->tmAscent << 16; // lower left + vecs[0].y = FontGDI->tmDescent << 16; // lower left } else if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BOTTOM) { - vecs[0].y = -FontGDI->tmHeight << 16; // upper left + vecs[1].y = 0; // upper left vecs[4].y = -FontGDI->tmDescent << 16; // baseline - vecs[1].y = 0; // lower left + vecs[0].y = -FontGDI->tmHeight << 16; // lower left } else /* TA_TOP */ { - vecs[0].y = 0; // upper left + vecs[1].y = FontGDI->tmHeight << 16; // upper left vecs[4].y = FontGDI->tmAscent << 16; // baseline - vecs[1].y = FontGDI->tmHeight << 16; // lower left + vecs[0].y = 0; // lower left } - vecs[3] = vecs[0]; // upper right - vecs[2] = vecs[1]; // lower right + vecs[2] = vecs[1]; // upper right + vecs[3] = vecs[0]; // lower right #undef VALIGN_MASK // underline @@ -5932,9 +5932,9 @@ GreExtTextOutW( vecs[i].y += dc->ptlDCOrig.y; } vecs[2].x += DeltaX64 >> 6; - vecs[2].y += DeltaY64 >> 6; // lower right + vecs[2].y += DeltaY64 >> 6; // upper right vecs[3].x += DeltaX64 >> 6; - vecs[3].y += DeltaY64 >> 6; // upper right + vecs[3].y += DeltaY64 >> 6; // lower right vecs[6].x += DeltaX64 >> 6; vecs[6].y += DeltaY64 >> 6; // underline right vecs[8].x += DeltaX64 >> 6; From bf8fcf69d429679ab1936ac7e85dd9b4cc47adcd Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 16:57:03 +0900 Subject: [PATCH 04/24] fix bounding box --- win32ss/gdi/ntgdi/freetype.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 3b4a0be8c6d..dd4e3db8b12 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5875,15 +5875,15 @@ GreExtTextOutW( } else if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BOTTOM) { - vecs[1].y = 0; // upper left + vecs[1].y = -FontGDI->tmHeight << 16; // upper left vecs[4].y = -FontGDI->tmDescent << 16; // baseline - vecs[0].y = -FontGDI->tmHeight << 16; // lower left + vecs[0].y = 0; // lower left } else /* TA_TOP */ { - vecs[1].y = FontGDI->tmHeight << 16; // upper left + vecs[1].y = 0; // upper left vecs[4].y = FontGDI->tmAscent << 16; // baseline - vecs[0].y = 0; // lower left + vecs[0].y = FontGDI->tmHeight << 16; // lower left } vecs[2] = vecs[1]; // upper right vecs[3] = vecs[0]; // lower right From 97b6f7bbdaa64e40094a09f72b663351d05f3e7f Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 17:06:48 +0900 Subject: [PATCH 05/24] underline position --- win32ss/gdi/ntgdi/freetype.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index dd4e3db8b12..626e04ee7db 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5898,13 +5898,13 @@ GreExtTextOutW( position = face->underline_position * face->size->metrics.y_ppem / face->units_per_EM; } - vecs[5].y = vecs[6].y = vecs[4].y + (position << 16); + vecs[5].y = vecs[6].y = vecs[4].y - (position << 16); } // strike through if (plf->lfStrikeOut) { - vecs[7].y = vecs[8].y = vecs[4].y - (((FontGDI->tmAscent * 2) / 3) << 16); + vecs[7].y = vecs[8].y = vecs[4].y - ((FontGDI->tmAscent / 3) << 16); } // invert y axis From 3329fe4d4f6730a0a6e9b916f3de2eaacfad65fc Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 17:45:25 +0900 Subject: [PATCH 06/24] fix shifted --- win32ss/gdi/ntgdi/freetype.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 626e04ee7db..c89c3a2fa02 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5726,6 +5726,7 @@ GreExtTextOutW( } /* NOTE: Don't trust face->size->metrics.ascender and descender values. */ + DC_vUpdateWorldToDevice(dc); if (dc->pdcattr->iGraphicsMode == GM_ADVANCED) { pmxWorldToDevice = DC_pmxWorldToDevice(dc); @@ -5918,8 +5919,8 @@ GreExtTextOutW( FT_Vector_Transform(&vecs[i], &matWidth); FT_Vector_Transform(&vecs[i], &matEscape); FT_Vector_Transform(&vecs[i], &matWorld); - vecs[i].x += FIX2LONG(pmxWorldToDevice->fxDx) * (1 << 16); - vecs[i].y += FIX2LONG(pmxWorldToDevice->fxDy) * (1 << 16); + //vecs[i].x += FIX2LONG(pmxWorldToDevice->fxDx) * (1 << 16); + //vecs[i].y += FIX2LONG(pmxWorldToDevice->fxDy) * (1 << 16); vecs[i].x += (Start.x << 16) + (XStart64 << 10); vecs[i].y += (Start.y << 16) + (YStart64 << 10); vecs[i].x >>= 16; From a030db7f6a5d5e165801855d85d1654cb41d67f4 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 18:09:52 +0900 Subject: [PATCH 07/24] fix world --- win32ss/gdi/ntgdi/freetype.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index c89c3a2fa02..173176d89f3 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -713,13 +713,13 @@ FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx) FLOATOBJ_MulLong(&ef, 0x00010000); pmat->xx = FLOATOBJ_GetLong(&ef); - ef = pmx->efM12; + ef = pmx->efM21; FLOATOBJ_MulLong(&ef, 0x00010000); - pmat->xy = FLOATOBJ_GetLong(&ef); + pmat->xy = -FLOATOBJ_GetLong(&ef); - ef = pmx->efM21; + ef = pmx->efM12; FLOATOBJ_MulLong(&ef, 0x00010000); - pmat->yx = FLOATOBJ_GetLong(&ef); + pmat->yx = -FLOATOBJ_GetLong(&ef); ef = pmx->efM22; FLOATOBJ_MulLong(&ef, 0x00010000); From 9e3ea935604255eb2a7b2ec16211495ac4d05583 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 18:38:53 +0900 Subject: [PATCH 08/24] fix world 2 --- win32ss/gdi/ntgdi/freetype.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 173176d89f3..4f64886d1e5 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -715,11 +715,11 @@ FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx) ef = pmx->efM21; FLOATOBJ_MulLong(&ef, 0x00010000); - pmat->xy = -FLOATOBJ_GetLong(&ef); + pmat->xy = FLOATOBJ_GetLong(&ef); ef = pmx->efM12; FLOATOBJ_MulLong(&ef, 0x00010000); - pmat->yx = -FLOATOBJ_GetLong(&ef); + pmat->yx = FLOATOBJ_GetLong(&ef); ef = pmx->efM22; FLOATOBJ_MulLong(&ef, 0x00010000); @@ -5743,6 +5743,8 @@ GreExtTextOutW( FT_Matrix_Multiply(&matEscape, &mat); FtMatrixFromMx(&matWorld, pmxWorldToDevice); + matWorld.yx = -matWorld.yx; + matWorld.xy = -matWorld.xy; FT_Matrix_Multiply(&matWorld, &mat); IntViewportMatrix(&matViewport, pdcattr); From 373a548be260383569b8ebf7de9e1602afe5daf4 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 19:45:00 +0900 Subject: [PATCH 09/24] fix XFORMOBJ_iSetXform --- win32ss/gdi/ntgdi/xformobj.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/win32ss/gdi/ntgdi/xformobj.c b/win32ss/gdi/ntgdi/xformobj.c index adf097233a2..908d73edb1d 100644 --- a/win32ss/gdi/ntgdi/xformobj.c +++ b/win32ss/gdi/ntgdi/xformobj.c @@ -154,9 +154,6 @@ XFORMOBJ_iSetXform( /* Check parameters */ if (!pxo || !pxform) return DDI_ERROR; - /* Check if the xform is valid */ - if ((pxform->eM11 == 0) || (pxform->eM22 == 0)) return DDI_ERROR; - /* Copy members */ FLOATOBJ_SetFloat(&pmx->efM11, pxform->eM11); FLOATOBJ_SetFloat(&pmx->efM12, pxform->eM12); From cf8ac28ae62e48fb48594967c6e997649034dd60 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 20:18:15 +0900 Subject: [PATCH 10/24] fix XFORMOBJ_iSetXform 2 --- win32ss/gdi/ntgdi/xformobj.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/win32ss/gdi/ntgdi/xformobj.c b/win32ss/gdi/ntgdi/xformobj.c index 908d73edb1d..1c82a50e676 100644 --- a/win32ss/gdi/ntgdi/xformobj.c +++ b/win32ss/gdi/ntgdi/xformobj.c @@ -150,10 +150,19 @@ XFORMOBJ_iSetXform( IN const XFORML *pxform) { PMATRIX pmx = XFORMOBJ_pmx(pxo); + FLOATOBJ ef1, ef2; /* Check parameters */ if (!pxo || !pxform) return DDI_ERROR; + /* eM11 * eM22 - eM12 * eM21 != 0 */ + FLOATOBJ_SetFloat(&ef1, pxform->eM11); + FLOATOBJ_MulFloat(&ef1, pxform->eM22); + FLOATOBJ_SetFloat(&ef2, pxform->eM12); + FLOATOBJ_MulFloat(&ef2, pxform->eM21); + if (FLOATOBJ_Equal(&ef1, &ef2)) + return DDI_ERROR; + /* Copy members */ FLOATOBJ_SetFloat(&pmx->efM11, pxform->eM11); FLOATOBJ_SetFloat(&pmx->efM12, pxform->eM12); From c3cbd1963b67d004e2d5b3b4d22cb749ab00c5f3 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 21:48:21 +0900 Subject: [PATCH 11/24] fix XFORMOBJ_iSetXform 3 --- win32ss/gdi/ntgdi/xformobj.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/win32ss/gdi/ntgdi/xformobj.c b/win32ss/gdi/ntgdi/xformobj.c index 1c82a50e676..e60ead3ac97 100644 --- a/win32ss/gdi/ntgdi/xformobj.c +++ b/win32ss/gdi/ntgdi/xformobj.c @@ -150,17 +150,19 @@ XFORMOBJ_iSetXform( IN const XFORML *pxform) { PMATRIX pmx = XFORMOBJ_pmx(pxo); - FLOATOBJ ef1, ef2; + FLOATOBJ ef1, ef2, ef3, ef4; /* Check parameters */ if (!pxo || !pxform) return DDI_ERROR; /* eM11 * eM22 - eM12 * eM21 != 0 */ FLOATOBJ_SetFloat(&ef1, pxform->eM11); - FLOATOBJ_MulFloat(&ef1, pxform->eM22); - FLOATOBJ_SetFloat(&ef2, pxform->eM12); - FLOATOBJ_MulFloat(&ef2, pxform->eM21); - if (FLOATOBJ_Equal(&ef1, &ef2)) + FLOATOBJ_SetFloat(&ef2, pxform->eM22); + FLOATOBJ_Mul(&ef1, &ef2); + FLOATOBJ_SetFloat(&ef3, pxform->eM12); + FLOATOBJ_SetFloat(&ef4, pxform->eM21); + FLOATOBJ_Mul(&ef3, &ef4); + if (FLOATOBJ_Equal(&ef1, &ef3)) return DDI_ERROR; /* Copy members */ From 2f3701b7c41a5fafdac341b7accead2adce2eea8 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 21:49:20 +0900 Subject: [PATCH 12/24] fix conversion --- win32ss/gdi/ntgdi/freetype.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 4f64886d1e5..3e47c5f9916 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -693,6 +693,7 @@ VOID FASTCALL IntEscapeMatrix(FT_Matrix *pmat, LONG lfEscapement) pmat->yy = pmat->xx; } +#if 0 VOID FASTCALL IntViewportMatrix(FT_Matrix *pmat, PDC_ATTR pdcattr) { ASSERT(pdcattr->szlWindowExt.cx != 0); @@ -702,6 +703,7 @@ VOID FASTCALL IntViewportMatrix(FT_Matrix *pmat, PDC_ATTR pdcattr) pmat->xy = 0; pmat->yy = (1 << 16) * pdcattr->szlViewportExt.cy / pdcattr->szlWindowExt.cy; } +#endif VOID FASTCALL FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx) @@ -5565,7 +5567,7 @@ GreExtTextOutW( BOOL EmuBold, EmuItalic; int thickness; BOOL bResult; - FT_Matrix mat = identityMat, matWidth, matEscape, matWorld, matViewport; + FT_Matrix mat = identityMat, matWidth, matEscape, matWorld; FT_Vector vecs[9]; /* Check if String is valid */ @@ -5747,8 +5749,8 @@ GreExtTextOutW( matWorld.xy = -matWorld.xy; FT_Matrix_Multiply(&matWorld, &mat); - IntViewportMatrix(&matViewport, pdcattr); - FT_Matrix_Multiply(&matViewport, &mat); + //IntViewportMatrix(&matViewport, pdcattr); + //FT_Matrix_Multiply(&matViewport, &mat); FT_Set_Transform(face, &mat, NULL); @@ -5912,27 +5914,29 @@ GreExtTextOutW( // invert y axis IntEscapeMatrix(&matEscape, -lfEscapement); - matWorld.yx = -matWorld.yx; - matWorld.xy = -matWorld.xy; + //matWorld.yx = -matWorld.yx; + //matWorld.xy = -matWorld.xy; // convert vecs for (i = 0; i < 9; ++i) { + POINT pt; FT_Vector_Transform(&vecs[i], &matWidth); FT_Vector_Transform(&vecs[i], &matEscape); - FT_Vector_Transform(&vecs[i], &matWorld); + //FT_Vector_Transform(&vecs[i], &matWorld); //vecs[i].x += FIX2LONG(pmxWorldToDevice->fxDx) * (1 << 16); //vecs[i].y += FIX2LONG(pmxWorldToDevice->fxDy) * (1 << 16); vecs[i].x += (Start.x << 16) + (XStart64 << 10); vecs[i].y += (Start.y << 16) + (YStart64 << 10); - vecs[i].x >>= 16; - vecs[i].y >>= 16; - vecs[i].x = (vecs[i].x - pdcattr->ptlWindowOrg.x) * pdcattr->szlViewportExt.cx / - pdcattr->szlWindowExt.cx + pdcattr->ptlViewportOrg.x; - vecs[i].y = (vecs[i].y - pdcattr->ptlWindowOrg.y) * pdcattr->szlViewportExt.cy / - pdcattr->szlWindowExt.cy + pdcattr->ptlViewportOrg.y; - vecs[i].x += dc->ptlDCOrig.x; - vecs[i].y += dc->ptlDCOrig.y; + pt.x = vecs[i].x >> 16; + pt.y = vecs[i].y >> 16; + IntLPtoDP(dc, &pt, 1); + //vecs[i].x = (vecs[i].x - pdcattr->ptlWindowOrg.x) * pdcattr->szlViewportExt.cx / + // pdcattr->szlWindowExt.cx + pdcattr->ptlViewportOrg.x; + //vecs[i].y = (vecs[i].y - pdcattr->ptlWindowOrg.y) * pdcattr->szlViewportExt.cy / + // pdcattr->szlWindowExt.cy + pdcattr->ptlViewportOrg.y; + vecs[i].x = pt.x + dc->ptlDCOrig.x; + vecs[i].y = pt.y + dc->ptlDCOrig.y; } vecs[2].x += DeltaX64 >> 6; vecs[2].y += DeltaY64 >> 6; // upper right From 179ecde113680f0020581436c7c6278dea40975a Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 21:50:58 +0900 Subject: [PATCH 13/24] trim --- win32ss/gdi/ntgdi/freetype.c | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 3e47c5f9916..b5285444a1d 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -693,18 +693,6 @@ VOID FASTCALL IntEscapeMatrix(FT_Matrix *pmat, LONG lfEscapement) pmat->yy = pmat->xx; } -#if 0 -VOID FASTCALL IntViewportMatrix(FT_Matrix *pmat, PDC_ATTR pdcattr) -{ - ASSERT(pdcattr->szlWindowExt.cx != 0); - ASSERT(pdcattr->szlWindowExt.cy != 0); - pmat->xx = (1 << 16) * pdcattr->szlViewportExt.cx / pdcattr->szlWindowExt.cx; - pmat->yx = 0; - pmat->xy = 0; - pmat->yy = (1 << 16) * pdcattr->szlViewportExt.cy / pdcattr->szlWindowExt.cy; -} -#endif - VOID FASTCALL FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx) { @@ -5749,14 +5737,9 @@ GreExtTextOutW( matWorld.xy = -matWorld.xy; FT_Matrix_Multiply(&matWorld, &mat); - //IntViewportMatrix(&matViewport, pdcattr); - //FT_Matrix_Multiply(&matViewport, &mat); - FT_Set_Transform(face, &mat, NULL); - /* - * Calculate displacement of the text. - */ + // Calculate displacement of the text. DxShift = fuOptions & ETO_PDY ? 1 : 0; use_kerning = FT_HAS_KERNING(face); previous = 0; @@ -5833,9 +5816,7 @@ GreExtTextOutW( DeltaY64 = TextTop64; } - /* - * Process the horizontal alignment and modify XStart accordingly. - */ + // Process the X and Y alignments. if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER) { XStart64 = -DeltaX64 / 2; @@ -5914,8 +5895,6 @@ GreExtTextOutW( // invert y axis IntEscapeMatrix(&matEscape, -lfEscapement); - //matWorld.yx = -matWorld.yx; - //matWorld.xy = -matWorld.xy; // convert vecs for (i = 0; i < 9; ++i) @@ -5923,18 +5902,11 @@ GreExtTextOutW( POINT pt; FT_Vector_Transform(&vecs[i], &matWidth); FT_Vector_Transform(&vecs[i], &matEscape); - //FT_Vector_Transform(&vecs[i], &matWorld); - //vecs[i].x += FIX2LONG(pmxWorldToDevice->fxDx) * (1 << 16); - //vecs[i].y += FIX2LONG(pmxWorldToDevice->fxDy) * (1 << 16); vecs[i].x += (Start.x << 16) + (XStart64 << 10); vecs[i].y += (Start.y << 16) + (YStart64 << 10); pt.x = vecs[i].x >> 16; pt.y = vecs[i].y >> 16; IntLPtoDP(dc, &pt, 1); - //vecs[i].x = (vecs[i].x - pdcattr->ptlWindowOrg.x) * pdcattr->szlViewportExt.cx / - // pdcattr->szlWindowExt.cx + pdcattr->ptlViewportOrg.x; - //vecs[i].y = (vecs[i].y - pdcattr->ptlWindowOrg.y) * pdcattr->szlViewportExt.cy / - // pdcattr->szlWindowExt.cy + pdcattr->ptlViewportOrg.y; vecs[i].x = pt.x + dc->ptlDCOrig.x; vecs[i].y = pt.y + dc->ptlDCOrig.y; } @@ -6002,9 +5974,7 @@ GreExtTextOutW( EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0); EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0); - /* - * The main rendering loop. - */ + // The main rendering loop. bResult = TRUE; TextLeft64 = vecs[4].x << 6; TextTop64 = vecs[4].y << 6; From 3573bb978a31c834c55ab2ac8dae2a8ce338cb2e Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 14 Jan 2019 22:01:13 +0900 Subject: [PATCH 14/24] trivial --- win32ss/gdi/ntgdi/freetype.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index b5285444a1d..5a1222589fd 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5939,6 +5939,10 @@ GreExtTextOutW( Rect.bottom = max(Rect.bottom, vecs[i].y); } } + else + { + // FIXME: Use pts[0] ... pts[3] and EngFillPath + } if (dc->fs & (DC_ACCUM_APP | DC_ACCUM_WMGR)) { From 8df0fa4afa24f3a2316dac0f9c243f1d546a5ae1 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:06:20 +0900 Subject: [PATCH 15/24] trivial 2 --- win32ss/gdi/ntgdi/freetype.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 5a1222589fd..ae344437ee4 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5927,10 +5927,8 @@ GreExtTextOutW( if ((mat.xy == 0 && mat.yx == 0) || (mat.xx == 0 && mat.yy == 0)) { - Rect.left = MAXLONG; - Rect.top = MAXLONG; - Rect.right = MINLONG; - Rect.bottom = MINLONG; + Rect.left = Rect.top = MAXLONG; + Rect.right = Rect.bottom = MINLONG; for (i = 0; i < 4; ++i) { Rect.left = min(Rect.left, vecs[i].x); From ac12167d267899c230f659314a1112fdd41345e4 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:07:14 +0900 Subject: [PATCH 16/24] displacement calc condition --- win32ss/gdi/ntgdi/freetype.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index ae344437ee4..63d6237c550 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5745,7 +5745,8 @@ GreExtTextOutW( previous = 0; if ((fuOptions & ETO_OPAQUE) || (pdcattr->lTextAlign & (TA_CENTER | TA_RIGHT)) || - lfEscapement || plf->lfUnderline || plf->lfStrikeOut) + memcmp(&mat, &identityMat, sizeof(mat)) != 0 || + plf->lfUnderline || plf->lfStrikeOut) { TextLeft64 = TextTop64 = 0; for (i = 0; i < Count; ++i) From 159dc58f23bba56d1a89dbddd30ac16c94f01cf3 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:07:56 +0900 Subject: [PATCH 17/24] trivial 3 --- win32ss/gdi/ntgdi/freetype.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 63d6237c550..f2d2e90ddb3 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -6220,8 +6220,7 @@ GreExtTextOutW( &dc->eboText.BrushObject, vecs[7].x + i, vecs[7].y, vecs[8].x + i, vecs[8].y, - NULL, - ROP2_TO_MIX(R2_COPYPEN)); + NULL, ROP2_TO_MIX(R2_COPYPEN)); } } } From 6697248b3e8290c2665011be79d007028b1dc602 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:11:13 +0900 Subject: [PATCH 18/24] optimize XFORMOBJ_iSetXform --- win32ss/gdi/ntgdi/xformobj.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/win32ss/gdi/ntgdi/xformobj.c b/win32ss/gdi/ntgdi/xformobj.c index e60ead3ac97..0d938df687e 100644 --- a/win32ss/gdi/ntgdi/xformobj.c +++ b/win32ss/gdi/ntgdi/xformobj.c @@ -150,19 +150,20 @@ XFORMOBJ_iSetXform( IN const XFORML *pxform) { PMATRIX pmx = XFORMOBJ_pmx(pxo); - FLOATOBJ ef1, ef2, ef3, ef4; + FLOATOBJ ef1, ef2, efTemp; /* Check parameters */ if (!pxo || !pxform) return DDI_ERROR; - /* eM11 * eM22 - eM12 * eM21 != 0 */ + /* Check if the xform is valid */ + /* M11 * M22 - M12 * M21 != 0 */ FLOATOBJ_SetFloat(&ef1, pxform->eM11); - FLOATOBJ_SetFloat(&ef2, pxform->eM22); - FLOATOBJ_Mul(&ef1, &ef2); - FLOATOBJ_SetFloat(&ef3, pxform->eM12); - FLOATOBJ_SetFloat(&ef4, pxform->eM21); - FLOATOBJ_Mul(&ef3, &ef4); - if (FLOATOBJ_Equal(&ef1, &ef3)) + FLOATOBJ_SetFloat(&efTemp, pxform->eM22); + FLOATOBJ_Mul(&ef1, &efTemp); + FLOATOBJ_SetFloat(&ef2, pxform->eM12); + FLOATOBJ_SetFloat(&efTemp, pxform->eM21); + FLOATOBJ_Mul(&ef2, &efTemp); + if (FLOATOBJ_Equal(&ef1, &ef2)) return DDI_ERROR; /* Copy members */ From a0cc284fc9b984ffea148cda953aadfade463a63 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:14:12 +0900 Subject: [PATCH 19/24] optimize displacement calculation --- win32ss/gdi/ntgdi/freetype.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index f2d2e90ddb3..848b63b343c 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5748,7 +5748,7 @@ GreExtTextOutW( memcmp(&mat, &identityMat, sizeof(mat)) != 0 || plf->lfUnderline || plf->lfStrikeOut) { - TextLeft64 = TextTop64 = 0; + DeltaX64 = DeltaY64 = 0; for (i = 0; i < Count; ++i) { glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); @@ -5782,39 +5782,36 @@ GreExtTextOutW( { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, 0, &delta); - TextLeft64 += delta.x; - TextTop64 -= delta.y; + DeltaX64 += delta.x; + DeltaY64 -= delta.y; } if (Dx == NULL) { - TextLeft64 += realglyph->root.advance.x >> 10; - TextTop64 -= realglyph->root.advance.y >> 10; + DeltaX64 += realglyph->root.advance.x >> 10; + DeltaY64 -= realglyph->root.advance.y >> 10; } else { - // FIXME this should probably be a matrix transform with TextTop64 as well. + // FIXME this should probably be a matrix transform with DeltaY64 as well. Scale = pdcattr->mxWorldToDevice.efM11; if (FLOATOBJ_Equal0(&Scale)) FLOATOBJ_Set1(&Scale); /* do the shift before multiplying to preserve precision */ FLOATOBJ_MulLong(&Scale, Dx[i << DxShift] << 6); - TextLeft64 += FLOATOBJ_GetLong(&Scale); + DeltaX64 += FLOATOBJ_GetLong(&Scale); } if (DxShift) { - TextTop64 -= Dx[2 * i + 1] << 6; + DeltaY64 -= Dx[2 * i + 1] << 6; } previous = glyph_index; FT_Done_Glyph((FT_Glyph)realglyph); } - - DeltaX64 = TextLeft64; - DeltaY64 = TextTop64; } // Process the X and Y alignments. From c0f193255e45bbbf450b757780aa26e63042a0ca Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:15:11 +0900 Subject: [PATCH 20/24] trivial 4 --- win32ss/gdi/ntgdi/freetype.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 848b63b343c..ffc14724607 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5612,9 +5612,7 @@ GreExtTextOutW( { Start.x = pdcattr->ptlCurrent.x; Start.y = pdcattr->ptlCurrent.y; - } - else - { + } else { Start.x = XStart; Start.y = YStart; } From ce3b724dbca917f164ca4586cf0d9618f4d5f28f Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:18:10 +0900 Subject: [PATCH 21/24] trivial 5 --- win32ss/gdi/ntgdi/freetype.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index ffc14724607..eb03a5ddd8e 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -6166,11 +6166,9 @@ GreExtTextOutW( if (plf->lfUnderline) { - INT i; for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) { - LONG dx = (LONG)(DeltaX64 >> 6); - LONG dy = (LONG)(DeltaY64 >> 6); + LONG dx = (LONG)(DeltaX64 >> 6), dy = (LONG)(DeltaY64 >> 6); if (labs(dx) > labs(dy)) { // move vertical @@ -6194,11 +6192,9 @@ GreExtTextOutW( if (plf->lfStrikeOut) { - INT i; for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) { - LONG dx = (LONG)(DeltaX64 >> 6); - LONG dy = (LONG)(DeltaY64 >> 6); + LONG dx = (LONG)(DeltaX64 >> 6), dy = (LONG)(DeltaY64 >> 6); if (labs(dx) > labs(dy)) { // move vertical From 95b7b338188f4b68eb15a0fa3844a27bd81eea66 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:32:37 +0900 Subject: [PATCH 22/24] bNeedCache --- win32ss/gdi/ntgdi/freetype.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index eb03a5ddd8e..0accf459715 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5979,9 +5979,11 @@ GreExtTextOutW( previous = 0; for (i = 0; i < Count; ++i) { + BOOL bNeedCache = (!EmuBold && !EmuItalic && + memcmp(&mat, &identityMat, sizeof(mat)) == 0); glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); realglyph = NULL; - if (!EmuBold && !EmuItalic && memcmp(&mat, &identityMat, sizeof(mat)) == 0) + if (bNeedCache) { realglyph = ftGdiGlyphCacheGet(face, glyph_index, plf->lfHeight, RenderMode, pmxWorldToDevice); @@ -5996,11 +5998,23 @@ GreExtTextOutW( break; } glyph = face->glyph; - if (EmuBold) - FT_GlyphSlot_Embolden(glyph); - if (EmuItalic) - FT_GlyphSlot_Oblique(glyph); - realglyph = ftGdiGlyphSet(face, glyph, RenderMode); + if (bNeedCache) + { + realglyph = ftGdiGlyphCacheSet(face, + glyph_index, + plf->lfHeight, + pmxWorldToDevice, + glyph, + RenderMode); + } + else + { + if (EmuBold) + FT_GlyphSlot_Embolden(glyph); + if (EmuItalic) + FT_GlyphSlot_Oblique(glyph); + realglyph = ftGdiGlyphSet(face, glyph, RenderMode); + } if (!realglyph) { DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); @@ -6148,7 +6162,7 @@ GreExtTextOutW( previous = glyph_index; /* No cache, so clean up */ - if (EmuBold || EmuItalic || memcmp(&mat, &identityMat, sizeof(mat)) != 0) + if (!bNeedCache) { FT_Done_Glyph((FT_Glyph)realglyph); } From 9b50172eb7c9a2e236d0cd04f8a3c630ea95b25b Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 09:43:10 +0900 Subject: [PATCH 23/24] fix displacement calculation --- win32ss/gdi/ntgdi/freetype.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 0accf459715..7d5ebbad15c 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5738,6 +5738,7 @@ GreExtTextOutW( FT_Set_Transform(face, &mat, NULL); // Calculate displacement of the text. + DeltaX64 = DeltaY64 = 0; DxShift = fuOptions & ETO_PDY ? 1 : 0; use_kerning = FT_HAS_KERNING(face); previous = 0; @@ -5746,7 +5747,6 @@ GreExtTextOutW( memcmp(&mat, &identityMat, sizeof(mat)) != 0 || plf->lfUnderline || plf->lfStrikeOut) { - DeltaX64 = DeltaY64 = 0; for (i = 0; i < Count; ++i) { glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); From 5f8276c1d126cdee227bd7f23de2196f46218d48 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 15 Jan 2019 10:02:08 +0900 Subject: [PATCH 24/24] trivial 5 --- win32ss/gdi/ntgdi/freetype.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 7d5ebbad15c..d76d63dfea8 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5935,7 +5935,7 @@ GreExtTextOutW( } else { - // FIXME: Use pts[0] ... pts[3] and EngFillPath + // FIXME: Use vecs[0] ... vecs[3] and EngFillPath } if (dc->fs & (DC_ACCUM_APP | DC_ACCUM_WMGR))