|
|
| version 1.4, 2001/04/12 14:07:34 | version 1.12, 2001/10/08 15:50:22 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: image manipulations impl1. | Parser: image manipulations impl1. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) |
| $Id$ | $Id$ |
| */ | |
| #include <string.h> | based on: gd |
| #include <stdlib.h> | |
| #include <math.h> | 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 "gif.h" |
| #include "mtables.h" | |
| //static void BrushApply(int x, int y); | //static void BrushApply(int x, int y); |
| //static void TileApply(int x, int y); | //static void TileApply(int x, int y); |
| Line 23 void gdImage::Create(int asx, int asy) { | Line 32 void gdImage::Create(int asx, int asy) { |
| pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx); | pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx); |
| polyInts = 0; | polyInts = 0; |
| polyAllocated = 0; | polyAllocated = 0; |
| styleWidth = 1; | lineWidth = 1; lineStyle=0; |
| for (i=0; (i<asx); i++) | for (i=0; (i<asx); i++) |
| pixels[i] = (unsigned char *) calloc(asy); | pixels[i] = (unsigned char *) calloc(asy); |
| colorsTotal = 0; | colorsTotal = 0; |
| Line 120 void gdImage::SetPixel(int x, int y, int | Line 129 void gdImage::SetPixel(int x, int y, int |
| { | { |
| //paf int p; | //paf int p; |
| switch (styleWidth){ | switch (lineWidth){ |
| case 1: { | case 1: { |
| DoSetPixel(x, y,color); | DoSetPixel(x, y,color); |
| return; | return; |
| Line 150 int gdImage::GetPixel(int x, int y) | Line 159 int gdImage::GetPixel(int x, int y) |
| /* Bresenham as presented in Foley & Van Dam */ | /* Bresenham as presented in Foley & Van Dam */ |
| 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; | |
| 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; | |
| } | |
| SetPixel(x, y, color); | |
| if (((y2 - y1) * ydirflag) > 0) { | |
| while (x < xend) { | |
| x++; | |
| if (d <0) { | |
| d+=incr1; | |
| } else { | |
| y++; | |
| d+=incr2; | |
| } | |
| SetPixel(x, y, color); | |
| } | |
| } else { | |
| while (x < xend) { | |
| x++; | |
| if (d <0) { | |
| d+=incr1; | |
| } else { | |
| y--; | |
| d+=incr2; | |
| } | |
| SetPixel(x, y, color); | |
| } | |
| } | |
| } 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; | |
| } | |
| SetPixel(x, y, color); | |
| if (((x2 - x1) * xdirflag) > 0) { | |
| while (y < yend) { | |
| y++; | |
| if (d <0) { | |
| d+=incr1; | |
| } else { | |
| x++; | |
| d+=incr2; | |
| } | |
| SetPixel(x, y, color); | |
| } | |
| } else { | |
| while (y < yend) { | |
| y++; | |
| if (d <0) { | |
| d+=incr1; | |
| } else { | |
| x--; | |
| d+=incr2; | |
| } | |
| SetPixel(x, y, color); | |
| } | |
| } | |
| } | |
| } | |
| /* As above, plus dashing */ | /* As above, plus dashing */ |
| #define dashedSet \ | #define styledSet \ |
| { \ | { \ |
| dashStep++; \ | if (lineStyle) { \ |
| if (dashStep == gdDashSize) { \ | if(!lineStyle[styleStep]) \ |
| dashStep = 0; \ | styleStep = 0; \ |
| on = !on; \ | on=lineStyle[styleStep++]!=' '; \ |
| } \ | } \ |
| if (on) { \ | if (on) { \ |
| SetPixel(x, y, color); \ | SetPixel(x, y, color); \ |
| } \ | } \ |
| } | } |
| void gdImage::DashedLine(int x1, int y1, int x2, int y2, int 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 dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; |
| int dashStep = 0; | int styleStep = 0; |
| int on = 1; | int on = 1; |
| dx = abs(x2-x1); | dx = abs(x2-x1); |
| dy = abs(y2-y1); | dy = abs(y2-y1); |
| Line 272 void gdImage::DashedLine(int x1, int y1, | Line 195 void gdImage::DashedLine(int x1, int y1, |
| ydirflag = 1; | ydirflag = 1; |
| xend = x2; | xend = x2; |
| } | } |
| dashedSet; | styledSet; |
| if (((y2 - y1) * ydirflag) > 0) { | if (((y2 - y1) * ydirflag) > 0) { |
| while (x < xend) { | while (x < xend) { |
| x++; | x++; |
| Line 282 void gdImage::DashedLine(int x1, int y1, | Line 205 void gdImage::DashedLine(int x1, int y1, |
| y++; | y++; |
| d+=incr2; | d+=incr2; |
| } | } |
| dashedSet; | styledSet; |
| } | } |
| } else { | } else { |
| while (x < xend) { | while (x < xend) { |
| Line 293 void gdImage::DashedLine(int x1, int y1, | Line 216 void gdImage::DashedLine(int x1, int y1, |
| y--; | y--; |
| d+=incr2; | d+=incr2; |
| } | } |
| dashedSet; | styledSet; |
| } | } |
| } | } |
| } else { | } else { |
| Line 311 void gdImage::DashedLine(int x1, int y1, | Line 234 void gdImage::DashedLine(int x1, int y1, |
| yend = y2; | yend = y2; |
| xdirflag = 1; | xdirflag = 1; |
| } | } |
| dashedSet; | styledSet; |
| if (((x2 - x1) * xdirflag) > 0) { | if (((x2 - x1) * xdirflag) > 0) { |
| while (y < yend) { | while (y < yend) { |
| y++; | y++; |
| Line 321 void gdImage::DashedLine(int x1, int y1, | Line 244 void gdImage::DashedLine(int x1, int y1, |
| x++; | x++; |
| d+=incr2; | d+=incr2; |
| } | } |
| dashedSet; | styledSet; |
| } | } |
| } else { | } else { |
| while (y < yend) { | while (y < yend) { |
| Line 332 void gdImage::DashedLine(int x1, int y1, | Line 255 void gdImage::DashedLine(int x1, int y1, |
| x--; | x--; |
| d+=incr2; | d+=incr2; |
| } | } |
| dashedSet; | styledSet; |
| } | } |
| } | } |
| } | } |
| Line 348 void gdImage::DashedLine(int x1, int y1, | Line 271 void gdImage::DashedLine(int x1, int y1, |
| at least for me) and there are other inefficiencies (small circles | at least for me) and there are other inefficiencies (small circles |
| do far too much work). */ | do far too much work). */ |
| void gdImage::Arc(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) { | |
| Line(lx, ly, x, y, color); | |
| } | |
| lx = x; | |
| ly = y; | |
| } | |
| } | |
| #if 0 | |
| /* Bresenham octant code, which I should use eventually */ | |
| int x, y, d; | |
| x = 0; | |
| y = w; | |
| d = 3-2*w; | |
| while (x < y) { | |
| SetPixel(cx+x, cy+y, color); | |
| if (d < 0) { | |
| d += 4 * x + 6; | |
| } else { | |
| d += 4 * (x - y) + 10; | |
| y--; | |
| } | |
| x++; | |
| } | |
| if (x == y) { | |
| SetPixel(cx+x, cy+y, color); | |
| } | |
| #endif | |
| 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) | void gdImage::FillToBorder(int x, int y, int border, int color) |
| { | { |
| if(!BoundsSafe(x, y)) //PAF | if(!BoundsSafe(x, y)) //PAF |
| Line 498 void gdImage::Rectangle(int x1, int y1, | Line 491 void gdImage::Rectangle(int x1, int y1, |
| void gdImage::FilledRectangle(int x1, int y1, int x2, int y2, int 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; | int x, y; |
| for (y=y1; (y<=y2); y++) | for (y=y1; (y<=y2); y++) |
| for (x=x1; (x<=x2); x++) | for (x=x1; (x<=x2); x++) |
| SetPixel(x, y, color); | SetPixel(x, y, color); |
| Line 591 static int gdGetByte(int *result, FILE * | Line 595 static int gdGetByte(int *result, FILE * |
| return 1; | return 1; |
| } | } |
| void gdImage::Polygon(Point *p, int n, int c) | void gdImage::Polygon(Point *p, int n, int c, bool closed) |
| { | { |
| int i; | int i; |
| int lx, ly; | int lx, ly; |
| Line 600 void gdImage::Polygon(Point *p, int n, i | Line 604 void gdImage::Polygon(Point *p, int n, i |
| } | } |
| lx = p->x; | lx = p->x; |
| ly = p->y; | ly = p->y; |
| Line(lx, ly, p[n-1].x, p[n-1].y, c); | if(closed) |
| Line(lx, ly, p[n-1].x, p[n-1].y, c); | |
| for (i=1; (i < n); i++) { | for (i=1; (i < n); i++) { |
| p++; | p++; |
| Line(lx, ly, p->x, p->y, c); | Line(lx, ly, p->x, p->y, c); |
| Line 609 void gdImage::Polygon(Point *p, int n, i | Line 614 void gdImage::Polygon(Point *p, int n, i |
| } | } |
| } | } |
| int gdCompareInt(const void *a, const void *b); | 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) | void gdImage::FilledPolygon(Point *p, int n, int c) |
| { | { |
| Line 851 void gdImage::FilledPolygonReplaceColor( | Line 861 void gdImage::FilledPolygonReplaceColor( |
| } | } |
| } | } |
| static int gdCompareInt(const void *a, const void *b) | void gdImage::SetInterlace(int interlaceArg) |
| { | { |
| return (*(const int *)a) - (*(const int *)b); | interlace = interlaceArg; |
| } | } |
| void gdImage::SetInterlace(int interlaceArg) | void gdImage::SetLineWidth(int width) |
| { | { |
| interlace = interlaceArg; | lineWidth=width; |
| } | } |
| void gdImage::SetStyle(int width) | void gdImage::SetLineStyle(const char *alineStyle) |
| { | { |
| styleWidth=width; | lineStyle=alineStyle; |
| } | } |