home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 110 / EnigmaAmiga110CD.iso / indispensabili / utility / apdf / xpdf-0.80 / xpdf / agfx.cc < prev    next >
C/C++ Source or Header  |  1999-05-04  |  7KB  |  362 lines

  1. //========================================================================
  2. //
  3. // AGfx.cc
  4. //
  5. // Copyright 1999 Emmanuel Lesueur
  6. //
  7. //========================================================================
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include "gmem.h"
  12.  
  13. #ifdef __SASC
  14. #   define throw(x) (printf("Exception: %s\n",x),exit(EXIT_FAILURE))
  15. #endif
  16.  
  17. #ifdef __PPC__
  18. //#define DEBUGMSG
  19. #include <exec/nodes.h>
  20. #include <exec/memory.h>
  21. #include <powerup/ppclib/message.h>
  22. #include <powerup/ppclib/tasks.h>
  23. #include <powerup/ppclib/memory.h>
  24. #include <powerup/gcclib/powerup_protos.h>
  25. #include "AGfx.h"
  26. #include "AGfxcomm.h"
  27. #include "AComm.h"
  28.  
  29.  
  30. AGfx::Image::Image(short w,short h)
  31.     : width(w),height(h),bytes_per_row(((w+15)>>4)<<4) {
  32.     im=(pixel_color*)PPCAllocVec(bytes_per_row*h,MEMF_ANY);
  33.     if(!im)
  34.     throw("No memory.");
  35. }
  36.  
  37. AGfx::Image::~Image() {
  38.     PPCFreeVec(im);
  39. }
  40.  
  41. AGfx::Image24::Image24(short w,short h)
  42.     : width(w),height(h) {
  43.     im=(Color*)PPCAllocVec(w*h*sizeof(Color),MEMF_ANY);
  44.     if(!im)
  45.     throw("No memory.");
  46. }
  47.  
  48. AGfx::Image24::~Image24() {
  49.     PPCFreeVec(im);
  50. }
  51.  
  52. AGfx::ColorTable::ColorTable(int n) : num(n) {
  53.     entries=(ColorEntry*)PPCAllocVec((n+1)*sizeof(ColorEntry),MEMF_ANY);
  54.     if(!entries)
  55.     throw("No memory.");
  56. }
  57.  
  58. AGfx::ColorTable::~ColorTable() {
  59.     PPCFreeVec(entries);
  60. }
  61.  
  62. #ifdef USE_GFX_PIPE
  63.  
  64. static const int bufsize=50000;
  65. static short stubbuf[10];
  66.  
  67. AGfx::AGfx(void* port1)
  68.     : port(port1),reply_port(NULL),buf(NULL),pipe(NULL),
  69.       msg(NULL),msg_sent(false),in_page_draw(false) {
  70.     buf=(short*)PPCAllocVec(sizeof(GfxPipe)+bufsize*2,MEMF_NOCACHESYNCPPC|MEMF_NOCACHESYNCM68K);
  71.     if(!buf) {
  72.     static GfxPipe p;
  73.     pipe=&p;
  74.     ptr=stubbuf;
  75.     end=ptr;
  76.     } else {
  77.     pipe=(volatile GfxPipe*)buf;
  78.     ptr=pipe->data;
  79.     end=ptr+bufsize;
  80.     }
  81.     if(buf) {
  82.     if(reply_port=PPCCreatePort(NULL))
  83.         msg=PPCCreateMessage(reply_port,bufsize*2);
  84.     }
  85. }
  86.  
  87. AGfx::~AGfx() {
  88.     if(msg_sent) {
  89.     pipe->done=1;
  90.     PPCWaitPort(reply_port);
  91.     PPCGetMessage(reply_port);
  92.     }
  93.     if(msg)
  94.     PPCDeleteMessage(msg);
  95.     if(reply_port)
  96.     PPCDeletePort(reply_port);
  97.     if(buf)
  98.     PPCFreeVec(buf);
  99. }
  100.  
  101. void AGfx::init() {
  102.     if(!buf)
  103.     ptr=stubbuf;
  104.     else if(!msg_sent && msg) {
  105.     // no need to flush caches here, so MSGLENGTH=0
  106.     pipe->done=0;
  107.     ptr=pipe->data;
  108.     pipe->writep=ptr;
  109.     pipe->readp=ptr;
  110.     PPCSendMessage(port,msg,buf,0,MSGID_GFXPIPE);
  111.     msg_sent=true;
  112.     }
  113. }
  114.  
  115. void AGfx::flush(bool complete) {
  116.     if(msg_sent) {
  117.     pipe->done=1;
  118.     PPCWaitPort(reply_port);
  119.     PPCGetMessage(reply_port);
  120.     msg_sent=false;
  121.     }
  122.     if(!complete)
  123.     init();
  124. }
  125.  
  126. #else
  127.  
  128. static const int bufsize=2000;
  129.  
  130. AGfx::AGfx(void* port1)
  131.     : port(port1),reply_port(NULL),buf(NULL),buf2(NULL),
  132.       msg(NULL),msg_sent(false),in_page_draw(false) {
  133.     buf=(short*)PPCAllocVec(bufsize*2,MEMF_ANY);
  134.     if(!buf) {
  135.     static short b[10];
  136.     ptr=b;
  137.     sz=10;
  138.     } else {
  139.     ptr=buf;
  140.     sz=bufsize;
  141.     }
  142.     if(buf) {
  143.     buf2=(short*)PPCAllocVec(bufsize*2,MEMF_ANY);
  144.     if(reply_port=PPCCreatePort(NULL))
  145.         msg=PPCCreateMessage(reply_port,bufsize*2);
  146.     }
  147. }
  148.  
  149. AGfx::~AGfx() {
  150.     if(msg_sent) {
  151.     PPCWaitPort(reply_port);
  152.     PPCGetMessage(reply_port);
  153.     }
  154.     if(msg)
  155.     PPCDeleteMessage(msg);
  156.     if(reply_port)
  157.     PPCDeletePort(reply_port);
  158.     if(buf)
  159.     PPCFreeVec(buf);
  160.     if(buf2)
  161.     PPCFreeVec(buf2);
  162. }
  163.  
  164. void AGfx::flush(bool complete) {
  165.     if(msg_sent) {
  166.     PPCWaitPort(reply_port);
  167.     PPCGetMessage(reply_port);
  168.     msg_sent=false;
  169.     }
  170.     if(buf) {
  171.     if(ptr!=buf && msg) {
  172.         //printf("flush\n");
  173.         if(buf2) {
  174.         short* t=buf;
  175.         buf=buf2;
  176.         buf2=t;
  177.         PPCSendMessage(port,msg,buf2,(ptr-buf2)*2,MSGID_GFX);
  178.         if(complete) {
  179.             PPCWaitPort(reply_port);
  180.             PPCGetMessage(reply_port);
  181.         } else
  182.             msg_sent=true;
  183.         } else {
  184.         PPCSendMessage(port,msg,buf,(ptr-buf)*2,MSGID_GFX);
  185.         PPCWaitPort(reply_port);
  186.         PPCGetMessage(reply_port);
  187.         }
  188.     }
  189.     ptr=buf;
  190.     sz=bufsize;
  191.     } else {
  192.     sz=10;
  193.     ptr=buf;
  194.     }
  195. }
  196. #endif
  197.  
  198. void AGfx::put_image(const Image& i,short x,short y) {
  199.     check_size(5);
  200.     short* p=get_ptr();
  201.     *p++=AGFX_IMAGE;
  202.     *p++=x;
  203.     *p++=y;
  204.     *p++=i.width;
  205.     *p++=i.height;
  206.     set_ptr(p);
  207.     flush(true);
  208.     if(msg) {
  209.     PPCSendMessage(port,msg,i.im,i.height*i.bytes_per_row,MSGID_GFXSYNC);
  210.     PPCWaitPort(reply_port);
  211.     PPCGetMessage(reply_port);
  212.     }
  213. }
  214.  
  215. void AGfx::get_image(Image& i,short x,short y) {
  216.     check_size(5);
  217.     short* p=get_ptr();
  218.     *p++=AGFX_GETIMAGE;
  219.     *p++=x;
  220.     *p++=y;
  221.     *p++=i.width;
  222.     *p++=i.height;
  223.     set_ptr(p);
  224.     flush(true);
  225.     if(msg) {
  226.     PPCSendMessage(port,msg,i.im,i.height*i.bytes_per_row,MSGID_GFXSYNC);
  227.     PPCWaitPort(reply_port);
  228.     PPCGetMessage(reply_port);
  229.     }
  230. }
  231.  
  232. void AGfx::put_image(const Image24& i,short x,short y) {
  233.     check_size(5);
  234.     short* p=get_ptr();
  235.     *p++=AGFX_IMAGE24;
  236.     *p++=x;
  237.     *p++=y;
  238.     *p++=i.width;
  239.     *p++=i.height;
  240.     set_ptr(p);
  241.     flush(true);
  242.     if(msg) {
  243.     PPCSendMessage(port,msg,i.im,i.height*i.width*sizeof(Color),MSGID_GFXSYNC);
  244.     PPCWaitPort(reply_port);
  245.     PPCGetMessage(reply_port);
  246.     }
  247. }
  248.  
  249. void AGfx::get_image(Image24& i,short x,short y) {
  250.     check_size(5);
  251.     short* p=get_ptr();
  252.     *p++=AGFX_GETIMAGE24;
  253.     *p++=x;
  254.     *p++=y;
  255.     *p++=i.width;
  256.     *p++=i.height;
  257.     set_ptr(p);
  258.     flush(true);
  259.     if(msg) {
  260.     PPCSendMessage(port,msg,i.im,i.height*i.width*sizeof(Color),MSGID_GFXSYNC);
  261.     PPCWaitPort(reply_port);
  262.     PPCGetMessage(reply_port);
  263.     }
  264. }
  265.  
  266. void AGfx::get_colors(ColorTable& t,int n) {
  267.     check_size(2);
  268.     short* p=get_ptr();
  269.     *p++=AGFX_GETCOLORS;
  270.     *p++=short(n);
  271.     set_ptr(p);
  272.     flush(true);
  273.     if(msg) {
  274.     PPCSendMessage(port,msg,t.entries,sizeof(ColorEntry)*n,MSGID_GFXSYNC);
  275.     PPCWaitPort(reply_port);
  276.     PPCGetMessage(reply_port);
  277.     }
  278. }
  279.  
  280. #else
  281.  
  282. #include "AGfx.h"
  283.  
  284. AGfx::Image::Image(short w,short h)
  285.     : width(w),height(h),bytes_per_row(((w+15)>>4)<<4) {
  286.     im=(pixel_color*)gmalloc(bytes_per_row*h);
  287.     if(!im)
  288.     throw("No memory.");
  289. }
  290.  
  291. AGfx::Image::~Image() {
  292.     gfree(im);
  293. }
  294.  
  295. AGfx::Image24::Image24(short w,short h)
  296.     : width(w),height(h) {
  297.     im=(Color*)gmalloc(w*h*sizeof(Color));
  298.     if(!im)
  299.     throw("No memory.");
  300. }
  301.  
  302. AGfx::Image24::~Image24() {
  303.     gfree(im);
  304. }
  305.  
  306. AGfx::ColorTable::ColorTable(int n) : num(n) {
  307.     entries=(ColorEntry*)gmalloc((n+1)*sizeof(ColorEntry));
  308.     if(!entries)
  309.     throw("No memory.");
  310. }
  311.  
  312. AGfx::ColorTable::~ColorTable() {
  313.     gfree(entries);
  314. }
  315.  
  316.  
  317. void AGfx::polydraw(const Polygon<short>& p) {
  318.     if(!p.empty()) {
  319.     Polygon<short> q;
  320.     short dx=x0;
  321.     short dy=y0;
  322.     if(dx || dy) {
  323.         q.reserve(p.size());
  324.         for(Polygon<short>::const_iterator v(p.begin());v!=p.end();++v) {
  325.         q.push_back(Vertex<short>(v->x-dx,v->y-dy));
  326.         }
  327.     } else
  328.         q=p;
  329.     Polygon<short>::const_iterator v(q.begin());
  330.     Move(rp,v->x,v->y);
  331.     PolyDraw(rp,q.size()-1,(short*)(v+1));
  332.     }
  333. }
  334.  
  335. #endif
  336.  
  337. AGfx::AreaDrawer::~AreaDrawer() {
  338.     gfx.initarea(n);
  339.     for(PArea<short>::const_iterator p(area.begin());p!=area.end();++p)
  340.     gfx.areapoly(*p);
  341.     gfx.areaend();
  342. }
  343.  
  344. void AGfx::AreaDrawer::add(const Polygon<short>& p) {
  345.     n+=p.size()+1;
  346. #ifndef __PPC__
  347.     short dx=gfx.x0;
  348.     short dy=gfx.y0;
  349.     if(dx || dy) {
  350.     Polygon<short> q;
  351.     q.reserve(p.size());
  352.     for(Polygon<short>::const_iterator v(p.begin());v!=p.end();++v) {
  353.         q.push_back(Vertex<short>(v->x-dx,v->y-dy));
  354.     }
  355.     area.push_back(q);
  356.     } else
  357. #endif
  358.     area.push_back(p);
  359. }
  360.  
  361.  
  362.