rjc@CS.UCLA.EDU (Robert Collins) (09/08/89)
Script started on Thu Sep 7 19:05:13 1989
bugs.cognet.ucla.edu% g++ -v -fthis-is-variable -c painter.cc
gcc version 1.36.0- (based on GCC 1.35.98+)
/usr/local/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ painter.cc /tmp/cca11072.cpp
GNU CPP version 1.35.98
/usr/local/lib/gcc-cc1plus /tmp/cca11072.cpp -quiet -dumpbase painter.cc -fthis-is-variable -version -o /tmp/cca11072.s
GNU C++ version 1.36.0- (based on GCC 1.35.98+) (sparc) compiled by GNU C version 1.35.98.
default target switches: -mfpu -mepilogue
g++: Program cc1plus got fatal signal 6.
bugs.cognet.ucla.edu% cat painter.cc
# 1 "painter.cc"
# 1 "../../../src/InterViews/brush.h" 1
# 1 "../../../src/InterViews/resource.h" 1
# 1 "../../../src/InterViews/defs.h" 1
enum boolean { false, true };
enum Alignment {
TopLeft, TopCenter, TopRight,
CenterLeft, Center, CenterRight,
BottomLeft, BottomCenter, BottomRight,
Left, Right, Top, Bottom, HorizCenter, VertCenter
};
enum TextStyle {
Plain = 0x0,
Boldface = 0x1,
Underlined = 0x2,
Reversed = 0x4,
Outlined = 0x8
};
typedef int Coord;
extern double inch, inches, cm, point, points;
static const int pixels = 1;
inline int min (int a, int b) {
return a < b ? a : b;
}
inline int max (int a, int b) {
return a > b ? a : b;
}
inline int round (double x) {
return x > 0 ? int(x+0.5) : -int(-x+0.5);
}
# 8 "../../../src/InterViews/resource.h" 2
class Resource {
public:
Resource () { refcount = 1; }
~Resource () { if (--refcount > 0) { this = 0; } }
void Reference () { ++refcount; }
boolean LastRef () { return refcount == 1; }
private:
unsigned refcount;
};
# 8 "../../../src/InterViews/brush.h" 2
class Brush : public Resource {
public:
Brush(int pattern, int width = 1);
Brush(int* pattern, int count, int width = 1);
~Brush();
int Width();
private:
friend class Painter;
class BrushRep* rep;
int width;
};
class BrushRep {
friend class Brush;
friend class Painter;
BrushRep(int* pattern, int count, int width);
~BrushRep();
void* info;
int count;
};
inline int Brush::Width () { return width; }
extern Brush* single;
# 5 "painter.cc" 2
# 1 "../../../src/InterViews/color.h" 1
# 1 "../../../src/InterViews/resource.h" 1
# 21 "../../../src/InterViews/resource.h"
# 8 "../../../src/InterViews/color.h" 2
typedef int ColorIntensity;
class Color : public Resource {
public:
Color(ColorIntensity r, ColorIntensity g, ColorIntensity b);
Color(const char*);
Color(const char*, int length);
Color(int pixel);
~Color();
void Intensities(ColorIntensity& r, ColorIntensity& g, ColorIntensity& b);
void DisplayIntensities(
ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
);
int PixelValue();
boolean Valid();
protected:
class ColorRep* rep;
ColorIntensity red, green, blue;
};
class ColorRep {
private:
friend class Color;
ColorRep(int pixel, ColorIntensity&, ColorIntensity&, ColorIntensity&);
ColorRep(const char*, ColorIntensity&, ColorIntensity&, ColorIntensity&);
ColorRep(ColorIntensity, ColorIntensity, ColorIntensity);
~ColorRep();
int GetPixel();
void GetIntensities(ColorIntensity&, ColorIntensity&, ColorIntensity&);
void* info;
};
extern Color* black;
extern Color* white;
inline void Color::Intensities (
ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
) {
r = red; g = green; b = blue;
}
inline void Color::DisplayIntensities (
ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
) {
rep->GetIntensities(r, g, b);
}
inline int Color::PixelValue () { return rep->GetPixel(); }
# 6 "painter.cc" 2
# 1 "../../../src/InterViews/font.h" 1
# 1 "../../../src/InterViews/resource.h" 1
# 21 "../../../src/InterViews/resource.h"
# 8 "../../../src/InterViews/font.h" 2
class Font : public Resource {
public:
Font(const char*);
Font(const char*, int);
~Font();
int Baseline();
boolean FixedWidth();
int Height();
int Index(const char*, int offset, boolean between);
int Index(const char*, int, int offset, boolean between);
boolean Valid();
int Width(const char*);
int Width(const char*, int);
void* Info();
private:
friend class Painter;
class FontRep* rep;
void GetFontByName(const char*);
void Init();
boolean Lookup(const char*, int);
};
class FontRep : public Resource {
friend class Font;
friend class Painter;
void* id;
void* info;
int height;
~FontRep();
};
extern Font* stdfont;
# 7 "painter.cc" 2
# 1 "../../../src/InterViews/painter.h" 1
# 1 "../../../src/InterViews/defs.h" 1
# 44 "../../../src/InterViews/defs.h"
# 8 "../../../src/InterViews/painter.h" 2
# 1 "../../../src/InterViews/resource.h" 1
# 21 "../../../src/InterViews/resource.h"
# 9 "../../../src/InterViews/painter.h" 2
class Canvas;
class Color;
class PainterRep;
class Pattern;
class Brush;
class Font;
class Transformer;
class Bitmap;
class Raster;
class Painter : public Resource {
public:
Painter();
Painter(Painter*);
~Painter();
void FillBg(boolean);
boolean BgFilled();
void SetColors(Color* f, Color* b);
Color* GetFgColor();
Color* GetBgColor();
void SetPattern(Pattern*);
Pattern* GetPattern();
void SetBrush(Brush*);
Brush* GetBrush();
void SetFont(Font*);
Font* GetFont();
void SetStyle(int);
int GetStyle();
void SetTransformer(Transformer*);
Transformer* GetTransformer();
void MoveTo(int x, int y);
void GetPosition(int& x, int& y);
void SetOrigin(int x0, int y0);
void GetOrigin(int& x0, int& y0);
void Translate(float dx, float dy);
void Scale(float x, float y);
void Rotate(float angle);
void Clip(Canvas*, Coord left, Coord bottom, Coord right, Coord top);
void NoClip();
void SetOverwrite(boolean);
void SetPlaneMask(int);
void Text(Canvas*, const char*);
void Text(Canvas*, const char*, int);
void Text(Canvas*, const char*, Coord, Coord);
void Text(Canvas*, const char*, int, Coord, Coord);
void Stencil(Canvas*, Coord x, Coord y, Bitmap* image, Bitmap* mask = 0 );
void RasterRect(Canvas*, Coord x, Coord y, Raster*);
void Point(Canvas*, Coord x, Coord y);
void MultiPoint(Canvas*, Coord x[], Coord y[], int n);
void Line(Canvas*, Coord x1, Coord y1, Coord x2, Coord y2);
void Rect(Canvas*, Coord x1, Coord y1, Coord x2, Coord y2);
void FillRect(Canvas*, Coord x1, Coord y1, Coord x2, Coord y2);
void ClearRect(Canvas*, Coord x1, Coord y1, Coord x2, Coord y2);
void Circle(Canvas*, Coord x, Coord y, int r);
void FillCircle(Canvas*, Coord x, Coord y, int r);
void Ellipse(Canvas*, Coord x, Coord y, int r1, int r2);
void FillEllipse(Canvas*, Coord x, Coord y, int r1, int r2);
void MultiLine(Canvas*, Coord x[], Coord y[], int n);
void Polygon(Canvas*, Coord x[], Coord y[], int n);
void FillPolygon(Canvas*, Coord x[], Coord y[], int n);
void BSpline(Canvas*, Coord x[], Coord y[], int n);
void ClosedBSpline(Canvas*, Coord x[], Coord y[], int n);
void FillBSpline(Canvas*, Coord x[], Coord y[], int n);
void Curve(Canvas*,
Coord x0, Coord y0, Coord x1, Coord y1,
Coord x2, Coord y2, Coord x3, Coord y3
);
void CurveTo(Canvas*,
Coord x0, Coord y0, Coord x1, Coord y1, Coord x2, Coord y2
);
void Copy(
Canvas* src, Coord x1, Coord y1, Coord x2, Coord y2,
Canvas* dst, Coord x0, Coord y0
);
void Read(Canvas*, void*, Coord x1, Coord y1, Coord x2, Coord y2);
void Write(Canvas*, const void*, Coord x1, Coord y1, Coord x2, Coord y2);
PainterRep* Rep();
private:
friend class Rubberband;
Color* foreground;
Color* background;
Pattern* pattern;
Brush* br;
Font* font;
int style;
Coord curx, cury;
int xoff, yoff;
Transformer* matrix;
PainterRep* rep;
void Init();
void Copy(Painter*);
void Begin_xor();
void End_xor();
void Map(Canvas*, Coord x, Coord y, Coord& mx, Coord& my);
void Map(Canvas*, Coord x, Coord y, short& sx, short& sy);
void MapList(Canvas*, Coord x[], Coord y[], int n, Coord mx[], Coord my[]);
void MapList(Canvas*, float x[], float y[], int n, Coord mx[], Coord my[]);
void MultiLineNoMap(Canvas* c, Coord x[], Coord y[], int n);
void FillPolygonNoMap(Canvas* c, Coord x[], Coord y[], int n);
};
inline PainterRep* Painter::Rep () { return rep; }
# 8 "painter.cc" 2
# 1 "../../../src/InterViews/pattern.h" 1
# 1 "../../../src/InterViews/resource.h" 1
# 21 "../../../src/InterViews/resource.h"
# 8 "../../../src/InterViews/pattern.h" 2
static const int patternHeight = 16;
static const int patternWidth = 16;
class Pattern : public Resource {
public:
Pattern(int p[patternHeight]);
Pattern(int dither);
Pattern(class Bitmap*);
~Pattern();
private:
friend class Painter;
void* info;
};
extern Pattern* solid;
extern Pattern* clear;
extern Pattern* lightgray;
extern Pattern* gray;
extern Pattern* darkgray;
# 9 "painter.cc" 2
# 1 "../../../src/InterViews/transformer.h" 1
# 1 "../../../src/InterViews/defs.h" 1
# 44 "../../../src/InterViews/defs.h"
# 8 "../../../src/InterViews/transformer.h" 2
# 1 "../../../src/InterViews/resource.h" 1
# 21 "../../../src/InterViews/resource.h"
# 9 "../../../src/InterViews/transformer.h" 2
class Transformer : public Resource {
float mat00, mat01, mat10, mat11, mat20, mat21;
float Det(Transformer* t);
public:
Transformer(Transformer* t =0 );
Transformer(
float a00, float a01, float a10, float a11, float a20, float a21
);
void GetEntries(
float& a00, float& a01, float& a10, float& a11, float& a20, float& a21
);
void Premultiply(Transformer* t);
void Postmultiply(Transformer* t);
void Invert();
void Translate(float dx, float dy);
void Scale(float sx, float sy);
void Rotate(float angle);
boolean Translated () { return mat20 != 0 || mat21 != 0; }
boolean Scaled () { return mat00 != 1 || mat11 != 1; }
boolean Stretched () { return mat00 != mat11; }
boolean Rotated () { return mat01 != 0 || mat10 != 0; }
boolean Rotated90 () { return Rotated() && mat00 == 0 && mat11 == 0; }
void Transform(Coord& x, Coord& y);
void Transform(Coord x, Coord y, Coord& tx, Coord& ty);
void Transform(float x, float y, float& tx, float& ty);
void TransformList(Coord x[], Coord y[], int n);
void TransformList(Coord x[], Coord y[], int n, Coord tx[], Coord ty[]);
void InvTransform(Coord& tx, Coord& ty);
void InvTransform(Coord tx, Coord ty, Coord& x, Coord& y);
void InvTransform(float tx, float ty, float& x, float& y);
void InvTransformList(Coord tx[], Coord ty[], int n);
void InvTransformList(Coord tx[], Coord ty[], int n, Coord x[], Coord y[]);
boolean operator == (Transformer&);
boolean operator != (Transformer&);
Transformer& operator = (Transformer&);
};
inline float Transformer::Det (Transformer *t) {
return t->mat00*t->mat11 - t->mat01*t->mat10;
}
# 10 "painter.cc" 2
# 1 "/usr/local/lib/g++-include/bstring.h" 1
#pragma once
# 1 "/usr/local/lib/g++-include/std.h" 1
#pragma once
#pragma once
overload abs;
overload atoi;
extern "C" {
void volatile _exit(int);
void volatile abort(void);
int abs(int);
int access(const char*, int);
int acct(const char*);
unsigned alarm(unsigned);
void* alloca(int);
double atof(const char*);
int atoi(const char*);
long atol(const char*);
int bcmp(const void*, const void*, int);
void bcopy(const void*, void*, int);
int bind(int, void*, int);
int brk(void*);
int bsearch (const void *, const void *, unsigned long,
unsigned long, auto int (*ptf)(const void*, const void*));
void bzero(void*, int);
void* calloc(unsigned, unsigned);
void cfree(void*);
int chdir(const char*);
int chmod(const char*, int);
int chown(const char*, int, int);
long clock(void);
int close(int);
int creat(const char*, unsigned long int);
char* crypt(const char*, const char*);
char* ctermid(char*);
char* cuserid(char*);
double drand48(void);
int dup(int);
int dup2(int, int);
int dysize(int);
char* ecvt(double, int, int*, int*);
char* encrypt(char*, int);
double erand(short*);
int execl(const char*, const char *, ...);
int execle(const char*, const char *, ...);
int execlp(const char*, const char*, ...);
int exect(const char*, const char**, char**);
int execv(const char*, const char**);
int execve(const char*, const char**, char**);
int execvp(const char*, const char**);
void volatile exit(int);
int fchmod(int, int);
int fchown(int, int, int);
int fcntl(int, int, ...);
char* fcvt(double, int, int*, int*);
int ffs(int);
int flock(int, int);
int fork(void);
void free(void*);
int fsync(int);
long ftok(const char*, int);
int ftruncate(int, unsigned long);
char* gcvt(double, int, char*);
char* getcwd(char*, int);
int getdomainname(char*, int);
int getdtablesize(void);
int getegid(void);
char* getenv(const char*);
int geteuid(void);
int getgid(void);
int getgroups(int, int*);
long gethostid(void);
int gethostname(char*, int);
char* getlogin(void);
int getopt(int, char**, char*);
int getpagesize(void);
char* getpass(const char*);
int getpgrp(void);
int getpid(void);
int getppid(void);
int getpriority(int, int);
int getpw(int, char*);
unsigned getuid(void);
char* getwd(char*);
char* index(const char*, int);
char* initstate(unsigned, char*, int);
int ioctl(int, int, char*);
int isatty(int);
long jrand48(short*);
int kill(int, int);
int killpg(int, int);
void lcong48(short*);
int link(const char*, const char*);
int listen(int, int);
int lock(int, int, long);
long lrand48(void);
long lseek(int, long, int);
void* malloc(unsigned);
void* memalign(unsigned, unsigned);
void* memccpy(void*, const void*, int, int);
void* memchr(const void*, int, int);
int memcmp(const void*, const void*, int);
void* memcpy(void*, const void*, int);
void* memset(void*, int, int);
int mkdir(const char*, int);
int mknod(const char*, int, int);
int mkstemp(char*);
char* mktemp(char*);
long mrand48(void);
int nice(int);
long nrand48(short*);
int open(const char*, int, ...);
void pause(void);
void perror(const char*);
int pipe(int*);
void profil(char*, int, int, int);
int psignal(unsigned, char*);
int ptrace(int, int, int, int);
int putenv(const char*);
int qsort(void*, int, unsigned, auto (*ptf)(void*,void*));
int rand(void);
long random(void);
int read(int, void*, unsigned);
int readlink(const char*, char*, int);
void* realloc(void*, unsigned);
int rename(const char*, const char*);
char* rindex(const char*, int);
int rmdir(const char*);
void* sbrk(int);
short* seed48(short*);
int send(int, char*, int, int);
int setgid(int);
int sethostname(char*, int);
int setkey(const char*);
int setpgrp(int, int);
int setpriority(int, int, int);
int setregid(int, int);
int setreuid(int, int);
char* setstate(char*);
int setuid(int);
int sigblock(int);
int siginterrupt(int, int);
int sigpause(int);
int sigsetmask(int);
unsigned sleep(unsigned);
int socket(int, int, int);
int srand(int);
void srand48(long);
void srandom(int);
int stime(long*);
char* strcat(char*, const char*);
char* strchr(const char*, int);
int strcmp(const char*, const char*);
char* strcpy(char*, const char*);
int strcspn(const char*, const char*);
char* strdup(const char*);
int strlen(const char*);
char* strncat(char*, const char*, int);
int strncmp(const char*, const char*, int);
char* strncpy(char*, const char*, int);
char* strpbrk(const char*, const char*);
char* strrchr(const char*, int);
int strspn(const char*, const char*);
double strtod(const char*, char**);
char* strtok(char*, const char*);
long strtol(const char*, char**, int);
void swab(void*, void*, int);
int symlink(const char*, const char*);
int syscall(int, ...);
int system(const char*);
char* tempnam(char*, char*);
int tgetent(char*, char*);
int tgetnum(char*);
int tgetflag(char*);
char* tgetstr(char *, char **);
char* tgoto(char*, int, int);
long time(long*);
char* tmpnam(char*);
int tputs(char *, int, auto int (*)());
int truncate(const char*, unsigned long);
char* ttyname(int);
int ttyslot(void);
unsigned ualarm(unsigned, unsigned);
long ulimit(int, long);
int umask(int);
int unlink(const char*);
unsigned usleep(unsigned);
int vadvise(int);
void* valloc(unsigned);
int vfork(void);
int vhangup(void);
int wait(int*);
int write(int, const void*, unsigned);
}
extern char** environ;
extern int errno;
extern char* sys_errlist[];
extern int sys_nerr;
extern char* optarg;
extern int opterr;
extern int optind;
# 2 "/usr/local/lib/g++-include/bstring.h" 2
# 11 "painter.cc" 2
# 1 "/usr/local/lib/g++-include/string.h" 1
# 12 "painter.cc" 2
void Painter::Init () {
if (solid == 0 ) {
solid = new Pattern(0xffff);
clear = new Pattern(0);
lightgray = new Pattern(0x8020);
gray = new Pattern(0xa5a5);
darkgray = new Pattern(0xfafa);
single = new Brush(0xffff, 0);
}
foreground = 0 ;
background = 0 ;
pattern = 0 ;
br = 0 ;
font = 0 ;
style = 0;
matrix = 0 ;
SetColors(black, white);
SetPattern(solid);
FillBg(true);
SetBrush(single);
SetFont(stdfont);
SetStyle(Plain);
SetOrigin(0, 0);
MoveTo(0, 0);
}
void Painter::Copy (Painter* copy) {
foreground = 0 ;
background = 0 ;
pattern = 0 ;
br = 0 ;
font = 0 ;
style = 0;
matrix = 0 ;
SetColors(copy->foreground, copy->background);
SetPattern(copy->pattern);
SetBrush(copy->br);
SetFont(copy->font);
SetStyle(copy->style);
SetTransformer(copy->matrix);
SetOrigin(copy->xoff, copy->yoff);
MoveTo(copy->curx, copy->cury);
}
Color* Painter::GetFgColor () {
return foreground;
}
Color* Painter::GetBgColor () {
return background;
}
Pattern* Painter::GetPattern () {
return pattern;
}
Brush* Painter::GetBrush () {
return br;
}
Font* Painter::GetFont () {
return font;
}
void Painter::SetStyle (int s) {
style = s;
}
int Painter::GetStyle () {
return style;
}
void Painter::SetTransformer (Transformer *t) {
if (matrix != t) {
delete matrix;
matrix = t;
if (matrix != 0 ) {
matrix->Reference();
}
}
}
Transformer* Painter::GetTransformer () {
return matrix;
}
void Painter::MoveTo (int x, int y) {
curx = x;
cury = y;
}
void Painter::GetPosition (int& x, int& y) {
x = curx;
y = cury;
}
void Painter::SetOrigin (int x0, int y0) {
xoff = x0;
yoff = y0;
}
void Painter::GetOrigin (int& x0, int& y0) {
x0 = xoff;
y0 = yoff;
}
void Painter::Translate (float dx, float dy) {
if (dx != 0.0 || dy != 0.0) {
if (matrix == 0 ) {
matrix = new Transformer;
}
matrix->Translate(dx, dy);
}
}
void Painter::Scale (float sx, float sy) {
if (sx != 1.0 || sy != 1.0) {
if (matrix == 0 ) {
matrix = new Transformer;
}
matrix->Scale(sx, sy);
}
}
void Painter::Rotate (float angle) {
if (angle - int(angle) != 0.0 || int(angle) % 360 != 0) {
if (matrix == 0 ) {
matrix = new Transformer;
}
matrix->Rotate(angle);
}
}
void Painter::CurveTo (Canvas* c,
Coord x0, Coord y0, Coord x1, Coord y1, Coord x2, Coord y2
) {
Curve(c, curx, cury, x0, y0, x1, y1, x2, y2);
curx = x2;
cury = y2;
}
void Painter::Text (Canvas* c, const char* s) {
int len = strlen(s);
Text(c, s, len, curx, cury);
curx += font->Width(s, len);
}
void Painter::Text (Canvas* c, const char* s, int len) {
Text(c, s, len, curx, cury);
curx += font->Width(s, len);
}
void Painter::Text (Canvas* c, const char* s, Coord x, Coord y) {
Text(c, s, strlen(s), x, y);
}
const int INITBUFSIZE = 100;
const double SMOOTHNESS = 1.0;
static int llsize = 0;
static int llcount = 0;
static Coord* llx;
static Coord* lly;
static void GrowBufs (Coord*& b1, Coord*& b2, int& cur) {
Coord* newb1;
Coord* newb2;
int newsize;
if (cur == 0) {
cur = INITBUFSIZE;
b1 = new Coord[INITBUFSIZE];
b2 = new Coord[INITBUFSIZE];
} else {
newsize = cur * 2;
newb1 = new Coord[newsize];
newb2 = new Coord[newsize];
bcopy(b1, newb1, newsize * sizeof(Coord));
bcopy(b2, newb2, newsize * sizeof(Coord));
delete b1;
delete b2;
b1 = newb1;
b2 = newb2;
cur = newsize;
}
}
inline void Midpoint (
double x0, double y0, double x1, double y1, double& mx, double& my
) {
mx = (x0 + x1) / 2.0;
my = (y0 + y1) / 2.0;
}
inline void ThirdPoint (
double x0, double y0, double x1, double y1, double& tx, double& ty
) {
tx = (2*x0 + x1) / 3.0;
ty = (2*y0 + y1) / 3.0;
}
inline boolean CanApproxWithLine (
double x0, double y0, double x2, double y2, double x3, double y3
) {
double triangleArea, sideSquared, dx, dy;
triangleArea = x0*y2 - x2*y0 + x2*y3 - x3*y2 + x3*y0 - x0*y3;
triangleArea *= triangleArea;
dx = x3 - x0;
dy = y3 - y0;
sideSquared = dx*dx + dy*dy;
return triangleArea <= SMOOTHNESS * sideSquared;
}
inline void AddLine (double x0, double y0, double x1, double y1) {
if (llcount >= llsize) {
GrowBufs(llx, lly, llsize);
}
if (llcount == 0) {
llx[llcount] = round(x0);
lly[llcount] = round(y0);
++llcount;
}
llx[llcount] = round(x1);
lly[llcount] = round(y1);
++llcount;
}
static void AddBezierCurve (
double x0, double y0, double x1, double y1,
double x2, double y2, double x3, double y3
) {
double midx01, midx12, midx23, midlsegx, midrsegx, cx;
double midy01, midy12, midy23, midlsegy, midrsegy, cy;
Midpoint(x0, y0, x1, y1, midx01, midy01);
Midpoint(x1, y1, x2, y2, midx12, midy12);
Midpoint(x2, y2, x3, y3, midx23, midy23);
Midpoint(midx01, midy01, midx12, midy12, midlsegx, midlsegy);
Midpoint(midx12, midy12, midx23, midy23, midrsegx, midrsegy);
Midpoint(midlsegx, midlsegy, midrsegx, midrsegy, cx, cy);
if (CanApproxWithLine(x0, y0, midlsegx, midlsegy, cx, cy)) {
AddLine(x0, y0, cx, cy);
} else if (
(midx01 != x1) || (midy01 != y1) ||
(midlsegx != x2) || (midlsegy != y2) ||
(cx != x3) || (cy != y3)
) {
AddBezierCurve(
x0, y0, midx01, midy01, midlsegx, midlsegy, cx, cy
);
}
if (CanApproxWithLine(cx, cy, midx23, midy23, x3, y3)) {
AddLine(cx, cy, x3, y3);
} else if (
(cx != x0) || (cy != y0) ||
(midrsegx != x1) || (midrsegy != y1) ||
(midx23 != x2) || (midy23 != y2)
) {
AddBezierCurve(
cx, cy, midrsegx, midrsegy, midx23, midy23, x3, y3
);
}
}
static void CalcBSpline (
Coord cminus1x, Coord cminus1y, Coord cx, Coord cy,
Coord cplus1x, Coord cplus1y, Coord cplus2x, Coord cplus2y
) {
double p0x, p1x, p2x, p3x, tempx,
p0y, p1y, p2y, p3y, tempy;
ThirdPoint(
double(cx), double(cy), double(cplus1x), double(cplus1y), p1x, p1y
);
ThirdPoint(
double(cplus1x), double(cplus1y), double(cx), double(cy), p2x, p2y
);
ThirdPoint(
double(cx), double(cy), double(cminus1x), double(cminus1y),
tempx, tempy
);
Midpoint(tempx, tempy, p1x, p1y, p0x, p0y);
ThirdPoint(
double(cplus1x), double(cplus1y), double(cplus2x), double(cplus2y),
tempx, tempy
);
Midpoint(tempx, tempy, p2x, p2y, p3x, p3y);
AddBezierCurve(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y);
}
inline void CreateOpenLineList (Coord *cpx, Coord *cpy, int cpcount) {
int cpi;
llcount = 0;
CalcBSpline(
cpx[0], cpy[0], cpx[0], cpy[0], cpx[0], cpy[0], cpx[1], cpy[1]
);
CalcBSpline(
cpx[0], cpy[0], cpx[0], cpy[0], cpx[1], cpy[1], cpx[2], cpy[2]
);
for (cpi = 1; cpi < cpcount - 2; ++cpi) {
CalcBSpline(
cpx[cpi - 1], cpy[cpi - 1], cpx[cpi], cpy[cpi],
cpx[cpi + 1], cpy[cpi + 1], cpx[cpi + 2], cpy[cpi + 2]
);
}
CalcBSpline(
cpx[cpi - 1], cpy[cpi - 1], cpx[cpi], cpy[cpi],
cpx[cpi + 1], cpy[cpi + 1], cpx[cpi + 1], cpy[cpi + 1]
);
CalcBSpline(
cpx[cpi], cpy[cpi], cpx[cpi + 1], cpy[cpi + 1],
cpx[cpi + 1], cpy[cpi + 1], cpx[cpi + 1], cpy[cpi + 1]
);
}
inline void CreateClosedLineList (Coord *cpx, Coord *cpy, int cpcount) {
int cpi;
llcount = 0;
CalcBSpline(
cpx[cpcount - 1], cpy[cpcount - 1], cpx[0], cpy[0],
cpx[1], cpy[1], cpx[2], cpy[2]
);
for (cpi = 1; cpi < cpcount - 2; ++cpi) {
CalcBSpline(
cpx[cpi - 1], cpy[cpi - 1], cpx[cpi], cpy[cpi],
cpx[cpi + 1], cpy[cpi + 1], cpx[cpi + 2], cpy[cpi + 2]
);
}
CalcBSpline(
cpx[cpi - 1], cpy[cpi - 1], cpx[cpi], cpy[cpi],
cpx[cpi + 1], cpy[cpi + 1], cpx[0], cpy[0]
);
CalcBSpline(
cpx[cpi], cpy[cpi], cpx[cpi + 1], cpy[cpi + 1],
cpx[0], cpy[0], cpx[1], cpy[1]
);
}
static int bufsize = 0;
static Coord* bufx, * bufy;
static void CheckBufs (Coord*& b1, Coord*& b2, int& cur, int desired) {
if (cur < desired) {
if (cur == 0) {
cur = max(INITBUFSIZE, desired);
} else {
delete b1;
delete b2;
cur = max(cur * 2, desired);
}
b1 = new Coord[cur];
b2 = new Coord[cur];
}
}
void Painter::Curve (
Canvas* c, Coord x0, Coord y0, Coord x1, Coord y1,
Coord x2, Coord y2, Coord x3, Coord y3
) {
Coord tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3;
llcount = 0;
Map(c, x0, y0, tx0, ty0);
Map(c, x1, y1, tx1, ty1);
Map(c, x2, y2, tx2, ty2);
Map(c, x3, y3, tx3, ty3);
AddBezierCurve(tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3);
MultiLineNoMap(c, llx, lly, llcount);
}
void Painter::BSpline (Canvas* c, Coord x[], Coord y[], int count) {
CheckBufs(bufx, bufy, bufsize, count);
MapList(c, x, y, count, bufx, bufy);
if (count < 3) {
MultiLineNoMap(c, bufx, bufy, count);
} else {
CreateOpenLineList(bufx, bufy, count);
MultiLineNoMap(c, llx, lly, llcount);
}
}
void Painter::ClosedBSpline (Canvas* c, Coord x[], Coord y[], int count) {
CheckBufs(bufx, bufy, bufsize, count);
MapList(c, x, y, count, bufx, bufy);
if (count < 3) {
MultiLineNoMap(c, bufx, bufy, count);
} else {
CreateClosedLineList(bufx, bufy, count);
MultiLineNoMap(c, llx, lly, llcount);
}
}
void Painter::FillBSpline (Canvas* c, Coord x[], Coord y[], int count) {
CheckBufs(bufx, bufy, bufsize, count);
MapList(c, x, y, count, bufx, bufy);
if (count < 3) {
FillPolygonNoMap(c, bufx, bufy, count);
} else {
CreateClosedLineList(bufx, bufy, count);
FillPolygonNoMap(c, llx, lly, llcount);
}
}
void Painter::Map (Canvas* c, Coord x, Coord y, short& sx, short& sy) {
Coord cx, cy;
Map(c, x, y, cx, cy);
sx = short(cx);
sy = short(cy);
}
const float axis = 0.42;
const float seen = 1.025;
void Painter::Ellipse (Canvas* c, Coord cx, Coord cy, int r1, int r2) {
float px1, py1, px2, py2, x[8], y[8];
px1 = float(r1)*axis; py1 = float(r2)*axis;
px2 = float(r1)*seen; py2 = float(r2)*seen;
x[0] = cx + px1; y[0] = cy + py2;
x[1] = cx - px1; y[1] = y[0];
x[2] = cx - px2; y[2] = cy + py1;
x[3] = x[2]; y[3] = cy - py1;
x[4] = x[1]; y[4] = cy - py2;
x[5] = x[0]; y[5] = y[4];
x[6] = cx + px2; y[6] = y[3];
x[7] = x[6]; y[7] = y[2];
CheckBufs(bufx, bufy, bufsize, 8);
MapList(c, (float*) x, (float*) y, 8, bufx, bufy);
CreateClosedLineList(bufx, bufy, 8);
MultiLineNoMap(c, llx, lly, llcount);
}
void Painter::FillEllipse (Canvas* c, Coord cx, Coord cy, int r1, int r2) {
float px1, py1, px2, py2, x[8], y[8];
px1 = float(r1)*axis; py1 = float(r2)*axis;
px2 = float(r1)*seen; py2 = float(r2)*seen;
x[0] = cx + px1; y[0] = cy + py2;
x[1] = cx - px1; y[1] = y[0];
x[2] = cx - px2; y[2] = cy + py1;
x[3] = x[2]; y[3] = cy - py1;
x[4] = x[1]; y[4] = cy - py2;
x[5] = x[0]; y[5] = y[4];
x[6] = cx + px2; y[6] = y[3];
x[7] = x[6]; y[7] = y[2];
CheckBufs(bufx, bufy, bufsize, 8);
MapList(c, (float*) x, (float*) y, 8, bufx, bufy);
CreateClosedLineList(bufx, bufy, 8);
FillPolygonNoMap(c, llx, lly, llcount);
}
bugs.cognet.ucla.edu% ^D
script done on Thu Sep 7 19:06:01 1989