diff --git a/reactos/dll/win32/gdi32/objects/dc.c b/reactos/dll/win32/gdi32/objects/dc.c index 4ecd2cbcd6e..5de287b376d 100644 --- a/reactos/dll/win32/gdi32/objects/dc.c +++ b/reactos/dll/win32/gdi32/objects/dc.c @@ -1561,23 +1561,19 @@ SelectObject(HDC hDC, return NtGdiSelectBitmap(hDC, hGdiObj); case GDI_OBJECT_TYPE_BRUSH: -#if 0 // enable this when support is ready in win32k hOldObj = pDc_Attr->hbrush; pDc_Attr->ulDirty_ |= DC_BRUSH_DIRTY; pDc_Attr->hbrush = hGdiObj; return hOldObj; -#endif - return NtGdiSelectBrush(hDC, hGdiObj); +// return NtGdiSelectBrush(hDC, hGdiObj); case GDI_OBJECT_TYPE_PEN: case GDI_OBJECT_TYPE_EXTPEN: -#if 0 // enable this when support is ready in win32k hOldObj = pDc_Attr->hpen; pDc_Attr->ulDirty_ |= DC_PEN_DIRTY; pDc_Attr->hpen = hGdiObj; return hOldObj; -#endif - return NtGdiSelectPen(hDC, hGdiObj); +// return NtGdiSelectPen(hDC, hGdiObj); case GDI_OBJECT_TYPE_FONT: hOldObj = pDc_Attr->hlfntNew; diff --git a/reactos/subsystems/win32/win32k/objects/bitblt.c b/reactos/subsystems/win32/win32k/objects/bitblt.c index f0598e131bc..db8e188e202 100644 --- a/reactos/subsystems/win32/win32k/objects/bitblt.c +++ b/reactos/subsystems/win32/win32k/objects/bitblt.c @@ -225,6 +225,9 @@ NtGdiBitBlt( Dc_Attr = DCDest->pDc_Attr; if (!Dc_Attr) Dc_Attr = &DCDest->Dc_Attr; + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(DCDest,Dc_Attr->hbrush); + /* Offset the destination and source by the origin of their DCs. */ XDest += DCDest->ptlDCOrig.x; YDest += DCDest->ptlDCOrig.y; @@ -484,6 +487,7 @@ done: * * Someone thought it would be faster to do it here and then switch back * to GDI32. I dunno. Write a test and let me know. + * A. It should be in here! */ static __inline BYTE @@ -781,6 +785,12 @@ NtGdiStretchBlt( } } + Dc_Attr = DCDest->pDc_Attr; + if (!Dc_Attr) Dc_Attr = &DCDest->Dc_Attr; + + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(DCDest,Dc_Attr->hbrush); + /* Offset the destination and source by the origin of their DCs. */ // FIXME: ptlDCOrig is in device coordinates! XOriginDest += DCDest->ptlDCOrig.x; @@ -880,8 +890,6 @@ NtGdiStretchBlt( if (UsesPattern) { - Dc_Attr = DCDest->pDc_Attr; - if (!Dc_Attr) Dc_Attr = &DCDest->Dc_Attr; BrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush); if (NULL == BrushObj) { @@ -1008,6 +1016,7 @@ IntGdiPolyPatBlt( int i; PPATRECT r; PGDIBRUSHOBJ BrushObj; + PDC_ATTR Dc_Attr; DC *dc; dc = DC_LockDc(hDC); @@ -1023,6 +1032,12 @@ IntGdiPolyPatBlt( return TRUE; } + Dc_Attr = dc->pDc_Attr; + if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + for (r = pRects, i = 0; i < cRects; i++) { BrushObj = BRUSHOBJ_LockBrush(r->hBrush); @@ -1074,8 +1089,6 @@ NtGdiPatBlt( SetLastWin32Error(ERROR_INVALID_HANDLE); return FALSE; } - Dc_Attr = dc->pDc_Attr; - if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; if (dc->DC_Type == DC_TYPE_INFO) { DC_UnlockDc(dc); @@ -1083,6 +1096,12 @@ NtGdiPatBlt( return TRUE; } + Dc_Attr = dc->pDc_Attr; + if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + BrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush); if (BrushObj == NULL) { diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index bffd0f1f445..245ab547745 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -130,8 +130,8 @@ NtGdiCreateCompatibleDC(HDC hDC) NewDC->DC_Type = DC_TYPE_MEMORY; // Always! NewDC->w.hBitmap = NtGdiGetStockObject(DEFAULT_BITMAP); NewDC->pPDev = OrigDC->pPDev; + NewDC->DcLevel.hpal = OrigDC->DcLevel.hpal; - NewDC->DcLevel.hpal = OrigDC->DcLevel.hpal; nDc_Attr->lTextAlign = oDc_Attr->lTextAlign; nDc_Attr->ulForegroundClr = oDc_Attr->ulForegroundClr; nDc_Attr->ulBackgroundClr = oDc_Attr->ulBackgroundClr; @@ -1138,6 +1138,13 @@ NtGdiGetDCObject(HDC hDC, INT ObjectType) } Dc_Attr = dc->pDc_Attr; if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + switch(ObjectType) { case GDI_OBJECT_TYPE_EXTPEN: diff --git a/reactos/subsystems/win32/win32k/objects/dcutil.c b/reactos/subsystems/win32/win32k/objects/dcutil.c index 23ef0558111..a76ce42558a 100644 --- a/reactos/subsystems/win32/win32k/objects/dcutil.c +++ b/reactos/subsystems/win32/win32k/objects/dcutil.c @@ -199,7 +199,7 @@ IntGdiSetBkColor(HDC hDC, COLORREF color) oldColor = Dc_Attr->crBackgroundClr; Dc_Attr->crBackgroundClr = color; Dc_Attr->ulBackgroundClr = (ULONG)color; - Dc_Attr->ulDirty_ &= ~DIRTY_LINE; // Clear Flag if set. + Dc_Attr->ulDirty_ &= ~(DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set. hBrush = Dc_Attr->hbrush; DC_UnlockDc(dc); NtGdiSelectBrush(hDC, hBrush); @@ -271,6 +271,7 @@ IntGdiSetTextColor(HDC hDC, oldColor = Dc_Attr->crForegroundClr; Dc_Attr->crForegroundClr = color; hBrush = Dc_Attr->hbrush; + Dc_Attr->ulDirty_ &= ~(DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL); DC_UnlockDc( dc ); NtGdiSelectBrush(hDC, hBrush); return oldColor; diff --git a/reactos/subsystems/win32/win32k/objects/fillshap.c b/reactos/subsystems/win32/win32k/objects/fillshap.c index 6bf346339d1..fc25c99edfe 100644 --- a/reactos/subsystems/win32/win32k/objects/fillshap.c +++ b/reactos/subsystems/win32/win32k/objects/fillshap.c @@ -95,6 +95,12 @@ IntGdiPolygon(PDC dc, DestRect.bottom = max(DestRect.bottom, Points[CurrentPoint].y); } + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + /* Special locking order to avoid lock-ups */ FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush); PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen); @@ -242,6 +248,12 @@ NtGdiEllipse( Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen); if (NULL == PenBrushObj) { @@ -544,6 +556,12 @@ IntRectangle(PDC dc, DestRect.bottom--; } + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + /* Special locking order to avoid lock-ups! */ FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush); PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen); @@ -703,6 +721,12 @@ IntRoundRect( Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen); if (!PenBrushObj) { @@ -1024,10 +1048,95 @@ NtGdiExtFloodFill( COLORREF Color, UINT FillType) { - DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n"); + PDC dc; + PDC_ATTR Dc_Attr; + BITMAPOBJ *BitmapObj = NULL; + PGDIBRUSHOBJ FillBrushObj = NULL; + GDIBRUSHINST FillBrushInst; + BOOL Ret = FALSE; + RECTL DestRect; + POINTL Pt; +// MIX Mix; - /* lie and say we succeded */ - return TRUE; + DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n"); + + dc = DC_LockDc(hDC); + if (!dc) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + if (dc->DC_Type == DC_TYPE_INFO) + { + DC_UnlockDc(dc); + /* Yes, Windows really returns TRUE in this case */ + return TRUE; + } + + Dc_Attr = dc->pDc_Attr; + if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + Pt.x = XStart; + Pt.y = YStart; + IntLPtoDP(dc, (LPPOINT)&Pt, 1); + + Ret = NtGdiPtInRegion(dc->w.hGCClipRgn, Pt.x, Pt.y); + if (Ret) + IntGdiGetRgnBox(dc->w.hGCClipRgn,(LPRECT)&DestRect); + else + goto cleanup; + + FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush); + if (!FillBrushObj) + { + Ret = FALSE; + goto cleanup; + } + BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + if (!BitmapObj) + { + Ret = FALSE; + goto cleanup; + } + + if ( FillBrushObj && (FillType == FLOODFILLBORDER)) + { + if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL)) + { + FillBrushObj->BrushAttr.lbColor = Color; + IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush); + Ret = IntEngBitBlt(&BitmapObj->SurfObj, + NULL, + NULL, + dc->CombinedClip, + NULL, + &DestRect, + NULL, + NULL, + &FillBrushInst.BrushObject, + NULL, + ROP3_TO_ROP4(PATCOPY)); + } + } + else + { + } + +cleanup: + if (FillBrushObj) + BRUSHOBJ_UnlockBrush(FillBrushObj); + + if (BitmapObj) + BITMAPOBJ_UnlockBitmap(BitmapObj); + + DC_UnlockDc(dc); + return Ret; } /* EOF */ diff --git a/reactos/subsystems/win32/win32k/objects/line.c b/reactos/subsystems/win32/win32k/objects/line.c index acb098caf48..c4368a812ca 100644 --- a/reactos/subsystems/win32/win32k/objects/line.c +++ b/reactos/subsystems/win32/win32k/objects/line.c @@ -115,6 +115,12 @@ IntGdiLineTo(DC *dc, } else { + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + BitmapObj = BITMAPOBJ_LockBitmap ( dc->w.hBitmap ); if (NULL == BitmapObj) { @@ -257,9 +263,16 @@ IntGdiPolyline(DC *dc, PDC_ATTR Dc_Attr = dc->pDc_Attr; if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + if (PATH_IsPathOpen(dc->DcLevel)) return PATH_Polyline(dc, pt, Count); + if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,Dc_Attr->hbrush); + + if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(dc,Dc_Attr->hpen); + /* Get BRUSHOBJ from current pen. */ PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen); /* FIXME - PenBrushObj can be NULL! Don't assert here! */ diff --git a/reactos/subsystems/win32/win32k/objects/path.c b/reactos/subsystems/win32/win32k/objects/path.c index 980041511f1..4365bc6eb76 100644 --- a/reactos/subsystems/win32/win32k/objects/path.c +++ b/reactos/subsystems/win32/win32k/objects/path.c @@ -1329,7 +1329,9 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath) if (pPath->state != PATH_Closed) return FALSE; - if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; + + /* Save the mapping mode info */ mapMode = Dc_Attr->iMapMode; IntGetViewportExtEx(dc, &szViewportExt); @@ -2265,8 +2267,9 @@ BOOL STDCALL NtGdiFillPath(HDC hDC) { - BOOL ret = TRUE; + BOOL ret = FALSE; PPATH pPath; + PDC_ATTR pDc_Attr; PDC dc = DC_LockDc ( hDC ); if ( !dc ) @@ -2281,6 +2284,12 @@ NtGdiFillPath(HDC hDC) return FALSE; } + pDc_Attr = dc->pDc_Attr; + if (!pDc_Attr) pDc_Attr = &dc->Dc_Attr; + + if (pDc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(dc,pDc_Attr->hbrush); + ret = PATH_FillPath( dc, pPath ); if ( ret ) { @@ -2534,6 +2543,7 @@ STDCALL NtGdiStrokeAndFillPath(HDC hDC) { DC *pDc; + PDC_ATTR pDc_Attr; PPATH pPath; BOOL bRet = FALSE; @@ -2550,6 +2560,15 @@ NtGdiStrokeAndFillPath(HDC hDC) DC_UnlockDc ( pDc ); return FALSE; } + + pDc_Attr = pDc->pDc_Attr; + if (!pDc_Attr) pDc_Attr = &pDc->Dc_Attr; + + if (pDc_Attr->ulDirty_ & DC_BRUSH_DIRTY) + IntGdiSelectBrush(pDc,pDc_Attr->hbrush); + if (pDc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(pDc,pDc_Attr->hpen); + bRet = PATH_FillPath(pDc, pPath); if (bRet) bRet = PATH_StrokePath(pDc, pPath); if (bRet) PATH_EmptyPath(pPath); @@ -2564,6 +2583,7 @@ STDCALL NtGdiStrokePath(HDC hDC) { DC *pDc; + PDC_ATTR pDc_Attr; PPATH pPath; BOOL bRet = FALSE; @@ -2581,6 +2601,12 @@ NtGdiStrokePath(HDC hDC) return FALSE; } + pDc_Attr = pDc->pDc_Attr; + if (!pDc_Attr) pDc_Attr = &pDc->Dc_Attr; + + if (pDc_Attr->ulDirty_ & DC_PEN_DIRTY) + IntGdiSelectPen(pDc,pDc_Attr->hpen); + bRet = PATH_StrokePath(pDc, pPath); PATH_EmptyPath(pPath); diff --git a/reactos/subsystems/win32/win32k/objects/pen.c b/reactos/subsystems/win32/win32k/objects/pen.c index a8c0eb40f57..83a03ad06e0 100644 --- a/reactos/subsystems/win32/win32k/objects/pen.c +++ b/reactos/subsystems/win32/win32k/objects/pen.c @@ -260,6 +260,8 @@ IntGdiSelectPen( XLATEOBJ *XlateObj; BOOLEAN bFailed; + if (pDC == NULL || hPen == NULL) return NULL; + pDc_Attr = pDC->pDc_Attr; if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;