pscanvas.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2001-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Mon Aug 27 17:20:09 2001
00010 // commit: $Id: pscanvas.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/gfx/pscanvas.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_GFX_PSCANVAS_CC_UTC20050626084023_DEFINED
00035 #define GROOVX_GFX_PSCANVAS_CC_UTC20050626084023_DEFINED
00036 
00037 #include "pscanvas.h"
00038 
00039 #include "geom/rect.h"
00040 #include "geom/span.h"
00041 #include "geom/txform.h"
00042 #include "geom/vec2.h"
00043 #include "geom/vec3.h"
00044 
00045 #include "gfx/rgbacolor.h"
00046 
00047 #include "media/bmapdata.h"
00048 
00049 #include "rutz/error.h"
00050 #include "rutz/sfmt.h"
00051 #include "rutz/time.h"
00052 #include "rutz/timeformat.h"
00053 
00054 #include <cmath> // for floor() and ceil()
00055 #include <cstdlib> // for getenv()
00056 #include <fstream>
00057 #include <list>
00058 #include <vector>
00059 
00060 #include "rutz/trace.h"
00061 #include "rutz/debug.h"
00062 GVX_DBG_REGISTER
00063 
00064 using geom::recti;
00065 using geom::rectd;
00066 using geom::vec2i;
00067 using geom::vec2d;
00068 using geom::vec3i;
00069 using geom::vec3d;
00070 
00071 class Gfx::PSCanvas::Impl
00072 {
00073   Impl(const Impl&);
00074   Impl& operator=(const Impl&);
00075 
00076 public:
00077 
00078   struct Primitive;
00079 
00080   struct State
00081   {
00082     State() :
00083       txform(geom::txform::identity()),
00084       lineWidth(1.0),
00085       polygonFill(false)
00086     {}
00087 
00088     geom::txform txform;
00089     double lineWidth; // in points
00090     bool polygonFill;
00091   };
00092 
00093   std::ofstream        itsFstream;
00094   std::vector<State>   itsStates;
00095   Primitive*           itsPrimPtr;
00096   bool                 itsSpanFirst;
00097   geom::span<double>   itsSpanX;
00098   geom::span<double>   itsSpanY;
00099 
00100   Impl(const char* filename) :
00101     itsFstream(filename),
00102     itsStates(),
00103     itsPrimPtr(0),
00104     itsSpanFirst(true),
00105     itsSpanX(),
00106     itsSpanY()
00107   {
00108     if (!itsFstream.is_open())
00109       raiseError(rutz::sfmt("couldn't open '%s' for writing", filename),
00110                  SRC_POS);
00111 
00112     itsStates.push_back(State());
00113 
00114     const rutz::fstring timestamp =
00115       rutz::format_time(rutz::time::wall_clock_now());
00116 
00117     itsFstream << "%!PS-Adobe-2.0 EPSF-1.2\n"
00118                << "%%Title: " << filename << "\n"
00119                << "%%Creator: Gfx::PSCanvas $Revision: 10065 $\n"
00120                << "%%CreationDate: " << timestamp << "\n";
00121 
00122     const char* username = getenv("USER");
00123 
00124     if (username != 0)
00125       itsFstream << "%%For: " << username << "\n";
00126 
00127     itsFstream << "%%Pages: 1\n"
00128                << "%%DocumentFonts:\n"
00129                << "%%BoundingBox: (atend)\n"
00130                << "%%EndComments\n"
00131                << "\n"
00132                << "%%Page: 1 1\n"
00133                << "%%BeginDocument: " << filename << "\n"
00134                << "%%DocumentFonts:\n"
00135                << "\n";
00136     translate(vec3d(306.0, 360.0, 0.0));
00137     scale(vec3d(72.0, 72.0, 1.0));
00138   }
00139 
00140   ~Impl()
00141   {
00142     itsFstream << "showpage\n"
00143                << "\n"
00144                << "%%EndDocument\n"
00145                << "\n"
00146                << "%%Trailer\n"
00147                << "%%BoundingBox: "
00148                << floor(itsSpanX.lo) << ' ' << floor(itsSpanY.lo) << ' '
00149                << ceil(itsSpanX.hi) << ' ' << ceil(itsSpanY.hi) << '\n'
00150                << "%%EOF\n"
00151                << std::flush;
00152   }
00153 
00154   State& current_state()
00155   {
00156     GVX_ASSERT(itsStates.size() > 0);
00157     return itsStates.back();
00158   }
00159 
00160   const State& current_state() const
00161   {
00162     GVX_ASSERT(itsStates.size() > 0);
00163     return itsStates.back();
00164   }
00165 
00166   //
00167   // Graphics primitive definitions
00168   //
00169 
00170   struct Primitive
00171   {
00172     typedef Gfx::PSCanvas::Impl PS;
00173 
00174     virtual ~Primitive() {}
00175 
00176     virtual void begin(PS* ps)
00177     {
00178       itsVcount = 0;
00179       onBegin(ps);
00180     }
00181 
00182     virtual void vertex(PS* ps, const vec3d& v)
00183     {
00184       onVertex(ps, v);
00185       ++itsVcount;
00186     }
00187 
00188     virtual void end(PS* ps)
00189     {
00190       onEnd(ps);
00191     }
00192 
00193     unsigned int vcount() const { return itsVcount; }
00194 
00195   private:
00196     unsigned int itsVcount;
00197 
00198     virtual void onBegin(PS* ps) = 0;
00199     virtual void onVertex(PS* ps, const vec3d& v) = 0;
00200     virtual void onEnd(PS* ps) = 0;
00201   };
00202 
00203   struct PointsPrim : public Primitive
00204   {
00205     virtual void onBegin(PS*) {}
00206 
00207     virtual void onVertex(PS* ps, const vec3d& v)
00208     {
00209       ps->newpath(); ps->moveto(v); ps->stroke();
00210     }
00211 
00212     virtual void onEnd(PS*) {}
00213   };
00214 
00215   struct LinesPrim : public Primitive
00216   {
00217     virtual void onBegin(PS* ps)
00218     {
00219       ps->newpath();
00220     }
00221     virtual void onVertex(PS* ps, const vec3d& v)
00222     {
00223       if (vcount() % 2)
00224         {
00225           ps->lineto(v); ps->stroke();
00226         }
00227       else
00228         {
00229           ps->moveto(v);
00230         }
00231     }
00232     virtual void onEnd(PS*) {}
00233   };
00234 
00235   struct LineStripPrim : public Primitive
00236   {
00237     virtual void onBegin(PS* ps)
00238     {
00239       ps->newpath();
00240     }
00241     virtual void onVertex(PS* ps, const vec3d& v)
00242     {
00243       if (vcount() == 0)
00244         {
00245           ps->moveto(v);
00246         }
00247       else
00248         {
00249           ps->lineto(v);
00250         }
00251     }
00252     virtual void onEnd(PS* ps)
00253     {
00254       ps->stroke();
00255     }
00256   };
00257 
00258   struct LineLoopPrim : public Primitive
00259   {
00260     virtual void onBegin(PS*) {}
00261     virtual void onVertex(PS* ps, const vec3d& v)
00262     {
00263       if (vcount() == 0)
00264         {
00265           ps->newpath(); ps->moveto(v);
00266         }
00267       else
00268         {
00269           ps->lineto(v);
00270         }
00271     }
00272     virtual void onEnd(PS* ps)
00273     {
00274       ps->closepath(); ps->stroke();
00275     }
00276   };
00277 
00278   struct TrianglesPrim : public Primitive
00279   {
00280     virtual void onBegin(PS* ps)
00281     {
00282       ps->newpath();
00283     }
00284     virtual void onVertex(PS* ps, const vec3d& v)
00285     {
00286       switch(vcount() % 3)
00287         {
00288         case 0:
00289           ps->moveto(v);
00290           break;
00291         case 1:
00292           ps->lineto(v);
00293           break;
00294         case 2:
00295           ps->lineto(v); ps->closepath(); ps->renderpolygon();
00296           break;
00297         }
00298     }
00299     virtual void onEnd(PS*) {}
00300   };
00301 
00302   struct TriangleStripPrim : public Primitive
00303   {
00304     virtual void onBegin(PS*) { /* FIXME */ }
00305     virtual void onVertex(PS*, const vec3d&) { /* FIXME */ }
00306     virtual void onEnd(PS*) { /* FIXME */ }
00307   };
00308 
00309   struct TriangleFanPrim : public Primitive
00310   {
00311     virtual void onBegin(PS*) { /* FIXME */ }
00312     virtual void onVertex(PS*, const vec3d&) { /* FIXME */ }
00313     virtual void onEnd(PS*) { /* FIXME */ }
00314   };
00315 
00316   struct QuadsPrim : public Primitive
00317   {
00318     virtual void onBegin(PS*) {}
00319 
00320     virtual void onVertex(PS* ps, const vec3d& v)
00321     {
00322       switch(vcount() % 4)
00323         {
00324         case 0:
00325           ps->moveto(v);
00326           break;
00327         case 1:
00328         case 2:
00329           ps->lineto(v);
00330           break;
00331         case 3:
00332           ps->lineto(v); ps->closepath(); ps->renderpolygon();
00333           break;
00334         }
00335     }
00336     virtual void onEnd(PS*) {}
00337   };
00338 
00339   struct QuadStripPrim : public Primitive
00340   {
00341     std::list<vec3d> itsEvenPts;
00342     std::list<vec3d> itsOddPts;
00343 
00344     QuadStripPrim() : itsEvenPts(), itsOddPts() {}
00345 
00346     virtual void onBegin(PS*)
00347     {
00348       itsEvenPts.clear();
00349       itsOddPts.clear();
00350     }
00351 
00352     virtual void onVertex(PS*, const vec3d& v)
00353     {
00354       if ((vcount() % 2) == 0)
00355         itsEvenPts.push_back(v);
00356       else
00357         itsOddPts.push_front(v);
00358     }
00359 
00360     virtual void onEnd(PS* ps)
00361     {
00362       ps->newpath();
00363 
00364       ps->moveto(itsEvenPts.front());
00365 
00366       while (!itsEvenPts.empty())
00367         {
00368           ps->lineto(itsEvenPts.front());
00369           itsEvenPts.pop_front();
00370         }
00371 
00372       while (!itsOddPts.empty())
00373         {
00374           ps->lineto(itsOddPts.front());
00375           itsOddPts.pop_front();
00376         }
00377 
00378       ps->closepath();
00379 
00380       ps->renderpolygon();
00381     }
00382   };
00383 
00384   struct PolygonPrim : public LineLoopPrim
00385   {
00386     virtual void onEnd(PS* ps)
00387     {
00388       ps->closepath(); ps->renderpolygon();
00389     }
00390   };
00391 
00392 
00393 
00394 
00395   void indent()
00396   {
00397     for (unsigned int i = 1; i < itsStates.size(); ++i)
00398       {
00399         itsFstream << '\t';
00400       }
00401   }
00402 
00403   void gsave(const char* comment)
00404   {
00405     indent(); itsFstream << "gsave";
00406     if (comment != 0 && comment[0] != '\0')
00407       itsFstream << " % " << comment;
00408     itsFstream << '\n';
00409     itsStates.push_back(current_state());
00410   }
00411 
00412   void grestore()
00413   {
00414     itsStates.pop_back();
00415     indent(); itsFstream << "grestore\n";
00416   }
00417 
00418   void translate(const vec3d& v)
00419   {
00420     current_state().txform.translate(v);
00421   }
00422 
00423   void scale(const vec3d& v)
00424   {
00425     current_state().txform.scale(v);
00426   }
00427 
00428   void rotate(const vec3d& axis, double angle)
00429   {
00430     current_state().txform.rotate(axis, angle);
00431   }
00432 
00433   // NOTE: these next four functions must be non-templates in order to avoid
00434   // "internal compiler errors" with g++-2.96 on Mac OS X.
00435 
00436   void moveto(const vec2d& v)
00437   {
00438     indent(); pushxy(v); itsFstream << "moveto\n";
00439   }
00440 
00441   void moveto(const vec3d& v)
00442   {
00443     indent(); pushxy(v); itsFstream << "moveto\n";
00444   }
00445 
00446   void lineto(const vec2d& v)
00447   {
00448     indent(); pushxy(v); itsFstream << "lineto\n";
00449   }
00450 
00451   void lineto(const vec3d& v)
00452   {
00453     indent(); pushxy(v); itsFstream << "lineto\n";
00454   }
00455 
00456   void newpath()
00457   {
00458     itsFstream << "\n"; indent(); itsFstream << "newpath\n";
00459   }
00460 
00461   void closepath()
00462   {
00463     indent(); itsFstream << "closepath\n";
00464   }
00465 
00466   void renderpolygon()
00467   {
00468     if (current_state().polygonFill)
00469       fill();
00470     else
00471       stroke();
00472   }
00473 
00474 #if 0
00475   // WARNING! The arc() and arcn() functions won't work properly with
00476   // maintaining our own 3-D coordinate transformation.
00477   void arc(double x, double y, double r, double start, double end,
00478            bool reverse=false)
00479   {
00480     indent(); push1(x); push1(y); push1(r); push1(start); push1(end);
00481     if (reverse)
00482       itsFstream << "arcn\n";
00483     else
00484       itsFstream << "arc\n";
00485     //      indent(); itsFstream << "4 { pop } repeat\n";
00486   }
00487 
00488   void arcn(double x, double y, double r, double start, double end)
00489   {
00490     arc(x, y, r, start, end, true);
00491   }
00492 #endif
00493 
00494   void circle(double x, double y, double r, bool reverse=false)
00495   {
00496     // A good cubic Bezier approximation for a radius-r 90 degree arc is:
00497     //
00498     //   (r,0) (r,r*a) (r*a,r) (0,r)
00499     //
00500     // where a = 4/3*(sqrt(2)-1).
00501 
00502     const double a = 4.0/3.0 * (sqrt(2.0)-1.0);
00503 
00504     const vec3d pt1 (x+r   , y ,     0.0); // right
00505     const vec3d pt2 (x+r   , y+r*a , 0.0);
00506     const vec3d pt3 (x+r*a , y+r ,   0.0);
00507     const vec3d pt4 (x     , y+r ,   0.0); // top
00508     const vec3d pt5 (x-r*a , y+r ,   0.0);
00509     const vec3d pt6 (x-r   , y+r*a , 0.0);
00510     const vec3d pt7 (x-r   , y ,     0.0); // left
00511     const vec3d pt8 (x-r   , y-r*a , 0.0);
00512     const vec3d pt9 (x-r*a , y-r ,   0.0);
00513     const vec3d pt10(x     , y-r ,   0.0); // bottom
00514     const vec3d pt11(x+r*a , y-r ,   0.0);
00515     const vec3d pt12(x+r   , y-r*a , 0.0);
00516 
00517     if (!reverse)
00518       {
00519         moveto(pt1);
00520         indent(); pushxy(pt2); pushxy(pt3); pushxy(pt4); itsFstream << "curveto\n";
00521         indent(); pushxy(pt5); pushxy(pt6); pushxy(pt7); itsFstream << "curveto\n";
00522         indent(); pushxy(pt8); pushxy(pt9); pushxy(pt10); itsFstream << "curveto\n";
00523         indent(); pushxy(pt11); pushxy(pt12); pushxy(pt1); itsFstream << "curveto\n";
00524       }
00525     else
00526       {
00527         moveto(pt1);
00528         indent(); pushxy(pt12); pushxy(pt11); pushxy(pt10); itsFstream << "curveto\n";
00529         indent(); pushxy(pt9); pushxy(pt8); pushxy(pt7); itsFstream << "curveto\n";
00530         indent(); pushxy(pt6); pushxy(pt5); pushxy(pt4); itsFstream << "curveto\n";
00531         indent(); pushxy(pt3); pushxy(pt2); pushxy(pt1); itsFstream << "curveto\n";
00532       }
00533   }
00534 
00535   void bezier(const vec3d& p1,
00536               const vec3d& p2,
00537               const vec3d& p3,
00538               const vec3d& p4)
00539   {
00540     newpath();
00541     moveto(p1);
00542     indent(); pushxy(p2); pushxy(p3); pushxy(p4);
00543     itsFstream << "curveto\n";
00544     stroke();
00545   }
00546 
00547   void fill()
00548   {
00549     indent(); itsFstream << "fill\n\n";
00550   }
00551 
00552   void stroke()
00553   {
00554     indent(); itsFstream << "stroke\n\n";
00555   }
00556 
00557   void setlinewidth(double w)
00558   {
00559     current_state().lineWidth = w;
00560 
00561     indent(); push1(w); itsFstream << "setlinewidth\n";
00562   }
00563 
00564   void setdash(unsigned short bit_pattern)
00565   {
00566     dbg_eval_nl(3, reinterpret_cast<void*>(int(bit_pattern)));
00567 
00568     bool prev_bit = (0x8000 & bit_pattern);
00569 
00570     // will hold the lengths of the individual bit runs
00571     int lengths[16] = { 0 };
00572     int pos = 0;
00573 
00574     for (unsigned short mask = 0x8000; mask != 0; mask >>= 1)
00575       {
00576         bool bit = (mask & bit_pattern);
00577         bool same = (bit == prev_bit);
00578 
00579         if (!same)
00580           {
00581             ++pos; lengths[pos] = 0;
00582           }
00583 
00584         ++lengths[pos];
00585 
00586         prev_bit = bit;
00587       }
00588 
00589     ++pos; // so we point at one-past-the-end
00590 
00591     int offset = 0;
00592 
00593     if ((pos % 2) == 1)
00594       {
00595         offset = lengths[--pos];
00596         lengths[0] += offset;
00597       }
00598 
00599     indent();
00600 
00601     push1("[");
00602     for (int i = 0; i < pos; ++i)
00603       {
00604         push1(lengths[i]);
00605       }
00606     push1("]");
00607 
00608     push1(offset); itsFstream << "setdash\n";
00609   }
00610 
00611   void setrgbcolor(const RgbaColor& col)
00612   {
00613     indent(); push1(col.r()); push1(col.g()); push1(col.b());
00614     itsFstream << "setrgbcolor\n";
00615   }
00616 
00617   // The push1() and pushxy() functions must be non-templates to placate
00618   // g++-2.96 on Mac OS X.
00619 
00620   void push1(double v)
00621   {
00622     itsFstream << v << " ";
00623   }
00624 
00625   void push1(int v)
00626   {
00627     itsFstream << v << " ";
00628   }
00629 
00630   void push1(const char* v)
00631   {
00632     itsFstream << v << " ";
00633   }
00634 
00635   void mergespan(const double x, const double y)
00636   {
00637     if (itsSpanFirst)
00638       {
00639         itsSpanX = geom::span<double>::from_any(x, x);
00640         itsSpanY = geom::span<double>::from_any(y, y);
00641         itsSpanFirst = false;
00642       }
00643     else
00644       {
00645         itsSpanX = itsSpanX.including(x);
00646         itsSpanY = itsSpanY.including(y);
00647       }
00648   }
00649 
00650   void pushxy(const vec2d& v)
00651   {
00652     vec2d t = current_state().txform.apply_to(v);
00653     this->mergespan(t.x(), t.y());
00654     itsFstream << t.x() << " " << t.y() << " ";
00655   }
00656 
00657   void pushxy(const vec3d& v)
00658   {
00659     vec3d t = current_state().txform.apply_to(v);
00660     this->mergespan(t.x(), t.y());
00661     itsFstream << t.x() << " " << t.y() << " ";
00662   }
00663 
00664   void raiseError(const rutz::fstring& msg, const rutz::file_pos& pos)
00665   {
00666     throw rutz::error(rutz::sfmt("PSCanvas error: %s", msg.c_str()), pos);
00667   }
00668 
00669   void beginPrimitive(Primitive* ptr, const char* comment)
00670   {
00671     if (itsPrimPtr != 0)
00672       raiseError("in beginPrimitive, already in graphics primitive",
00673                  SRC_POS);
00674 
00675     if (comment != 0 && comment[0] != '\0')
00676       {
00677         indent(); itsFstream << "% " << comment << " (begin)\n";
00678       }
00679 
00680     itsPrimPtr = ptr;
00681     itsPrimPtr->begin(this);
00682   }
00683 
00684   void endPrimitive()
00685   {
00686     if (itsPrimPtr == 0)
00687       {
00688         raiseError("called endPrimitive outside graphics primitive",
00689                    SRC_POS);
00690       }
00691 
00692     itsPrimPtr->end(this);
00693     itsPrimPtr = 0;
00694   }
00695 };
00696 
00697 namespace
00698 {
00699   Gfx::PSCanvas::Impl::PointsPrim        thePointsPrim;
00700   Gfx::PSCanvas::Impl::LinesPrim         theLinesPrim;
00701   Gfx::PSCanvas::Impl::LineStripPrim     theLineStripPrim;
00702   Gfx::PSCanvas::Impl::LineLoopPrim      theLineLoopPrim;
00703   Gfx::PSCanvas::Impl::TrianglesPrim     theTrianglesPrim;
00704   Gfx::PSCanvas::Impl::TriangleStripPrim theTriangleStripPrim;
00705   Gfx::PSCanvas::Impl::TriangleFanPrim   theTriangleFanPrim;
00706   Gfx::PSCanvas::Impl::QuadsPrim         theQuadsPrim;
00707   Gfx::PSCanvas::Impl::QuadStripPrim     theQuadStripPrim;
00708   Gfx::PSCanvas::Impl::PolygonPrim       thePolygonPrim;
00709 }
00710 
00711 Gfx::PSCanvas::PSCanvas(const char* filename) :
00712   rep(new Impl(filename))
00713 {
00714 GVX_TRACE("Gfx::PSCanvas::PSCanvas");
00715 }
00716 
00717 Gfx::PSCanvas::~PSCanvas() throw()
00718 {
00719 GVX_TRACE("Gfx::PSCanvas::~PSCanvas");
00720   delete rep;
00721 }
00722 
00723 vec3d Gfx::PSCanvas::screenFromWorld3(const vec3d& /*world_pos*/) const
00724 {
00725 GVX_TRACE("Gfx::PSCanvas::screenFromWorld3");
00726 // FIXME
00727   rep->raiseError("not implemented", SRC_POS);
00728   return vec3d();
00729 }
00730 
00731 vec3d Gfx::PSCanvas::worldFromScreen3(const vec3d& /*screen_pos*/) const
00732 {
00733 GVX_TRACE("Gfx::PSCanvas::worldFromScreen3");
00734 // FIXME
00735   rep->raiseError("not implemented", SRC_POS);
00736   return vec3d();
00737 }
00738 
00739 
00740 recti Gfx::PSCanvas::getScreenViewport() const
00741 {
00742 GVX_TRACE("Gfx::PSCanvas::getScreenViewport()");
00743 // FIXME
00744   rep->raiseError("not implemented", SRC_POS);
00745   return recti();
00746 }
00747 
00748 
00749 bool Gfx::PSCanvas::isRgba() const
00750 {
00751 GVX_TRACE("Gfx::PSCanvas::isRgba");
00752   return true;
00753 }
00754 
00755 bool Gfx::PSCanvas::isColorIndex() const
00756 {
00757 GVX_TRACE("Gfx::PSCanvas::isColorIndex");
00758   return false;
00759 }
00760 
00761 bool Gfx::PSCanvas::isDoubleBuffered() const
00762 {
00763 GVX_TRACE("Gfx::PSCanvas::isDoubleBuffered");
00764   return false;
00765 }
00766 
00767 unsigned int Gfx::PSCanvas::bitsPerPixel() const
00768 {
00769 GVX_TRACE("Gfx::PSCanvas::bitsPerPixel");
00770   return 24;
00771 }
00772 
00773 void Gfx::PSCanvas::throwIfError(const char* where,
00774                                  const rutz::file_pos& pos) const
00775 {
00776 GVX_TRACE("Gfx::PSCanvas::throwIfError");
00777   if (rep->itsFstream.fail())
00778     rep->raiseError(where, pos);
00779 }
00780 
00781 
00782 void Gfx::PSCanvas::pushAttribs(const char* comment)
00783 {
00784 GVX_TRACE("Gfx::PSCanvas::pushAttribs");
00785   rep->gsave(comment);
00786 }
00787 
00788 void Gfx::PSCanvas::popAttribs()
00789 {
00790 GVX_TRACE("Gfx::PSCanvas::popAttribs");
00791   rep->grestore();
00792 }
00793 
00794 void Gfx::PSCanvas::drawOnFrontBuffer()
00795 {
00796 GVX_TRACE("Gfx::PSCanvas::drawOnFrontBuffer");
00797   ;// nothing
00798 }
00799 
00800 void Gfx::PSCanvas::drawOnBackBuffer()
00801 {
00802 GVX_TRACE("Gfx::PSCanvas::drawOnBackBuffer");
00803   ;// nothing
00804 }
00805 
00806 void Gfx::PSCanvas::setColor(const RgbaColor& col)
00807 {
00808 GVX_TRACE("Gfx::PSCanvas::setColor");
00809   rep->setrgbcolor(col);
00810 }
00811 
00812 void Gfx::PSCanvas::setClearColor(const RgbaColor&)
00813 {
00814 GVX_TRACE("Gfx::PSCanvas::setClearColor");
00815   ;//nothing
00816 }
00817 
00818 void Gfx::PSCanvas::setColorIndex(unsigned int /*index*/)
00819 {
00820 GVX_TRACE("Gfx::PSCanvas::setColorIndex");
00821 // FIXME
00822   rep->raiseError("not implemented", SRC_POS);
00823 }
00824 
00825 void Gfx::PSCanvas::setClearColorIndex(unsigned int /*index*/)
00826 {
00827 GVX_TRACE("Gfx::PSCanvas::setClearColorIndex");
00828 // FIXME
00829   rep->raiseError("not implemented", SRC_POS);
00830 }
00831 
00832 void Gfx::PSCanvas::swapForeBack()
00833 {
00834 GVX_TRACE("Gfx::PSCanvas::swapForeBack");
00835 // FIXME
00836   rep->raiseError("not implemented", SRC_POS);
00837 }
00838 
00839 void Gfx::PSCanvas::setPolygonFill(bool on)
00840 {
00841 GVX_TRACE("Gfx::PSCanvas::setPolygonFill");
00842 
00843   rep->current_state().polygonFill = on;
00844 }
00845 
00846 void Gfx::PSCanvas::setPointSize(double size)
00847 {
00848 GVX_TRACE("Gfx::PSCanvas::setPointSize");
00849 // FIXME
00850   if (size != 1.0)
00851     rep->raiseError("not implemented", SRC_POS);
00852 }
00853 
00854 void Gfx::PSCanvas::setLineWidth(double width)
00855 {
00856 GVX_TRACE("Gfx::PSCanvas::setLineWidth");
00857 
00858   rep->setlinewidth(width);
00859 }
00860 
00861 void Gfx::PSCanvas::setLineStipple(unsigned short bit_pattern)
00862 {
00863 GVX_TRACE("Gfx::PSCanvas::setLineStipple");
00864 
00865   rep->setdash(bit_pattern);
00866 }
00867 
00868 void Gfx::PSCanvas::enableAntialiasing()
00869 {
00870 GVX_TRACE("Gfx::PSCanvas::enableAntialiasing");
00871   // nothing, antialiasing is default in postscript
00872 }
00873 
00874 
00875 
00876 void Gfx::PSCanvas::viewport(int /*x*/, int /*y*/, int /*w*/, int /*h*/)
00877 {
00878 GVX_TRACE("Gfx::PSCanvas::viewport");
00879 // FIXME
00880   rep->raiseError("not implemented", SRC_POS);
00881 }
00882 
00883 void Gfx::PSCanvas::orthographic(const rectd& /*bounds*/,
00884                                  double /*zNear*/, double /*zFar*/)
00885 {
00886 GVX_TRACE("Gfx::PSCanvas::orthographic");
00887 // FIXME
00888 }
00889 
00890 void Gfx::PSCanvas::perspective(double /*fovy*/, double /*aspect*/,
00891                                 double /*zNear*/, double /*zFar*/)
00892 {
00893 GVX_TRACE("Gfx::PSCanvas::perspective");
00894 // FIXME
00895 }
00896 
00897 
00898 void Gfx::PSCanvas::pushMatrix(const char* comment)
00899 {
00900 GVX_TRACE("Gfx::PSCanvas::pushMatrix");
00901   rep->gsave(comment);
00902 }
00903 
00904 void Gfx::PSCanvas::popMatrix()
00905 {
00906 GVX_TRACE("Gfx::PSCanvas::popMatrix");
00907   rep->grestore();
00908 }
00909 
00910 void Gfx::PSCanvas::translate(const vec3d& v)
00911 {
00912 GVX_TRACE("Gfx::PSCanvas::translate");
00913   rep->translate(v);
00914 }
00915 
00916 void Gfx::PSCanvas::scale(const vec3d& v)
00917 {
00918 GVX_TRACE("Gfx::PSCanvas::scale");
00919   rep->scale(v);
00920 }
00921 
00922 void Gfx::PSCanvas::rotate(const vec3d& axis, double angle_in_degrees)
00923 {
00924 GVX_TRACE("Gfx::PSCanvas::rotate");
00925   rep->rotate(axis, angle_in_degrees);
00926 }
00927 
00928 void Gfx::PSCanvas::transform(const geom::txform& tx)
00929 {
00930 GVX_TRACE("Gfx::PSCanvas::transform");
00931   rep->current_state().txform.transform(tx);
00932 }
00933 
00934 void Gfx::PSCanvas::loadMatrix(const geom::txform& tx)
00935 {
00936 GVX_TRACE("Gfx::PSCanvas::loadMatrix");
00937   rep->current_state().txform = tx;
00938 }
00939 
00940 
00941 void Gfx::PSCanvas::drawPixels(const media::bmap_data& /*data*/,
00942                                const vec3d& /*world_pos*/,
00943                                const vec2d& /*zoom*/)
00944 {
00945 GVX_TRACE("Gfx::PSCanvas::drawPixels");
00946 // FIXME
00947   rep->raiseError("not implemented", SRC_POS);
00948 }
00949 
00950 void Gfx::PSCanvas::drawBitmap(const media::bmap_data& /*data*/,
00951                                const vec3d& /*world_pos*/)
00952 {
00953 GVX_TRACE("Gfx::PSCanvas::drawBitmap");
00954 // FIXME
00955   rep->raiseError("not implemented", SRC_POS);
00956 }
00957 
00958 void Gfx::PSCanvas::grabPixels(const recti&, media::bmap_data&)
00959 {
00960 GVX_TRACE("Gfx::PSCanvas::grabPixels");
00961   rep->raiseError("grabPixels not possible in PostScript canvas",
00962                   SRC_POS);
00963 }
00964 
00965 void Gfx::PSCanvas::clearColorBuffer()
00966 {
00967 GVX_TRACE("Gfx::PSCanvas::clearColorBuffer");
00968 // FIXME
00969   rep->raiseError("not implemented", SRC_POS);
00970 }
00971 
00972 void Gfx::PSCanvas::clearColorBuffer(const recti& /*screen_rect*/)
00973 {
00974 GVX_TRACE("Gfx::PSCanvas::clearColorBuffer(geom::rect)");
00975 // FIXME
00976   rep->raiseError("not implemented", SRC_POS);
00977 }
00978 
00979 void Gfx::PSCanvas::drawRect(const rectd& r)
00980 {
00981 GVX_TRACE("Gfx::PSCanvas::drawRect");
00982 
00983   rep->newpath();
00984   rep->moveto(r.bottom_left());
00985   rep->lineto(r.bottom_right());
00986   rep->lineto(r.top_right());
00987   rep->lineto(r.top_left());
00988   rep->closepath();
00989   if (rep->current_state().polygonFill)
00990     rep->fill();
00991   else
00992     rep->stroke();
00993 }
00994 
00995 void Gfx::PSCanvas::drawCircle(double inner_radius, double outer_radius,
00996                                bool fill, unsigned int, unsigned int)
00997 {
00998 GVX_TRACE("Gfx::PSCanvas::drawCircle");
00999 
01000   rep->newpath();
01001   rep->circle(0.0, 0.0, outer_radius);
01002   if (fill)
01003     {
01004       if (inner_radius > 0)
01005         rep->circle(0.0, 0.0, inner_radius, true);
01006       rep->fill();
01007     }
01008   else
01009     {
01010       rep->stroke();
01011     }
01012 }
01013 
01014 void Gfx::PSCanvas::drawCylinder(double /*base_radius*/, double /*top_radius*/,
01015                                  double /*height*/, int /*slices*/, int /*stacks*/,
01016                                  bool /*fill*/)
01017 {
01018   // FIXME
01019   rep->raiseError("not implemented", SRC_POS);
01020 }
01021 
01022 void Gfx::PSCanvas::drawSphere(double /*radius*/, int /*slices*/, int /*stacks*/,
01023                                bool /*fill*/)
01024 {
01025   // FIXME
01026   rep->raiseError("not implemented", SRC_POS);
01027 }
01028 
01029 void Gfx::PSCanvas::drawBezier4(const vec3d& p1,
01030                                 const vec3d& p2,
01031                                 const vec3d& p3,
01032                                 const vec3d& p4,
01033                                 unsigned int /*subdivisions*/)
01034 {
01035 GVX_TRACE("Gfx::PSCanvas::drawBezier4");
01036   rep->bezier(p1, p2, p3, p4);
01037 }
01038 
01039 void Gfx::PSCanvas::drawBezierFill4(const vec3d& /*center*/,
01040                                     const vec3d& /*p1*/,
01041                                     const vec3d& /*p2*/,
01042                                     const vec3d& /*p3*/,
01043                                     const vec3d& /*p4*/,
01044                                     unsigned int /*subdivisions*/)
01045 {
01046 GVX_TRACE("Gfx::PSCanvas::drawBezierFill4");
01047   // FIXME
01048   rep->raiseError("not implemented", SRC_POS);
01049 }
01050 
01051 void Gfx::PSCanvas::beginPoints(const char* comment)
01052 {
01053 GVX_TRACE("Gfx::PSCanvas::beginPoints");
01054   rep->beginPrimitive(&thePointsPrim, comment);
01055 }
01056 
01057 void Gfx::PSCanvas::beginLines(const char* comment)
01058 {
01059 GVX_TRACE("Gfx::PSCanvas::beginLines");
01060   rep->beginPrimitive(&theLinesPrim, comment);
01061 }
01062 
01063 void Gfx::PSCanvas::beginLineStrip(const char* comment)
01064 {
01065 GVX_TRACE("Gfx::PSCanvas::beginLineStrip");
01066   rep->beginPrimitive(&theLineStripPrim, comment);
01067 }
01068 
01069 void Gfx::PSCanvas::beginLineLoop(const char* comment)
01070 {
01071 GVX_TRACE("Gfx::PSCanvas::beginLineLoop");
01072   rep->beginPrimitive(&theLineLoopPrim, comment);
01073 }
01074 
01075 void Gfx::PSCanvas::beginTriangles(const char* comment)
01076 {
01077 GVX_TRACE("Gfx::PSCanvas::beginTriangles");
01078   rep->beginPrimitive(&theTrianglesPrim, comment);
01079 }
01080 
01081 void Gfx::PSCanvas::beginTriangleStrip(const char* comment)
01082 {
01083 GVX_TRACE("Gfx::PSCanvas::beginTriangleStrip");
01084   rep->beginPrimitive(&theTriangleStripPrim, comment);
01085 }
01086 
01087 void Gfx::PSCanvas::beginTriangleFan(const char* comment)
01088 {
01089 GVX_TRACE("Gfx::PSCanvas::beginTriangleFan");
01090   rep->beginPrimitive(&theTriangleFanPrim, comment);
01091 }
01092 
01093 void Gfx::PSCanvas::beginQuads(const char* comment)
01094 {
01095 GVX_TRACE("Gfx::PSCanvas::beginQuads");
01096   rep->beginPrimitive(&theQuadsPrim, comment);
01097 }
01098 
01099 void Gfx::PSCanvas::beginQuadStrip(const char* comment)
01100 {
01101 GVX_TRACE("Gfx::PSCanvas::beginQuadStrip");
01102   rep->beginPrimitive(&theQuadStripPrim, comment);
01103 }
01104 
01105 void Gfx::PSCanvas::beginPolygon(const char* comment)
01106 {
01107 GVX_TRACE("Gfx::PSCanvas::beginPolygon");
01108   rep->beginPrimitive(&thePolygonPrim, comment);
01109 }
01110 
01111 void Gfx::PSCanvas::vertex2(const vec2d& v)
01112 {
01113 GVX_TRACE("Gfx::PSCanvas::vertex2");
01114   vertex3(vec3d(v.x(), v.y(), 0.0));
01115 }
01116 
01117 void Gfx::PSCanvas::vertex3(const vec3d& v)
01118 {
01119 GVX_TRACE("Gfx::PSCanvas::vertex3");
01120 
01121   if (rep->itsPrimPtr == 0)
01122     {
01123       rep->raiseError("called vertex() outside graphics primitive",
01124                       SRC_POS);
01125     }
01126 
01127   rep->itsPrimPtr->vertex(rep, v);
01128 }
01129 
01130 void Gfx::PSCanvas::end()
01131 {
01132 GVX_TRACE("Gfx::PSCanvas::end");
01133   rep->endPrimitive();
01134 }
01135 
01136 void Gfx::PSCanvas::drawRasterText(const rutz::fstring& /*text*/,
01137                                    const GxRasterFont& /*font*/)
01138 {
01139 GVX_TRACE("Gfx::PSCanvas::drawRasterText");
01140   throw rutz::error("PSCanvas::drawRasterText not implemented", SRC_POS);
01141 }
01142 
01143 void Gfx::PSCanvas::drawVectorText(const rutz::fstring& /*text*/,
01144                                    const GxVectorFont& /*font*/)
01145 {
01146 GVX_TRACE("Gfx::PSCanvas::drawVectorText");
01147   throw rutz::error("PSCanvas::drawVectorText not implemented", SRC_POS);
01148 }
01149 
01150 void Gfx::PSCanvas::flushOutput()
01151 {
01152 GVX_TRACE("Gfx::PSCanvas::flushOutput");
01153   rep->itsFstream << std::flush;
01154 }
01155 
01156 static const char __attribute__((used)) vcid_groovx_gfx_pscanvas_cc_utc20050626084023[] = "$Id: pscanvas.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
01157 #endif // !GROOVX_GFX_PSCANVAS_CC_UTC20050626084023_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:39 2008 by Doxygen version 1.5.5.