- Refactor GreExtTextOutW to use a single exit path instead of 3
- Call MouseSafetyOnDraw* only for direct DCs

svn path=/trunk/; revision=75566
This commit is contained in:
Timo Kreuzer 2017-08-16 13:37:15 +00:00
parent 66de37e22f
commit 93cecddaa8

View file

@ -5102,6 +5102,14 @@ GreExtTextOutW(
LOGFONTW *plf; LOGFONTW *plf;
BOOL EmuBold, EmuItalic; BOOL EmuBold, EmuItalic;
int thickness; int thickness;
BOOL bResult;
/* Check if String is valid */
if ((Count > 0xFFFF) || (Count > 0 && String == NULL))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
// TODO: Write test-cases to exactly match real Windows in different // TODO: Write test-cases to exactly match real Windows in different
// bad parameters (e.g. does Windows check the DC or the RECT first?). // bad parameters (e.g. does Windows check the DC or the RECT first?).
@ -5112,43 +5120,31 @@ GreExtTextOutW(
return FALSE; return FALSE;
} }
pdcattr = dc->pdcattr;
if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE)
{
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
DC_vUpdateBackgroundBrush(dc);
}
/* Check if String is valid */
if ((Count > 0xFFFF) || (Count > 0 && String == NULL))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
goto fail;
}
DxShift = fuOptions & ETO_PDY ? 1 : 0;
if (PATH_IsPathOpen(dc->dclevel)) if (PATH_IsPathOpen(dc->dclevel))
{ {
if (!PATH_ExtTextOut( dc, bResult = PATH_ExtTextOut(dc,
XStart, XStart,
YStart, YStart,
fuOptions, fuOptions,
(const RECTL *)lprc, (const RECTL *)lprc,
String, String,
Count, Count,
(const INT *)Dx)) goto fail; (const INT *)Dx);
goto good; DC_UnlockDc(dc);
return bResult;
} }
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
if (!dc->dclevel.pSurface) if (!dc->dclevel.pSurface)
{ {
/* Memory DC with no surface selected */ /* Memory DC with no surface selected */
DC_UnlockDc(dc); bResult = FALSE; // TRUE?
return TRUE; goto Cleanup;
} }
pdcattr = dc->pdcattr;
if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED))) if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED)))
{ {
IntLPtoDP(dc, (POINT *)lprc, 2); IntLPtoDP(dc, (POINT *)lprc, 2);
@ -5191,10 +5187,10 @@ GreExtTextOutW(
IntUpdateBoundsRect(dc, &DestRect); IntUpdateBoundsRect(dc, &DestRect);
} }
DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
DC_vUpdateBackgroundBrush(dc); DC_vUpdateBackgroundBrush(dc);
if (dc->dctype == DCTYPE_DIRECT)
MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
psurf = dc->dclevel.pSurface; psurf = dc->dclevel.pSurface;
IntEngBitBlt( IntEngBitBlt(
@ -5209,8 +5205,11 @@ GreExtTextOutW(
&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);
fuOptions &= ~ETO_OPAQUE; fuOptions &= ~ETO_OPAQUE;
DC_vFinishBlit(dc, NULL);
} }
else else
{ {
@ -5223,7 +5222,8 @@ GreExtTextOutW(
TextObj = RealizeFontInit(pdcattr->hlfntNew); TextObj = RealizeFontInit(pdcattr->hlfntNew);
if (TextObj == NULL) if (TextObj == NULL)
{ {
goto fail; bResult = FALSE;
goto Cleanup;
} }
FontObj = TextObj->Font; FontObj = TextObj->Font;
@ -5247,7 +5247,8 @@ GreExtTextOutW(
if (!TextIntUpdateSize(dc, TextObj, FontGDI, FALSE)) if (!TextIntUpdateSize(dc, TextObj, FontGDI, FALSE))
{ {
IntUnLockFreeType; IntUnLockFreeType;
goto fail; bResult = FALSE;
goto Cleanup;
} }
if (dc->pdcattr->iGraphicsMode == GM_ADVANCED) if (dc->pdcattr->iGraphicsMode == GM_ADVANCED)
@ -5284,7 +5285,7 @@ GreExtTextOutW(
/* /*
* Process the horizontal alignment and modify XStart accordingly. * Process the horizontal alignment and modify XStart accordingly.
*/ */
DxShift = fuOptions & ETO_PDY ? 1 : 0;
if (pdcattr->lTextAlign & (TA_RIGHT | TA_CENTER)) if (pdcattr->lTextAlign & (TA_RIGHT | TA_CENTER))
{ {
ULONGLONG TextWidth = 0; ULONGLONG TextWidth = 0;
@ -5348,7 +5349,7 @@ GreExtTextOutW(
{ {
DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType; IntUnLockFreeType;
goto fail; goto Cleanup;
} }
} }
@ -5384,15 +5385,9 @@ GreExtTextOutW(
} }
} }
/* Lock blit with a dummy rect */
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
psurf = dc->dclevel.pSurface; psurf = dc->dclevel.pSurface;
SurfObj = &psurf->SurfObj ; SurfObj = &psurf->SurfObj ;
EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND)) if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND))
DC_vUpdateBackgroundBrush(dc) ; DC_vUpdateBackgroundBrush(dc) ;
@ -5429,8 +5424,7 @@ GreExtTextOutW(
{ {
DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index); DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType; IntUnLockFreeType;
DC_vFinishBlit(dc, NULL); goto Cleanup; // FIXME
goto fail2;
} }
glyph = face->glyph; glyph = face->glyph;
@ -5443,8 +5437,7 @@ GreExtTextOutW(
{ {
DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType; IntUnLockFreeType;
DC_vFinishBlit(dc, NULL); goto Cleanup; // FIXME
goto fail2;
} }
/* retrieve kerning distance and move pen position */ /* retrieve kerning distance and move pen position */
@ -5525,6 +5518,12 @@ GreExtTextOutW(
} }
} }
EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
/* Assume success */
bResult = TRUE;
/* /*
* The main rendering loop. * The main rendering loop.
*/ */
@ -5549,9 +5548,8 @@ GreExtTextOutW(
if (error) if (error)
{ {
DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index); DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index);
IntUnLockFreeType; bResult = FALSE;
DC_vFinishBlit(dc, NULL); break;
goto fail2;
} }
glyph = face->glyph; glyph = face->glyph;
@ -5575,9 +5573,8 @@ GreExtTextOutW(
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; bResult = FALSE;
DC_vFinishBlit(dc, NULL); break;
goto fail2;
} }
} }
@ -5598,7 +5595,9 @@ GreExtTextOutW(
DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6; DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6;
DestRect.top = TextTop + yoff - ((fixAscender + 32) >> 6); DestRect.top = TextTop + yoff - ((fixAscender + 32) >> 6);
DestRect.bottom = TextTop + yoff + ((32 - fixDescender) >> 6); DestRect.bottom = TextTop + yoff + ((32 - fixDescender) >> 6);
MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
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)) if (dc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
{ {
IntUpdateBoundsRect(dc, &DestRect); IntUpdateBoundsRect(dc, &DestRect);
@ -5615,7 +5614,10 @@ GreExtTextOutW(
&dc->eboBackground.BrushObject, &dc->eboBackground.BrushObject,
&BrushOrigin, &BrushOrigin,
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY)); ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
MouseSafetyOnDrawEnd(dc->ppdev);
if (dc->dctype == DCTYPE_DIRECT)
MouseSafetyOnDrawEnd(dc->ppdev);
BackgroundLeft = DestRect.right; BackgroundLeft = DestRect.right;
} }
@ -5644,18 +5646,16 @@ GreExtTextOutW(
{ {
DPRINT1("WARNING: EngCreateBitmap() failed!\n"); DPRINT1("WARNING: EngCreateBitmap() failed!\n");
// FT_Done_Glyph(realglyph); // FT_Done_Glyph(realglyph);
IntUnLockFreeType; bResult = FALSE;
DC_vFinishBlit(dc, NULL); break;
goto fail2;
} }
SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph); SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
if ( !SourceGlyphSurf ) if ( !SourceGlyphSurf )
{ {
EngDeleteSurface((HSURF)HSourceGlyph); EngDeleteSurface((HSURF)HSourceGlyph);
DPRINT1("WARNING: EngLockSurface() failed!\n"); DPRINT1("WARNING: EngLockSurface() failed!\n");
IntUnLockFreeType; bResult = FALSE;
DC_vFinishBlit(dc, NULL); break;
goto fail2;
} }
/* /*
@ -5676,7 +5676,10 @@ GreExtTextOutW(
{ {
DestRect.bottom = lprc->bottom + dc->ptlDCOrig.y; DestRect.bottom = lprc->bottom + dc->ptlDCOrig.y;
} }
MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
if (dc->dctype == DCTYPE_DIRECT)
MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
if (!IntEngMaskBlt( if (!IntEngMaskBlt(
SurfObj, SurfObj,
SourceGlyphSurf, SourceGlyphSurf,
@ -5691,7 +5694,8 @@ GreExtTextOutW(
DPRINT1("Failed to MaskBlt a glyph!\n"); DPRINT1("Failed to MaskBlt a glyph!\n");
} }
MouseSafetyOnDrawEnd(dc->ppdev) ; if (dc->dctype == DCTYPE_DIRECT)
MouseSafetyOnDrawEnd(dc->ppdev) ;
EngUnlockSurface(SourceGlyphSurf); EngUnlockSurface(SourceGlyphSurf);
EngDeleteSurface((HSURF)HSourceGlyph); EngDeleteSurface((HSURF)HSourceGlyph);
@ -5782,27 +5786,18 @@ GreExtTextOutW(
IntUnLockFreeType; IntUnLockFreeType;
DC_vFinishBlit(dc, NULL) ;
EXLATEOBJ_vCleanup(&exloRGB2Dst); EXLATEOBJ_vCleanup(&exloRGB2Dst);
EXLATEOBJ_vCleanup(&exloDst2RGB); EXLATEOBJ_vCleanup(&exloDst2RGB);
if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj);
good:
DC_UnlockDc( dc );
return TRUE; Cleanup:
DC_vFinishBlit(dc, NULL);
fail2:
EXLATEOBJ_vCleanup(&exloRGB2Dst);
EXLATEOBJ_vCleanup(&exloDst2RGB);
fail:
if (TextObj != NULL) if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj); TEXTOBJ_UnlockText(TextObj);
DC_UnlockDc(dc); DC_UnlockDc(dc);
return FALSE; return bResult;
} }
#define STACK_TEXT_BUFFER_SIZE 100 #define STACK_TEXT_BUFFER_SIZE 100