📄 gradient.c
字号:
ex[line] -= dy[line]; \
}
#define GOLINE(a,b,line) \
if(y >= a->y && y <= b->y) \
{
#define ENDLINE(a,b,line) \
}
#define INITLINE(a,b,line) \
x[line] = a->x; \
sx[line] = a->x + pptlDitherOrg->x; \
dx[line] = abs(b->x - a->x); \
dy[line] = abs(b->y - a->y); \
incx[line] = LINC[b->x > a->x]; \
ex[line] = -(dy[line]>>1); \
destx[line] = b->x
#define DOINIT(a, b, line) \
INITLINE(a, b, line); \
INITCOL(a, b, line, Red, 0); \
INITCOL(a, b, line, Green, 1); \
INITCOL(a, b, line, Blue, 2);
#define SMALLER(a,b) (a->y < b->y) || (a->y == b->y && a->x < b->x)
#define SWAP(a,b,c) c = a;\
a = b;\
a = c
#define NLINES 3
BOOL FASTCALL
IntEngGradientFillTriangle(
IN SURFOBJ *psoDest,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN TRIVERTEX *pVertex,
IN ULONG nVertex,
IN PGRADIENT_TRIANGLE gTriangle,
IN RECTL *prclExtents,
IN POINTL *pptlDitherOrg)
{
SURFOBJ *OutputObj;
PTRIVERTEX v1, v2, v3;
RECT_ENUM RectEnum;
BOOL EnumMore;
ULONG i;
POINTL Translate;
INTENG_ENTER_LEAVE EnterLeave;
RECTL FillRect;
ULONG Color;
BOOL sx[NLINES];
LONG x[NLINES], dx[NLINES], dy[NLINES], incx[NLINES], ex[NLINES], destx[NLINES];
LONG c[NLINES][3], dc[NLINES][3], ec[NLINES][3], ic[NLINES][3]; /* colors on lines */
LONG g, gx, gxi, gc[3], gd[3], ge[3], gi[3]; /* colors in triangle */
LONG sy, y, bt;
v1 = (pVertex + gTriangle->Vertex1);
v2 = (pVertex + gTriangle->Vertex2);
v3 = (pVertex + gTriangle->Vertex3);
/* bubble sort */
if(SMALLER(v2,v1))
{
TRIVERTEX *t;
SWAP(v1,v2,t);
}
if(SMALLER(v3,v2))
{
TRIVERTEX *t;
SWAP(v2,v3,t);
if(SMALLER(v2,v1))
{
SWAP(v1,v2,t);
}
}
DbgPrint("Triangle: (%i,%i) (%i,%i) (%i,%i)\n", v1->x, v1->y, v2->x, v2->y, v3->x, v3->y);
if(!IntEngEnter(&EnterLeave, psoDest, &FillRect, FALSE, &Translate, &OutputObj))
{
return FALSE;
}
if(VCMPCLRS(v1, v2, v3))
{
CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
do
{
EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++)
{
if(IntGdiIntersectRect((PRECT)&FillRect, (PRECT)&RectEnum.arcl[i], (PRECT)prclExtents))
{
BOOL InY;
DOINIT(v1, v3, 0);
DOINIT(v1, v2, 1);
DOINIT(v2, v3, 2);
y = v1->y;
sy = v1->y + pptlDitherOrg->y;
bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom);
while(sy < bt)
{
InY = !(sy < FillRect.top || sy >= FillRect.bottom);
GOLINE(v1, v3, 0);
DOLINE(v1, v3, 0);
ENDLINE(v1, v3, 0);
GOLINE(v1, v2, 1);
DOLINE(v1, v2, 1);
FILLLINE(0, 1);
ENDLINE(v1, v2, 1);
GOLINE(v2, v3, 2);
DOLINE(v2, v3, 2);
FILLLINE(0, 2);
ENDLINE(23, v3, 2);
y++;
sy++;
}
}
}
} while(EnumMore);
return IntEngLeave(&EnterLeave);
}
/* fill triangle with one solid color */
Color = XLATEOBJ_iXlate(pxlo, RGB(v1->Red >> 8, v1->Green >> 8, v1->Blue >> 8));
CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
do
{
EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++)
{
if(IntGdiIntersectRect((PRECT)&FillRect, (PRECT)&RectEnum.arcl[i], (PRECT)prclExtents))
{
S_INITLINE(v1, v3, 0);
S_INITLINE(v1, v2, 1);
S_INITLINE(v2, v3, 2);
y = v1->y;
sy = v1->y + pptlDitherOrg->y;
bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom);
while(sy < bt)
{
S_GOLINE(v1, v3, 0);
S_DOLINE(v1, v3, 0);
S_ENDLINE(v1, v3, 0);
S_GOLINE(v1, v2, 1);
S_DOLINE(v1, v2, 1);
S_FILLLINE(0, 1);
S_ENDLINE(v1, v2, 1);
S_GOLINE(v2, v3, 2);
S_DOLINE(v2, v3, 2);
S_FILLLINE(0, 2);
S_ENDLINE(23, v3, 2);
y++;
sy++;
}
}
}
} while(EnumMore);
return IntEngLeave(&EnterLeave);
}
BOOL static
IntEngIsNULLTriangle(TRIVERTEX *pVertex, GRADIENT_TRIANGLE *gt)
{
if(COMPAREVERTEX(VERTEX(Vertex1), VERTEX(Vertex2)))
return TRUE;
if(COMPAREVERTEX(VERTEX(Vertex1), VERTEX(Vertex3)))
return TRUE;
if(COMPAREVERTEX(VERTEX(Vertex2), VERTEX(Vertex3)))
return TRUE;
return FALSE;
}
BOOL STDCALL
EngGradientFill(
IN SURFOBJ *psoDest,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN TRIVERTEX *pVertex,
IN ULONG nVertex,
IN PVOID pMesh,
IN ULONG nMesh,
IN RECTL *prclExtents,
IN POINTL *pptlDitherOrg,
IN ULONG ulMode)
{
ULONG i;
switch(ulMode)
{
case GRADIENT_FILL_RECT_H:
case GRADIENT_FILL_RECT_V:
{
PGRADIENT_RECT gr = (PGRADIENT_RECT)pMesh;
for(i = 0; i < nMesh; i++, gr++)
{
if(!IntEngGradientFillRect(psoDest, pco, pxlo, pVertex, nVertex, gr, prclExtents,
pptlDitherOrg, (ulMode == GRADIENT_FILL_RECT_H)))
{
return FALSE;
}
}
return TRUE;
}
case GRADIENT_FILL_TRIANGLE:
{
PGRADIENT_TRIANGLE gt = (PGRADIENT_TRIANGLE)pMesh;
for(i = 0; i < nMesh; i++, gt++)
{
if(IntEngIsNULLTriangle(pVertex, gt))
{
/* skip empty triangles */
continue;
}
if(!IntEngGradientFillTriangle(psoDest, pco, pxlo, pVertex, nVertex, gt, prclExtents,
pptlDitherOrg))
{
return FALSE;
}
}
return TRUE;
}
}
return FALSE;
}
BOOL STDCALL
IntEngGradientFill(
IN SURFOBJ *psoDest,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN TRIVERTEX *pVertex,
IN ULONG nVertex,
IN PVOID pMesh,
IN ULONG nMesh,
IN RECTL *prclExtents,
IN POINTL *pptlDitherOrg,
IN ULONG ulMode)
{
BOOL Ret;
BITMAPOBJ *pboDest;
ASSERT(psoDest);
ASSERT(pco);
pboDest = CONTAINING_RECORD(psoDest, BITMAPOBJ, SurfObj);
ASSERT(pboDest);
BITMAPOBJ_LockBitmapBits(pboDest);
MouseSafetyOnDrawStart(
psoDest,
pco->rclBounds.left,
pco->rclBounds.top,
pco->rclBounds.right,
pco->rclBounds.bottom);
if(pboDest->flHooks & HOOK_GRADIENTFILL)
{
Ret = GDIDEVFUNCS(psoDest).GradientFill(
psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh,
prclExtents, pptlDitherOrg, ulMode);
MouseSafetyOnDrawEnd(psoDest);
return Ret;
}
Ret = EngGradientFill(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents,
pptlDitherOrg, ulMode);
MouseSafetyOnDrawEnd(psoDest);
BITMAPOBJ_UnlockBitmapBits(pboDest);
return Ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -