mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 12:02:02 +00:00
[Win32SS] Add TextOut to GDI Batch
Add fix ups to PolyPatBlt and freetype. TextOut supports 580 characters w/o Dx and Dx at a max of 193 characters with Dx*1, both if offset is 0. Noticed a lot of over drawing with start menu from ComCtl32 SB_SETTEXT going through User32 DrawText/Worker ExtTextOutW. Explain why it might be slowing down. If issues arise, commenting out lines in win32ss/include/gdi32p.h can help. Example: else if (Cmd == GdiBCTextOut) cjSize = 0;//sizeof(GDIBSTEXTOUT); <---- this one most of all. else if (Cmd == GdiBCExtTextOut) cjSize = 0;//sizeof(GDIBSEXTTEXTOUT); Test results: https://reactos.org/testman/compare.php?ids=66260,66262
This commit is contained in:
parent
6676b7c48b
commit
d57f7becc3
6 changed files with 255 additions and 24 deletions
|
@ -390,8 +390,8 @@ GdiAllocBatchCommand(
|
||||||
/* Get the size of the entry */
|
/* Get the size of the entry */
|
||||||
if (Cmd == GdiBCPatBlt) cjSize = sizeof(GDIBSPATBLT);
|
if (Cmd == GdiBCPatBlt) cjSize = sizeof(GDIBSPATBLT);
|
||||||
else if (Cmd == GdiBCPolyPatBlt) cjSize = sizeof(GDIBSPPATBLT);
|
else if (Cmd == GdiBCPolyPatBlt) cjSize = sizeof(GDIBSPPATBLT);
|
||||||
else if (Cmd == GdiBCTextOut) cjSize = 0;
|
else if (Cmd == GdiBCTextOut) cjSize = sizeof(GDIBSTEXTOUT);
|
||||||
else if (Cmd == GdiBCExtTextOut) cjSize = 0;
|
else if (Cmd == GdiBCExtTextOut) cjSize = sizeof(GDIBSEXTTEXTOUT);
|
||||||
else if (Cmd == GdiBCSetBrushOrg) cjSize = sizeof(GDIBSSETBRHORG);
|
else if (Cmd == GdiBCSetBrushOrg) cjSize = sizeof(GDIBSSETBRHORG);
|
||||||
else if (Cmd == GdiBCExtSelClipRgn) cjSize = 0;
|
else if (Cmd == GdiBCExtSelClipRgn) cjSize = 0;
|
||||||
else if (Cmd == GdiBCSelObj) cjSize = sizeof(GDIBSOBJECT);
|
else if (Cmd == GdiBCSelObj) cjSize = sizeof(GDIBSOBJECT);
|
||||||
|
|
|
@ -548,7 +548,8 @@ PolyPatBlt(
|
||||||
pgO = GdiAllocBatchCommand(hdc, GdiBCPolyPatBlt);
|
pgO = GdiAllocBatchCommand(hdc, GdiBCPolyPatBlt);
|
||||||
if (pgO)
|
if (pgO)
|
||||||
{
|
{
|
||||||
USHORT cjSize = sizeof(GDIBSPPATBLT) + (nCount-1) * sizeof(PATRECT);
|
USHORT cjSize = 0;
|
||||||
|
if (nCount > 1) cjSize = (nCount-1) * sizeof(PATRECT);
|
||||||
|
|
||||||
if ((pTeb->GdiTebBatch.Offset + cjSize) <= GDIBATCHBUFSIZE)
|
if ((pTeb->GdiTebBatch.Offset + cjSize) <= GDIBATCHBUFSIZE)
|
||||||
{
|
{
|
||||||
|
@ -563,10 +564,14 @@ PolyPatBlt(
|
||||||
pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
|
pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
|
||||||
pgO->ulBrushClr = pdcattr->ulBrushClr;
|
pgO->ulBrushClr = pdcattr->ulBrushClr;
|
||||||
RtlCopyMemory(pgO->pRect, pPoly, nCount * sizeof(PATRECT));
|
RtlCopyMemory(pgO->pRect, pPoly, nCount * sizeof(PATRECT));
|
||||||
// Recompute offset, remember one is already accounted for in the structure.
|
// Recompute offset and return size, remember one is already accounted for in the structure.
|
||||||
pTeb->GdiTebBatch.Offset += (nCount-1) * sizeof(PATRECT);
|
pTeb->GdiTebBatch.Offset += cjSize;
|
||||||
|
((PGDIBATCHHDR)pgO)->Size += cjSize;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
// Reset offset and count then fall through
|
||||||
|
pTeb->GdiTebBatch.Offset -= sizeof(GDIBSPPATBLT);
|
||||||
|
pTeb->GdiBatchCount--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NtGdiPolyPatBlt(hdc, dwRop, pPoly, nCount, dwMode);
|
return NtGdiPolyPatBlt(hdc, dwRop, pPoly, nCount, dwMode);
|
||||||
|
|
|
@ -488,6 +488,8 @@ ExtTextOutW(
|
||||||
_In_ UINT cwc,
|
_In_ UINT cwc,
|
||||||
_In_reads_opt_(cwc) const INT *lpDx)
|
_In_reads_opt_(cwc) const INT *lpDx)
|
||||||
{
|
{
|
||||||
|
PDC_ATTR pdcattr;
|
||||||
|
|
||||||
HANDLE_METADC(BOOL,
|
HANDLE_METADC(BOOL,
|
||||||
ExtTextOut,
|
ExtTextOut,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
@ -506,6 +508,101 @@ ExtTextOutW(
|
||||||
return LpkExtTextOut(hdc, x, y, fuOptions, lprc, lpString, cwc , lpDx, 0);
|
return LpkExtTextOut(hdc, x, y, fuOptions, lprc, lpString, cwc , lpDx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the DC attribute */
|
||||||
|
pdcattr = GdiGetDcAttr(hdc);
|
||||||
|
if ( pdcattr &&
|
||||||
|
!(pdcattr->ulDirty_ & DC_DIBSECTION) &&
|
||||||
|
!(pdcattr->lTextAlign & TA_UPDATECP))
|
||||||
|
{
|
||||||
|
if ( lprc && !cwc )
|
||||||
|
{
|
||||||
|
if ( fuOptions & ETO_OPAQUE )
|
||||||
|
{
|
||||||
|
PGDIBSEXTTEXTOUT pgO;
|
||||||
|
|
||||||
|
pgO = GdiAllocBatchCommand(hdc, GdiBCExtTextOut);
|
||||||
|
if (pgO)
|
||||||
|
{
|
||||||
|
pgO->Count = cwc;
|
||||||
|
pgO->Rect = *lprc;
|
||||||
|
pgO->Options = fuOptions;
|
||||||
|
/* Snapshot attribute */
|
||||||
|
pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
|
||||||
|
pgO->ptlViewportOrg = pdcattr->ptlViewportOrg;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Do nothing, old explorer pops this off.
|
||||||
|
{
|
||||||
|
DPRINT1("GdiBCExtTextOut nothing\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
} // Max 580 wchars, if offset 0
|
||||||
|
else if ( cwc <= ((GDIBATCHBUFSIZE - sizeof(GDIBSTEXTOUT)) / sizeof(WCHAR)) )
|
||||||
|
{
|
||||||
|
PGDIBSTEXTOUT pgO;
|
||||||
|
PTEB pTeb = NtCurrentTeb();
|
||||||
|
|
||||||
|
pgO = GdiAllocBatchCommand(hdc, GdiBCTextOut);
|
||||||
|
if (pgO)
|
||||||
|
{
|
||||||
|
USHORT cjSize = 0;
|
||||||
|
ULONG DxSize = 0;
|
||||||
|
|
||||||
|
if (cwc > 2) cjSize = (cwc * sizeof(WCHAR)) - sizeof(pgO->String);
|
||||||
|
|
||||||
|
/* Calculate buffer size for string and Dx values */
|
||||||
|
if (lpDx)
|
||||||
|
{
|
||||||
|
/* If ETO_PDY is specified, we have pairs of INTs */
|
||||||
|
DxSize = (cwc * sizeof(INT)) * (fuOptions & ETO_PDY ? 2 : 1);
|
||||||
|
cjSize += DxSize;
|
||||||
|
// The structure buffer holds 4 bytes. Store Dx data then string.
|
||||||
|
// Result one wchar -> Buf[ Dx ]Str[wC], [4][2][X] one extra unused wchar
|
||||||
|
// to assure alignment of 4.
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pTeb->GdiTebBatch.Offset + cjSize ) <= GDIBATCHBUFSIZE)
|
||||||
|
{
|
||||||
|
pgO->cbCount = cwc;
|
||||||
|
pgO->x = x;
|
||||||
|
pgO->y = y;
|
||||||
|
pgO->Options = fuOptions;
|
||||||
|
pgO->iCS_CP = 0;
|
||||||
|
|
||||||
|
if (lprc) pgO->Rect = *lprc;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pgO->Options |= GDIBS_NORECT; // Tell the other side lprc is nill.
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Snapshot attributes */
|
||||||
|
pgO->crForegroundClr = pdcattr->crForegroundClr;
|
||||||
|
pgO->crBackgroundClr = pdcattr->crBackgroundClr;
|
||||||
|
pgO->ulForegroundClr = pdcattr->ulForegroundClr;
|
||||||
|
pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
|
||||||
|
pgO->lBkMode = pdcattr->lBkMode == OPAQUE ? OPAQUE : TRANSPARENT;
|
||||||
|
pgO->hlfntNew = pdcattr->hlfntNew;
|
||||||
|
pgO->flTextAlign = pdcattr->flTextAlign;
|
||||||
|
pgO->ptlViewportOrg = pdcattr->ptlViewportOrg;
|
||||||
|
|
||||||
|
pgO->Size = DxSize; // of lpDx then string after.
|
||||||
|
/* Put the Dx before the String to assure alignment of 4 */
|
||||||
|
if (lpDx) RtlCopyMemory( &pgO->Buffer, lpDx, DxSize);
|
||||||
|
|
||||||
|
if (cwc) RtlCopyMemory( &pgO->String[DxSize/sizeof(WCHAR)], lpString, cwc * sizeof(WCHAR));
|
||||||
|
|
||||||
|
// Recompute offset and return size
|
||||||
|
pTeb->GdiTebBatch.Offset += cjSize;
|
||||||
|
((PGDIBATCHHDR)pgO)->Size += cjSize;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
// Reset offset and count then fall through
|
||||||
|
pTeb->GdiTebBatch.Offset -= sizeof(GDIBSTEXTOUT);
|
||||||
|
pTeb->GdiBatchCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return NtGdiExtTextOutW(hdc,
|
return NtGdiExtTextOutW(hdc,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
|
|
@ -5814,7 +5814,7 @@ IntExtTextOutW(
|
||||||
if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND))
|
if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND))
|
||||||
DC_vUpdateBackgroundBrush(dc) ;
|
DC_vUpdateBackgroundBrush(dc) ;
|
||||||
|
|
||||||
if(dc->pdcattr->ulDirty_ & DIRTY_TEXT)
|
if (dc->pdcattr->ulDirty_ & DIRTY_TEXT)
|
||||||
DC_vUpdateTextBrush(dc) ;
|
DC_vUpdateTextBrush(dc) ;
|
||||||
|
|
||||||
thickness = 1;
|
thickness = 1;
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
BOOL FASTCALL IntPatBlt( PDC,INT,INT,INT,INT,DWORD,PEBRUSHOBJ);
|
BOOL FASTCALL IntPatBlt( PDC,INT,INT,INT,INT,DWORD,PEBRUSHOBJ);
|
||||||
|
BOOL APIENTRY IntExtTextOutW(IN PDC,IN INT,IN INT,IN UINT,IN OPTIONAL PRECTL,IN LPCWSTR,IN INT,IN OPTIONAL LPINT,IN DWORD);
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Gdi Batch Flush support functions.
|
// Gdi Batch Flush support functions.
|
||||||
|
@ -40,7 +42,7 @@ DoDeviceSync( SURFOBJ *Surface, PRECTL Rect, FLONG fl)
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
SynchonizeDriver(FLONG Flags)
|
SynchronizeDriver(FLONG Flags)
|
||||||
{
|
{
|
||||||
SURFOBJ *SurfObj;
|
SURFOBJ *SurfObj;
|
||||||
//PPDEVOBJ Device;
|
//PPDEVOBJ Device;
|
||||||
|
@ -130,7 +132,7 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
|
||||||
dc->pdcattr->ulForegroundClr = pgDPB->ulForegroundClr;
|
dc->pdcattr->ulForegroundClr = pgDPB->ulForegroundClr;
|
||||||
dc->pdcattr->ulBackgroundClr = pgDPB->ulBackgroundClr;
|
dc->pdcattr->ulBackgroundClr = pgDPB->ulBackgroundClr;
|
||||||
dc->pdcattr->ulBrushClr = pgDPB->ulBrushClr;
|
dc->pdcattr->ulBrushClr = pgDPB->ulBrushClr;
|
||||||
// Process dirty attributes if any
|
// Process dirty attributes if any.
|
||||||
if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||||
DC_vUpdateFillBrush(dc);
|
DC_vUpdateFillBrush(dc);
|
||||||
if (dc->pdcattr->ulDirty_ & DIRTY_TEXT)
|
if (dc->pdcattr->ulDirty_ & DIRTY_TEXT)
|
||||||
|
@ -157,7 +159,7 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
|
||||||
EBRUSHOBJ eboFill;
|
EBRUSHOBJ eboFill;
|
||||||
PBRUSH pbrush;
|
PBRUSH pbrush;
|
||||||
PPATRECT pRects;
|
PPATRECT pRects;
|
||||||
INT cRects, i;
|
INT i;
|
||||||
DWORD dwRop, flags;
|
DWORD dwRop, flags;
|
||||||
COLORREF crColor, crBkColor, crBrushClr;
|
COLORREF crColor, crBkColor, crBrushClr;
|
||||||
ULONG ulForegroundClr, ulBackgroundClr, ulBrushClr;
|
ULONG ulForegroundClr, ulBackgroundClr, ulBrushClr;
|
||||||
|
@ -200,10 +202,9 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
|
||||||
DC_vUpdateBackgroundBrush(dc);
|
DC_vUpdateBackgroundBrush(dc);
|
||||||
|
|
||||||
DPRINT1("GdiBCPolyPatBlt Testing\n");
|
DPRINT1("GdiBCPolyPatBlt Testing\n");
|
||||||
pRects = pgDPB->pRect;
|
pRects = &pgDPB->pRect[0];
|
||||||
cRects = pgDPB->Count;
|
|
||||||
|
|
||||||
for (i = 0; i < cRects; i++)
|
for (i = 0; i < pgDPB->Count; i++)
|
||||||
{
|
{
|
||||||
pbrush = BRUSH_ShareLockBrush(pRects->hBrush);
|
pbrush = BRUSH_ShareLockBrush(pRects->hBrush);
|
||||||
|
|
||||||
|
@ -238,21 +239,141 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
|
||||||
dc->pdcattr->ulBrushClr = ulBrushClr;
|
dc->pdcattr->ulBrushClr = ulBrushClr;
|
||||||
dc->pdcattr->ulDirty_ |= flags;
|
dc->pdcattr->ulDirty_ |= flags;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GdiBCTextOut:
|
case GdiBCTextOut:
|
||||||
|
{
|
||||||
|
PGDIBSTEXTOUT pgO;
|
||||||
|
COLORREF crColor = -1, crBkColor;
|
||||||
|
ULONG ulForegroundClr, ulBackgroundClr;
|
||||||
|
DWORD flags = 0, saveflags;
|
||||||
|
FLONG flTextAlign = -1;
|
||||||
|
HANDLE hlfntNew;
|
||||||
|
PRECTL lprc;
|
||||||
|
USHORT jBkMode;
|
||||||
|
LONG lBkMode;
|
||||||
|
if (!dc) break;
|
||||||
|
pgO = (PGDIBSTEXTOUT) pHdr;
|
||||||
|
|
||||||
|
// Save current attributes, flags and Set the attribute snapshots
|
||||||
|
saveflags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_TEXT|DIRTY_FILL|DC_BRUSH_DIRTY|DIRTY_CHARSET);
|
||||||
|
|
||||||
|
// In this instance check for differences and set the appropriate dirty flags.
|
||||||
|
if ( dc->pdcattr->crForegroundClr != pgO->crForegroundClr)
|
||||||
|
{
|
||||||
|
crColor = dc->pdcattr->crForegroundClr;
|
||||||
|
dc->pdcattr->crForegroundClr = pgO->crForegroundClr;
|
||||||
|
ulForegroundClr = dc->pdcattr->ulForegroundClr;
|
||||||
|
dc->pdcattr->ulForegroundClr = pgO->ulForegroundClr;
|
||||||
|
flags |= (DIRTY_FILL|DIRTY_LINE|DIRTY_TEXT);
|
||||||
|
}
|
||||||
|
if (dc->pdcattr->crBackgroundClr != pgO->crBackgroundClr)
|
||||||
|
{
|
||||||
|
crBkColor = dc->pdcattr->ulBackgroundClr;
|
||||||
|
dc->pdcattr->crBackgroundClr = pgO->crBackgroundClr;
|
||||||
|
ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
|
||||||
|
dc->pdcattr->ulBackgroundClr = pgO->ulBackgroundClr;
|
||||||
|
flags |= (DIRTY_FILL|DIRTY_LINE|DIRTY_TEXT|DIRTY_BACKGROUND);
|
||||||
|
}
|
||||||
|
if (dc->pdcattr->flTextAlign != pgO->flTextAlign)
|
||||||
|
{
|
||||||
|
flTextAlign = dc->pdcattr->flTextAlign;
|
||||||
|
dc->pdcattr->flTextAlign = pgO->flTextAlign;
|
||||||
|
}
|
||||||
|
if (dc->pdcattr->hlfntNew != pgO->hlfntNew)
|
||||||
|
{
|
||||||
|
hlfntNew = dc->pdcattr->hlfntNew;
|
||||||
|
dc->pdcattr->hlfntNew = pgO->hlfntNew;
|
||||||
|
dc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
|
||||||
|
flags |= DIRTY_CHARSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
dc->pdcattr->ulDirty_ |= flags;
|
||||||
|
|
||||||
|
jBkMode = dc->pdcattr->jBkMode;
|
||||||
|
dc->pdcattr->jBkMode = pgO->lBkMode;
|
||||||
|
lBkMode = dc->pdcattr->lBkMode;
|
||||||
|
dc->pdcattr->lBkMode = pgO->lBkMode;
|
||||||
|
|
||||||
|
lprc = (pgO->Options & GDIBS_NORECT) ? NULL : &pgO->Rect;
|
||||||
|
pgO->Options &= ~GDIBS_NORECT;
|
||||||
|
|
||||||
|
IntExtTextOutW( dc,
|
||||||
|
pgO->x,
|
||||||
|
pgO->y,
|
||||||
|
pgO->Options,
|
||||||
|
lprc,
|
||||||
|
(LPCWSTR)&pgO->String[pgO->Size/sizeof(WCHAR)],
|
||||||
|
pgO->cbCount,
|
||||||
|
pgO->Size ? (LPINT)&pgO->Buffer : NULL,
|
||||||
|
pgO->iCS_CP );
|
||||||
|
|
||||||
|
// Restore attributes and flags
|
||||||
|
dc->pdcattr->jBkMode = jBkMode;
|
||||||
|
dc->pdcattr->lBkMode = lBkMode;
|
||||||
|
|
||||||
|
if (flags & DIRTY_TEXT && crColor != -1)
|
||||||
|
{
|
||||||
|
dc->pdcattr->crForegroundClr = crColor;
|
||||||
|
dc->pdcattr->ulForegroundClr = ulForegroundClr;
|
||||||
|
}
|
||||||
|
if (flags & DIRTY_BACKGROUND)
|
||||||
|
{
|
||||||
|
dc->pdcattr->crBackgroundClr = crBkColor;
|
||||||
|
dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
|
||||||
|
}
|
||||||
|
if (flTextAlign != -1)
|
||||||
|
{
|
||||||
|
dc->pdcattr->flTextAlign = flTextAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & DIRTY_CHARSET)
|
||||||
|
{
|
||||||
|
dc->pdcattr->hlfntNew = hlfntNew;
|
||||||
|
dc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
|
||||||
|
}
|
||||||
|
dc->pdcattr->ulDirty_ |= saveflags | flags;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GdiBCExtTextOut:
|
case GdiBCExtTextOut:
|
||||||
{
|
{
|
||||||
//GreExtTextOutW( hDC,
|
PGDIBSEXTTEXTOUT pgO;
|
||||||
// XStart,
|
COLORREF crBkColor;
|
||||||
// YStart,
|
ULONG ulBackgroundClr;
|
||||||
// fuOptions,
|
DWORD flags = 0, saveflags;
|
||||||
// &SafeRect,
|
if (!dc) break;
|
||||||
// SafeString,
|
pgO = (PGDIBSEXTTEXTOUT) pHdr;
|
||||||
// Count,
|
|
||||||
// SafeDx,
|
saveflags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_FILL|DC_BRUSH_DIRTY|DIRTY_CHARSET);
|
||||||
// dwCodePage );
|
|
||||||
|
if (dc->pdcattr->crBackgroundClr != pgO->ulBackgroundClr)
|
||||||
|
{
|
||||||
|
crBkColor = dc->pdcattr->crBackgroundClr;
|
||||||
|
ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
|
||||||
|
dc->pdcattr->crBackgroundClr = pgO->ulBackgroundClr;
|
||||||
|
dc->pdcattr->ulBackgroundClr = pgO->ulBackgroundClr;
|
||||||
|
flags |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
dc->pdcattr->ulDirty_ |= flags;
|
||||||
|
|
||||||
|
IntExtTextOutW( dc,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
pgO->Options,
|
||||||
|
&pgO->Rect,
|
||||||
|
NULL,
|
||||||
|
pgO->Count,
|
||||||
|
NULL,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
if (flags & DIRTY_BACKGROUND)
|
||||||
|
{
|
||||||
|
dc->pdcattr->crBackgroundClr = crBkColor;
|
||||||
|
dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
|
||||||
|
}
|
||||||
|
dc->pdcattr->ulDirty_ |= saveflags | flags;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +429,7 @@ APIENTRY
|
||||||
NtGdiFlush(
|
NtGdiFlush(
|
||||||
VOID)
|
VOID)
|
||||||
{
|
{
|
||||||
SynchonizeDriver(GCAPS2_SYNCFLUSH);
|
SynchronizeDriver(GCAPS2_SYNCFLUSH);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -495,12 +495,17 @@ typedef struct _GDIBSPPATBLT
|
||||||
PATRECT pRect[1]; // POLYPATBLT
|
PATRECT pRect[1]; // POLYPATBLT
|
||||||
} GDIBSPPATBLT, *PGDIBSPPATBLT;
|
} GDIBSPPATBLT, *PGDIBSPPATBLT;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Both ExtSelectClipRgn and TextOut pass a nill RECT.
|
||||||
|
//
|
||||||
|
#define GDIBS_NORECT 0x80000000
|
||||||
|
|
||||||
typedef struct _GDIBSTEXTOUT
|
typedef struct _GDIBSTEXTOUT
|
||||||
{
|
{
|
||||||
GDIBATCHHDR gbHdr;
|
GDIBATCHHDR gbHdr;
|
||||||
COLORREF crForegroundClr;
|
COLORREF crForegroundClr;
|
||||||
COLORREF crBackgroundClr;
|
COLORREF crBackgroundClr;
|
||||||
LONG lmBkMode;
|
LONG lBkMode;
|
||||||
ULONG ulForegroundClr;
|
ULONG ulForegroundClr;
|
||||||
ULONG ulBackgroundClr;
|
ULONG ulBackgroundClr;
|
||||||
int x;
|
int x;
|
||||||
|
@ -513,7 +518,10 @@ typedef struct _GDIBSTEXTOUT
|
||||||
HANDLE hlfntNew;
|
HANDLE hlfntNew;
|
||||||
FLONG flTextAlign;
|
FLONG flTextAlign;
|
||||||
POINTL ptlViewportOrg;
|
POINTL ptlViewportOrg;
|
||||||
|
union {
|
||||||
WCHAR String[2];
|
WCHAR String[2];
|
||||||
|
ULONG Buffer[1];
|
||||||
|
};
|
||||||
} GDIBSTEXTOUT, *PGDIBSTEXTOUT;
|
} GDIBSTEXTOUT, *PGDIBSTEXTOUT;
|
||||||
|
|
||||||
typedef struct _GDIBSEXTTEXTOUT
|
typedef struct _GDIBSEXTTEXTOUT
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue