[0.4.12][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
d6cfeaef51
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

I intend to restore the function to that same state in master today.
This commit is contained in:
Joachim Henze 2019-07-07 18:21:19 +02:00
parent 1a9f0bc429
commit 021f498cb2

View file

@ -5615,7 +5615,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;
@ -5639,7 +5639,6 @@ IntExtTextOutW(
BOOL EmuBold, EmuItalic;
int thickness;
BOOL bResult;
ULONGLONG TextWidth;
/* Check if String is valid */
if ((Count > 0xFFFF) || (Count > 0 && String == NULL))
@ -5809,95 +5808,107 @@ IntExtTextOutW(
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->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)
{
DPRINT1("Failed to load glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType();
bResult = FALSE;
goto Cleanup;
}
glyph = face->glyph;
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);
IntUnLockFreeType();
bResult = FALSE;
goto Cleanup;
}
/* retrieve kerning distance and move pen position */
if (use_kerning && previous && glyph_index && Dx == NULL)
{
FT_Vector delta;
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
TextLeft += delta.x;
}
if (Dx == NULL)
{
TextLeft += realglyph->root.advance.x >> 10;
}
else
{
// 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);
TextLeft += FLOATOBJ_GetLong(&Scale);
}
if (DxShift)
{
TextTop -= Dx[2 * i + 1] << 6;
}
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)
DxShift = fuOptions & ETO_PDY ? 1 : 0;
if (pdcattr->lTextAlign & (TA_RIGHT | 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;
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;
@ -5921,45 +5932,113 @@ IntExtTextOutW(
thickness = 1;
}
if (fuOptions & ETO_OPAQUE)
if ((fuOptions & ETO_OPAQUE) && plf->lfItalic)
{
/* 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))
TextLeft = RealXStart;
TextTop = YStart;
BackgroundLeft = (RealXStart + 32) >> 6;
for (i = 0; i < Count; ++i)
{
IntUpdateBoundsRect(dc, &Rect);
}
glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions);
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
DC_vUpdateBackgroundBrush(dc);
if (dc->dctype == DCTYPE_DIRECT)
MouseSafetyOnDrawStart(dc->ppdev, Rect.left, Rect.top, Rect.right, Rect.bottom);
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
if (error)
{
DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType();
goto Cleanup;
}
SourcePoint.x = SourcePoint.y = 0;
BrushOrigin.x = BrushOrigin.y = 0;
glyph = face->glyph;
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);
IntUnLockFreeType();
goto Cleanup;
}
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));
/* retrieve kerning distance and move pen position */
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);
if (dc->dctype == DCTYPE_DIRECT)
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;
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
{
// 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);
TextLeft += FLOATOBJ_GetLong(&Scale);
DPRINT("New TextLeft2: %I64d\n", TextLeft);
}
if (DxShift)
{
TextTop -= Dx[2 * i + 1] << 6;
}
previous = glyph_index;
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
realglyph = NULL;
}
}
}
EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
@ -5973,7 +6052,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);
@ -6030,6 +6109,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;
@ -6054,12 +6166,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);
@ -6068,11 +6176,6 @@ IntExtTextOutW(
EngDeleteSurface((HSURF)HSourceGlyph);
DPRINT1("WARNING: EngLockSurface() failed!\n");
bResult = FALSE;
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}
break;
}
@ -6121,11 +6224,6 @@ IntExtTextOutW(
if (DoBreak)
{
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}
break;
}
@ -6196,10 +6294,10 @@ IntExtTextOutW(
previous = glyph_index;
/* No cache, so clean up */
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
realglyph = NULL;
}
}