GRAPHICS: Move generic primitives from WAGE engine
This commit is contained in:
parent
1d5220ef3f
commit
5e002c4fe2
4 changed files with 378 additions and 378 deletions
|
@ -226,7 +226,7 @@ void Design::drawRect(Graphics::Surface *surface, Common::ReadStream &in,
|
||||||
plotData pd(surface, &patterns, fillType, 1);
|
plotData pd(surface, &patterns, fillType, 1);
|
||||||
|
|
||||||
if (fillType <= patterns.size())
|
if (fillType <= patterns.size())
|
||||||
drawFilledRect(r, kColorBlack, drawPixel, &pd);
|
Graphics::drawFilledRect(r, kColorBlack, drawPixel, &pd);
|
||||||
|
|
||||||
pd.fillType = borderFillType;
|
pd.fillType = borderFillType;
|
||||||
pd.thickness = borderThickness;
|
pd.thickness = borderThickness;
|
||||||
|
@ -256,13 +256,13 @@ void Design::drawRoundRect(Graphics::Surface *surface, Common::ReadStream &in,
|
||||||
plotData pd(surface, &patterns, fillType, 1);
|
plotData pd(surface, &patterns, fillType, 1);
|
||||||
|
|
||||||
if (fillType <= patterns.size())
|
if (fillType <= patterns.size())
|
||||||
drawRoundRect(r, arc/2, kColorBlack, true, drawPixel, &pd);
|
Graphics::drawRoundRect(r, arc/2, kColorBlack, true, drawPixel, &pd);
|
||||||
|
|
||||||
pd.fillType = borderFillType;
|
pd.fillType = borderFillType;
|
||||||
pd.thickness = borderThickness;
|
pd.thickness = borderThickness;
|
||||||
|
|
||||||
if (borderThickness > 0 && borderFillType <= patterns.size())
|
if (borderThickness > 0 && borderFillType <= patterns.size())
|
||||||
drawRoundRect(r, arc/2, kColorBlack, false, drawPixel, &pd);
|
Graphics::drawRoundRect(r, arc/2, kColorBlack, false, drawPixel, &pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in,
|
void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in,
|
||||||
|
@ -326,7 +326,7 @@ void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in,
|
||||||
plotData pd(surface, &patterns, fillType, 1);
|
plotData pd(surface, &patterns, fillType, 1);
|
||||||
|
|
||||||
if (fillType <= patterns.size()) {
|
if (fillType <= patterns.size()) {
|
||||||
drawPolygonScan(xpoints, ypoints, npoints, bbox, kColorBlack, drawPixel, &pd);
|
Graphics::drawPolygonScan(xpoints, ypoints, npoints, bbox, kColorBlack, drawPixel, &pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
pd.fillType = borderFillType;
|
pd.fillType = borderFillType;
|
||||||
|
@ -349,13 +349,13 @@ void Design::drawOval(Graphics::Surface *surface, Common::ReadStream &in,
|
||||||
plotData pd(surface, &patterns, fillType, 1);
|
plotData pd(surface, &patterns, fillType, 1);
|
||||||
|
|
||||||
if (fillType <= patterns.size())
|
if (fillType <= patterns.size())
|
||||||
drawEllipse(x1, y1, x2-1, y2-1, true, drawPixel, &pd);
|
Graphics::drawEllipse(x1, y1, x2-1, y2-1, kColorBlack, true, drawPixel, &pd);
|
||||||
|
|
||||||
pd.fillType = borderFillType;
|
pd.fillType = borderFillType;
|
||||||
pd.thickness = borderThickness;
|
pd.thickness = borderThickness;
|
||||||
|
|
||||||
if (borderThickness > 0 && borderFillType <= patterns.size())
|
if (borderThickness > 0 && borderFillType <= patterns.size())
|
||||||
drawEllipse(x1, y1, x2-1, y2-1, false, drawPixel, &pd);
|
Graphics::drawEllipse(x1, y1, x2-1, y2-1, kColorBlack, false, drawPixel, &pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::drawBitmap(Graphics::Surface *surface, Common::ReadStream &in) {
|
void Design::drawBitmap(Graphics::Surface *surface, Common::ReadStream &in) {
|
||||||
|
@ -460,383 +460,25 @@ void Design::drawFilledRect(Graphics::Surface *surface, Common::Rect &rect, int
|
||||||
plotData pd(surface, &patterns, fillType, 1);
|
plotData pd(surface, &patterns, fillType, 1);
|
||||||
|
|
||||||
for (int y = rect.top; y <= rect.bottom; y++)
|
for (int y = rect.top; y <= rect.bottom; y++)
|
||||||
drawHLine(rect.left, rect.right, y, color, drawPixel, &pd);
|
Graphics::drawHLine(rect.left, rect.right, y, color, drawPixel, &pd);
|
||||||
}
|
|
||||||
|
|
||||||
void Design::drawFilledRect(Common::Rect &rect, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
|
||||||
for (int y = rect.top; y <= rect.bottom; y++)
|
|
||||||
drawHLine(rect.left, rect.right, y, color, plotProc, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::drawFilledRoundRect(Graphics::Surface *surface, Common::Rect &rect, int arc, int color, Patterns &patterns, byte fillType) {
|
void Design::drawFilledRoundRect(Graphics::Surface *surface, Common::Rect &rect, int arc, int color, Patterns &patterns, byte fillType) {
|
||||||
plotData pd(surface, &patterns, fillType, 1);
|
plotData pd(surface, &patterns, fillType, 1);
|
||||||
|
|
||||||
drawRoundRect(rect, arc, color, true, drawPixel, &pd);
|
Graphics::drawRoundRect(rect, arc, color, true, drawPixel, &pd);
|
||||||
}
|
|
||||||
|
|
||||||
// http://members.chello.at/easyfilter/bresenham.html
|
|
||||||
void Design::drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*plotProc)(int, int, int, void *), void *data) {
|
|
||||||
if (rect.height() < rect.width()) {
|
|
||||||
int x = -arc, y = 0, err = 2-2*arc; /* II. Quadrant */
|
|
||||||
int dy = rect.height() - arc * 2;
|
|
||||||
int r = arc;
|
|
||||||
int stop = 0;
|
|
||||||
int lastx, lasty;
|
|
||||||
if (dy < 0)
|
|
||||||
stop = -dy / 2;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (filled) {
|
|
||||||
drawHLine(rect.left+x+r, rect.right-x-r, rect.top-y+r-stop, color, plotProc, data);
|
|
||||||
drawHLine(rect.left+x+r, rect.right-x-r, rect.bottom+y-r+stop, color, plotProc, data);
|
|
||||||
} else {
|
|
||||||
(*plotProc)(rect.left+x+r, rect.top-y+r-stop, color, data);
|
|
||||||
(*plotProc)(rect.right-x-r, rect.top-y+r-stop, color, data);
|
|
||||||
(*plotProc)(rect.left+x+r, rect.bottom+y-r+stop, color, data);
|
|
||||||
(*plotProc)(rect.right-x-r, rect.bottom+y-r+stop, color, data);
|
|
||||||
|
|
||||||
lastx = x;
|
|
||||||
lasty = y;
|
|
||||||
}
|
|
||||||
arc = err;
|
|
||||||
if (arc <= y) err += ++y*2+1; /* e_xy+e_y < 0 */
|
|
||||||
if (arc > x || err > y) err += ++x*2+1; /* e_xy+e_x > 0 or no 2nd y-step */
|
|
||||||
if (stop && y > stop)
|
|
||||||
break;
|
|
||||||
} while (x < 0);
|
|
||||||
|
|
||||||
if (!filled) {
|
|
||||||
x = lastx;
|
|
||||||
y = lasty;
|
|
||||||
|
|
||||||
drawHLine(rect.left+x+r, rect.right-x-r, rect.top-y+r-stop, color, plotProc, data);
|
|
||||||
drawHLine(rect.left+x+r, rect.right-x-r, rect.bottom+y-r+stop, color, plotProc, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < dy; i++) {
|
|
||||||
if (filled) {
|
|
||||||
drawHLine(rect.left, rect.right, rect.top + r + i, color, plotProc, data);
|
|
||||||
} else {
|
|
||||||
(*plotProc)(rect.left, rect.top + r + i, color, data);
|
|
||||||
(*plotProc)(rect.right, rect.top + r + i, color, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int y = -arc, x = 0, err = 2-2*arc; /* II. Quadrant */
|
|
||||||
int dx = rect.width() - arc * 2;
|
|
||||||
int r = arc;
|
|
||||||
int stop = 0;
|
|
||||||
int lastx, lasty;
|
|
||||||
if (dx < 0)
|
|
||||||
stop = -dx / 2;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (filled) {
|
|
||||||
drawVLine(rect.left-x+r-stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
|
||||||
drawVLine(rect.right+x-r+stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
|
||||||
} else {
|
|
||||||
(*plotProc)(rect.left-x+r-stop, rect.top+y+r, color, data);
|
|
||||||
(*plotProc)(rect.left-x+r-stop, rect.bottom-y-r, color, data);
|
|
||||||
(*plotProc)(rect.right+x-r+stop, rect.top+y+r, color, data);
|
|
||||||
(*plotProc)(rect.right+x-r+stop, rect.bottom-y-r, color, data);
|
|
||||||
|
|
||||||
lastx = x;
|
|
||||||
lasty = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
arc = err;
|
|
||||||
if (arc <= x) err += ++x*2+1; /* e_xy+e_y < 0 */
|
|
||||||
if (arc > y || err > x) err += ++y*2+1; /* e_xy+e_x > 0 or no 2nd y-step */
|
|
||||||
if (stop && x > stop)
|
|
||||||
break;
|
|
||||||
} while (y < 0);
|
|
||||||
|
|
||||||
if (!filled) {
|
|
||||||
x = lastx;
|
|
||||||
y = lasty;
|
|
||||||
drawVLine(rect.left-x+r-stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
|
||||||
drawVLine(rect.right+x-r+stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < dx; i++) {
|
|
||||||
if (filled) {
|
|
||||||
drawVLine(rect.left + r + i, rect.top, rect.bottom, color, plotProc, data);
|
|
||||||
} else {
|
|
||||||
(*plotProc)(rect.left + r + i, rect.top, color, data);
|
|
||||||
(*plotProc)(rect.left + r + i, rect.bottom, color, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Based on public-domain code by Darel Rex Finley, 2007
|
|
||||||
// http://alienryderflex.com/polygon_fill/
|
|
||||||
void Design::drawPolygonScan(int *polyX, int *polyY, int npoints, Common::Rect &bbox, int color,
|
|
||||||
void (*plotProc)(int, int, int, void *), void *data) {
|
|
||||||
int *nodeX = (int *)calloc(npoints, sizeof(int));
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// Loop through the rows of the image.
|
|
||||||
for (int pixelY = bbox.top; pixelY < bbox.bottom; pixelY++) {
|
|
||||||
// Build a list of nodes.
|
|
||||||
int nodes = 0;
|
|
||||||
j = npoints - 1;
|
|
||||||
|
|
||||||
for (i = 0; i < npoints; i++) {
|
|
||||||
if ((polyY[i] < pixelY && polyY[j] >= pixelY) || (polyY[j] < pixelY && polyY[i] >= pixelY)) {
|
|
||||||
nodeX[nodes++] = (int)(polyX[i] + (double)(pixelY - polyY[i]) / (double)(polyY[j]-polyY[i]) *
|
|
||||||
(double)(polyX[j] - polyX[i]) + 0.5);
|
|
||||||
}
|
|
||||||
j = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the nodes, via a simple “Bubble” sort.
|
|
||||||
i = 0;
|
|
||||||
while (i < nodes - 1) {
|
|
||||||
if (nodeX[i] > nodeX[i + 1]) {
|
|
||||||
SWAP(nodeX[i], nodeX[i + 1]);
|
|
||||||
if (i)
|
|
||||||
i--;
|
|
||||||
} else {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill the pixels between node pairs.
|
|
||||||
for (i = 0; i < nodes; i += 2) {
|
|
||||||
if (nodeX[i ] >= bbox.right)
|
|
||||||
break;
|
|
||||||
if (nodeX[i + 1] > bbox.left) {
|
|
||||||
nodeX[i] = MAX<int16>(nodeX[i], bbox.left);
|
|
||||||
nodeX[i + 1] = MIN<int16>(nodeX[i + 1], bbox.right);
|
|
||||||
|
|
||||||
drawHLine(nodeX[i], nodeX[i + 1], pixelY, color, plotProc, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(nodeX);
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://members.chello.at/easyfilter/bresenham.html
|
|
||||||
void Design::drawEllipse(int x0, int y0, int x1, int y1, bool filled, void (*plotProc)(int, int, int, void *), void *data) {
|
|
||||||
int a = abs(x1-x0), b = abs(y1-y0), b1 = b&1; /* values of diameter */
|
|
||||||
long dx = 4*(1-a)*b*b, dy = 4*(b1+1)*a*a; /* error increment */
|
|
||||||
long err = dx+dy+b1*a*a, e2; /* error of 1.step */
|
|
||||||
|
|
||||||
if (x0 > x1) { x0 = x1; x1 += a; } /* if called with swapped points */
|
|
||||||
if (y0 > y1) y0 = y1; /* .. exchange them */
|
|
||||||
y0 += (b+1)/2; y1 = y0-b1; /* starting pixel */
|
|
||||||
a *= 8*a; b1 = 8*b*b;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (filled) {
|
|
||||||
drawHLine(x0, x1, y0, kColorBlack, plotProc, data);
|
|
||||||
drawHLine(x0, x1, y1, kColorBlack, plotProc, data);
|
|
||||||
} else {
|
|
||||||
(*plotProc)(x1, y0, kColorBlack, data); /* I. Quadrant */
|
|
||||||
(*plotProc)(x0, y0, kColorBlack, data); /* II. Quadrant */
|
|
||||||
(*plotProc)(x0, y1, kColorBlack, data); /* III. Quadrant */
|
|
||||||
(*plotProc)(x1, y1, kColorBlack, data); /* IV. Quadrant */
|
|
||||||
}
|
|
||||||
e2 = 2*err;
|
|
||||||
if (e2 <= dy) { y0++; y1--; err += dy += a; } /* y step */
|
|
||||||
if (e2 >= dx || 2*err > dy) { x0++; x1--; err += dx += b1; } /* x step */
|
|
||||||
} while (x0 <= x1);
|
|
||||||
|
|
||||||
while (y0-y1 < b) { /* too early stop of flat ellipses a=1 */
|
|
||||||
if (filled) {
|
|
||||||
drawHLine(x0-1, x0-1, y0, kColorBlack, plotProc, data); /* -> finish tip of ellipse */
|
|
||||||
drawHLine(x1+1, x1+1, y0, kColorBlack, plotProc, data);
|
|
||||||
drawHLine(x0-1, x0-1, y1, kColorBlack, plotProc, data);
|
|
||||||
drawHLine(x1+1, x1+1, y1, kColorBlack, plotProc, data);
|
|
||||||
} else {
|
|
||||||
(*plotProc)(x0-1, y0, kColorBlack, data); /* -> finish tip of ellipse */
|
|
||||||
(*plotProc)(x1+1, y0, kColorBlack, data);
|
|
||||||
(*plotProc)(x0-1, y1, kColorBlack, data);
|
|
||||||
(*plotProc)(x1+1, y1, kColorBlack, data);
|
|
||||||
}
|
|
||||||
y0++;
|
|
||||||
y1--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::drawHLine(Graphics::Surface *surface, int x1, int x2, int y, int thickness, int color, Patterns &patterns, byte fillType) {
|
void Design::drawHLine(Graphics::Surface *surface, int x1, int x2, int y, int thickness, int color, Patterns &patterns, byte fillType) {
|
||||||
plotData pd(surface, &patterns, fillType, thickness);
|
plotData pd(surface, &patterns, fillType, thickness);
|
||||||
|
|
||||||
drawHLine(x1, x2, y, color, drawPixel, &pd);
|
Graphics::drawHLine(x1, x2, y, color, drawPixel, &pd);
|
||||||
}
|
|
||||||
|
|
||||||
void Design::drawHLine(int x1, int x2, int y, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
|
||||||
if (x1 > x2)
|
|
||||||
SWAP(x1, x2);
|
|
||||||
|
|
||||||
for (int x = x1; x <= x2; x++)
|
|
||||||
(*plotProc)(x, y, color, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Design::drawVLine(Graphics::Surface *surface, int x, int y1, int y2, int thickness, int color, Patterns &patterns, byte fillType) {
|
void Design::drawVLine(Graphics::Surface *surface, int x, int y1, int y2, int thickness, int color, Patterns &patterns, byte fillType) {
|
||||||
plotData pd(surface, &patterns, fillType, thickness);
|
plotData pd(surface, &patterns, fillType, thickness);
|
||||||
|
|
||||||
drawVLine(x, y1, y2, color, drawPixel, &pd);
|
Graphics::drawVLine(x, y1, y2, color, drawPixel, &pd);
|
||||||
}
|
|
||||||
|
|
||||||
void Design::drawVLine(int x, int y1, int y2, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
|
||||||
if (y1 > y2)
|
|
||||||
SWAP(y1, y2);
|
|
||||||
|
|
||||||
for (int y = y1; y <= y2; y++)
|
|
||||||
(*plotProc)(x, y, color, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bresenham as presented in Foley & Van Dam */
|
|
||||||
/* Code is based on GD lib http://libgd.github.io/ */
|
|
||||||
void Design::drawThickLine (int x1, int y1, int x2, int y2, int thick, int color,
|
|
||||||
void (*plotProc)(int, int, int, void *), void *data) {
|
|
||||||
int incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
|
|
||||||
int wid;
|
|
||||||
int w, wstart;
|
|
||||||
|
|
||||||
int dx = abs(x2 - x1);
|
|
||||||
int dy = abs(y2 - y1);
|
|
||||||
|
|
||||||
if (dx == 0) {
|
|
||||||
if (y1 > y2)
|
|
||||||
SWAP(y1, y2);
|
|
||||||
Common::Rect r(x1, y1, x1 + thick - 1, y2);
|
|
||||||
drawFilledRect(r, color, plotProc, data);
|
|
||||||
return;
|
|
||||||
} else if (dy == 0) {
|
|
||||||
if (x1 > x2)
|
|
||||||
SWAP(x1, x2);
|
|
||||||
Common::Rect r(x1, y1, x2, y1 + thick - 1);
|
|
||||||
drawFilledRect(r, color, plotProc, data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dy <= dx) {
|
|
||||||
/* More-or-less horizontal. use wid for vertical stroke */
|
|
||||||
/* Doug Claar: watch out for NaN in atan2 (2.0.5) */
|
|
||||||
|
|
||||||
/* 2.0.12: Michael Schwartz: divide rather than multiply;
|
|
||||||
TBB: but watch out for /0! */
|
|
||||||
double ac = cos(atan2 (dy, dx));
|
|
||||||
if (ac != 0) {
|
|
||||||
wid = thick / ac;
|
|
||||||
} else {
|
|
||||||
wid = 1;
|
|
||||||
}
|
|
||||||
if (wid == 0) {
|
|
||||||
wid = 1;
|
|
||||||
}
|
|
||||||
d = 2 * dy - dx;
|
|
||||||
incr1 = 2 * dy;
|
|
||||||
incr2 = 2 * (dy - dx);
|
|
||||||
if (x1 > x2) {
|
|
||||||
x = x2;
|
|
||||||
y = y2;
|
|
||||||
ydirflag = (-1);
|
|
||||||
xend = x1;
|
|
||||||
} else {
|
|
||||||
x = x1;
|
|
||||||
y = y1;
|
|
||||||
ydirflag = 1;
|
|
||||||
xend = x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up line thickness */
|
|
||||||
wstart = y - wid / 2;
|
|
||||||
for (w = wstart; w < wstart + wid; w++)
|
|
||||||
(*plotProc)(x, y, color, data);
|
|
||||||
|
|
||||||
if (((y2 - y1) * ydirflag) > 0) {
|
|
||||||
while (x < xend) {
|
|
||||||
x++;
|
|
||||||
if (d < 0) {
|
|
||||||
d += incr1;
|
|
||||||
} else {
|
|
||||||
y++;
|
|
||||||
d += incr2;
|
|
||||||
}
|
|
||||||
wstart = y - wid / 2;
|
|
||||||
for (w = wstart; w < wstart + wid; w++)
|
|
||||||
(*plotProc)(x, w, color, data);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (x < xend) {
|
|
||||||
x++;
|
|
||||||
if (d < 0) {
|
|
||||||
d += incr1;
|
|
||||||
} else {
|
|
||||||
y--;
|
|
||||||
d += incr2;
|
|
||||||
}
|
|
||||||
wstart = y - wid / 2;
|
|
||||||
for (w = wstart; w < wstart + wid; w++)
|
|
||||||
(*plotProc)(x, w, color, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* More-or-less vertical. use wid for horizontal stroke */
|
|
||||||
/* 2.0.12: Michael Schwartz: divide rather than multiply;
|
|
||||||
TBB: but watch out for /0! */
|
|
||||||
double as = sin(atan2(dy, dx));
|
|
||||||
if (as != 0) {
|
|
||||||
wid = thick / as;
|
|
||||||
} else {
|
|
||||||
wid = 1;
|
|
||||||
}
|
|
||||||
if (wid == 0)
|
|
||||||
wid = 1;
|
|
||||||
|
|
||||||
d = 2 * dx - dy;
|
|
||||||
incr1 = 2 * dx;
|
|
||||||
incr2 = 2 * (dx - dy);
|
|
||||||
if (y1 > y2) {
|
|
||||||
y = y2;
|
|
||||||
x = x2;
|
|
||||||
yend = y1;
|
|
||||||
xdirflag = (-1);
|
|
||||||
} else {
|
|
||||||
y = y1;
|
|
||||||
x = x1;
|
|
||||||
yend = y2;
|
|
||||||
xdirflag = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up line thickness */
|
|
||||||
wstart = x - wid / 2;
|
|
||||||
for (w = wstart; w < wstart + wid; w++)
|
|
||||||
(*plotProc)(w, y, color, data);
|
|
||||||
|
|
||||||
if (((x2 - x1) * xdirflag) > 0) {
|
|
||||||
while (y < yend) {
|
|
||||||
y++;
|
|
||||||
if (d < 0) {
|
|
||||||
d += incr1;
|
|
||||||
} else {
|
|
||||||
x++;
|
|
||||||
d += incr2;
|
|
||||||
}
|
|
||||||
wstart = x - wid / 2;
|
|
||||||
for (w = wstart; w < wstart + wid; w++)
|
|
||||||
(*plotProc)(w, y, color, data);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (y < yend) {
|
|
||||||
y++;
|
|
||||||
if (d < 0) {
|
|
||||||
d += incr1;
|
|
||||||
} else {
|
|
||||||
x--;
|
|
||||||
d += incr2;
|
|
||||||
}
|
|
||||||
wstart = x - wid / 2;
|
|
||||||
for (w = wstart; w < wstart + wid; w++)
|
|
||||||
(*plotProc)(w, y, color, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FloodFill::FloodFill(Graphics::Surface *surface, byte color1, byte color2) {
|
FloodFill::FloodFill(Graphics::Surface *surface, byte color1, byte color2) {
|
||||||
|
|
|
@ -93,16 +93,6 @@ private:
|
||||||
void drawOval(Graphics::Surface *surface, Common::ReadStream &in,
|
void drawOval(Graphics::Surface *surface, Common::ReadStream &in,
|
||||||
Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType);
|
Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType);
|
||||||
void drawBitmap(Graphics::Surface *surface, Common::ReadStream &in);
|
void drawBitmap(Graphics::Surface *surface, Common::ReadStream &in);
|
||||||
|
|
||||||
void drawFilledRect(Common::Rect &rect, int color, void (*plotProc)(int, int, int, void *), void *data);
|
|
||||||
static void drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*plotProc)(int, int, int, void *), void *data);
|
|
||||||
void drawPolygonScan(int *polyX, int *polyY, int npoints, Common::Rect &bbox, int color,
|
|
||||||
void (*plotProc)(int, int, int, void *), void *data);
|
|
||||||
void drawEllipse(int x0, int y0, int x1, int y1, bool filled, void (*plotProc)(int, int, int, void *), void *data);
|
|
||||||
static void drawHLine(int x1, int x2, int y, int color, void (*plotProc)(int, int, int, void *), void *data);
|
|
||||||
static void drawVLine(int x, int y1, int y2, int color, void (*plotProc)(int, int, int, void *), void *data);
|
|
||||||
void drawThickLine (int x1, int y1, int x2, int y2, int thick, int color,
|
|
||||||
void (*plotProc)(int, int, int, void *), void *data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloodFill {
|
class FloodFill {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
#include "graphics/primitives.h"
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
|
@ -62,6 +63,22 @@ void drawLine(int x0, int y0, int x1, int y1, int color, void (*plotProc)(int, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawHLine(int x1, int x2, int y, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
|
if (x1 > x2)
|
||||||
|
SWAP(x1, x2);
|
||||||
|
|
||||||
|
for (int x = x1; x <= x2; x++)
|
||||||
|
(*plotProc)(x, y, color, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawVLine(int x, int y1, int y2, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
|
if (y1 > y2)
|
||||||
|
SWAP(y1, y2);
|
||||||
|
|
||||||
|
for (int y = y1; y <= y2; y++)
|
||||||
|
(*plotProc)(x, y, color, data);
|
||||||
|
}
|
||||||
|
|
||||||
void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
assert(penX > 0 && penY > 0);
|
assert(penX > 0 && penY > 0);
|
||||||
|
|
||||||
|
@ -79,4 +96,344 @@ void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, int color
|
||||||
drawLine(x0 + x, y0 + y, x1 + x, y1 + y, color, plotProc, data);
|
drawLine(x0 + x, y0 + y, x1 + x, y1 + y, color, plotProc, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bresenham as presented in Foley & Van Dam */
|
||||||
|
/* Code is based on GD lib http://libgd.github.io/ */
|
||||||
|
void drawThickLine2(int x1, int y1, int x2, int y2, int thick, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
|
int incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
|
||||||
|
int wid;
|
||||||
|
int w, wstart;
|
||||||
|
|
||||||
|
int dx = abs(x2 - x1);
|
||||||
|
int dy = abs(y2 - y1);
|
||||||
|
|
||||||
|
if (dx == 0) {
|
||||||
|
if (y1 > y2)
|
||||||
|
SWAP(y1, y2);
|
||||||
|
Common::Rect r(x1, y1, x1 + thick - 1, y2);
|
||||||
|
drawFilledRect(r, color, plotProc, data);
|
||||||
|
return;
|
||||||
|
} else if (dy == 0) {
|
||||||
|
if (x1 > x2)
|
||||||
|
SWAP(x1, x2);
|
||||||
|
Common::Rect r(x1, y1, x2, y1 + thick - 1);
|
||||||
|
drawFilledRect(r, color, plotProc, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dy <= dx) {
|
||||||
|
/* More-or-less horizontal. use wid for vertical stroke */
|
||||||
|
/* Doug Claar: watch out for NaN in atan2 (2.0.5) */
|
||||||
|
|
||||||
|
/* 2.0.12: Michael Schwartz: divide rather than multiply;
|
||||||
|
TBB: but watch out for /0! */
|
||||||
|
double ac = cos(atan2 (dy, dx));
|
||||||
|
if (ac != 0) {
|
||||||
|
wid = thick / ac;
|
||||||
|
} else {
|
||||||
|
wid = 1;
|
||||||
|
}
|
||||||
|
if (wid == 0) {
|
||||||
|
wid = 1;
|
||||||
|
}
|
||||||
|
d = 2 * dy - dx;
|
||||||
|
incr1 = 2 * dy;
|
||||||
|
incr2 = 2 * (dy - dx);
|
||||||
|
if (x1 > x2) {
|
||||||
|
x = x2;
|
||||||
|
y = y2;
|
||||||
|
ydirflag = (-1);
|
||||||
|
xend = x1;
|
||||||
|
} else {
|
||||||
|
x = x1;
|
||||||
|
y = y1;
|
||||||
|
ydirflag = 1;
|
||||||
|
xend = x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up line thickness */
|
||||||
|
wstart = y - wid / 2;
|
||||||
|
for (w = wstart; w < wstart + wid; w++)
|
||||||
|
(*plotProc)(x, y, color, data);
|
||||||
|
|
||||||
|
if (((y2 - y1) * ydirflag) > 0) {
|
||||||
|
while (x < xend) {
|
||||||
|
x++;
|
||||||
|
if (d < 0) {
|
||||||
|
d += incr1;
|
||||||
|
} else {
|
||||||
|
y++;
|
||||||
|
d += incr2;
|
||||||
|
}
|
||||||
|
wstart = y - wid / 2;
|
||||||
|
for (w = wstart; w < wstart + wid; w++)
|
||||||
|
(*plotProc)(x, w, color, data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (x < xend) {
|
||||||
|
x++;
|
||||||
|
if (d < 0) {
|
||||||
|
d += incr1;
|
||||||
|
} else {
|
||||||
|
y--;
|
||||||
|
d += incr2;
|
||||||
|
}
|
||||||
|
wstart = y - wid / 2;
|
||||||
|
for (w = wstart; w < wstart + wid; w++)
|
||||||
|
(*plotProc)(x, w, color, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* More-or-less vertical. use wid for horizontal stroke */
|
||||||
|
/* 2.0.12: Michael Schwartz: divide rather than multiply;
|
||||||
|
TBB: but watch out for /0! */
|
||||||
|
double as = sin(atan2(dy, dx));
|
||||||
|
if (as != 0) {
|
||||||
|
wid = thick / as;
|
||||||
|
} else {
|
||||||
|
wid = 1;
|
||||||
|
}
|
||||||
|
if (wid == 0)
|
||||||
|
wid = 1;
|
||||||
|
|
||||||
|
d = 2 * dx - dy;
|
||||||
|
incr1 = 2 * dx;
|
||||||
|
incr2 = 2 * (dx - dy);
|
||||||
|
if (y1 > y2) {
|
||||||
|
y = y2;
|
||||||
|
x = x2;
|
||||||
|
yend = y1;
|
||||||
|
xdirflag = (-1);
|
||||||
|
} else {
|
||||||
|
y = y1;
|
||||||
|
x = x1;
|
||||||
|
yend = y2;
|
||||||
|
xdirflag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up line thickness */
|
||||||
|
wstart = x - wid / 2;
|
||||||
|
for (w = wstart; w < wstart + wid; w++)
|
||||||
|
(*plotProc)(w, y, color, data);
|
||||||
|
|
||||||
|
if (((x2 - x1) * xdirflag) > 0) {
|
||||||
|
while (y < yend) {
|
||||||
|
y++;
|
||||||
|
if (d < 0) {
|
||||||
|
d += incr1;
|
||||||
|
} else {
|
||||||
|
x++;
|
||||||
|
d += incr2;
|
||||||
|
}
|
||||||
|
wstart = x - wid / 2;
|
||||||
|
for (w = wstart; w < wstart + wid; w++)
|
||||||
|
(*plotProc)(w, y, color, data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (y < yend) {
|
||||||
|
y++;
|
||||||
|
if (d < 0) {
|
||||||
|
d += incr1;
|
||||||
|
} else {
|
||||||
|
x--;
|
||||||
|
d += incr2;
|
||||||
|
}
|
||||||
|
wstart = x - wid / 2;
|
||||||
|
for (w = wstart; w < wstart + wid; w++)
|
||||||
|
(*plotProc)(w, y, color, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawFilledRect(Common::Rect &rect, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
|
for (int y = rect.top; y <= rect.bottom; y++)
|
||||||
|
drawHLine(rect.left, rect.right, y, color, plotProc, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://members.chello.at/easyfilter/bresenham.html
|
||||||
|
void drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
|
if (rect.height() < rect.width()) {
|
||||||
|
int x = -arc, y = 0, err = 2-2*arc; /* II. Quadrant */
|
||||||
|
int dy = rect.height() - arc * 2;
|
||||||
|
int r = arc;
|
||||||
|
int stop = 0;
|
||||||
|
int lastx, lasty;
|
||||||
|
if (dy < 0)
|
||||||
|
stop = -dy / 2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (filled) {
|
||||||
|
drawHLine(rect.left+x+r, rect.right-x-r, rect.top-y+r-stop, color, plotProc, data);
|
||||||
|
drawHLine(rect.left+x+r, rect.right-x-r, rect.bottom+y-r+stop, color, plotProc, data);
|
||||||
|
} else {
|
||||||
|
(*plotProc)(rect.left+x+r, rect.top-y+r-stop, color, data);
|
||||||
|
(*plotProc)(rect.right-x-r, rect.top-y+r-stop, color, data);
|
||||||
|
(*plotProc)(rect.left+x+r, rect.bottom+y-r+stop, color, data);
|
||||||
|
(*plotProc)(rect.right-x-r, rect.bottom+y-r+stop, color, data);
|
||||||
|
|
||||||
|
lastx = x;
|
||||||
|
lasty = y;
|
||||||
|
}
|
||||||
|
arc = err;
|
||||||
|
if (arc <= y) err += ++y*2+1; /* e_xy+e_y < 0 */
|
||||||
|
if (arc > x || err > y) err += ++x*2+1; /* e_xy+e_x > 0 or no 2nd y-step */
|
||||||
|
if (stop && y > stop)
|
||||||
|
break;
|
||||||
|
} while (x < 0);
|
||||||
|
|
||||||
|
if (!filled) {
|
||||||
|
x = lastx;
|
||||||
|
y = lasty;
|
||||||
|
|
||||||
|
drawHLine(rect.left+x+r, rect.right-x-r, rect.top-y+r-stop, color, plotProc, data);
|
||||||
|
drawHLine(rect.left+x+r, rect.right-x-r, rect.bottom+y-r+stop, color, plotProc, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < dy; i++) {
|
||||||
|
if (filled) {
|
||||||
|
drawHLine(rect.left, rect.right, rect.top + r + i, color, plotProc, data);
|
||||||
|
} else {
|
||||||
|
(*plotProc)(rect.left, rect.top + r + i, color, data);
|
||||||
|
(*plotProc)(rect.right, rect.top + r + i, color, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int y = -arc, x = 0, err = 2-2*arc; /* II. Quadrant */
|
||||||
|
int dx = rect.width() - arc * 2;
|
||||||
|
int r = arc;
|
||||||
|
int stop = 0;
|
||||||
|
int lastx, lasty;
|
||||||
|
if (dx < 0)
|
||||||
|
stop = -dx / 2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (filled) {
|
||||||
|
drawVLine(rect.left-x+r-stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
||||||
|
drawVLine(rect.right+x-r+stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
||||||
|
} else {
|
||||||
|
(*plotProc)(rect.left-x+r-stop, rect.top+y+r, color, data);
|
||||||
|
(*plotProc)(rect.left-x+r-stop, rect.bottom-y-r, color, data);
|
||||||
|
(*plotProc)(rect.right+x-r+stop, rect.top+y+r, color, data);
|
||||||
|
(*plotProc)(rect.right+x-r+stop, rect.bottom-y-r, color, data);
|
||||||
|
|
||||||
|
lastx = x;
|
||||||
|
lasty = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
arc = err;
|
||||||
|
if (arc <= x) err += ++x*2+1; /* e_xy+e_y < 0 */
|
||||||
|
if (arc > y || err > x) err += ++y*2+1; /* e_xy+e_x > 0 or no 2nd y-step */
|
||||||
|
if (stop && x > stop)
|
||||||
|
break;
|
||||||
|
} while (y < 0);
|
||||||
|
|
||||||
|
if (!filled) {
|
||||||
|
x = lastx;
|
||||||
|
y = lasty;
|
||||||
|
drawVLine(rect.left-x+r-stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
||||||
|
drawVLine(rect.right+x-r+stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < dx; i++) {
|
||||||
|
if (filled) {
|
||||||
|
drawVLine(rect.left + r + i, rect.top, rect.bottom, color, plotProc, data);
|
||||||
|
} else {
|
||||||
|
(*plotProc)(rect.left + r + i, rect.top, color, data);
|
||||||
|
(*plotProc)(rect.left + r + i, rect.bottom, color, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on public-domain code by Darel Rex Finley, 2007
|
||||||
|
// http://alienryderflex.com/polygon_fill/
|
||||||
|
void drawPolygonScan(int *polyX, int *polyY, int npoints, Common::Rect &bbox, int color, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
|
int *nodeX = (int *)calloc(npoints, sizeof(int));
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
// Loop through the rows of the image.
|
||||||
|
for (int pixelY = bbox.top; pixelY < bbox.bottom; pixelY++) {
|
||||||
|
// Build a list of nodes.
|
||||||
|
int nodes = 0;
|
||||||
|
j = npoints - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < npoints; i++) {
|
||||||
|
if ((polyY[i] < pixelY && polyY[j] >= pixelY) || (polyY[j] < pixelY && polyY[i] >= pixelY)) {
|
||||||
|
nodeX[nodes++] = (int)(polyX[i] + (double)(pixelY - polyY[i]) / (double)(polyY[j]-polyY[i]) *
|
||||||
|
(double)(polyX[j] - polyX[i]) + 0.5);
|
||||||
|
}
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the nodes, via a simple “Bubble” sort.
|
||||||
|
i = 0;
|
||||||
|
while (i < nodes - 1) {
|
||||||
|
if (nodeX[i] > nodeX[i + 1]) {
|
||||||
|
SWAP(nodeX[i], nodeX[i + 1]);
|
||||||
|
if (i)
|
||||||
|
i--;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the pixels between node pairs.
|
||||||
|
for (i = 0; i < nodes; i += 2) {
|
||||||
|
if (nodeX[i ] >= bbox.right)
|
||||||
|
break;
|
||||||
|
if (nodeX[i + 1] > bbox.left) {
|
||||||
|
nodeX[i] = MAX<int16>(nodeX[i], bbox.left);
|
||||||
|
nodeX[i + 1] = MIN<int16>(nodeX[i + 1], bbox.right);
|
||||||
|
|
||||||
|
drawHLine(nodeX[i], nodeX[i + 1], pixelY, color, plotProc, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(nodeX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://members.chello.at/easyfilter/bresenham.html
|
||||||
|
void drawEllipse(int x0, int y0, int x1, int y1, int color, bool filled, void (*plotProc)(int, int, int, void *), void *data) {
|
||||||
|
int a = abs(x1-x0), b = abs(y1-y0), b1 = b&1; /* values of diameter */
|
||||||
|
long dx = 4*(1-a)*b*b, dy = 4*(b1+1)*a*a; /* error increment */
|
||||||
|
long err = dx+dy+b1*a*a, e2; /* error of 1.step */
|
||||||
|
|
||||||
|
if (x0 > x1) { x0 = x1; x1 += a; } /* if called with swapped points */
|
||||||
|
if (y0 > y1) y0 = y1; /* .. exchange them */
|
||||||
|
y0 += (b+1)/2; y1 = y0-b1; /* starting pixel */
|
||||||
|
a *= 8*a; b1 = 8*b*b;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (filled) {
|
||||||
|
drawHLine(x0, x1, y0, color, plotProc, data);
|
||||||
|
drawHLine(x0, x1, y1, color, plotProc, data);
|
||||||
|
} else {
|
||||||
|
(*plotProc)(x1, y0, color, data); /* I. Quadrant */
|
||||||
|
(*plotProc)(x0, y0, color, data); /* II. Quadrant */
|
||||||
|
(*plotProc)(x0, y1, color, data); /* III. Quadrant */
|
||||||
|
(*plotProc)(x1, y1, color, data); /* IV. Quadrant */
|
||||||
|
}
|
||||||
|
e2 = 2*err;
|
||||||
|
if (e2 <= dy) { y0++; y1--; err += dy += a; } /* y step */
|
||||||
|
if (e2 >= dx || 2*err > dy) { x0++; x1--; err += dx += b1; } /* x step */
|
||||||
|
} while (x0 <= x1);
|
||||||
|
|
||||||
|
while (y0-y1 < b) { /* too early stop of flat ellipses a=1 */
|
||||||
|
if (filled) {
|
||||||
|
drawHLine(x0-1, x0-1, y0, color, plotProc, data); /* -> finish tip of ellipse */
|
||||||
|
drawHLine(x1+1, x1+1, y0, color, plotProc, data);
|
||||||
|
drawHLine(x0-1, x0-1, y1, color, plotProc, data);
|
||||||
|
drawHLine(x1+1, x1+1, y1, color, plotProc, data);
|
||||||
|
} else {
|
||||||
|
(*plotProc)(x0-1, y0, color, data); /* -> finish tip of ellipse */
|
||||||
|
(*plotProc)(x1+1, y0, color, data);
|
||||||
|
(*plotProc)(x0-1, y1, color, data);
|
||||||
|
(*plotProc)(x1+1, y1, color, data);
|
||||||
|
}
|
||||||
|
y0++;
|
||||||
|
y1--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Graphics
|
} // End of namespace Graphics
|
||||||
|
|
|
@ -23,10 +23,21 @@
|
||||||
#ifndef GRAPHICS_PRIMITIVES_H
|
#ifndef GRAPHICS_PRIMITIVES_H
|
||||||
#define GRAPHICS_PRIMITIVES_H
|
#define GRAPHICS_PRIMITIVES_H
|
||||||
|
|
||||||
|
#include "common/rect.h"
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
void drawLine(int x0, int y0, int x1, int y1, int color, void (*plotProc)(int, int, int, void *), void *data);
|
void drawLine(int x0, int y0, int x1, int y1, int color, void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
void drawHLine(int x1, int x2, int y, int color, void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
void drawVLine(int x, int y1, int y2, int color, void (*plotProc)(int, int, int, void *), void *data);
|
||||||
void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, int color, void (*plotProc)(int, int, int, void *), void *data);
|
void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, int color, void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
void drawThickLine2(int x1, int y1, int x2, int y2, int thick, int color,
|
||||||
|
void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
void drawFilledRect(Common::Rect &rect, int color, void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
void drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
void drawPolygonScan(int *polyX, int *polyY, int npoints, Common::Rect &bbox, int color,
|
||||||
|
void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
void drawEllipse(int x0, int y0, int x1, int y1, int color, bool filled, void (*plotProc)(int, int, int, void *), void *data);
|
||||||
|
|
||||||
} // End of namespace Graphics
|
} // End of namespace Graphics
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue