BOOL FASTCALL IntGdiPolyPolygon(DC *dc, LPPOINT Points, PULONG PolyCounts, int Count) { if (PATH_IsPathOpen(dc->dclevel)) return PATH_PolyPolygon ( dc, Points, (PINT)PolyCounts, Count); while (--Count >=0) { if (!IntGdiPolygon ( dc, Points, *PolyCounts )) return FALSE; Points+=*PolyCounts++; } return TRUE; }
BOOL FASTCALL IntRoundRect( PDC dc, int Left, int Top, int Right, int Bottom, int xCurveDiameter, int yCurveDiameter) { PDC_ATTR pdcattr; PBRUSH pbrLine, pbrFill; RECTL RectBounds; LONG PenWidth, PenOrigWidth; BOOL ret = TRUE; // Default to success BRUSH brushTemp; ASSERT ( dc ); // Caller's responsibility to set this up if ( PATH_IsPathOpen(dc->dclevel) ) return PATH_RoundRect ( dc, Left, Top, Right, Bottom, xCurveDiameter, yCurveDiameter ); if ((Left == Right) || (Top == Bottom)) return TRUE; xCurveDiameter = max(abs( xCurveDiameter ), 1); yCurveDiameter = max(abs( yCurveDiameter ), 1); if (Right < Left) { INT tmp = Right; Right = Left; Left = tmp; } if (Bottom < Top) { INT tmp = Bottom; Bottom = Top; Top = tmp; } pdcattr = dc->pdcattr; if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(dc); if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(dc); pbrLine = PEN_ShareLockPen(pdcattr->hpen); if (!pbrLine) { /* Nothing to do, as we don't have a bitmap */ EngSetLastError(ERROR_INTERNAL_ERROR); return FALSE; } PenOrigWidth = PenWidth = pbrLine->ptPenWidth.x; if (pbrLine->ulPenStyle == PS_NULL) PenWidth = 0; if (pbrLine->ulPenStyle == PS_INSIDEFRAME) { if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2; if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2; Left += PenWidth / 2; Right -= (PenWidth - 1) / 2; Top += PenWidth / 2; Bottom -= (PenWidth - 1) / 2; } if (!PenWidth) PenWidth = 1; pbrLine->ptPenWidth.x = PenWidth; RectBounds.left = Left; RectBounds.top = Top; RectBounds.right = Right; RectBounds.bottom = Bottom; IntLPtoDP(dc, (LPPOINT)&RectBounds, 2); RectBounds.left += dc->ptlDCOrig.x; RectBounds.top += dc->ptlDCOrig.y; RectBounds.right += dc->ptlDCOrig.x; RectBounds.bottom += dc->ptlDCOrig.y; pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush); if (!pbrFill) { DPRINT1("FillRound Fail\n"); EngSetLastError(ERROR_INTERNAL_ERROR); ret = FALSE; } else { DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds); RtlCopyMemory(&brushTemp, pbrFill, sizeof(brushTemp)); brushTemp.ptOrigin.x += RectBounds.left - Left; brushTemp.ptOrigin.y += RectBounds.top - Top; ret = IntFillRoundRect( dc, RectBounds.left, RectBounds.top, RectBounds.right, RectBounds.bottom, xCurveDiameter, yCurveDiameter, &brushTemp); BRUSH_ShareUnlockBrush(pbrFill); if (ret) { ret = IntDrawRoundRect( dc, RectBounds.left, RectBounds.top, RectBounds.right, RectBounds.bottom, xCurveDiameter, yCurveDiameter, pbrLine); } DC_vFinishBlit(dc, NULL); } pbrLine->ptPenWidth.x = PenOrigWidth; PEN_ShareUnlockPen(pbrLine); return ret; }
BOOL FASTCALL IntRectangle(PDC dc, int LeftRect, int TopRect, int RightRect, int BottomRect) { SURFACE *psurf = NULL; PBRUSH pbrLine, pbrFill; BOOL ret = FALSE; // Default to failure RECTL DestRect; MIX Mix; PDC_ATTR pdcattr; POINTL BrushOrigin; ASSERT ( dc ); // Caller's responsibility to set this up pdcattr = dc->pdcattr; // Rectangle Path only. if ( PATH_IsPathOpen(dc->dclevel) ) { return PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect ); } /* Make sure rectangle is not inverted */ DestRect.left = min(LeftRect, RightRect); DestRect.right = max(LeftRect, RightRect); DestRect.top = min(TopRect, BottomRect); DestRect.bottom = max(TopRect, BottomRect); IntLPtoDP(dc, (LPPOINT)&DestRect, 2); DestRect.left += dc->ptlDCOrig.x; DestRect.right += dc->ptlDCOrig.x; DestRect.top += dc->ptlDCOrig.y; DestRect.bottom += dc->ptlDCOrig.y; /* In GM_COMPATIBLE, don't include bottom and right edges */ if (pdcattr->iGraphicsMode == GM_COMPATIBLE) { DestRect.right--; DestRect.bottom--; } DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect); if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(dc); if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(dc); pbrFill = dc->dclevel.pbrFill; pbrLine = dc->dclevel.pbrLine; if (!pbrLine) { ret = FALSE; goto cleanup; } psurf = dc->dclevel.pSurface; if (!psurf) { ret = FALSE; goto cleanup; } if (pbrFill) { if (!(pbrFill->flAttrs & BR_IS_NULL)) { BrushOrigin = *((PPOINTL)&pbrFill->ptOrigin); BrushOrigin.x += dc->ptlDCOrig.x; BrushOrigin.y += dc->ptlDCOrig.y; ret = IntEngBitBlt(&psurf->SurfObj, NULL, NULL, dc->rosdc.CombinedClip, NULL, &DestRect, NULL, NULL, &dc->eboFill.BrushObject, &BrushOrigin, ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY)); } } // Draw the rectangle with the current pen ret = TRUE; // Change default to success if (!(pbrLine->flAttrs & BR_IS_NULL)) { Mix = ROP2_TO_MIX(pdcattr->jROP2); ret = ret && IntEngLineTo(&psurf->SurfObj, dc->rosdc.CombinedClip, &dc->eboLine.BrushObject, DestRect.left, DestRect.top, DestRect.right, DestRect.top, &DestRect, // Bounding rectangle Mix); ret = ret && IntEngLineTo(&psurf->SurfObj, dc->rosdc.CombinedClip, &dc->eboLine.BrushObject, DestRect.right, DestRect.top, DestRect.right, DestRect.bottom, &DestRect, // Bounding rectangle Mix); ret = ret && IntEngLineTo(&psurf->SurfObj, dc->rosdc.CombinedClip, &dc->eboLine.BrushObject, DestRect.right, DestRect.bottom, DestRect.left, DestRect.bottom, &DestRect, // Bounding rectangle Mix); ret = ret && IntEngLineTo(&psurf->SurfObj, dc->rosdc.CombinedClip, &dc->eboLine.BrushObject, DestRect.left, DestRect.bottom, DestRect.left, DestRect.top, &DestRect, // Bounding rectangle Mix); } cleanup: DC_vFinishBlit(dc, NULL); /* Move current position in DC? MSDN: The current position is neither used nor updated by Rectangle. */ return ret; }
BOOL APIENTRY NtGdiEllipse( HDC hDC, int Left, int Top, int Right, int Bottom) { PDC dc; PDC_ATTR pdcattr; RECTL RectBounds; PBRUSH pbrush; BOOL ret = TRUE; LONG PenWidth, PenOrigWidth; LONG RadiusX, RadiusY, CenterX, CenterY; PBRUSH pFillBrushObj; BRUSH tmpFillBrushObj; if ((Left == Right) || (Top == Bottom)) return TRUE; dc = DC_LockDc(hDC); if (dc == NULL) { EngSetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (dc->dctype == DC_TYPE_INFO) { DC_UnlockDc(dc); /* Yes, Windows really returns TRUE in this case */ return TRUE; } if (PATH_IsPathOpen(dc->dclevel)) { ret = PATH_Ellipse(dc, Left, Top, Right, Bottom); DC_UnlockDc(dc); return ret; } if (Right < Left) { INT tmp = Right; Right = Left; Left = tmp; } if (Bottom < Top) { INT tmp = Bottom; Bottom = Top; Top = tmp; } pdcattr = dc->pdcattr; if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(dc); if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(dc); pbrush = PEN_ShareLockPen(pdcattr->hpen); if (!pbrush) { DPRINT1("Ellipse Fail 1\n"); DC_UnlockDc(dc); EngSetLastError(ERROR_INTERNAL_ERROR); return FALSE; } PenOrigWidth = PenWidth = pbrush->ptPenWidth.x; if (pbrush->ulPenStyle == PS_NULL) PenWidth = 0; if (pbrush->ulPenStyle == PS_INSIDEFRAME) { if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2; if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2; Left += PenWidth / 2; Right -= (PenWidth - 1) / 2; Top += PenWidth / 2; Bottom -= (PenWidth - 1) / 2; } if (!PenWidth) PenWidth = 1; pbrush->ptPenWidth.x = PenWidth; RectBounds.left = Left; RectBounds.right = Right; RectBounds.top = Top; RectBounds.bottom = Bottom; IntLPtoDP(dc, (LPPOINT)&RectBounds, 2); RectBounds.left += dc->ptlDCOrig.x; RectBounds.right += dc->ptlDCOrig.x; RectBounds.top += dc->ptlDCOrig.y; RectBounds.bottom += dc->ptlDCOrig.y; // Setup for dynamic width and height. RadiusX = max((RectBounds.right - RectBounds.left) / 2, 2); // Needs room RadiusY = max((RectBounds.bottom - RectBounds.top) / 2, 2); CenterX = (RectBounds.right + RectBounds.left) / 2; CenterY = (RectBounds.bottom + RectBounds.top) / 2; DPRINT("Ellipse 1: Left: %d, Top: %d, Right: %d, Bottom: %d\n", RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom); DPRINT("Ellipse 2: XLeft: %d, YLeft: %d, Width: %d, Height: %d\n", CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2); pFillBrushObj = BRUSH_ShareLockBrush(pdcattr->hbrush); if (NULL == pFillBrushObj) { DPRINT1("FillEllipse Fail\n"); EngSetLastError(ERROR_INTERNAL_ERROR); ret = FALSE; } else { RtlCopyMemory(&tmpFillBrushObj, pFillBrushObj, sizeof(tmpFillBrushObj)); //tmpFillBrushObj.ptOrigin.x += RectBounds.left - Left; //tmpFillBrushObj.ptOrigin.y += RectBounds.top - Top; tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x; tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y; DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds); ret = IntFillEllipse( dc, CenterX - RadiusX, CenterY - RadiusY, RadiusX*2, // Width RadiusY*2, // Height &tmpFillBrushObj); BRUSH_ShareUnlockBrush(pFillBrushObj); if (ret) { ret = IntDrawEllipse( dc, CenterX - RadiusX, CenterY - RadiusY, RadiusX*2, // Width RadiusY*2, // Height pbrush); } DC_vFinishBlit(dc, NULL); } pbrush->ptPenWidth.x = PenOrigWidth; PEN_ShareUnlockPen(pbrush); DC_UnlockDc(dc); DPRINT("Ellipse Exit.\n"); return ret; }
BOOL FASTCALL IntGdiArcInternal( ARCTYPE arctype, DC *dc, int LeftRect, int TopRect, int RightRect, int BottomRect, int XStartArc, int YStartArc, int XEndArc, int YEndArc) { BOOL Ret; //PDC_ATTR pdcattr; DPRINT("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n", XStartArc,YStartArc,XEndArc,YEndArc); DPRINT("Left: %d, Top: %d, Right: %d, Bottom: %d\n", LeftRect,TopRect,RightRect,BottomRect); if ((LeftRect == RightRect) || (TopRect == BottomRect)) return TRUE; if (PATH_IsPathOpen(dc->dclevel)) { return PATH_Arc( dc, LeftRect, TopRect, RightRect, BottomRect, XStartArc, YStartArc, XEndArc, YEndArc, arctype); } //pdcattr = dc->pdcattr; if (arctype == GdiTypeArcTo) { if (dc->dclevel.flPath & DCPATH_CLOCKWISE) IntGdiLineTo(dc, XEndArc, YEndArc); else IntGdiLineTo(dc, XStartArc, YStartArc); } Ret = IntArc( dc, LeftRect, TopRect, RightRect, BottomRect, XStartArc, YStartArc, XEndArc, YEndArc, arctype); if (arctype == GdiTypeArcTo) { if (dc->dclevel.flPath & DCPATH_CLOCKWISE) IntGdiMoveToEx(dc, XStartArc, YStartArc, NULL, TRUE); else IntGdiMoveToEx(dc, XEndArc, YEndArc, NULL, TRUE); } return Ret; }