/** @file
Parser: image manipulations impl1.
Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
$Id: gif.C,v 1.16 2001/10/16 07:47:16 parser Exp $
based on: gd
Written by Tom Boutell, 5/94.
Copyright 1994, Cold Spring Harbor Labs.
Permission granted to use this code in any fashion provided
that this notice is retained and any alterations are
labeled as such. It is requested, but not required, that
you share extensions to this module with us so that we
can incorporate them into new versions.
*/
#include "gif.h"
#include "mtables.h"
//static void BrushApply(int x, int y);
//static void TileApply(int x, int y);
void gdImage::Create(int asx, int asy) {
sx = asx;
sy = asy;
int i;
pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx);
polyInts = 0;
polyAllocated = 0;
lineWidth = 1; lineStyle=0;
for (i=0; (i<asx); i++)
pixels[i] = (unsigned char *) calloc(asy);
colorsTotal = 0;
transparent = (-1);
interlace = 0;
}
int gdImage::ColorClosest(int r, int g, int b)
{
int i;
long rd, gd, bd;
int ct = (-1);
long mindist = 0;
for (i=0; (i<(colorsTotal)); i++) {
long dist;
if (open[i]) {
continue;
}
rd = (red[i] - r);
gd = (green[i] - g);
bd = (blue[i] - b);
dist = rd * rd + gd * gd + bd * bd;
if ((i == 0) || (dist < mindist)) {
mindist = dist;
ct = i;
}
}
return ct;
}
int gdImage::ColorExact(int r, int g, int b)
{
int i;
for (i=0; (i<(colorsTotal)); i++) {
if (open[i]) {
continue;
}
if ((red[i] == r) &&
(green[i] == g) &&
(blue[i] == b)) {
return i;
}
}
return -1;
}
int gdImage::ColorAllocate(int r, int g, int b)
{
int i;
int ct = (-1);
for (i=0; (i<(colorsTotal)); i++) {
if (open[i]) {
ct = i;
break;
}
}
if (ct == (-1)) {
ct = colorsTotal;
if (ct == gdMaxColors) {
return -1;
}
colorsTotal++;
}
red[ct] = r;
green[ct] = g;
blue[ct] = b;
open[ct] = 0;
return ct;
}
int gdImage::ColorRGB(int r, int g, int b){
int idx=ColorExact(r,g,b);
return idx<0 ? ColorAllocate(r,g,b) : idx;
}
int gdImage::Color(unsigned int rgb){
unsigned int b=rgb, g=b>>8, r=g>>8;
return ColorRGB(r & 0xFF,g & 0xFF,b & 0xFF);
}
void gdImage::ColorDeallocate(int color)
{
/* Mark it open. */
open[color] = 1;
}
void gdImage::SetColorTransparent(int color)
{
transparent = color;
}
void gdImage::SetPixel(int x, int y, int color)
{
//paf int p;
switch (lineWidth){
case 1: {
DoSetPixel(x, y,color);
return;
}
case 2: {
DoSetPixel(x, y-1,color);
DoSetPixel(x-1, y,color);
DoSetPixel(x, y,color);
DoSetPixel(x+1, y,color);
DoSetPixel(x, y+1,color);
return;
}
default:{
int i,j;
for (i=-1;i<=1;i++) DoSetPixel(x+i, y-2,color);
for (j=-1;j<=1;j++) for (i=-2;i<=2;i++) DoSetPixel(x+i, y+j,color);
for (i=-1;i<=1;i++) DoSetPixel(x+i, y+2,color);
return;
}
}
}
int gdImage::GetPixel(int x, int y)
{
return BoundsSafe(x, y) ? pixels[x][y]:0;
}
/* Bresenham as presented in Foley & Van Dam */
/* As above, plus dashing */
#define styledSet \
{ \
if (lineStyle) { \
if(!lineStyle[styleStep]) \
styleStep = 0; \
on=lineStyle[styleStep++]!=' '; \
} \
if (on) { \
SetPixel(x, y, color); \
} \
}
void gdImage::Line(int x1, int y1, int x2, int y2, int color)
{
int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
int styleStep = 0;
int on = 1;
dx = abs(x2-x1);
dy = abs(y2-y1);
if (dy <= dx) {
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;
}
styledSet;
if (((y2 - y1) * ydirflag) > 0) {
while (x < xend) {
x++;
if (d <0) {
d+=incr1;
} else {
y++;
d+=incr2;
}
styledSet;
}
} else {
while (x < xend) {
x++;
if (d <0) {
d+=incr1;
} else {
y--;
d+=incr2;
}
styledSet;
}
}
} else {
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;
}
styledSet;
if (((x2 - x1) * xdirflag) > 0) {
while (y < yend) {
y++;
if (d <0) {
d+=incr1;
} else {
x++;
d+=incr2;
}
styledSet;
}
} else {
while (y < yend) {
y++;
if (d <0) {
d+=incr1;
} else {
x--;
d+=incr2;
}
styledSet;
}
}
}
}
/* s and e are integers modulo 360 (degrees), with 0 degrees
being the rightmost extreme and degrees changing clockwise.
cx and cy are the center in pixels; w and h are the horizontal
and vertical diameter in pixels. Nice interface, but slow, since
I don't yet use Bresenham (I'm using an inefficient but
simple solution with too much work going on in it; generalizing
Bresenham to ellipses and partial arcs of ellipses is non-trivial,
at least for me) and there are other inefficiencies (small circles
do far too much work). */
void gdImage::Arc(int cx, int cy, int w, int h, int s, int e, int color)
{
#if 0
if(s==0 && e==360) { // full
if(w==h) { // circle?
/* Bresenham octant code, which I should use eventually */
int x, y, d;
x = 0;
y = w/2;
d = 3-w;
while (x <= y) {
SetPixel(cx+x, cy+y, color);
SetPixel(cx+x, cy-y, color);
SetPixel(cx-x, cy+y, color);
SetPixel(cx-x, cy-y, color);
SetPixel(cx+y, cy+x, color);
SetPixel(cx+y, cy-x, color);
SetPixel(cx-y, cy+x, color);
SetPixel(cx-y, cy-x, color);
if (d < 0) {
d += 4 * x + 6;
} else {
d += 4 * (x - y) + 10;
y--;
}
x++;
}
} else { // full ellipse
w/=2;
h/=2;
int elx, ely;
long aa, aa2, bb, bb2, d, dx, dy;
elx = 0; ely = h; aa = (long)w * w; aa2 = 2 * aa;
bb = (long)h * h; bb2 = 2 * bb;
d = bb - aa * h + aa/4; dx = 0; dy = aa2 * h;
SetPixel(cx, cy - ely, color); SetPixel(cx, cy + ely, color);
SetPixel(cx - w, cy, color); SetPixel(cx + w, cy, color);
while (dx < dy)
{
if (d > 0) { ely--; dy-=aa2; d-=dy;}
elx++; dx+=bb2; d+=bb+dx;
SetPixel(cx + elx, cy + ely, color);
SetPixel(cx - elx, cy + ely, color);
SetPixel(cx + elx, cy - ely, color);
SetPixel(cx - elx, cy - ely, color);
};
d+=(3 * (aa - bb)/2 - (dx + dy))/2;
while (ely > 0)
{
if (d < 0) {elx++; dx+=bb2; d+=bb + dx;}
ely--; dy-=aa2; d+=aa - dy;
SetPixel(cx + elx, cy + ely, color);
SetPixel(cx - elx, cy + ely, color);
SetPixel(cx + elx, cy - ely, color);
SetPixel(cx - elx, cy - ely, color);
};
}
} else {
#endif
int i;
int lx = 0, ly = 0;
int w2, h2;
w2 = w/2;
h2 = h/2;
while (e < s) {
e += 360;
}
for (i=s; (i <= e); i++) {
int x, y;
x = ((long)cost[i % 360] * (long)w2 / costScale) + cx;
y = ((long)sint[i % 360] * (long)h2 / sintScale) + cy;
if (i != s) {
Line(lx, ly, x, y, color);
}
lx = x;
ly = y;
}
#if 0
}
#endif
}
/*
// http://firststeps.narod.ru/cgi/18.html
int CGIScreen::Ellipse(int exc, int eyc, int ea, int eb , unsigned char Color)
{
int elx, ely;
long aa, aa2, bb, bb2, d, dx, dy;
elx = 0; ely = eb; aa = (long)ea * ea; aa2 = 2 * aa;
bb = (long)eb * eb; bb2 = 2 * bb;
d = bb - aa * eb + aa/4; dx = 0; dy = aa2 * eb;
PutPixel(exc, eyc - ely, Color); PutPixel(exc, eyc + ely, Color);
PutPixel(exc - ea, eyc, Color); PutPixel(exc + ea, eyc, Color);
while (dx < dy)
{
if (d > 0) { ely--; dy-=aa2; d-=dy;}
elx++; dx+=bb2; d+=bb+dx;
PutPixel(exc + elx, eyc + ely, Color);
PutPixel(exc - elx, eyc + ely, Color);
PutPixel(exc + elx, eyc - ely, Color);
PutPixel(exc - elx, eyc - ely, Color);
};
d+=(3 * (aa - bb)/2 - (dx + dy))/2;
while (ely > 0)
{
if (d < 0) {elx++; dx+=bb2; d+=bb + dx;}
ely--; dy-=aa2; d+=aa - dy;
PutPixel(exc + elx, eyc + ely, Color);
PutPixel(exc - elx, eyc + ely, Color);
PutPixel(exc + elx, eyc - ely, Color);
PutPixel(exc - elx, eyc - ely, Color);
};
return 0;
};
*/
void gdImage::Sector(int cx, int cy, int w, int h, int s, int e, int color)
{
int i;
int lx = 0, ly = 0;
int w2, h2;
w2 = w/2;
h2 = h/2;
while (e < s) {
e += 360;
}
for (i=s; (i <= e); i++) {
int x, y;
x = ((long)cost[i % 360] * (long)w2 / costScale) + cx;
y = ((long)sint[i % 360] * (long)h2 / sintScale) + cy;
if(i==s || i==e)
Line(cx, cy, x, y, color);
if (i != s) {
Line(lx, ly, x, y, color);
}
lx = x;
ly = y;
}
}
void gdImage::FillToBorder(int x, int y, int border, int color)
{
if(!BoundsSafe(x, y)) //PAF
return;
int lastBorder;
/* Seek left */
int leftLimit, rightLimit;
int i;
leftLimit = (-1);
if (border < 0) {
/* Refuse to fill to a non-solid border */
return;
}
for (i = x; (i >= 0); i--) {
if (GetPixel(i, y) == border) {
break;
}
SetPixel(i, y, color);
leftLimit = i;
}
if (leftLimit == (-1)) {
return;
}
/* Seek right */
rightLimit = x;
for (i = (x+1); (i < sx); i++) {
if (GetPixel(i, y) == border) {
break;
}
SetPixel(i, y, color);
rightLimit = i;
}
/* Look at lines above and below and start paints */
/* Above */
if (y > 0) {
lastBorder = 1;
for (i = leftLimit; (i <= rightLimit); i++) {
int c;
c = GetPixel(i, y-1);
if (lastBorder) {
if ((c != border) && (c != color)) {
FillToBorder(i, y-1,
border, color);
lastBorder = 0;
}
} else if ((c == border) || (c == color)) {
lastBorder = 1;
}
}
}
/* Below */
if (y < ((sy) - 1)) {
lastBorder = 1;
for (i = leftLimit; (i <= rightLimit); i++) {
int c;
c = GetPixel(i, y+1);
if (lastBorder) {
if ((c != border) && (c != color)) {
FillToBorder(i, y+1,
border, color);
lastBorder = 0;
}
} else if ((c == border) || (c == color)) {
lastBorder = 1;
}
}
}
}
void gdImage::Fill(int x, int y, int color)
{
if(!BoundsSafe(x, y)) //PAF
return;
int lastBorder;
int old;
int leftLimit, rightLimit;
int i;
old = GetPixel(x, y);
if (old == color) {
/* Nothing to be done */
return;
}
/* Seek left */
leftLimit = (-1);
for (i = x; (i >= 0); i--) {
if (GetPixel(i, y) != old) {
break;
}
SetPixel(i, y, color);
leftLimit = i;
}
if (leftLimit == (-1)) {
return;
}
/* Seek right */
rightLimit = x;
for (i = (x+1); (i < sx); i++) {
if (GetPixel(i, y) != old) {
break;
}
SetPixel(i, y, color);
rightLimit = i;
}
/* Look at lines above and below and start paints */
/* Above */
if (y > 0) {
lastBorder = 1;
for (i = leftLimit; (i <= rightLimit); i++) {
int c;
c = GetPixel(i, y-1);
if (lastBorder) {
if (c == old) {
Fill(i, y-1, color);
lastBorder = 0;
}
} else if (c != old) {
lastBorder = 1;
}
}
}
/* Below */
if (y < ((sy) - 1)) {
lastBorder = 1;
for (i = leftLimit; (i <= rightLimit); i++) {
int c;
c = GetPixel(i, y+1);
if (lastBorder) {
if (c == old) {
Fill(i, y+1, color);
lastBorder = 0;
}
} else if (c != old) {
lastBorder = 1;
}
}
}
}
void gdImage::Rectangle(int x1, int y1, int x2, int y2, int color)
{
Line(x1, y1, x2, y1, color);
Line(x1, y2, x2, y2, color);
Line(x1, y1, x1, y2, color);
Line(x2, y1, x2, y2, color);
}
void gdImage::FilledRectangle(int x1, int y1, int x2, int y2, int color)
{
if(x1>x2) {
int t=x1;
x1=x2;
x2=t;
}
if(y1>y2) {
int t=y1;
y1=y2;
y2=t;
}
int x, y;
for (y=y1; (y<=y2); y++)
for (x=x1; (x<=x2); x++)
SetPixel(x, y, color);
}
void gdImage::Copy(gdImage& dst, int dstX, int dstY, int srcX, int srcY, int w, int h)
{
int c;
int x, y;
int tox, toy;
int i;
int colorMap[gdMaxColors];
for (i=0; (i<gdMaxColors); i++) {
colorMap[i] = (-1);
}
toy = dstY;
for (y=srcY; (y < (srcY + h)); y++) {
tox = dstX;
for (x=srcX; (x < (srcX + w)); x++) {
int nc;
c = GetPixel(x, y);
/* Added 7/24/95: support transparent copies */
if (GetTransparent() == c) {
tox++;
continue;
}
/* Have we established a mapping for this color? */
if (colorMap[c] == (-1)) {
/* If it's the same image, mapping is trivial */
if (&dst == this) {
nc = c;
} else {
/* First look for an exact match */
nc = dst.ColorExact(
red[c], green[c],
blue[c]);
}
if (nc == (-1)) {
/* No, so try to allocate it */
nc = dst.ColorAllocate(
red[c], green[c],
blue[c]);
/* If we're out of colors, go for the
closest color */
if (nc == (-1)) {
nc = dst.ColorClosest(
red[c], green[c],
blue[c]);
}
}
colorMap[c] = nc;
}
dst.SetPixel(tox, toy, colorMap[c]);
tox++;
}
toy++;
}
}
void gdImage::CopyResized(gdImage& dst, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
{
gdImage& src=*this;
int c;
int x, y;
int tox, toy;
int ydest;
int i;
int colorMap[gdMaxColors];
/* Stretch vectors */
int *stx;
int *sty;
/* We only need to use floating point to determine the correct
stretch vector for one line's worth. */
double accum;
stx = (int *) malloc(sizeof(int) * srcW);
sty = (int *) malloc(sizeof(int) * srcH);
accum = 0;
for (i=0; (i < srcW); i++) {
int got;
accum += (double)dstW/(double)srcW;
got = floor(accum);
stx[i] = got;
accum -= got;
}
accum = 0;
for (i=0; (i < srcH); i++) {
int got;
accum += (double)dstH/(double)srcH;
got = floor(accum);
sty[i] = got;
accum -= got;
}
for (i=0; (i<gdMaxColors); i++) {
colorMap[i] = (-1);
}
toy = dstY;
for (y=srcY; (y < (srcY + srcH)); y++) {
for (ydest=0; (ydest < sty[y-srcY]); ydest++) {
tox = dstX;
for (x=srcX; (x < (srcX + srcW)); x++) {
int nc;
if (!stx[x - srcX]) {
continue;
}
c = src.GetPixel(x, y);
/* Added 7/24/95: support transparent copies */
if (src.GetTransparent() == c) {
tox += stx[x-srcX];
continue;
}
/* Have we established a mapping for this color? */
if (colorMap[c] == (-1)) {
/* If it's the same image, mapping is trivial */
if (&dst == &src) {
nc = c;
} else {
/* First look for an exact match */
nc = dst.ColorExact(
src.red[c], src.green[c],
src.blue[c]);
}
if (nc == (-1)) {
/* No, so try to allocate it */
nc = dst.ColorAllocate(
src.red[c], src.green[c],
src.blue[c]);
/* If we're out of colors, go for the
closest color */
if (nc == (-1)) {
nc = dst.ColorClosest(
src.red[c], src.green[c],
src.blue[c]);
}
}
colorMap[c] = nc;
}
for (i=0; (i < stx[x - srcX]); i++) {
dst.SetPixel(tox, toy, colorMap[c]);
tox++;
}
}
toy++;
}
}
free(stx);
free(sty);
}
static int gdGetWord(int *result, FILE *in)
{
int r;
r = getc(in);
if (r == EOF) {
return 0;
}
*result = r << 8;
r = getc(in);
if (r == EOF) {
return 0;
}
*result += r;
return 1;
}
static void gdPutWord(int w, FILE *out)
{
putc((unsigned char)(w >> 8), out);
putc((unsigned char)(w & 0xFF), out);
}
static int gdGetByte(int *result, FILE *in)
{
int r;
r = getc(in);
if (r == EOF) {
return 0;
}
*result = r;
return 1;
}
void gdImage::Polygon(Point *p, int n, int c, bool closed)
{
int i;
int lx, ly;
if (!n) {
return;
}
lx = p->x;
ly = p->y;
if(closed)
Line(lx, ly, p[n-1].x, p[n-1].y, c);
for (i=1; (i < n); i++) {
p++;
Line(lx, ly, p->x, p->y, c);
lx = p->x;
ly = p->y;
}
}
static int gdCompareInt(const void *a, const void *b)
{
return (*(const int *)a) - (*(const int *)b);
}
void gdImage::FilledPolygon(Point *p, int n, int c)
{
int i;
int y;
int y1, y2;
int ints;
if (!n) {
return;
}
if (!polyAllocated) {
polyInts = (int *) malloc(sizeof(int) * n);
polyAllocated = n;
}
if (polyAllocated < n) {
while (polyAllocated < n) {
polyAllocated *= 2;
}
polyInts = (int *) realloc(polyInts,
sizeof(int) * polyAllocated);
}
y1 = p[0].y;
y2 = p[0].y;
for (i=1; (i < n); i++) {
if (p[i].y < y1) {
y1 = p[i].y;
}
if (p[i].y > y2) {
y2 = p[i].y;
}
}
for (y=y1; (y <= y2); y++) {
int interLast = 0;
int dirLast = 0;
int interFirst = 1;
ints = 0;
for (i=0; (i <= n); i++) {
int x1, x2;
int y1, y2;
int dir;
int ind1, ind2;
int lastInd1 = 0;
if ((i == n) || (!i)) {
ind1 = n-1;
ind2 = 0;
} else {
ind1 = i-1;
ind2 = i;
}
y1 = p[ind1].y;
y2 = p[ind2].y;
if (y1 < y2) {
y1 = p[ind1].y;
y2 = p[ind2].y;
x1 = p[ind1].x;
x2 = p[ind2].x;
dir = -1;
} else if (y1 > y2) {
y2 = p[ind1].y;
y1 = p[ind2].y;
x2 = p[ind1].x;
x1 = p[ind2].x;
dir = 1;
} else {
/* Horizontal; just draw it */
Line(
p[ind1].x, y1,
p[ind2].x, y1,
c);
continue;
}
if ((y >= y1) && (y <= y2)) {
int inter =
(y-y1) * (x2-x1) / (y2-y1) + x1;
/* Only count intersections once
except at maxima and minima. Also,
if two consecutive intersections are
endpoints of the same horizontal line
that is not at a maxima or minima,
discard the leftmost of the two. */
if (!interFirst) {
if ((p[ind1].y == p[lastInd1].y) &&
(p[ind1].x != p[lastInd1].x)) {
if (dir == dirLast) {
if (inter > interLast) {
/* Replace the old one */
polyInts[ints] = inter;
} else {
/* Discard this one */
}
continue;
}
}
if (inter == interLast) {
if (dir == dirLast) {
continue;
}
}
}
if (i > 0) {
polyInts[ints++] = inter;
}
lastInd1 = i;
dirLast = dir;
interLast = inter;
interFirst = 0;
}
}
qsort(polyInts, ints, sizeof(int), gdCompareInt);
for (i=0; (i < (ints-1)); i+=2)
Line(polyInts[i], y, polyInts[i+1], y, c);
}
}
//001005paf this used in drawing straight lines in gdImage::FilledPolygonReplaceColor
void gdImage::LineReplaceColor(int x1, int y1, int x2, int y2, int a, int b) {
if(y1!=y2)
return;
for(int x=x1; x<=x2; x++) {
unsigned char *pixel=&pixels[x][y1];
if(*pixel==a)
*pixel=b;
}
}
void gdImage::FilledPolygonReplaceColor(Point *p, int n, int a, int b)
{
int i;
int y;
int y1, y2;
int ints;
if (!n) {
return;
}
if (!polyAllocated) {
polyInts = (int *) malloc(sizeof(int) * n);
polyAllocated = n;
}
if (polyAllocated < n) {
while (polyAllocated < n) {
polyAllocated *= 2;
}
polyInts = (int *) realloc(polyInts,
sizeof(int) * polyAllocated);
}
y1 = p[0].y;
y2 = p[0].y;
for (i=1; (i < n); i++) {
if (p[i].y < y1) {
y1 = p[i].y;
}
if (p[i].y > y2) {
y2 = p[i].y;
}
}
for (y=y1; (y <= y2); y++) {
int interLast = 0;
int dirLast = 0;
int interFirst = 1;
ints = 0;
for (i=0; (i <= n); i++) {
int x1, x2;
int y1, y2;
int dir;
int ind1, ind2;
int lastInd1 = 0;
if ((i == n) || (!i)) {
ind1 = n-1;
ind2 = 0;
} else {
ind1 = i-1;
ind2 = i;
}
y1 = p[ind1].y;
y2 = p[ind2].y;
if (y1 < y2) {
y1 = p[ind1].y;
y2 = p[ind2].y;
x1 = p[ind1].x;
x2 = p[ind2].x;
dir = -1;
} else if (y1 > y2) {
y2 = p[ind1].y;
y1 = p[ind2].y;
x2 = p[ind1].x;
x1 = p[ind2].x;
dir = 1;
} else {
/* Horizontal; just draw it */
LineReplaceColor(
p[ind1].x, y1,
p[ind2].x, y1,
a,b);
continue;
}
if ((y >= y1) && (y <= y2)) {
int inter =
(y-y1) * (x2-x1) / (y2-y1) + x1;
/* Only count intersections once
except at maxima and minima. Also,
if two consecutive intersections are
endpoints of the same horizontal line
that is not at a maxima or minima,
discard the leftmost of the two. */
if (!interFirst) {
if ((p[ind1].y == p[lastInd1].y) &&
(p[ind1].x != p[lastInd1].x)) {
if (dir == dirLast) {
if (inter > interLast) {
/* Replace the old one */
polyInts[ints] = inter;
} else {
/* Discard this one */
}
continue;
}
}
if (inter == interLast) {
if (dir == dirLast) {
continue;
}
}
}
if (i > 0) {
polyInts[ints++] = inter;
}
lastInd1 = i;
dirLast = dir;
interLast = inter;
interFirst = 0;
}
}
qsort(polyInts, ints, sizeof(int), gdCompareInt);
for (i=0; (i < (ints-1)); i+=2) {
LineReplaceColor(polyInts[i], y,
polyInts[i+1], y, a,b);
}
}
}
void gdImage::SetInterlace(int interlaceArg)
{
interlace = interlaceArg;
}
void gdImage::SetLineWidth(int width)
{
lineWidth=width;
}
void gdImage::SetLineStyle(const char *alineStyle)
{
lineStyle=alineStyle;
}
E-mail: