mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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:
parent
1a9f0bc429
commit
021f498cb2
1 changed files with 230 additions and 132 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue