https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8f482af0a876d269cca642...
commit 8f482af0a876d269cca64288f114eb1fe1180ef0 Author: Joachim Henze Joachim.Henze@reactos.org AuthorDate: Thu Jun 6 02:24:20 2019 +0200 Commit: Joachim Henze Joachim.Henze@reactos.org CommitDate: Thu Jun 6 02:24:20 2019 +0200
[WIN32SS][FREETYPE] Avoid performance regression CORE-16020
by reverting essential parts of "Font rotation at arbitrary angles" which was once committed in several steps:
Initial commit (PR#1207) 0.4.12-dev-243-g f757a135192c02a3c41d8da47eb9dba21d34ebd1 broke font rendering for GTK apps CORE-15623
Second commit (PR#1238) 0.4.12-dev-558-g 64987cf2731f9762d0316274bf7877a9bd3d88ba restored font rendering in GTK apps but introduced slowdown CORE-16020
Katayama agreed to the temporal revert and will try to come up later with a performance optimized version. We revert in 0.4.12-RC and 0.4.13-dev.
The revert will cause failure-increases in gdi32:TextTransform https://reactos.org/testman/compare.php?ids=67898,67901 --- win32ss/gdi/ntgdi/freetype.c | 475 ++++++++++++++++--------------------------- win32ss/gdi/ntgdi/xformobj.c | 11 +- 2 files changed, 179 insertions(+), 307 deletions(-)
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 3b653270714..6a2fae1ed71 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -740,16 +740,33 @@ FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx) pmat->yy = FLOATOBJ_GetLong(&ef); }
-FORCEINLINE VOID FASTCALL +VOID FtSetCoordinateTransform( FT_Face face, PMATRIX pmx) { - FT_Matrix mat; - FtMatrixFromMx(&mat, pmx); + FT_Matrix ftmatrix; + FLOATOBJ efTemp; + + /* Create a freetype matrix, by converting to 16.16 fixpoint format */ + efTemp = pmx->efM11; + FLOATOBJ_MulLong(&efTemp, 0x00010000); + ftmatrix.xx = FLOATOBJ_GetLong(&efTemp); + + efTemp = pmx->efM12; + FLOATOBJ_MulLong(&efTemp, 0x00010000); + ftmatrix.xy = FLOATOBJ_GetLong(&efTemp); + + efTemp = pmx->efM21; + FLOATOBJ_MulLong(&efTemp, 0x00010000); + ftmatrix.yx = FLOATOBJ_GetLong(&efTemp); + + efTemp = pmx->efM22; + FLOATOBJ_MulLong(&efTemp, 0x00010000); + ftmatrix.yy = FLOATOBJ_GetLong(&efTemp);
/* Set the transformation matrix */ - FT_Set_Transform(face, &mat, 0); + FT_Set_Transform(face, &ftmatrix, 0); }
static BOOL @@ -2855,8 +2872,6 @@ ftGdiGlyphCacheGet( FT_Face Face, INT GlyphIndex, INT Height, - INT Width, - INT Escapement, FT_Render_Mode RenderMode, PMATRIX pmx) { @@ -2873,8 +2888,6 @@ ftGdiGlyphCacheGet( if ((FontEntry->Face == Face) && (FontEntry->GlyphIndex == GlyphIndex) && (FontEntry->Height == Height) && - (FontEntry->Width == Width) && - (FontEntry->Escapement == Escapement) && (FontEntry->RenderMode == RenderMode) && (SameScaleMatrix(&FontEntry->mxWorldToDevice, pmx))) break; @@ -2937,8 +2950,6 @@ ftGdiGlyphCacheSet( FT_Face Face, INT GlyphIndex, INT Height, - INT Width, - INT Escapement, PMATRIX pmx, FT_GlyphSlot GlyphSlot, FT_Render_Mode RenderMode) @@ -2992,8 +3003,6 @@ ftGdiGlyphCacheSet( NewEntry->Face = Face; NewEntry->BitmapGlyph = BitmapGlyph; NewEntry->Height = Height; - NewEntry->Width = Width; - NewEntry->Escapement = Escapement; NewEntry->RenderMode = RenderMode; NewEntry->mxWorldToDevice = *pmx;
@@ -3980,7 +3989,6 @@ TextIntGetTextExtentPoint(PDC dc, realglyph = NULL; else realglyph = ftGdiGlyphCacheGet(face, glyph_index, plf->lfHeight, - plf->lfWidth, plf->lfEscapement, RenderMode, pmxWorldToDevice);
if (EmuBold || EmuItalic || !realglyph) @@ -4006,8 +4014,6 @@ TextIntGetTextExtentPoint(PDC dc, realglyph = ftGdiGlyphCacheSet(face, glyph_index, plf->lfHeight, - plf->lfWidth, - plf->lfEscapement, pmxWorldToDevice, glyph, RenderMode); @@ -5581,14 +5587,6 @@ ScaleLong(LONG lValue, PFLOATOBJ pef) return lValue; }
-FORCEINLINE LONG FASTCALL -IntNormalizeAngle(LONG nTenthAngle) -{ - const LONG nFullAngle = 360 * 10; - nTenthAngle %= nFullAngle; - return (nTenthAngle + nFullAngle) % nFullAngle; -} - BOOL APIENTRY IntExtTextOutW( @@ -5615,14 +5613,15 @@ IntExtTextOutW( FT_Face face; FT_GlyphSlot glyph; FT_BitmapGlyph realglyph; - LONGLONG TextLeft64, TextTop64, TextWidth64, DeltaX64, DeltaY64, XStart64, YStart64; - ULONG previous; + LONGLONG TextLeft, RealXStart; + ULONG TextTop, previous; FT_Bool use_kerning; RECTL DestRect, MaskRect; POINTL SourcePoint, BrushOrigin; HBITMAP HSourceGlyph; SURFOBJ *SourceGlyphSurf; SIZEL bitSize; + INT yoff; FONTOBJ *FontObj; PFONTGDI FontGDI; PTEXTOBJ TextObj = NULL; @@ -5633,15 +5632,13 @@ IntExtTextOutW( BOOL DoBreak = FALSE; USHORT DxShift; PMATRIX pmxWorldToDevice; - LONG lfEscapement, lfWidth; + LONG fixAscender, fixDescender; FLOATOBJ Scale; LOGFONTW *plf; BOOL EmuBold, EmuItalic; int thickness; BOOL bResult; - FT_Matrix mat = identityMat, matWidth, matEscape, matWorld; - FT_Vector vecs[9]; - BOOL bNeedCache; + ULONGLONG TextWidth;
/* Check if String is valid */ if ((Count > 0xFFFF) || (Count > 0 && String == NULL)) @@ -5681,16 +5678,19 @@ IntExtTextOutW( IntLPtoDP(dc, (POINT *)lprc, 2); }
- if (pdcattr->flTextAlign & TA_UPDATECP) - { - IntGetCurrentPositionEx(dc, &Start); - } - else + if (pdcattr->lTextAlign & TA_UPDATECP) { + Start.x = pdcattr->ptlCurrent.x; + Start.y = pdcattr->ptlCurrent.y; + } else { Start.x = XStart; Start.y = YStart; }
+ IntLPtoDP(dc, &Start, 1); + RealXStart = ((LONGLONG)Start.x + dc->ptlDCOrig.x) << 6; + YStart = Start.y + dc->ptlDCOrig.y; + SourcePoint.x = 0; SourcePoint.y = 0; MaskRect.left = 0; @@ -5765,15 +5765,6 @@ IntExtTextOutW( plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; EmuBold = (plf->lfWeight >= FW_BOLD && FontGDI->OriginalWeight <= FW_NORMAL); EmuItalic = (plf->lfItalic && !FontGDI->OriginalItalic); - if (FT_IS_SCALABLE(face)) - { - lfEscapement = IntNormalizeAngle(plf->lfEscapement); - lfWidth = labs(plf->lfWidth); - } - else - { - lfEscapement = lfWidth = 0; - }
if (Render) RenderMode = IntGetFontRenderMode(plf); @@ -5787,22 +5778,53 @@ IntExtTextOutW( goto Cleanup; }
- FT_Set_Transform(face, NULL, NULL); + /* NOTE: Don't trust face->size->metrics.ascender and descender values. */ + if (dc->pdcattr->iGraphicsMode == GM_ADVANCED) + { + pmxWorldToDevice = DC_pmxWorldToDevice(dc); + FtSetCoordinateTransform(face, pmxWorldToDevice);
- // Calculate the text width. - TextWidth64 = 0; + fixAscender = ScaleLong(FontGDI->tmAscent, &pmxWorldToDevice->efM22) << 6; + fixDescender = ScaleLong(FontGDI->tmDescent, &pmxWorldToDevice->efM22) << 6; + } + else + { + pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault; + FtSetCoordinateTransform(face, pmxWorldToDevice); + + fixAscender = FontGDI->tmAscent << 6; + fixDescender = FontGDI->tmDescent << 6; + } + + /* + * Process the vertical alignment and determine the yoff. + */ +#define VALIGN_MASK (TA_TOP | TA_BASELINE | TA_BOTTOM) + if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BASELINE) + yoff = 0; + else if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BOTTOM) + yoff = -(fixDescender >> 6); + else /* TA_TOP */ + yoff = fixAscender >> 6; +#undef VALIGN_MASK + + /* + * Calculate width of the text. + */ + TextWidth = 0; DxShift = fuOptions & ETO_PDY ? 1 : 0; use_kerning = FT_HAS_KERNING(face); previous = 0; if ((fuOptions & ETO_OPAQUE) || - (pdcattr->flTextAlign & (TA_CENTER | TA_RIGHT)) || - memcmp(&mat, &identityMat, sizeof(mat)) != 0 || - plf->lfUnderline || plf->lfStrikeOut) + (pdcattr->lTextAlign & (TA_CENTER | TA_RIGHT))) { + TextLeft = RealXStart; + TextTop = YStart; for (i = 0; i < Count; ++i) { glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions);
+ // FIXME: Use FT_LOAD_BITMAP_METRICS_ONLY or cache. error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); if (error) { @@ -5831,68 +5853,51 @@ IntExtTextOutW( { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, 0, &delta); - TextWidth64 += delta.x; + TextLeft += delta.x; }
if (Dx == NULL) { - TextWidth64 += realglyph->root.advance.x >> 10; + TextLeft += realglyph->root.advance.x >> 10; } else { - // FIXME this should probably be a matrix transform with DeltaY64 as well. + // FIXME this should probably be a matrix transform with TextTop 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); - TextWidth64 += FLOATOBJ_GetLong(&Scale); + TextLeft += FLOATOBJ_GetLong(&Scale); + } + + if (DxShift) + { + TextTop -= Dx[2 * i + 1] << 6; }
previous = glyph_index;
FT_Done_Glyph((FT_Glyph)realglyph); } - }
- /* NOTE: Don't trust face->size->metrics.ascender and descender values. */ - if (lfWidth) - { - lfWidth = IntWidthMatrix(face, &matWidth, lfWidth); - FT_Matrix_Multiply(&matWidth, &mat); + TextWidth = TextLeft - RealXStart; }
- if (lfEscapement) - { - IntEscapeMatrix(&matEscape, lfEscapement); - FT_Matrix_Multiply(&matEscape, &mat); - } - - DC_vUpdateWorldToDevice(dc); - if (dc->pdcattr->iGraphicsMode == GM_ADVANCED) + /* + * Process the horizontal alignment and modify XStart accordingly. + */ + if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER) { - pmxWorldToDevice = DC_pmxWorldToDevice(dc); + RealXStart -= TextWidth / 2; } - else + else if ((pdcattr->lTextAlign & TA_RIGHT) == TA_RIGHT) { - pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault; + RealXStart -= TextWidth; + if (((RealXStart + TextWidth + 32) >> 6) <= Start.x + dc->ptlDCOrig.x) + RealXStart += 1 << 6; } - FtMatrixFromMx(&matWorld, pmxWorldToDevice); - matWorld.xy = -matWorld.xy; - matWorld.yx = -matWorld.yx; - FT_Matrix_Multiply(&matWorld, &mat); - - vecs[0].x = TextWidth64 << 10; - vecs[0].y = 0; - FT_Vector_Transform(&vecs[0], &mat); - DeltaX64 = vecs[0].x >> 10; - DeltaY64 = -vecs[0].y >> 10; - - XStart64 = (Start.x << 6); - YStart64 = (Start.y << 6); - - FT_Set_Transform(face, &mat, NULL);
psurf = dc->dclevel.pSurface; SurfObj = &psurf->SurfObj ; @@ -5900,11 +5905,14 @@ IntExtTextOutW( if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND)) DC_vUpdateBackgroundBrush(dc) ;
- if (dc->pdcattr->ulDirty_ & DIRTY_TEXT) + if(dc->pdcattr->ulDirty_ & DIRTY_TEXT) DC_vUpdateTextBrush(dc) ;
- thickness = 1; - if (face->units_per_EM) + if (!face->units_per_EM) + { + thickness = 1; + } + else { thickness = face->underline_thickness * face->size->metrics.y_ppem / face->units_per_EM; @@ -5912,111 +5920,15 @@ IntExtTextOutW( thickness = 1; }
- /* Process the vertical alignment */ -#define VALIGN_MASK (TA_TOP | TA_BASELINE | TA_BOTTOM) - RtlZeroMemory(vecs, sizeof(vecs)); - if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BASELINE) - { - vecs[1].y = -FontGDI->tmAscent << 16; // upper left - vecs[4].y = 0; // baseline - vecs[0].y = FontGDI->tmDescent << 16; // lower left - } - else if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BOTTOM) - { - vecs[1].y = -FontGDI->tmHeight << 16; // upper left - vecs[4].y = -FontGDI->tmDescent << 16; // baseline - vecs[0].y = 0; // lower left - } - else /* TA_TOP */ - { - vecs[1].y = 0; // upper left - vecs[4].y = FontGDI->tmAscent << 16; // baseline - vecs[0].y = FontGDI->tmHeight << 16; // lower left - } - vecs[2] = vecs[1]; - vecs[2].x += (TextWidth64 << 10); // upper right - vecs[3] = vecs[0]; - vecs[3].x += (TextWidth64 << 10); // lower right -#undef VALIGN_MASK - - // underline - if (plf->lfUnderline) - { - int position = 0; - if (face->units_per_EM) - { - 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[6].x += (TextWidth64 << 10); - } - - // strike through - if (plf->lfStrikeOut) - { - vecs[7].y = vecs[8].y = vecs[4].y - ((FontGDI->tmAscent / 3) << 16); - vecs[8].x += (TextWidth64 << 10); - } - - if (lfEscapement) - { - // invert y axis - IntEscapeMatrix(&matEscape, -lfEscapement); - } - - // convert vecs - for (i = 0; i < 9; ++i) - { - if (lfWidth) - { - FT_Vector_Transform(&vecs[i], &matWidth); - } - if (lfEscapement) - { - FT_Vector_Transform(&vecs[i], &matEscape); - } - vecs[i].x += (XStart64 << 10); - vecs[i].y += (YStart64 << 10); - vecs[i].x >>= 16; - vecs[i].y >>= 16; - IntLPtoDP(dc, &vecs[i], 1); - if ((pdcattr->flTextAlign & TA_CENTER) == TA_CENTER) - { - vecs[i].x -= (DeltaX64 >> 6) / 2; - vecs[i].y -= (DeltaY64 >> 6) / 2; - } - else if ((pdcattr->flTextAlign & TA_RIGHT) == TA_RIGHT) - { - vecs[i].x -= (DeltaX64 >> 6); - vecs[i].y -= (DeltaY64 >> 6); - } - vecs[i].x += dc->ptlDCOrig.x; - vecs[i].y += dc->ptlDCOrig.y; - } - if (fuOptions & ETO_OPAQUE) { /* Draw background */ RECTL Rect; - RtlZeroMemory(&Rect, sizeof(Rect));
- if ((mat.xy == 0 && mat.yx == 0) || (mat.xx == 0 && mat.yy == 0)) - { - Rect.left = Rect.top = MAXLONG; - Rect.right = 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); - } - } - else - { - // FIXME: Use vecs[0] ... vecs[3] and EngFillPath - } + Rect.left = (RealXStart + 32) >> 6; + Rect.top = TextTop + yoff - ((fixAscender + 32) >> 6); + Rect.right = (RealXStart + TextWidth + 32) >> 6; + Rect.bottom = Rect.top + ((fixAscender + fixDescender) >> 6);
if (dc->fs & (DC_ACCUM_APP | DC_ACCUM_WMGR)) { @@ -6052,22 +5964,24 @@ IntExtTextOutW( EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0); EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
- // The main rendering loop. + /* Assume success */ bResult = TRUE; - TextLeft64 = vecs[4].x << 6; - TextTop64 = vecs[4].y << 6; + + /* + * The main rendering loop. + */ + TextLeft = RealXStart; + TextTop = YStart; previous = 0; - bNeedCache = (!EmuBold && !EmuItalic); for (i = 0; i < Count; ++i) { glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); - realglyph = NULL; - if (bNeedCache) - { + + if (EmuBold || EmuItalic) + realglyph = NULL; + else realglyph = ftGdiGlyphCacheGet(face, glyph_index, plf->lfHeight, - lfWidth, lfEscapement, RenderMode, pmxWorldToDevice); - } if (!realglyph) { error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); @@ -6077,17 +5991,9 @@ IntExtTextOutW( bResult = FALSE; break; } + glyph = face->glyph; - if (bNeedCache) - { - realglyph = ftGdiGlyphCacheSet(face, - glyph_index, - plf->lfHeight, lfWidth, lfEscapement, - pmxWorldToDevice, - glyph, - RenderMode); - } - else + if (EmuBold || EmuItalic) { if (EmuBold) FT_GlyphSlot_Embolden(glyph); @@ -6095,6 +6001,15 @@ IntExtTextOutW( FT_GlyphSlot_Oblique(glyph); realglyph = ftGdiGlyphSet(face, glyph, RenderMode); } + else + { + realglyph = ftGdiGlyphCacheSet(face, + glyph_index, + plf->lfHeight, + pmxWorldToDevice, + glyph, + RenderMode); + } if (!realglyph) { DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); @@ -6108,16 +6023,15 @@ IntExtTextOutW( { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, 0, &delta); - TextLeft64 += delta.x; - TextTop64 -= delta.y; + TextLeft += delta.x; } - DPRINT("TextLeft64: %I64d\n", TextLeft64); - DPRINT("TextTop64: %I64d\n", TextTop64); + DPRINT("TextLeft: %I64d\n", TextLeft); + DPRINT("TextTop: %lu\n", TextTop); DPRINT("Advance: %d\n", realglyph->root.advance.x);
- DestRect.left = ((TextLeft64 + 32) >> 6) + realglyph->left; + DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left; DestRect.right = DestRect.left + realglyph->bitmap.width; - DestRect.top = ((TextTop64 + 32) >> 6) - realglyph->top; + DestRect.top = TextTop + yoff - realglyph->top; DestRect.bottom = DestRect.top + realglyph->bitmap.rows;
bitSize.cx = realglyph->bitmap.width; @@ -6214,115 +6128,82 @@ IntExtTextOutW( break; }
+ if (plf->lfUnderline) + { + int i, position; + if (!face->units_per_EM) + { + position = 0; + } + else + { + position = face->underline_position * + face->size->metrics.y_ppem / face->units_per_EM; + } + for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) + { + EngLineTo(SurfObj, + (CLIPOBJ *)&dc->co, + &dc->eboText.BrushObject, + (TextLeft >> 6), + TextTop + yoff - position + i, + ((TextLeft + (realglyph->root.advance.x >> 10)) >> 6), + TextTop + yoff - position + i, + NULL, + ROP2_TO_MIX(R2_COPYPEN)); + } + } + if (plf->lfStrikeOut) + { + int i; + for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) + { + EngLineTo(SurfObj, + (CLIPOBJ *)&dc->co, + &dc->eboText.BrushObject, + (TextLeft >> 6), + TextTop + yoff - (fixAscender >> 6) / 3 + i, + ((TextLeft + (realglyph->root.advance.x >> 10)) >> 6), + TextTop + yoff - (fixAscender >> 6) / 3 + i, + NULL, + ROP2_TO_MIX(R2_COPYPEN)); + } + } + if (NULL == Dx) { - TextLeft64 += realglyph->root.advance.x >> 10; - TextTop64 -= realglyph->root.advance.y >> 10; - DPRINT("New TextLeft64: %I64d\n", TextLeft64); - DPRINT("New TextTop64: %I64d\n", TextTop64); + TextLeft += realglyph->root.advance.x >> 10; + DPRINT("New TextLeft: %I64d\n", TextLeft); } else { - // FIXME this should probably be a matrix transform with TextTop64 as well. + // FIXME this should probably be a matrix transform with TextTop 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); - DPRINT("New TextLeft64 2: %I64d\n", TextLeft64); + TextLeft += FLOATOBJ_GetLong(&Scale); + DPRINT("New TextLeft2: %I64d\n", TextLeft); }
if (DxShift) { - TextTop64 -= Dx[2 * i + 1] << 6; + TextTop -= Dx[2 * i + 1] << 6; }
previous = glyph_index;
/* No cache, so clean up */ - if (!bNeedCache) + if (EmuBold || EmuItalic) { FT_Done_Glyph((FT_Glyph)realglyph); } }
- if (plf->lfUnderline || plf->lfStrikeOut) - { - 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) - { - for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) - { - LONG dx = (LONG)(DeltaX64 >> 6), dy = (LONG)(DeltaY64 >> 6); - if (labs(dx) > labs(dy)) - { - // move vertical - EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, - &dc->eboText.BrushObject, - vecs[5].x, vecs[5].y + i, - vecs[6].x, vecs[6].y + i, - NULL, ROP2_TO_MIX(R2_COPYPEN)); - } - else - { - // move horizontal - EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, - &dc->eboText.BrushObject, - vecs[5].x + i, vecs[5].y, - vecs[6].x + i, vecs[6].y, - NULL, ROP2_TO_MIX(R2_COPYPEN)); - } - } - } - - if (plf->lfStrikeOut) - { - for (i = -thickness / 2; i < -thickness / 2 + thickness; ++i) - { - LONG dx = (LONG)(DeltaX64 >> 6), dy = (LONG)(DeltaY64 >> 6); - if (labs(dx) > labs(dy)) - { - // move vertical - EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, - &dc->eboText.BrushObject, - vecs[7].x, vecs[7].y + i, - vecs[8].x, vecs[8].y + i, - NULL, ROP2_TO_MIX(R2_COPYPEN)); - } - else - { - // move horizontal - EngLineTo(SurfObj, (CLIPOBJ *)&dc->co, - &dc->eboText.BrushObject, - vecs[7].x + i, vecs[7].y, - vecs[8].x + i, vecs[8].y, - NULL, ROP2_TO_MIX(R2_COPYPEN)); - } - } - } - - if (plf->lfUnderline || plf->lfStrikeOut) - { - if (dc->dctype == DCTYPE_DIRECT) - MouseSafetyOnDrawEnd(dc->ppdev); - } - - if (pdcattr->flTextAlign & TA_UPDATECP) - { - pdcattr->ptlCurrent.x = vecs[2].x - dc->ptlDCOrig.x; - pdcattr->ptlCurrent.y = vecs[2].y - dc->ptlDCOrig.y; - IntDPtoLP(dc, &pdcattr->ptlCurrent, 1); - pdcattr->ulDirty_ &= ~DIRTY_PTLCURRENT; - pdcattr->ulDirty_ |= (DIRTY_PTFXCURRENT | DIRTY_STYLESTATE); + if (pdcattr->lTextAlign & TA_UPDATECP) { + pdcattr->ptlCurrent.x = DestRect.right - dc->ptlDCOrig.x; }
IntUnLockFreeType(); diff --git a/win32ss/gdi/ntgdi/xformobj.c b/win32ss/gdi/ntgdi/xformobj.c index 02216a58591..fccf5517b38 100644 --- a/win32ss/gdi/ntgdi/xformobj.c +++ b/win32ss/gdi/ntgdi/xformobj.c @@ -151,21 +151,12 @@ XFORMOBJ_iSetXform( IN const XFORML *pxform) { PMATRIX pmx = XFORMOBJ_pmx(pxo); - FLOATOBJ ef1, ef2, efTemp;
/* Check parameters */ if (!pxo || !pxform) return DDI_ERROR;
/* Check if the xform is valid */ - /* M11 * M22 - M12 * M21 != 0 */ - FLOATOBJ_SetFloat(&ef1, pxform->eM11); - 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; + if ((pxform->eM11 == 0) || (pxform->eM22 == 0)) return DDI_ERROR;
/* Copy members */ FLOATOBJ_SetFloat(&pmx->efM11, pxform->eM11);