diff options
Diffstat (limited to 'cd/src/drv/cdirgb.c')
-rwxr-xr-x | cd/src/drv/cdirgb.c | 235 |
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, |