📄 guicallback.c
字号:
pLineData->y2 = y2;
return LINE_HORIZONTAL;
}
/* Vertical line */
if (x1 == x2)
{
/* Out of clip rectangle */
if (x1 < pClipRect->x1 || x1 >= pClipRect->x2)
return LINE_NONE;
if (y1 < y2)
y2--;
else
{
y2++;
EXCHANGE(y1, y2);
reverse = 1;
}
y1 = MAX(y1, pClipRect->y1);
y2 = MIN(y2, pClipRect->y2 - 1);
if (y1 > y2)
return LINE_NONE;
if (reverse)
{
pLineDraw->start_x = x1;
pLineDraw->start_y = y2;
pLineDraw->end_x = x2;
pLineDraw->end_y = y1;
pLineDraw->cliped = pLineData->y1 - y2;
}
else
{
pLineDraw->start_x = x1;
pLineDraw->start_y = y1;
pLineDraw->end_x = x2;
pLineDraw->end_y = y2;
pLineDraw->cliped = y1 - pLineData->y1;
}
pLineData->x1 = x1;
pLineData->y1 = y1;
pLineData->x2 = x2;
pLineData->y2 = y2;
return LINE_VERTICAL;
}
dx = ABS(x1 - x2);
dy = ABS(y1 - y2);
twodx = dx * 2;
twody = dy * 2;
if (dx >= dy)
{
/* the delta data item store the increase that is dependent on the
** step data item. the step data item is the independent variable
** and increase one by one.
** the line drawing is controled by the step.
*/
pLineDraw->delta = dy;
pLineDraw->step = dx;
/* dir data item is used to determine the direction of the line and
** the sign of linebytes or pixelbytes of the display device.
*/
if (y1 > y2)
pLineDraw->dir = REVR_DIR;
else
pLineDraw->dir = NORM_DIR;
if (x1 > x2)
{
EXCHANGE(x1, x2);
EXCHANGE(y1, y2);
reverse = 1;
}
if (x1 >= pClipRect->x2 || x2 < pClipRect->x1)
return LINE_NONE;
/*
** Compute the x coordinate for given y:
** DIV_CEILING(a, b) (((a) * 2 + (b)) / ((b) * 2))
** dx
** x =---- * (y - y1) + x1
** dy
** x = x1 + (y - y1) * dx / dy
** = x1 + ((y - y1) * dx * 2 + dy) / (dy * 2)
** = x1 + DIV_CEILING((y - y1) * dx, dy)
**
** y = y1 + DIV_CEILING((x - x1) * dy, dx)
*/
tx1 = x1;
tx2 = x2;
ty1 = y1;
ty2 = y2;
if (y1 < y2) /* "\" type line*/
{
if (y1 >= pClipRect->y2 || y2 < pClipRect->y1)
return LINE_NONE;
if (ty1 < pClipRect->y1)
{
ty1 = pClipRect->y1;
if (reverse)
{
/* Calculate the tx1 that decided by the ty1. The result
** tx1 is most close to the exactness. But there is a
** problem that sometimes draw the line point ,usint DDA
** method, with x = tx1 + 1, the result y is also equal
** to ty1.
** So we should recalculate the tx1. The correct tx1
** must be a critical value that meet follow conditions.
**
** When x = tx1, y = ty1
** When x = tx1 - 1, y = ty1 - 1.
*/
tx1 = x2 - DIV_CEILING((y2 - ty1) * dx, dy);
tx1 -= ((twodx - ((x2 - tx1) * twody + dx) % twodx) +
twody - 1) / twody - 1;
}
else
{
tx1 = x1 + DIV_CEILING((ty1 - y1) * dx, dy);
/*
** When x = tx1, y = ty1
** When x = tx1 - 1, y = ty1 - 1.
*/
tx1 -= (((tx1 - x1) * twody + dx) % twodx) / twody;
}
if (tx1 > tx2 || tx1 >= pClipRect->x2)
return LINE_NONE;
}
if (tx1 < pClipRect->x1)
{
tx1 = pClipRect->x1;
ty1 = y1 + DIV_CEILING((tx1 - x1) * dy, dx);
if (tx1 > tx2 || ty1 >= pClipRect->y2)
return LINE_NONE;
}
if (ty2 >= pClipRect->y2)
{
ty2 = pClipRect->y2 - 1;
if (reverse)
{
/*
** When x = tx2, y = ty2
** When x = tx2 + 1, y = ty2 + 1.
*/
tx2 = x2 - DIV_CEILING((y2 - ty2) * dx, dy);
tx2 += (((x2 - tx2) * twody + dx) % twodx) / twody;
}
else
{
/*
** When x = tx2, y = ty2
** When x = tx2 + 1, y = ty2 + 1.
*/
tx2 = x1 + DIV_CEILING((ty2 - y1) * dx, dy);
tx2 += ((twodx - ((tx2 - x1) * twody + dx) % twodx) +
twody - 1) / twody - 1;
}
if (tx1 > tx2 || tx2 < pClipRect->x1)
return LINE_NONE;
}
if (tx2 >= pClipRect->x2)
{
tx2 = pClipRect->x2 - 1;
ty2 = y1 + DIV_CEILING((tx2 - x1) * dy, dx);
if (tx1 > tx2 || ty2 < pClipRect->y1)
return LINE_NONE;
}
}
else /* "/" type line */
{
if (y1 < pClipRect->y1 || y2 >= pClipRect->y2)
return LINE_NONE;
if (ty1 >= pClipRect->y2)
{
ty1 = pClipRect->y2 - 1;
if (reverse)
{
/*
** When x = tx1, y = ty1
** When x = tx1 - 1, y = ty1 + 1.
*/
tx1 = x2 - DIV_CEILING((ty1 - y2) * dx, dy);
tx1 -= ((twodx - ((x2 - tx1) * twody + dx) % twodx) +
twody - 1) / twody - 1;
}
else
{
/*
** When x = tx1, y = ty1
** When x = tx1 - 1, y = ty1 + 1.
*/
tx1 = x1 + DIV_CEILING((y1 - ty1) * dx, dy);
tx1 -= (((tx1 - x1) * twody + dx) % twodx) / twody;
}
if (tx1 > tx2 || tx1 >= pClipRect->x2)
return LINE_NONE;
}
if (tx1 < pClipRect->x1)
{
tx1 = pClipRect->x1;
ty1 = y1 - DIV_CEILING((tx1 - x1) * dy, dx);
if (tx1 > tx2 || ty1 < pClipRect->y1)
return LINE_NONE;
}
if (ty2 < pClipRect->y1)
{
ty2 = pClipRect->y1;
if (reverse)
{
/*
** When x = tx2, y = ty2
** When x = tx2 + 1, y = ty2 - 1.
*/
tx2 = x2 - DIV_CEILING((ty2 - y2) * dx, dy);
tx2 += (((x2 - tx2) * twody + dx) % twodx) / twody;
}
else
{
/*
** When x = tx2, y = ty2
** When x = tx2 + 1, y = ty2 - 1.
*/
tx2 = x1 + DIV_CEILING((y1 - ty2) * dx, dy);
tx2 += ((twodx - ((tx2 - x1) * twody + dx) % twodx) +
twody - 1) / twody - 1;
}
if (tx1 > tx2 || tx2 < pClipRect->x1)
return LINE_NONE;
}
if (tx2 >= pClipRect->x2)
{
tx2 = pClipRect->x2 - 1;
ty2 = y1 - DIV_CEILING((tx2 - x1) * dy, dx);
if (tx1 > tx2 || ty2 >= pClipRect->y2)
return LINE_NONE;
}
}
if (reverse)
{
pLineDraw->start_x = tx2;
pLineDraw->start_y = ty2;
pLineDraw->end_x = tx1;
pLineDraw->end_y = ty1;
/* calculate the cliped points number
*/
pLineDraw->cliped = x2 - tx2;
/* The end point of the origin line is not cliped and should not
** be drawn.
*/
/*
** If the left of the line cliped is only the last point, we can't
** draw the line at all.
*/
if (tx1 == pLineData->x2)
{
if (tx2 == tx1)
return LINE_NONE;
pLineDraw->end_x ++;
}
}
else
{
pLineDraw->start_x = tx1;
pLineDraw->start_y = ty1;
pLineDraw->end_x = tx2;
pLineDraw->end_y = ty2;
/* calculate the cliped points number
*/
pLineDraw->cliped = tx1 - x1;
/* The end point of the origin line is not cliped and should not
** be drawn.
*/
/*
** If the left of the line cliped is only the last point, we can't
** draw the line at all.
*/
if (tx2 == pLineData->x2)
{
if (tx2 == tx1)
return LINE_NONE;
pLineDraw->end_x --;
}
}
pLineDraw->type = LINE_CTRLX;
}
else /* dy > dx */
{
pLineDraw->delta = dx;
pLineDraw->step = dy;
if (x1 > x2)
pLineDraw->dir = REVR_DIR;
else
pLineDraw->dir = NORM_DIR;
if (y1 > y2)
{
EXCHANGE(x1, x2);
EXCHANGE(y1, y2);
reverse = 1;
}
if (y1 >= pClipRect->y2 || y2 < pClipRect->y1)
return LINE_NONE;
tx1 = x1;
tx2 = x2;
ty1 = y1;
ty2 = y2;
if (x1 < x2) /* "\" type line*/
{
if (x1 >= pClipRect->x2 || x2 < pClipRect->x1)
return LINE_NONE;
if (tx1 < pClipRect->x1)
{
tx1 = pClipRect->x1;
if (reverse)
{
/*
** When y = ty1, x = tx1
** When y = ty1 - 1, y = tx1 - 1.
*/
ty1 = y2 - DIV_CEILING((x2 - tx1) * dy, dx);
ty1 -= ((twody - ((y2 - ty1) * twodx + dy) % twody) +
twodx - 1) / twodx - 1;
}
else
{
/*
** When y = ty1, x = tx1
** When y = ty1 - 1, y = tx1 - 1.
*/
ty1 = y1 + DIV_CEILING((tx1 - x1) * dy, dx);
ty1 -= (((ty1 - y1) * twodx + dy) % twody) / twodx;
}
if (ty1 > ty2 || ty1 >= pClipRect->y2)
return LINE_NONE;
}
if (ty1 < pClipRect->y1)
{
ty1 = pClipRect->y1;
tx1 = x1 + DIV_CEILING((ty1 - y1) * dx, dy);
if (ty1 > ty2 || tx1 >= pClipRect->x2)
return LINE_NONE;
}
if (tx2 >= pClipRect->x2)
{
tx2 = pClipRect->x2 - 1;
if (reverse)
{
/*
** When y = ty2, x = tx2
** When y = ty2 + 1, y = tx2 + 1.
*/
ty2 = y2 - DIV_CEILING((x2 - tx2) * dy, dx);
ty2 += (((y2 - ty2) * twodx + dy) % twody) / twodx;
}
else
{
/*
** When y = ty2, x = tx2
** When y = ty2 + 1, y = tx2 + 1.
*/
ty2 = y1 + DIV_CEILING((tx2 - x1) * dy, dx);
ty2 += ((twody - ((ty2 - y1) * twodx + dy) % twody) +
twodx - 1) / twodx - 1;
}
if (ty1 > ty2 || ty2 < pClipRect->y1)
return LINE_NONE;
}
if (ty2 >= pClipRect->y2)
{
ty2 = pClipRect->y2 - 1;
tx2 = x1 + DIV_CEILING((ty2 - y1) * dx, dy);
if (ty1 > ty2 || tx2 < pClipRect->x1)
return LINE_NONE;
}
}
else /* "/" type line */
{
if (x1 < pClipRect->x1 || x2 >= pClipRect->x2)
return LINE_NONE;
if (tx1 >= pClipRect->x2)
{
tx1 = pClipRect->x2 - 1;
if (reverse)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -