[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

Analog revert was applied before to 0.4.12-RC-42-g
021f498cb2
This commit is contained in:
Joachim Henze 2019-07-07 20:50:30 +02:00
parent 019e3ffe5f
commit b5478a7873

View file

@ -5618,7 +5618,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;
@ -5642,7 +5642,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))
@ -5812,95 +5811,107 @@ IntExtTextOutW(
yoff = fixAscender >> 6; yoff = fixAscender >> 6;
#undef VALIGN_MASK #undef VALIGN_MASK
use_kerning = FT_HAS_KERNING(face);
previous = 0;
/*
* Process the horizontal alignment and modify XStart accordingly.
*/
DxShift = fuOptions & ETO_PDY ? 1 : 0;
if (pdcattr->lTextAlign & (TA_RIGHT | TA_CENTER))
{
ULONGLONG TextWidth = 0;
LPCWSTR TempText = String;
int iStart;
/* /*
* Calculate width of the text. * 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. 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); error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
if (error) if (error)
{ {
DPRINT1("Failed to load glyph! [index: %d]\n", glyph_index); DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType();
bResult = FALSE;
goto Cleanup;
} }
glyph = face->glyph; glyph = face->glyph;
if (EmuBold || EmuItalic)
{
if (EmuBold) if (EmuBold)
FT_GlyphSlot_Embolden(glyph); FT_GlyphSlot_Embolden(glyph);
if (EmuItalic) if (EmuItalic)
FT_GlyphSlot_Oblique(glyph); FT_GlyphSlot_Oblique(glyph);
realglyph = ftGdiGlyphSet(face, glyph, RenderMode); realglyph = ftGdiGlyphSet(face, glyph, RenderMode);
}
else
{
realglyph = ftGdiGlyphCacheSet(face,
glyph_index,
plf->lfHeight,
pmxWorldToDevice,
glyph,
RenderMode);
}
if (!realglyph) if (!realglyph)
{ {
DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType(); IntUnLockFreeType();
bResult = FALSE;
goto Cleanup; goto Cleanup;
} }
/* retrieve kerning distance and move pen position */ }
if (use_kerning && previous && glyph_index && Dx == NULL) /* Retrieve kerning distance */
if (use_kerning && previous && glyph_index)
{ {
FT_Vector delta; FT_Vector delta;
FT_Get_Kerning(face, previous, glyph_index, 0, &delta); FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
TextLeft += delta.x; TextWidth += delta.x;
} }
if (Dx == NULL) TextWidth += realglyph->root.advance.x >> 10;
{
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 */ if (EmuBold || EmuItalic)
FLOATOBJ_MulLong(&Scale, Dx[i << DxShift] << 6);
TextLeft += FLOATOBJ_GetLong(&Scale);
}
if (DxShift)
{ {
TextTop -= Dx[2 * i + 1] << 6; FT_Done_Glyph((FT_Glyph)realglyph);
realglyph = NULL;
} }
previous = glyph_index; previous = glyph_index;
TempText++;
FT_Done_Glyph((FT_Glyph)realglyph);
} }
TextWidth = TextLeft - RealXStart; previous = 0;
}
/*
* Process the horizontal alignment and modify XStart accordingly.
*/
if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER) if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER)
{ {
RealXStart -= TextWidth / 2; RealXStart -= TextWidth / 2;
} }
else if ((pdcattr->lTextAlign & TA_RIGHT) == TA_RIGHT) else
{ {
RealXStart -= TextWidth; RealXStart -= TextWidth;
if (((RealXStart + TextWidth + 32) >> 6) <= Start.x + dc->ptlDCOrig.x) }
RealXStart += 1 << 6;
} }
psurf = dc->dclevel.pSurface; psurf = dc->dclevel.pSurface;
@ -5924,45 +5935,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);
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;
} }
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) glyph = face->glyph;
DC_vUpdateBackgroundBrush(dc); if (EmuBold)
if (dc->dctype == DCTYPE_DIRECT) FT_GlyphSlot_Embolden(glyph);
MouseSafetyOnDrawStart(dc->ppdev, Rect.left, Rect.top, Rect.right, Rect.bottom); 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;
}
SourcePoint.x = SourcePoint.y = 0; /* retrieve kerning distance and move pen position */
BrushOrigin.x = BrushOrigin.y = 0; 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);
psurf = dc->dclevel.pSurface; 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( IntEngBitBlt(
&psurf->SurfObj, &psurf->SurfObj,
NULL, NULL,
NULL, NULL,
(CLIPOBJ *)&dc->co, (CLIPOBJ *)&dc->co,
NULL, NULL,
&Rect, &DestRect,
&SourcePoint, &SourcePoint,
&SourcePoint, &SourcePoint,
&dc->eboBackground.BrushObject, &dc->eboBackground.BrushObject,
&BrushOrigin, &BrushOrigin,
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY)); ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
if (dc->dctype == DCTYPE_DIRECT)
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);
@ -5976,7 +6055,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);
@ -6033,6 +6112,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;
@ -6057,12 +6169,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);
@ -6071,11 +6179,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;
} }
@ -6124,11 +6227,6 @@ IntExtTextOutW(
if (DoBreak) if (DoBreak)
{ {
if (EmuBold || EmuItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}
break; break;
} }
@ -6199,10 +6297,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;
} }
} }