📄 fillshap.c
字号:
return TRUE;
}
BOOL
STDCALL
NtGdiRectangle(HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect)
{
DC *dc;
BOOL ret; // default to failure
dc = DC_LockDc(hDC);
if(!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (dc->IsIC)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
DC_UnlockDc ( dc );
return ret;
}
BOOL
FASTCALL
IntRoundRect(
PDC dc,
int left,
int top,
int right,
int bottom,
int xCurveDiameter,
int yCurveDiameter)
{
BITMAPOBJ *BitmapObj;
PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
GDIBRUSHINST FillBrushInst, PenBrushInst;
RECTL RectBounds;
int potential_steps;
int i, col, row, width, height, x1, x1start, x2, x2start, y1, y2;
int xradius, yradius;
//float aspect_square;
long a_square, b_square,
two_a_square, two_b_square,
four_a_square, four_b_square,
d, dinc, ddec;
BOOL first,
ret = TRUE; // default to success
ASSERT ( dc ); // caller's responsibility to set this up
if ( PATH_IsPathOpen(dc->w.path) )
return PATH_RoundRect ( dc, left, top, right, bottom,
xCurveDiameter, yCurveDiameter );
xradius = xCurveDiameter >> 1;
yradius = yCurveDiameter >> 1;
left += dc->w.DCOrgX;
right += dc->w.DCOrgX;
top += dc->w.DCOrgY;
bottom += dc->w.DCOrgY;
RectBounds.left = left;
RectBounds.right = right;
RectBounds.top = top;
RectBounds.bottom = bottom;
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
if (!BitmapObj)
{
/* Nothing to do, as we don't have a bitmap */
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return FALSE;
}
FillBrushObj = BRUSHOBJ_LockBrush(dc->Dc_Attr.hbrush);
if (FillBrushObj)
{
if (FillBrushObj->flAttrs & GDIBRUSH_IS_NULL)
{
/* make null brush check simpler... */
BRUSHOBJ_UnlockBrush(FillBrushObj);
FillBrushObj = NULL;
}
else
{
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
}
}
PenBrushObj = PENOBJ_LockPen(dc->Dc_Attr.hpen);
if (PenBrushObj)
{
if (PenBrushObj->flAttrs & GDIBRUSH_IS_NULL)
{
/* make null pen check simpler... */
PENOBJ_UnlockPen(PenBrushObj);
PenBrushObj = NULL;
}
else
{
IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
}
}
right--;
bottom--;
width = right - left;
height = bottom - top;
if ( (xradius<<1) > width )
xradius = width >> 1;
if ( (yradius<<1) > height )
yradius = height >> 1;
b_square = yradius * yradius;
a_square = xradius * xradius;
row = yradius;
col = 0;
two_a_square = a_square << 1;
four_a_square = a_square << 2;
four_b_square = b_square << 2;
two_b_square = b_square << 1;
d = two_a_square * ((row - 1) * (row))
+ a_square
+ two_b_square * (1 - a_square);
x1 = left+xradius;
x2 = right-xradius;
y1 = top;
y2 = bottom;
x1start = x1;
x2start = x2;
dinc = two_b_square*3; /* two_b_square * (3 + (col << 1)); */
ddec = four_a_square * row;
first = TRUE;
for ( ;; )
{
if ( d >= 0 )
{
if ( FillBrushObj )
PUTLINE ( x1, y1, x2, y1, FillBrushInst );
if ( first )
{
if ( PenBrushObj )
{
if ( x1start > x1 )
{
PUTLINE ( x1, y1, x1start, y1, PenBrushInst );
PUTLINE ( x2start+1, y2, x2+1, y2, PenBrushInst );
}
else
{
PUTPIXEL ( x1, y1, PenBrushInst );
PUTPIXEL ( x2, y2, PenBrushInst );
}
}
first = FALSE;
}
else
{
if ( FillBrushObj )
PUTLINE ( x1, y2, x2, y2, FillBrushInst );
if ( PenBrushObj )
{
if ( x1start >= x1 )
{
PUTLINE ( x1, y1, x1start+1, y1, PenBrushInst );
PUTLINE ( x2start, y2, x2+1, y2, PenBrushInst );
}
else
{
PUTPIXEL ( x1, y1, PenBrushInst );
PUTPIXEL ( x2, y2, PenBrushInst );
}
}
}
if ( PenBrushObj )
{
if ( x1start > x1 )
{
PUTLINE ( x1, y2, x1start+1, y2, PenBrushInst );
PUTLINE ( x2start, y1, x2+1, y1, PenBrushInst );
}
else
{
PUTPIXEL ( x1, y2, PenBrushInst );
PUTPIXEL ( x2, y1, PenBrushInst );
}
}
x1start = x1-1;
x2start = x2+1;
row--, y1++, y2--, ddec -= four_a_square;
d -= ddec;
}
potential_steps = ( a_square * row ) / b_square - col + 1;
while ( d < 0 && potential_steps-- )
{
d += dinc; /* two_b_square * (3 + (col << 1)); */
col++, x1--, x2++, dinc += four_b_square;
}
if ( a_square * row <= b_square * col )
break;
};
d = two_b_square * (col + 1) * col
+ two_a_square * (row * (row - 2) + 1)
+ (1 - two_a_square) * b_square;
dinc = ddec; /* four_b_square * col; */
ddec = two_a_square * ((row << 1) - 3);
while ( row )
{
if ( FillBrushObj )
{
PUTLINE ( x1, y1, x2, y1, FillBrushInst );
PUTLINE ( x1, y2, x2, y2, FillBrushInst );
}
if ( PenBrushObj )
{
PUTPIXEL ( x2, y1, PenBrushInst );
PUTPIXEL ( x1, y2, PenBrushInst );
PUTPIXEL ( x2, y2, PenBrushInst );
PUTPIXEL ( x1, y1, PenBrushInst );
}
if ( d <= 0 )
{
col++, x1--, x2++, dinc += four_b_square;
d += dinc; //four_b_square * col;
}
row--, y1++, y2--, ddec -= four_a_square;
d -= ddec; //two_a_square * ((row << 1) - 3);
}
if ( FillBrushObj )
{
PUTLINE ( left, y1, right, y1, FillBrushInst );
PUTLINE ( left, y2, right, y2, FillBrushInst );
}
if ( PenBrushObj )
{
if ( x1 > (left+1) )
{
PUTLINE ( left, y1, x1, y1, PenBrushInst );
PUTLINE ( x2+1, y1, right, y1, PenBrushInst );
PUTLINE ( left+1, y2, x1, y2, PenBrushInst );
PUTLINE ( x2+1, y2, right+1, y2, PenBrushInst );
}
else
{
PUTPIXEL ( left, y1, PenBrushInst );
PUTPIXEL ( right, y2, PenBrushInst );
}
}
x1 = left+xradius;
x2 = right-xradius;
y1 = top+yradius;
y2 = bottom-yradius;
if ( FillBrushObj )
{
for ( i = y1+1; i < y2; i++ )
PUTLINE ( left, i, right, i, FillBrushInst );
}
if ( PenBrushObj )
{
PUTLINE ( x1, top, x2, top, PenBrushInst );
PUTLINE ( right, y1, right, y2, PenBrushInst );
PUTLINE ( x2, bottom, x1, bottom, PenBrushInst );
PUTLINE ( left, y2, left, y1, PenBrushInst );
}
BITMAPOBJ_UnlockBitmap(BitmapObj);
if(PenBrushObj != NULL)
PENOBJ_UnlockPen(PenBrushObj);
if(FillBrushObj != NULL)
BRUSHOBJ_UnlockBrush(FillBrushObj);
return ret;
}
BOOL
STDCALL
NtGdiRoundRect(
HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect,
int Width,
int Height)
{
DC *dc = DC_LockDc(hDC);
BOOL ret = FALSE; /* default to failure */
DPRINT("NtGdiRoundRect(0x%x,%i,%i,%i,%i,%i,%i)\n",hDC,LeftRect,TopRect,RightRect,BottomRect,Width,Height);
if ( !dc )
{
DPRINT1("NtGdiRoundRect() - hDC is invalid\n");
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
else if (dc->IsIC)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
ret = TRUE;
}
else
{
ret = IntRoundRect ( dc, LeftRect, TopRect, RightRect, BottomRect, Width, Height );
DC_UnlockDc ( dc );
}
return ret;
}
BOOL FASTCALL
IntGdiGradientFill(
DC *dc,
PTRIVERTEX pVertex,
ULONG uVertex,
PVOID pMesh,
ULONG uMesh,
ULONG ulMode)
{
BITMAPOBJ *BitmapObj;
PPALGDI PalDestGDI;
XLATEOBJ *XlateObj;
RECTL Extent;
POINTL DitherOrg;
ULONG Mode, i;
BOOL Ret;
ASSERT(dc);
ASSERT(pVertex);
ASSERT(uVertex);
ASSERT(pMesh);
ASSERT(uMesh);
/* check parameters */
if(ulMode & GRADIENT_FILL_TRIANGLE)
{
PGRADIENT_TRIANGLE tr = (PGRADIENT_TRIANGLE)pMesh;
for(i = 0; i < uMesh; i++, tr++)
{
if(tr->Vertex1 >= uVertex ||
tr->Vertex2 >= uVertex ||
tr->Vertex3 >= uVertex)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
}
else
{
PGRADIENT_RECT rc = (PGRADIENT_RECT)pMesh;
for(i = 0; i < uMesh; i++, rc++)
{
if(rc->UpperLeft >= uVertex || rc->LowerRight >= uVertex)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
}
/* calculate extent */
Extent.left = Extent.right = pVertex->x;
Extent.top = Extent.bottom = pVertex->y;
for(i = 0; i < uVertex; i++)
{
Extent.left = min(Extent.left, (pVertex + i)->x);
Extent.right = max(Extent.right, (pVertex + i)->x);
Extent.top = min(Extent.top, (pVertex + i)->y);
Extent.bottom = max(Extent.bottom, (pVertex + i)->y);
}
DitherOrg.x = dc->w.DCOrgX;
DitherOrg.y = dc->w.DCOrgY;
Extent.left += DitherOrg.x;
Extent.right += DitherOrg.x;
Extent.top += DitherOrg.y;
Extent.bottom += DitherOrg.y;
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
/* FIXME - BitmapObj can be NULL!!! Don't assert but handle this case gracefully! */
ASSERT(BitmapObj);
PalDestGDI = PALETTE_LockPalette(dc->w.hPalette);
/* FIXME - PalDestGDI can be NULL!!! Don't assert but handle this case gracefully! */
ASSERT(PalDestGDI);
Mode = PalDestGDI->Mode;
PALETTE_UnlockPalette(PalDestGDI);
XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
ASSERT(XlateObj);
Ret = IntEngGradientFill(&BitmapObj->SurfObj,
dc->CombinedClip,
XlateObj,
pVertex,
uVertex,
pMesh,
uMesh,
&Extent,
&DitherOrg,
ulMode);
BITMAPOBJ_UnlockBitmap(BitmapObj);
EngDeleteXlate(XlateObj);
return Ret;
}
BOOL
STDCALL
NtGdiGradientFill(
HDC hdc,
PTRIVERTEX pVertex,
ULONG uVertex,
PVOID pMesh,
ULONG uMesh,
ULONG ulMode)
{
DC *dc;
BOOL Ret;
PTRIVERTEX SafeVertex;
PVOID SafeMesh;
ULONG SizeMesh;
NTSTATUS Status = STATUS_SUCCESS;
dc = DC_LockDc(hdc);
if(!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (dc->IsIC)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if(!pVertex || !uVertex || !pMesh || !uMesh)
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch(ulMode)
{
case GRADIENT_FILL_RECT_H:
case GRADIENT_FILL_RECT_V:
SizeMesh = uMesh * sizeof(GRADIENT_RECT);
break;
case GRADIENT_FILL_TRIANGLE:
SizeMesh = uMesh * sizeof(TRIVERTEX);
break;
default:
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
_SEH_TRY
{
ProbeForRead(pVertex,
uVertex * sizeof(TRIVERTEX),
1);
ProbeForRead(pMesh,
SizeMesh,
1);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status))
{
DC_UnlockDc(dc);
SetLastWin32Error(Status);
return FALSE;
}
if(!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) + SizeMesh, TAG_SHAPE)))
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex);
_SEH_TRY
{
/* pointers were already probed! */
RtlCopyMemory(SafeVertex,
pVertex,
uVertex * sizeof(TRIVERTEX));
RtlCopyMemory(SafeMesh,
pMesh,
SizeMesh);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(dc);
ExFreePool(SafeVertex);
SetLastNtError(Status);
return FALSE;
}
Ret = IntGdiGradientFill(dc, SafeVertex, uVertex, SafeMesh, uMesh, ulMode);
DC_UnlockDc(dc);
ExFreePool(SafeVertex);
return Ret;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -