[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_GlyphSlot glyph;
FT_BitmapGlyph realglyph; FT_BitmapGlyph realglyph;
LONGLONG TextLeft, RealXStart; LONGLONG TextLeft, RealXStart;
ULONG TextTop, previous; ULONG TextTop, previous, BackgroundLeft;
FT_Bool use_kerning; FT_Bool use_kerning;
RECTL DestRect, MaskRect; RECTL DestRect, MaskRect;
POINTL SourcePoint, BrushOrigin; POINTL SourcePoint, BrushOrigin;
@ -5639,7 +5639,6 @@ IntExtTextOutW(
BOOL EmuBold, EmuItalic; BOOL EmuBold, EmuItalic;
int thickness; int thickness;
BOOL bResult; BOOL bResult;
ULONGLONG TextWidth;
/* Check if String is valid */ /* Check if String is valid */
if ((Count > 0xFFFF) || (Count > 0 && String == NULL)) if ((Count > 0xFFFF) || (Count > 0 && String == NULL))
@ -5809,95 +5808,107 @@ IntExtTextOutW(
yoff = fixAscender >> 6; yoff = fixAscender >> 6;
#undef VALIGN_MASK #undef VALIGN_MASK
/*
* Calculate width of the text.
*/
TextWidth = 0;
DxShift = fuOptions & ETO_PDY ? 1 : 0;
use_kerning = FT_HAS_KERNING(face); use_kerning = FT_HAS_KERNING(face);
previous = 0; 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. * 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; ULONGLONG TextWidth = 0;
} LPCWSTR TempText = String;
else if ((pdcattr->lTextAlign & TA_RIGHT) == TA_RIGHT) int iStart;
{
RealXStart -= TextWidth; /*
if (((RealXStart + TextWidth + 32) >> 6) <= Start.x + dc->ptlDCOrig.x) * Calculate width of the text.
RealXStart += 1 << 6; */
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; psurf = dc->dclevel.pSurface;
@ -5921,45 +5932,113 @@ IntExtTextOutW(
thickness = 1; thickness = 1;
} }
if (fuOptions & ETO_OPAQUE) if ((fuOptions & ETO_OPAQUE) && plf->lfItalic)
{ {
/* Draw background */ /* Draw background */
RECTL Rect; TextLeft = RealXStart;
TextTop = YStart;
Rect.left = (RealXStart + 32) >> 6; BackgroundLeft = (RealXStart + 32) >> 6;
Rect.top = TextTop + yoff - ((fixAscender + 32) >> 6); for (i = 0; i < Count; ++i)
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); glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions);
}
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
DC_vUpdateBackgroundBrush(dc); if (error)
if (dc->dctype == DCTYPE_DIRECT) {
MouseSafetyOnDrawStart(dc->ppdev, Rect.left, Rect.top, Rect.right, Rect.bottom); DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType();
goto Cleanup;
}
SourcePoint.x = SourcePoint.y = 0; glyph = face->glyph;
BrushOrigin.x = BrushOrigin.y = 0; 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; /* retrieve kerning distance and move pen position */
IntEngBitBlt( if (use_kerning && previous && glyph_index && NULL == Dx)
&psurf->SurfObj, {
NULL, FT_Vector delta;
NULL, FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
(CLIPOBJ *)&dc->co, TextLeft += delta.x;
NULL, }
&Rect, DPRINT("TextLeft: %I64d\n", TextLeft);
&SourcePoint, DPRINT("TextTop: %lu\n", TextTop);
&SourcePoint, DPRINT("Advance: %d\n", realglyph->root.advance.x);
&dc->eboBackground.BrushObject,
&BrushOrigin,
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
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); 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); EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
@ -5973,7 +6052,7 @@ IntExtTextOutW(
*/ */
TextLeft = RealXStart; TextLeft = RealXStart;
TextTop = YStart; TextTop = YStart;
previous = 0; BackgroundLeft = (RealXStart + 32) >> 6;
for (i = 0; i < Count; ++i) for (i = 0; i < Count; ++i)
{ {
glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions); glyph_index = get_glyph_index_flagged(face, String[i], ETO_GLYPH_INDEX, fuOptions);
@ -6030,6 +6109,39 @@ IntExtTextOutW(
DPRINT("TextTop: %lu\n", TextTop); DPRINT("TextTop: %lu\n", TextTop);
DPRINT("Advance: %d\n", realglyph->root.advance.x); 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.left = ((TextLeft + 32) >> 6) + realglyph->left;
DestRect.right = DestRect.left + realglyph->bitmap.width; DestRect.right = DestRect.left + realglyph->bitmap.width;
DestRect.top = TextTop + yoff - realglyph->top; DestRect.top = TextTop + yoff - realglyph->top;
@ -6054,12 +6166,8 @@ IntExtTextOutW(
if ( !HSourceGlyph ) if ( !HSourceGlyph )
{ {
DPRINT1("WARNING: EngCreateBitmap() failed!\n"); DPRINT1("WARNING: EngCreateBitmap() failed!\n");
// FT_Done_Glyph(realglyph);
bResult = FALSE; bResult = FALSE;
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}
break; break;
} }
SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph); SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
@ -6068,11 +6176,6 @@ IntExtTextOutW(
EngDeleteSurface((HSURF)HSourceGlyph); EngDeleteSurface((HSURF)HSourceGlyph);
DPRINT1("WARNING: EngLockSurface() failed!\n"); DPRINT1("WARNING: EngLockSurface() failed!\n");
bResult = FALSE; bResult = FALSE;
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}
break; break;
} }
@ -6121,11 +6224,6 @@ IntExtTextOutW(
if (DoBreak) if (DoBreak)
{ {
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}
break; break;
} }
@ -6196,10 +6294,10 @@ IntExtTextOutW(
previous = glyph_index; previous = glyph_index;
/* No cache, so clean up */
if (EmuBold || EmuItalic) if (EmuBold || EmuItalic)
{ {
FT_Done_Glyph((FT_Glyph)realglyph); FT_Done_Glyph((FT_Glyph)realglyph);
realglyph = NULL;
} }
} }