summaryrefslogtreecommitdiff
path: root/cd/src/drv/cdirgb.c
diff options
context:
space:
mode:
Diffstat (limited to 'cd/src/drv/cdirgb.c')
-rwxr-xr-xcd/src/drv/cdirgb.c235
1 files changed, 69 insertions, 166 deletions
diff --git a/cd/src/drv/cdirgb.c b/cd/src/drv/cdirgb.c
index 433a684..0c2913f 100755
--- a/cd/src/drv/cdirgb.c
+++ b/cd/src/drv/cdirgb.c
@@ -275,7 +275,7 @@ static void sCombineRGBALine(cdCtxCanvas* ctxcanvas, int offset, const unsigned
}
}
-static void irgbSolidLine(cdCanvas* canvas, int xmin, int y, int xmax)
+static void irgbSolidLine(cdCanvas* canvas, int xmin, int y, int xmax, long color)
{
int x;
unsigned long offset = y * canvas->w;
@@ -292,7 +292,7 @@ static void irgbSolidLine(cdCanvas* canvas, int xmin, int y, int xmax)
xmax = (canvas->w-1);
for (x = xmin; x <= xmax; x++)
- sCombineRGBColor(canvas->ctxcanvas, offset + x, canvas->foreground);
+ sCombineRGBColor(canvas->ctxcanvas, offset + x, color);
}
static void irgbPatternLine(cdCanvas* canvas, int xmin, int xmax, int y, int pw, const long *pattern)
@@ -506,7 +506,7 @@ static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdP
memcpy(t_poly, poly, sizeof(cdPoint)*n);
poly = t_poly;
- for(i = 0; i < n; i++)
+ for(i = 0; i < n; i++) /* must duplicate because clip poly is stored */
cdMatrixTransformPoint(canvas->matrix, poly[i].x, poly[i].y, &poly[i].x, &poly[i].y);
}
@@ -568,79 +568,6 @@ static void irgbClipPoly(cdCtxCanvas* ctxcanvas, unsigned char* clip_region, cdP
irgPostProcessIntersect(ctxcanvas->clip_region, ctxcanvas->canvas->w * ctxcanvas->canvas->h);
}
-static void irgbClipElipse(cdCtxCanvas* ctxcanvas, int xc, int yc, int width, int height, double angle1, double angle2, int sector)
-{
- float c, s, sx, sy, x, y, prev_x, prev_y;
- double da;
- int i, p;
- cdPoint* poly;
-
- /* number of segments of equivalent poligonal for a full ellipse */
- int n = simCalcEllipseNumSegments(ctxcanvas->canvas, xc, yc, width, height);
-
- /* number of segments for the arc */
- n = cdRound((fabs(angle2-angle1)*n)/360);
- if (n < 1) n = 1;
-
- poly = (cdPoint*)malloc(sizeof(cdPoint)*(n+2+1)); /* n+1 points +1 center */
-
- /* converts degrees into radians */
- angle1 *= CD_DEG2RAD;
- angle2 *= CD_DEG2RAD;
-
- /* generates arc points at origin with axis x and y */
-
- da = (angle2-angle1)/n;
- c = (float)cos(da);
- s = (float)sin(da);
- sx = -(width*s)/height;
- sy = (height*s)/width;
-
- x = xc + (width/2.0f)*(float)cos(angle1);
- y = yc + (height/2.0f)*(float)sin(angle1);
- poly[0].x = _cdRound(x);
- poly[0].y = _cdRound(y);
- prev_x = x;
- prev_y = y;
- p = 1;
-
- for (i = 1; i < n+1; i++) /* n+1 points */
- {
- x = xc + c*(prev_x-xc) + sx*(prev_y-yc);
- y = yc + sy*(prev_x-xc) + c*(prev_y-yc);
-
- poly[p].x = _cdRound(x);
- poly[p].y = _cdRound(y);
-
- if (poly[p-1].x != poly[p].x || poly[p-1].y != poly[p].y)
- p++;
-
- prev_x = x;
- prev_y = y;
- }
-
- if (poly[p-1].x != poly[0].x || poly[p-1].y != poly[0].y)
- {
- if (sector) /* cdSector */
- {
- /* add center */
- poly[p].x = xc;
- poly[p].y = yc;
- }
- else /* cdChord */
- {
- /* add initial point */
- poly[p].x = poly[0].x;
- poly[p].y = poly[0].y;
- }
- p++;
- }
-
- irgbClipPoly(ctxcanvas, ctxcanvas->clip_region, poly, p, ctxcanvas->canvas->combine_mode);
-
- free(poly);
-}
-
static void irgbClipBox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
int combine_mode = ctxcanvas->canvas->combine_mode;
@@ -858,39 +785,31 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
{
if (ctxcanvas->canvas->new_region)
{
+ /* matrix transformation is done inside irgbClip* if necessary */
irgbClipBox(ctxcanvas, xmin, xmax, ymin, ymax);
return;
}
- cdboxSIM(ctxcanvas, xmin, xmax, ymin, ymax);
-}
-
-static void cdsector(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
-{
- if (ctxcanvas->canvas->new_region)
- {
- irgbClipElipse(ctxcanvas, xc, yc, w, h, a1, a2, 1);
- return;
- }
-
- cdsectorSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdSimBox(ctxcanvas, xmin, xmax, ymin, ymax);
}
-static void cdchord(cdCtxCanvas *ctxcanvas, int xc, int yc, int w, int h, double a1, double a2)
+static void cdfbox(cdCtxCanvas *ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
if (ctxcanvas->canvas->new_region)
{
- irgbClipElipse(ctxcanvas, xc, yc, w, h, a1, a2, 0);
+ /* matrix transformation is done inside irgbClip* if necessary */
+ irgbClipBox(ctxcanvas, _cdRound(xmin), _cdRound(xmax), _cdRound(ymin), _cdRound(ymax));
return;
}
- cdchordSIM(ctxcanvas, xc, yc, w, h, a1, a2);
+ cdfSimBox(ctxcanvas, xmin, xmax, ymin, ymax);
}
static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
if (ctxcanvas->canvas->new_region)
{
+ /* matrix transformation is done inside irgbClip* if necessary */
irgbClipPoly(ctxcanvas, ctxcanvas->clip_region, poly, n, ctxcanvas->canvas->combine_mode);
return;
}
@@ -898,11 +817,15 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
if (mode == CD_CLIP)
{
/* set directly to clip */
- memset(ctxcanvas->clip, 1, ctxcanvas->canvas->w * ctxcanvas->canvas->h); /* CD_CLIPOFF */
+
+ /* CD_CLIPOFF */
+ memset(ctxcanvas->clip, 1, ctxcanvas->canvas->w * ctxcanvas->canvas->h);
+
+ /* matrix transformation is done inside irgbClip* if necessary */
irgbClipPoly(ctxcanvas, ctxcanvas->clip, poly, n, CD_UNION);
}
else
- cdpolySIM(ctxcanvas, mode, poly, n);
+ cdSimPoly(ctxcanvas, mode, poly, n);
}
static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *r, unsigned char *g, unsigned char *b, int x, int y, int w, int h)
@@ -952,20 +875,27 @@ static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *r, unsigned cha
}
}
+static void sFixImageY(int *topdown, int *y, int *h)
+{
+ if (*h < 0)
+ {
+ *h = -(*h);
+ *y -= (*h - 1); /* y is at top-left, move it to bottom-left */
+ *topdown = 1; /* image pointer will start at top-left */
+ }
+ else
+ *topdown = 0;
+}
+
static void cdputimagerectrgba_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
int t_xmin, t_xmax, t_ymin, t_ymax,
- t_x, t_y, img_topdown = 0, dst_offset;
+ t_x, t_y, topdown, dst_offset;
float i_x, i_y, xfactor, yfactor;
unsigned char sr, sg, sb, sa = 255;
double inv_matrix[6];
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* calculate the destination limits */
cdImageRGBCalcDstLimits(ctxcanvas->canvas, x, y, w, h, &t_xmin, &t_xmax, &t_ymin, &t_ymax, NULL);
@@ -984,7 +914,7 @@ static void cdputimagerectrgba_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, co
if (i_x > xmin && i_y > ymin && i_x < xmax+1 && i_y < ymax+1)
{
- if (img_topdown) /* image is top-bottom */
+ if (topdown) /* image is top-bottom */
i_y = ih-1 - i_y;
if (t_x == 350 && t_y == 383)
@@ -1007,17 +937,12 @@ static void cdputimagerectrgba_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, co
static void cdputimagerectmap_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
int t_xmin, t_xmax, t_ymin, t_ymax,
- t_x, t_y, img_topdown = 0, dst_offset;
+ t_x, t_y, topdown, dst_offset;
float i_x, i_y, xfactor, yfactor;
unsigned char si;
double inv_matrix[6];
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left (undocumented feature) */
- }
+ sFixImageY(&topdown, &y, &h);
/* calculate the destination limits */
cdImageRGBCalcDstLimits(ctxcanvas->canvas, x, y, w, h, &t_xmin, &t_xmax, &t_ymin, &t_ymax, NULL);
@@ -1036,7 +961,7 @@ static void cdputimagerectmap_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, con
if (i_x > xmin && i_y > ymin && i_x < xmax+1 && i_y < ymax+1)
{
- if (img_topdown) /* image is top-bottom */
+ if (topdown) /* image is top-bottom */
i_y = ih-1 - i_y;
si = cdZeroOrderInterpolation(iw, ih, index, i_x, i_y);
@@ -1048,7 +973,7 @@ static void cdputimagerectmap_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, con
static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
- int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rh, rw, img_topdown = 0;
+ int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rh, rw, topdown;
const unsigned char *src_red, *src_green, *src_blue;
if (ctxcanvas->canvas->use_matrix)
@@ -1057,12 +982,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
return;
}
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* verifica se esta dentro da area de desenho */
if (x > (ctxcanvas->canvas->w-1) || y > (ctxcanvas->canvas->h-1) ||
@@ -1090,7 +1010,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
for(l = 0; l < ysize; l++)
{
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = YTab[(ih - 1) - (l + (ypos - y))] * iw;
else
src_offset = YTab[l + (ypos - y)] * iw;
@@ -1117,7 +1037,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset = xpos + ypos * ctxcanvas->canvas->w;
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = (xpos - x + xmin) + ((ih - 1) - (ypos - y + ymin)) * iw;
else
src_offset = (xpos - x + xmin) + (ypos - y + ymin) * iw;
@@ -1132,7 +1052,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset += ctxcanvas->canvas->w;
- if (img_topdown)
+ if (topdown)
{
r -= iw;
g -= iw;
@@ -1150,7 +1070,7 @@ static void cdputimagerectrgb(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
- int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, img_topdown = 0;
+ int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, topdown;
const unsigned char *src_red, *src_green, *src_blue, *src_alpha;
if (ctxcanvas->canvas->use_matrix)
@@ -1159,12 +1079,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
return;
}
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* verifica se esta dentro da area de desenho */
if (x > (ctxcanvas->canvas->w-1) || y > (ctxcanvas->canvas->h-1) ||
@@ -1192,7 +1107,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
for(l = 0; l < ysize; l++)
{
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = YTab[(ih - 1) - (l + (ypos - y))] * iw;
else
src_offset = YTab[l + (ypos - y)] * iw;
@@ -1220,7 +1135,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
dst_offset = xpos + ypos * ctxcanvas->canvas->w;
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = (xpos - x + xmin) + ((ih - 1) - (ypos - y + ymin)) * iw;
else
src_offset = (xpos - x + xmin) + (ypos - y + ymin) * iw;
@@ -1236,7 +1151,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
dst_offset += ctxcanvas->canvas->w;
- if (img_topdown)
+ if (topdown)
{
r -= iw;
g -= iw;
@@ -1256,7 +1171,7 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int iw, int ih, const uns
static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
- int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, pal_size, idx, img_topdown = 0;
+ int l, c, xsize, ysize, xpos, ypos, src_offset, dst_offset, rw, rh, idx, topdown;
const unsigned char *src_index;
if (ctxcanvas->canvas->use_matrix)
@@ -1265,12 +1180,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
return;
}
- if (h < 0)
- {
- h = -h;
- y -= (h - 1); /* y is at top-left, move it to bottom-left */
- img_topdown = 1; /* image pointer will start at top-left */
- }
+ sFixImageY(&topdown, &y, &h);
/* verifica se esta dentro da area de desenho */
if (x > (ctxcanvas->canvas->w-1) || y > (ctxcanvas->canvas->h-1) ||
@@ -1286,22 +1196,6 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
rw = xmax-xmin+1;
rh = ymax-ymin+1;
- /* Como nao sabemos o tamanho da palette a priori,
- teremos que ver qual o maior indice usado na imagem. */
- pal_size = 0;
-
- for (l=0; l<ih; l++)
- {
- for (c=0; c<iw; c++)
- {
- idx = index[l*iw + c];
- if (idx > pal_size)
- pal_size = idx;
- }
- }
-
- pal_size++;
-
/* testa se tem que fazer zoom */
if (rw != w || rh != h)
{
@@ -1314,7 +1208,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
for(l = 0; l < ysize; l++)
{
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = YTab[(ih - 1) - (l + (ypos - y))] * iw;
else
src_offset = YTab[l + (ypos - y)] * iw;
@@ -1340,7 +1234,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset = xpos + ypos * ctxcanvas->canvas->w;
/* ajusta posicao inicial em source */
- if (img_topdown)
+ if (topdown)
src_offset = (xpos - x + xmin) + ((ih - 1) - (ypos - y + ymin)) * iw;
else
src_offset = (xpos - x + xmin) + (ypos - y + ymin) * iw;
@@ -1357,7 +1251,7 @@ static void cdputimagerectmap(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsi
dst_offset += ctxcanvas->canvas->w;
- if (img_topdown)
+ if (topdown)
index -= iw;
else
index += iw;
@@ -1696,6 +1590,7 @@ static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
if (data)
{
+ /* use this configuration when there is NO native tranformation support */
sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
&ctxcanvas->rotate_center_x,
&ctxcanvas->rotate_center_y);
@@ -1859,15 +1754,23 @@ static void cdinittable(cdCanvas* canvas)
canvas->cxClear = cdclear;
canvas->cxPixel = cdpixel;
- canvas->cxLine = cdlineSIM;
- canvas->cxRect = cdrectSIM;
+ canvas->cxLine = cdSimLine;
+ canvas->cxRect = cdSimRect;
canvas->cxBox = cdbox;
- canvas->cxArc = cdarcSIM;
- canvas->cxSector = cdsector;
- canvas->cxChord = cdchord;
+ canvas->cxArc = cdSimArc;
+ canvas->cxSector = cdSimSector;
+ canvas->cxChord = cdSimChord;
canvas->cxPoly = cdpoly;
canvas->cxText = NULL;
+ canvas->cxFLine = cdfSimLine;
+ canvas->cxFRect = cdfSimRect;
+ canvas->cxFBox = cdfbox;
+ canvas->cxFArc = cdfSimArc;
+ canvas->cxFSector = cdfSimSector;
+ canvas->cxFChord = cdfSimChord;
+ canvas->cxFPoly = cdfSimPoly;
+
canvas->cxKillCanvas = cdkillcanvas;
/* use simulation */
@@ -1885,9 +1788,9 @@ static void cdinittable(cdCanvas* canvas)
static cdContext cdImageRGBContext =
{
- CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_FPRIMTIVES |
- CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION |
- CD_CAP_PALETTE | CD_CAP_TEXTORIENTATION),
+ CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY |
+ CD_CAP_LINECAP | CD_CAP_LINEJOIN |
+ CD_CAP_PALETTE ),
0,
cdcreatecanvas,
cdinittable,
@@ -2003,9 +1906,9 @@ static void cdinittableDB(cdCanvas* canvas)
static cdContext cdDBufferRGBContext =
{
- CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_FPRIMTIVES |
- CD_CAP_LINECAP | CD_CAP_LINEJOIN | CD_CAP_REGION |
- CD_CAP_PALETTE | CD_CAP_TEXTORIENTATION),
+ CD_CAP_ALL & ~(CD_CAP_PLAY |
+ CD_CAP_LINECAP | CD_CAP_LINEJOIN |
+ CD_CAP_PALETTE ),
0,
cdcreatecanvasDB,
cdinittableDB,