home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Enigma Amiga Life 110
/
EnigmaAmiga110CD.iso
/
indispensabili
/
utility
/
apdf
/
xpdf-0.80
/
xpdf
/
agfx.h
< prev
next >
Wrap
C/C++ Source or Header
|
1999-06-10
|
12KB
|
631 lines
//========================================================================
//
// 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