--- parser3/src/classes/gd/Attic/gif.C 2001/09/26 10:32:25 1.9 +++ parser3/src/classes/gd/Attic/gif.C 2003/03/24 09:39:55 1.30.2.4.2.2 @@ -1,11 +1,8 @@ /** @file Parser: image manipulations impl1. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) - - $Id: gif.C,v 1.9 2001/09/26 10:32:25 parser Exp $ - + Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) based on: gd Written by Tom Boutell, 5/94. @@ -17,8 +14,13 @@ can incorporate them into new versions. */ +static const char* IDENT_GIF_C="$Date: 2003/03/24 09:39:55 $"; + #include "gif.h" +#include "mtables.h" +#include "pa_common.h" + //static void BrushApply(int x, int y); //static void TileApply(int x, int y); @@ -30,15 +32,15 @@ void gdImage::Create(int asx, int asy) { pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx); polyInts = 0; polyAllocated = 0; - lineWidth = 1; lineStyle=0; + lineWidth = 1; for (i=0; (i 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; + // paf + while(s<0) s+=360; + while(s>360) s-=360; + while(e<0) e+=360; + while(e>360) e-=360; + for (i=s; (i <= e); i++) { + int x, y; + x = ((long)cost[i] * (long)w2 / costScale) + cx; + y = ((long)sint[i] * (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; + // paf + while(s<0) s+=360; + while(s>360) s-=360; + while(e<0) e+=360; + while(e>360) e-=360; + for (i=s; (i <= e); i++) { + int x, y; + x = ((long)cost[i] * (long)w2 / costScale) + cx; + y = ((long)sint[i] * (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 @@ -419,7 +577,18 @@ void gdImage::Rectangle(int x1, int y1, 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); @@ -479,6 +648,137 @@ void gdImage::Copy(gdImage& dst, int dst } } +void gdImage::CopyResampled(gdImage& dst, + int dstX, int dstY, + int srcX, int srcY, + int dstW, int dstH, + int srcW, int srcH, + int tolerance) +{ + gdImage& src=*this; + int x, y; + int srcTransparent=src.GetTransparent(); + int dstTransparent=dst.GetTransparent(); + for (y = dstY; (y < dstY + dstH); y++) { + for (x = dstX; (x < dstX + dstW); x++) { + int pd = dst.GetPixel (x, y); + /* Added 7/24/95: support transparent copies */ + /* fixed by paf 20030116, another fix below */ + if (pd == dstTransparent) + continue; + + double sy1, sy2, sx1, sx2; + double sx, sy; + double spixels = 0; + double red = 0.0, green = 0.0, blue = 0.0; + bool transparent=true; + sy1 = ((double) y - (double) dstY) * (double) srcH / + (double) dstH; + sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH / + (double) dstH; + sy = sy1; + do + { + double yportion; + if (floor (sy) == floor (sy1)) + { + yportion = 1.0 - (sy - floor (sy)); + if (yportion > sy2 - sy1) + { + yportion = sy2 - sy1; + } + sy = floor (sy); + } + else if (sy == floor (sy2)) + { + yportion = sy2 - floor (sy2); + } + else + { + yportion = 1.0; + } + sx1 = ((double) x - (double) dstX) * (double) srcW / + dstW; + sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / + dstW; + sx = sx1; + do + { + double xportion; + double pcontribution; + int p; + if (floor (sx) == floor (sx1)) + { + xportion = 1.0 - (sx - floor (sx)); + if (xportion > sx2 - sx1) + { + xportion = sx2 - sx1; + } + sx = floor (sx); + } + else if (sx == floor (sx2)) + { + xportion = sx2 - floor (sx2); + } + else + { + xportion = 1.0; + } + pcontribution = xportion * yportion; + p = src.GetPixel ( + (int) sx, + (int) sy); + // fix added 20020116 by paf to support transparent src + if (p!=srcTransparent) { + transparent = false; + red += Red (p) * pcontribution; + green += Green (p) * pcontribution; + blue += Blue (p) * pcontribution; + } + spixels += xportion * yportion; + sx += 1.0; + } while (sx < sx2); + sy += 1.0; + } while (sy < sy2); + + if(transparent) + continue; + + if (spixels != 0.0) { + red /= spixels; + green /= spixels; + blue /= spixels; + } + /* Clamping to allow for rounding errors above */ + if (red > 255.0) + red = 255.0; + if (green > 255.0) + green = 255.0; + if (blue > 255.0) + blue = 255.0; + + red=round(red); + green=round(green); + blue=round(blue); + /* First look for an exact match */ + int nc = dst.ColorExact((int)red, (int)green, (int)blue); + if (nc == (-1)) { + /* No, so go for the closest color with high tolerance */ + nc = dst.ColorClosest((int)red, (int)green, (int)blue, tolerance); + if (nc == (-1)) { + /* Not found with even high tolerance, so try to allocate it */ + nc = dst.ColorAllocate((int)red, (int)green, (int)blue); + + /* If we're out of colors, go for the closest color */ + if (nc == (-1)) + nc = dst.ColorClosest((int)red, (int)green, (int)blue); + } + } + dst.SetPixel(x, y, nc); + } + } +} + static int gdGetWord(int *result, FILE *in) { int r; @@ -656,11 +956,12 @@ void gdImage::LineReplaceColor(int x1, i if(y1!=y2) return; - for(int x=x1; x<=x2; x++) { - unsigned char *pixel=&pixels[x][y1]; - if(*pixel==a) - *pixel=b; - } + for(int x=x1; x<=x2; x++) + if(BoundsSafe(x, y1)) { + unsigned char *pixel=&pixels[x][y1]; + if(*pixel==a) + *pixel=b; + } } void gdImage::FilledPolygonReplaceColor(Point *p, int n, int a, int b) @@ -788,7 +1089,7 @@ void gdImage::SetLineWidth(int width) lineWidth=width; } -void gdImage::SetLineStyle(const char *alineStyle) +void gdImage::SetLineStyle(const char* alineStyle) { lineStyle=alineStyle; }