home *** CD-ROM | disk | FTP | other *** search
- //========================================================================
- //
- // AGfx.h
- //
- // Copyright 1999 Emmanuel Lesueur
- //
- //========================================================================
-
- #ifndef AGFX_H
- #define AGFX_H
-
- #include "poly.h"
-
- #ifdef __PPC__
- # include <string.h>
- # include "AComm.h"
- # include "AGfxcomm.h"
- typedef unsigned long ULONG;
- typedef unsigned char UBYTE;
- #else
- # define Object ZZObject
- # include <graphics/layers.h>
- # include <hardware/blit.h>
- # include <cybergraphics/cybergraphics.h>
- # include <proto/graphics.h>
- # include <proto/cybergraphics.h>
- # undef Object
- struct DocData;
- extern "C" void initgfx(DocData**,struct RastPort**,short*,short*);
- extern "C" void initarea(struct RastPort*,int);
- extern "C" void areapoly(struct RastPort*,int,short*,short,short);
- extern "C" void areaend(struct RastPort*);
- extern "C" void reset_pens(DocData*);
- extern "C" void add_pens(DocData*,ULONG*,int);
- extern "C" void add_pen(DocData*,ULONG,ULONG,ULONG);
- extern "C" ULONG get_pen(DocData*,short);
- extern "C" void clear_clip(DocData*);
- extern "C" void init_clip(DocData*);
- extern "C" void rect_clip(DocData*,short,short,short,short);
- extern "C" void poly_clip(DocData*,int,short*);
- extern "C" void install_clip(DocData*);
- extern "C" void openfont(DocData*,int,const char*,short,short);
- extern "C" void closefont(DocData*,int);
- extern "C" void setfont(DocData*,int);
- #endif
-
- typedef Vertex<short> XPoint;
-
- struct Color {
- UBYTE r, g, b;
- };
-
- struct Color32 {
- ULONG r, g, b;
- };
-
- struct ColorEntry {
- int index;
- Color32 color;
- };
-
-
- class AGfx {
- #ifdef __PPC__
- # ifdef USE_GFX_PIPE
- void check_size(int n) {
- if(ptr+n>end)
- flush(false);
- }
- bool fits(int n) {
- return ptr+n<=end;
- }
- short* get_ptr() {
- return ptr;
- }
- void set_ptr(short* p) {
- pipe->writep=ptr=p;
- }
- # else
- void check_size(int n) {
- if(sz<n)
- flush(false);
- }
- bool fits(int n) {
- return sz>=n;
- }
- short* get_ptr() {
- return ptr;
- }
- void set_ptr(short* p) {
- sz-=p-ptr;
- ptr=p;
- }
- # endif
- #endif
- public:
-
- typedef unsigned char pixel_color;
-
- class ColorTable {
- friend class AGfx;
- public:
- explicit ColorTable(int);
- ~ColorTable();
- ColorEntry* data() const { return entries; }
- private:
- ColorTable(const ColorTable&);
- ColorTable& operator = (const ColorTable&);
- ColorEntry* entries;
- int num;
- };
-
- class ColorTablePtr {
- public:
- explicit ColorTablePtr(ColorTable* t=NULL) : table(t) {}
- ColorTablePtr(ColorTablePtr& t) : table(t.table) { t.table=NULL; }
- ~ColorTablePtr() { delete table; }
- ColorTablePtr& operator = (ColorTablePtr& t) {
- delete table;
- table=t.table;
- t.table=NULL;
- return *this;
- }
- ColorTablePtr& operator = (ColorTable* t) {
- delete table;
- table=t;
- return *this;
- }
- ColorTable& operator * () const { return *table; }
- ColorTable* operator -> () const { return table; }
- private:
- ColorTable* table;
- };
-
- class Image {
- friend class AGfx;
- public:
- Image(short w,short h);
- ~Image();
-
- void put(short x,short y,pixel_color c) {
- im[y*bytes_per_row+x]=c;
- }
- pixel_color* data() const { return im; }
-
- private:
- Image(const Image&);
- Image& operator = (const Image&);
-
- pixel_color* im;
- short width;
- short height;
- short bytes_per_row;
- };
-
- class ImagePtr {
- public:
- explicit ImagePtr(Image* q=NULL) : p(q) {}
- ImagePtr(ImagePtr& x) : p(x.p) { x.p=NULL; }
- ~ImagePtr() { delete p; }
- ImagePtr& operator = (ImagePtr& x) {
- delete p;
- p=x.p;
- x.p=NULL;
- return *this;
- }
- ImagePtr& operator = (Image* q) {
- delete p;
- p=q;
- return *this;
- }
- Image& operator * () const { return *p; }
- Image* operator -> () const { return p; }
- Image* get() const { return p; }
- operator bool () const { return p!=NULL; }
- private:
- Image* p;
- };
-
- class Image24 {
- friend class AGfx;
- public:
- Image24(short w,short h);
- ~Image24();
-
- void put(short x,short y,const Color& c) {
- im[y*width+x]=c;
- }
- Color* data() const { return im; }
-
- private:
- Image24(const Image24&);
- Image24& operator = (const Image24&);
-
- Color* im;
- short width;
- short height;
- };
-
- class Image24Ptr {
- public:
- explicit Image24Ptr(Image24* q=NULL) : p(q) {}
- Image24Ptr(Image24Ptr& x) : p(x.p) { x.p=NULL; }
- ~Image24Ptr() { delete p; }
- Image24Ptr& operator = (Image24Ptr& x) {
- delete p;
- p=x.p;
- x.p=NULL;
- return *this;
- }
- Image24Ptr& operator = (Image24* q) {
- delete p;
- p=q;
- return *this;
- }
- Image24& operator * () const { return *p; }
- Image24* operator -> () const { return p; }
- Image24* get() const { return p; }
- operator bool () const { return p!=NULL; }
- private:
- Image24* p;
- };
-
-
- #ifdef __PPC__
- AGfx(PPCPort* port1);
- ~AGfx();
- #else
- AGfx() : rp(NULL),x0(0),y0(0),dat(NULL),in_page_draw(false) {
- initgfx(&dat,&rp,&x0,&y0);
- }
- #endif
-
- // those would be better, but SAS/C++ and gcc have
- // troubles with A(A&) constructors...
- /*ImagePtr allocate_image(short width,short height) {
- return ImagePtr(new Image(width,height));
- }
- Image24Ptr allocate_image24(short width,short height) {
- return Image24Ptr(new Image24(width,height));
- }
- ColorTablePtr allocate_color_table(int n) {
- return ColorTablePtr(new ColorTable(n));
- }*/
- Image* allocate_image(short width,short height) {
- return new Image(width,height);
- }
- Image24* allocate_image24(short width,short height) {
- return new Image24(width,height);
- }
- ColorTable* allocate_color_table(int n) {
- return new ColorTable(n);
- }
-
- #if defined(__PPC__) && defined(USE_GFX_PIPE)
- void init();
- #else
- void init() {}
- #endif
-
- #ifdef __PPC__
- void flush(bool complete=true);
- #else
- void flush(bool complete=true) {}
- #endif
-
- void setapen(short n) {
- #ifdef __PPC__
- check_size(2);
- short* p=get_ptr();
- *p++=AGFX_SETAPEN;
- *p++=n;
- set_ptr(p);
- #else
- SetAPen(rp,get_pen(dat,n));
- #endif
- }
-
- void openfont(int id,const char* name,short size,short style) {
- #ifdef __PPC__
- size_t sz=(strlen(name)+2)/2;
- check_size(sz+6);
- if(fits(sz+6)) {
- short* p=get_ptr();
- *p++=AGFX_OPENFONT;
- *reinterpret_cast<int*>(p)=id;
- p+=2;
- *p++=sz;
- strcpy((char*)p,name);
- p+=sz;
- *p++=size;
- *p++=style;
- set_ptr(p);
- }
- #else
- ::openfont(dat,id,name,size,style);
- #endif
- }
-
- void closefont(int id) {
- if(in_page_draw) {
- #ifdef __PPC__
- check_size(3);
- short* p=get_ptr();
- *p++=AGFX_CLOSEFONT;
- *reinterpret_cast<int*>(p)=id;
- p+=2;
- set_ptr(p);
- #else
- ::closefont(dat,id);
- #endif
- }
- }
-
- void setfont(int id) {
- #ifdef __PPC__
- check_size(3);
- short* p=get_ptr();
- *p++=AGFX_SETFONT;
- *reinterpret_cast<int*>(p)=id;
- p+=2;
- set_ptr(p);
- #else
- ::setfont(dat,id);
- #endif
- }
-
- void set_line_ptrn(short mask,short start) {
- #ifdef __PPC__
- check_size(3);
- short* p=get_ptr();
- *p++=AGFX_LINEPTRN;
- *p++=mask;
- *p++=start;
- set_ptr(p);
- #else
- rp->LinePtrn=mask;
- rp->linpatcnt=start;
- #endif
- }
-
- #ifdef __PPC__
- void polydraw(const Polygon<short>& q) {
- int n=q.size();
- check_size(n*2+2);
- if(fits(n*2+2)) {
- short* p=get_ptr();
- *p++=AGFX_POLYDRAW;
- *p++=n;
- memcpy(p,q.begin(),n*4);
- p+=n*2;
- set_ptr(p);
- }
- }
- #else
- void polydraw(const Polygon<short>&);
- #endif
-
- void addchar(short x,short y,char c) {
- #ifdef __PPC__
- check_size(4);
- short* p=get_ptr();
- *p++=AGFX_ADDCHAR;
- *p++=x;
- *p++=y;
- *p++=c;
- set_ptr(p);
- #else
- Move(rp,x-x0,y-y0);
- Text(rp,&c,1);
- #endif
- }
-
- void rectfill(short x1,short y1,short x2,short y2) {
- #ifdef __PPC__
- check_size(5);
- short* p=get_ptr();
- *p++=AGFX_RECTFILL;
- *p++=x1;
- *p++=y1;
- *p++=x2;
- *p++=y2;
- set_ptr(p);
- #else
- RectFill(rp,x1-x0,y1-y0,x2-x0,y2-y0);
- #endif
- }
-
- #ifdef __PPC__
- void get_image(Image&,short x,short y);
- #else
- void get_image(Image& im,short x,short y) {
- x-=x0;
- y-=y0;
- struct BitMap* bm;
- if(bm=AllocBitMap((im.width+15)&~15,1,8,BMF_MINPLANES,rp->BitMap)) {
- struct RastPort rp2;
- rp2=*rp;
- rp2.Layer=NULL;
- rp2.BitMap=bm;
- ReadPixelArray8(rp,x,y,x+im.width-1,y+im.height-1,im.data(),&rp2);
- FreeBitMap(bm);
- }
- }
- #endif
-
- #ifdef __PPC__
- void get_image(Image24&,short x,short y);
- #else
- void get_image(Image24& im,short x,short y) {
- ReadPixelArray(im.data(),0,0,im.width*3,rp,x-x0,y-y0,im.width,im.height,RECTFMT_RGB);
- }
- #endif
-
- #ifdef __PPC__
- void put_image(const Image&,short x,short y);
- #else
- void put_image(const Image& im,short x,short y) {
- x-=x0;
- y-=y0;
- struct BitMap* bm;
- if(bm=AllocBitMap((im.width+15)&~15,1,8,BMF_MINPLANES,rp->BitMap)) {
- struct RastPort rp2;
- rp2=*rp;
- rp2.Layer=NULL;
- rp2.BitMap=bm;
- WritePixelArray8(rp,x,y,x+im.width-1,y+im.height-1,im.data(),&rp2);
- WaitBlit();
- FreeBitMap(bm);
- }
- }
- #endif
-
- #ifdef __PPC__
- void put_image(const Image24&,short x,short y);
- #else
- void put_image(const Image24& im,short x,short y) {
- WritePixelArray(im.data(),0,0,im.width*3,rp,x-x0,y-y0,im.width,im.height,RECTFMT_RGB);
- }
- #endif
-
-
- friend class AreaDrawer {
- public:
- AreaDrawer(AGfx& g) : gfx(g),n(0) {}
- ~AreaDrawer();
- void add(const Polygon<short>& p);
- private:
- AreaDrawer(const AreaDrawer&);
- AreaDrawer& operator = (const AreaDrawer&);
- AGfx& gfx;
- int n;
- PArea<short> area;
- };
-
-
- void clearclip() {
- #ifdef __PPC__
- check_size(1);
- short* p=get_ptr();
- *p++=AGFX_INITCLIP;
- set_ptr(p);
- #else
- init_clip(dat);
- #endif
- }
-
- void rectclip(short x1,short y1,short x2,short y2) {
- #ifdef __PPC__
- check_size(5);
- short* p=get_ptr();
- *p++=AGFX_RECTCLIP;
- *p++=x1;
- *p++=y1;
- *p++=x2;
- *p++=y2;
- set_ptr(p);
- #else
- rect_clip(dat,x1,y1,x2,y2);
- #endif
- }
- void polyclip(const Polygon<short>& q) {
- int n=q.size();
- #ifdef __PPC__
- check_size(n*2+2);
- if(fits(n*2+2)) {
- short* p=get_ptr();
- *p++=AGFX_POLYCLIP;
- *p++=n;
- memcpy(p,q.begin(),n*4);
- p+=n*2;
- set_ptr(p);
- }
- #else
- poly_clip(dat,n,(short*)q.begin());
- #endif
- }
-
- void installclip() {
- #ifdef __PPC__
- check_size(1);
- short* p=get_ptr();
- *p++=AGFX_INSTALLCLIP;
- set_ptr(p);
- #else
- install_clip(dat);
- #endif
- }
-
- void start_page() {
- #ifdef __PPC__
- check_size(1);
- short* p=get_ptr();
- *p++=AGFX_STARTPAGE;
- set_ptr(p);
- #else
- reset_pens(dat);
- SetRast(rp,get_pen(dat,1));
- SetAPen(rp,get_pen(dat,0));
- #endif
- in_page_draw=true;
- }
-
- void end_page() {
- in_page_draw=false;
- #if 0
- check_size(1);
- short* p=get_ptr();
- *p++=AGFX_ENDPAGE;
- set_ptr(p);
- #endif
- }
-
- void color(ULONG r,ULONG g,ULONG b) {
- #ifdef __PPC__
- check_size(7);
- short* p=get_ptr();
- *p++=AGFX_PENCOLOR;
- *reinterpret_cast<ULONG*>(p)=r;
- p+=2;
- *reinterpret_cast<ULONG*>(p)=g;
- p+=2;
- *reinterpret_cast<ULONG*>(p)=b;
- p+=2;
- set_ptr(p);
- #else
- add_pen(dat,r,g,b);
- #endif
- }
-
- #ifdef __PPC__
- void get_colors(ColorTable&,int);
- #else
- void get_colors(ColorTable& ct,int num) {
- add_pens(dat,(ULONG*)ct.entries,num);
- }
- #endif
-
- private:
- AGfx(const AGfx&);
- AGfx& operator = (const AGfx&);
- bool in_page_draw;
- #ifdef __PPC__
- # ifdef USE_GFX_PIPE
- volatile GfxPipe* pipe;
- volatile short* buf;
- volatile short* end;
- volatile short* ptr;
- # else
- short* buf;
- short* ptr;
- short* buf2;
- int sz;
- # endif
- PPCPort* port;
- PPCPort* reply_port;
- PPCMsg* msg;
- bool msg_sent;
- #else
- struct RastPort* rp;
- short x0;
- short y0;
- DocData* dat;
- #endif
-
- void initarea(int n) {
- #ifdef __PPC__
- check_size(2);
- short* p=get_ptr();
- *p++=AGFX_INITAREA;
- *p++=n;
- set_ptr(p);
- #else
- ::initarea(rp,n);
- #endif
- }
-
- void areapoly(const Polygon<short>& q) {
- int n=q.size();
- #ifdef __PPC__
- check_size(n*2+2);
- if(fits(n*2+2)) {
- short* p=get_ptr();
- *p++=AGFX_AREAPOLY;
- *p++=n;
- memcpy(p,q.begin(),n*4);
- p+=n*2;
- set_ptr(p);
- }
- #else
- ::areapoly(rp,n,(short*)q.begin(),0,0);
- #endif
- }
-
- void areaend() {
- #ifdef __PPC__
- check_size(1);
- short* p=get_ptr();
- *p++=AGFX_AREAEND;
- set_ptr(p);
- #else
- ::areaend(rp);
- #endif
- }
-
-
- };
-
- #endif
-
-