https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b5478a7873d48c678ef9c3...
commit b5478a7873d48c678ef9c344f45ffe0b1c0e4989 Author: Joachim Henze Joachim.Henze@reactos.org AuthorDate: Sun Jul 7 20:50:30 2019 +0200 Commit: Joachim Henze Joachim.Henze@reactos.org CommitDate: Sun Jul 7 20:50:30 2019 +0200
[WIN32SS][FREETYPE] Fix performance regression FreeBASIC console output CORE-16177
By restoring historic state of GreExtTextOutW() / IntExtTextOutW()
This reverts guilty rev 0.4.12-dev-190-g d6cfeaef5105dc6db2f12682bc48f17f9caacdcc as well as some follow ups that dealt with new errors popping up afterwards. The revert got ack of Katayama Hirofumi MZ.
Test VBox on master: https://reactos.org/testman/compare.php?ids=68471,68475 Test KVM on master: https://reactos.org/testman/compare.php?ids=68472,68476
Analog revert was applied before to 0.4.12-RC-42-g 021f498cb2bf50ea210696431786d24536da2691 --- win32ss/gdi/ntgdi/freetype.c | 320 ++++++++++++++++++++++++++++--------------- 1 file changed, 209 insertions(+), 111 deletions(-)
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 027ccdb66e2..854085d01e0 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -5618,7 +5618,7 @@ IntExtTextOutW( FT_GlyphSlot glyph; FT_BitmapGlyph realglyph; LONGLONG TextLeft, RealXStart; - ULONG TextTop, previous; + ULONG TextTop, previous, BackgroundLeft; FT_Bool use_kerning; RECTL DestRect, MaskRect; POINTL SourcePoint, BrushOrigin; @@ -5642,7 +5642,6 @@ IntExtTextOutW( BOOL EmuBold, EmuItalic; int thickness; BOOL bResult; - ULONGLONG TextWidth;
/* Check if String is valid */ if ((Count > 0xFFFF) || (Count > 0 && String == NULL)) @@ -5812,29 +5811,145 @@ IntExtTextOutW( yoff = fixAscender >> 6; #undef VALIGN_MASK
+ use_kerning = FT_HAS_KERNING(face); + previous = 0; + /* - * Calculate width of the text. + * Process the horizontal alignment and modify XStart accordingly. */ - TextWidth = 0; DxShift = fuOptions & ETO_PDY ? 1 : 0; - use_kerning = FT_HAS_KERNING(face); - previous = 0; - if ((fuOptions & ETO_OPAQUE) || - (pdcattr->lTextAlign & (TA_CENTER | TA_RIGHT))) + if (pdcattr->lTextAlign & (TA_RIGHT | TA_CENTER)) { + ULONGLONG TextWidth = 0; + LPCWSTR TempText = String; + int iStart; + + /* + * Calculate width of the text. + */ + + if (NULL != Dx) + { + iStart = Count < 2 ? 0 : Count - 2; + TextWidth = Count < 2 ? 0 : (Dx[(Count-2)<<DxShift] << 6); + } + else + { + iStart = 0; + } + TempText = String + iStart; + + for (i = iStart; i < Count; i++) + { + glyph_index = get_glyph_index_flagged(face, *TempText, ETO_GLYPH_INDEX, fuOptions); + + if (EmuBold || EmuItalic) + realglyph = NULL; + else + realglyph = ftGdiGlyphCacheGet(face, glyph_index, plf->lfHeight, + RenderMode, pmxWorldToDevice); + if (!realglyph) + { + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); + if (error) + { + DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n", glyph_index); + } + + glyph = face->glyph; + if (EmuBold || EmuItalic) + { + 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 (!realglyph) + { + DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); + IntUnLockFreeType(); + goto Cleanup; + } + + } + /* Retrieve kerning distance */ + if (use_kerning && previous && glyph_index) + { + FT_Vector delta; + FT_Get_Kerning(face, previous, glyph_index, 0, &delta); + TextWidth += delta.x; + } + + TextWidth += realglyph->root.advance.x >> 10; + + if (EmuBold || EmuItalic) + { + FT_Done_Glyph((FT_Glyph)realglyph); + realglyph = NULL; + } + + previous = glyph_index; + TempText++; + } + + previous = 0; + + if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER) + { + RealXStart -= TextWidth / 2; + } + else + { + RealXStart -= TextWidth; + } + } + + psurf = dc->dclevel.pSurface; + SurfObj = &psurf->SurfObj ; + + if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND)) + DC_vUpdateBackgroundBrush(dc) ; + + if(dc->pdcattr->ulDirty_ & DIRTY_TEXT) + DC_vUpdateTextBrush(dc) ; + + if (!face->units_per_EM) + { + thickness = 1; + } + else + { + thickness = face->underline_thickness * + face->size->metrics.y_ppem / face->units_per_EM; + if (thickness <= 0) + thickness = 1; + } + + if ((fuOptions & ETO_OPAQUE) && plf->lfItalic) + { + /* Draw background */ TextLeft = RealXStart; TextTop = YStart; + BackgroundLeft = (RealXStart + 32) >> 6; 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) { - DPRINT1("Failed to load glyph! [index: %d]\n", glyph_index); + DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index); IntUnLockFreeType(); - bResult = FALSE; goto Cleanup; }
@@ -5848,21 +5963,58 @@ IntExtTextOutW( { DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); IntUnLockFreeType(); - bResult = FALSE; goto Cleanup; }
/* retrieve kerning distance and move pen position */ - if (use_kerning && previous && glyph_index && Dx == NULL) + if (use_kerning && previous && glyph_index && NULL == Dx) { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, 0, &delta); TextLeft += delta.x; } + DPRINT("TextLeft: %I64d\n", TextLeft); + DPRINT("TextTop: %lu\n", TextTop); + DPRINT("Advance: %d\n", realglyph->root.advance.x); + + DestRect.left = BackgroundLeft; + DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6; + DestRect.top = TextTop + yoff - ((fixAscender + 32) >> 6); + DestRect.bottom = DestRect.top + ((fixAscender + fixDescender) >> 6); + MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom); + if (dc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR)) + { + IntUpdateBoundsRect(dc, &DestRect); + } + IntEngBitBlt( + &psurf->SurfObj, + NULL, + NULL, + (CLIPOBJ *)&dc->co, + NULL, + &DestRect, + &SourcePoint, + &SourcePoint, + &dc->eboBackground.BrushObject, + &BrushOrigin, + ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY)); + MouseSafetyOnDrawEnd(dc->ppdev); + BackgroundLeft = DestRect.right; + + DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left; + DestRect.right = DestRect.left + realglyph->bitmap.width; + DestRect.top = TextTop + yoff - realglyph->top; + DestRect.bottom = DestRect.top + realglyph->bitmap.rows;
- if (Dx == NULL) + bitSize.cx = realglyph->bitmap.width; + bitSize.cy = realglyph->bitmap.rows; + MaskRect.right = realglyph->bitmap.width; + MaskRect.bottom = realglyph->bitmap.rows; + + if (NULL == Dx) { TextLeft += realglyph->root.advance.x >> 10; + DPRINT("New TextLeft: %I64d\n", TextLeft); } else { @@ -5872,8 +6024,9 @@ IntExtTextOutW( FLOATOBJ_Set1(&Scale);
/* do the shift before multiplying to preserve precision */ - FLOATOBJ_MulLong(&Scale, Dx[i << DxShift] << 6); + FLOATOBJ_MulLong(&Scale, Dx[i<<DxShift] << 6); TextLeft += FLOATOBJ_GetLong(&Scale); + DPRINT("New TextLeft2: %I64d\n", TextLeft); }
if (DxShift) @@ -5883,86 +6036,12 @@ IntExtTextOutW(
previous = glyph_index;
- FT_Done_Glyph((FT_Glyph)realglyph); - } - - TextWidth = TextLeft - RealXStart; - } - - /* - * Process the horizontal alignment and modify XStart accordingly. - */ - if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER) - { - RealXStart -= TextWidth / 2; - } - else if ((pdcattr->lTextAlign & TA_RIGHT) == TA_RIGHT) - { - RealXStart -= TextWidth; - if (((RealXStart + TextWidth + 32) >> 6) <= Start.x + dc->ptlDCOrig.x) - RealXStart += 1 << 6; - } - - psurf = dc->dclevel.pSurface; - SurfObj = &psurf->SurfObj ; - - if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND)) - DC_vUpdateBackgroundBrush(dc) ; - - if(dc->pdcattr->ulDirty_ & DIRTY_TEXT) - DC_vUpdateTextBrush(dc) ; - - if (!face->units_per_EM) - { - thickness = 1; - } - else - { - thickness = face->underline_thickness * - face->size->metrics.y_ppem / face->units_per_EM; - if (thickness <= 0) - thickness = 1; - } - - if (fuOptions & ETO_OPAQUE) - { - /* Draw background */ - RECTL Rect; - - 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)) - { - IntUpdateBoundsRect(dc, &Rect); + if (EmuBold || EmuItalic) + { + FT_Done_Glyph((FT_Glyph)realglyph); + realglyph = NULL; + } } - - if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) - DC_vUpdateBackgroundBrush(dc); - if (dc->dctype == DCTYPE_DIRECT) - MouseSafetyOnDrawStart(dc->ppdev, Rect.left, Rect.top, Rect.right, Rect.bottom); - - SourcePoint.x = SourcePoint.y = 0; - BrushOrigin.x = BrushOrigin.y = 0; - - psurf = dc->dclevel.pSurface; - IntEngBitBlt( - &psurf->SurfObj, - NULL, - NULL, - (CLIPOBJ *)&dc->co, - NULL, - &Rect, - &SourcePoint, - &SourcePoint, - &dc->eboBackground.BrushObject, - &BrushOrigin, - ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY)); - - if (dc->dctype == DCTYPE_DIRECT) - MouseSafetyOnDrawEnd(dc->ppdev); }
EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0); @@ -5976,7 +6055,7 @@ IntExtTextOutW( */ TextLeft = RealXStart; TextTop = YStart; - previous = 0; + BackgroundLeft = (RealXStart + 32) >> 6; for (i = 0; i < Count; ++i) { glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); @@ -6033,6 +6112,39 @@ IntExtTextOutW( DPRINT("TextTop: %lu\n", TextTop); DPRINT("Advance: %d\n", realglyph->root.advance.x);
+ if ((fuOptions & ETO_OPAQUE) && !plf->lfItalic) + { + DestRect.left = BackgroundLeft; + DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6; + DestRect.top = TextTop + yoff - ((fixAscender + 32) >> 6); + DestRect.bottom = DestRect.top + ((fixAscender + fixDescender) >> 6); + + if (dc->dctype == DCTYPE_DIRECT) + MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom); + + if (dc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR)) + { + IntUpdateBoundsRect(dc, &DestRect); + } + IntEngBitBlt( + &psurf->SurfObj, + NULL, + NULL, + (CLIPOBJ *)&dc->co, + NULL, + &DestRect, + &SourcePoint, + &SourcePoint, + &dc->eboBackground.BrushObject, + &BrushOrigin, + ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY)); + + if (dc->dctype == DCTYPE_DIRECT) + MouseSafetyOnDrawEnd(dc->ppdev); + + BackgroundLeft = DestRect.right; + } + DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left; DestRect.right = DestRect.left + realglyph->bitmap.width; DestRect.top = TextTop + yoff - realglyph->top; @@ -6057,12 +6169,8 @@ IntExtTextOutW( if ( !HSourceGlyph ) { DPRINT1("WARNING: EngCreateBitmap() failed!\n"); + // FT_Done_Glyph(realglyph); bResult = FALSE; - if (EmuBold || EmuItalic) - { - FT_Done_Glyph((FT_Glyph)realglyph); - } - break; } SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph); @@ -6071,11 +6179,6 @@ IntExtTextOutW( EngDeleteSurface((HSURF)HSourceGlyph); DPRINT1("WARNING: EngLockSurface() failed!\n"); bResult = FALSE; - if (EmuBold || EmuItalic) - { - FT_Done_Glyph((FT_Glyph)realglyph); - } - break; }
@@ -6124,11 +6227,6 @@ IntExtTextOutW(
if (DoBreak) { - if (EmuBold || EmuItalic) - { - FT_Done_Glyph((FT_Glyph)realglyph); - } - break; }
@@ -6199,10 +6297,10 @@ IntExtTextOutW(
previous = glyph_index;
- /* No cache, so clean up */ if (EmuBold || EmuItalic) { FT_Done_Glyph((FT_Glyph)realglyph); + realglyph = NULL; } }