////////////////////////////////////////////////////////////////////// // // File: playpen.h // Description: Declaration of the playpen as described // in CVu 9-2. A few things have been assumed. // Like should the display vanish on ~playpen, // and what does colour(n) actually mean. // History: // // 1.0 19-01-1997 SDW Original // rewritten by Francis Glassborow 29/09/2002 Modifie Frs 20/04/2004 // uses namespaces and exceptions // plus style changes // minor mods by Garry Lancaster 10/2002 ///////////////////////////////////////////////////////////////////// #if !defined (PLAYPEN_H) #define PLAYPEN_H #include "fgw_text.h" #include #include #include namespace studentgraphics { class playpen; // Frequently used elements of the standard library. using std::cout; using std::cin; using std::endl; using std::string; using std::istream; using std::ostream; using std::bitset; // Wrapper for OS-specific sleep function. void Wait(unsigned ms); namespace detail { // Forward declare the class that provides the OS specific code class SingletonWindow; } // A class to support palette codes and limit the operators that can be used class hue{ public: hue(unsigned char code = 0):code_(code){} hue(int code):code_(code%256){} operator unsigned char()const{return code_;} bool operator[](int bit)const {if(bit <0 or bit >7) return false; return bitset<8>(code_)[bit];} class ref; friend class hue::ref; class ref{ public: ref(hue & h, int n):h_(h),bit(n){}; operator bool(){if (bit <0 or bit >7) return false; return bitset<8>(h_)[bit];} void operator=(bool val){if(bit <0 or bit >7) return; bitset<8> v(h_); v[bit] = val; h_ = (unsigned char)v.to_ulong();} private: hue & h_; int bit; }; ref operator[](int bit){return ref(*this, bit);} unsigned char value()const{return code_;} hue operator +=(hue h){code_ |= h.code_; return code_;} hue operator -=(hue h){code_ &= ~h.code_; return code_;} private: unsigned char code_; }; inline hue operator+(hue code1, hue code2){return (code1.value() | code2.value());} inline hue operator+(unsigned char code1, hue code2){return (code1 | code2.value());} inline hue operator+(hue code1, unsigned char code2){return (code1.value() | code2);} inline hue operator-(hue code1, hue code2){return (code1.value() & ~(code2.value()));} inline hue operator-(unsigned char code1, hue code2){return (code1 & ~(code2.value()));} inline hue operator-(hue code1, unsigned char code2){return (code1.value() & ~(code2));} // prevent multiplication/division of palette codes hue operator*(hue, hue); hue operator/(hue, hue); // provide special values for rgbpalette //Francisation du nom des couleurs hue const blanc(255); hue const noir(0); hue const rouge4(128); hue const rouge2(64); hue const rouge1(32); hue const vert4(16); hue const vert2(8); hue const vert1(1); hue const bleu4(4); hue const bleu2(2); hue const bleu1(1); hue const turquoise(1); //Fin francisation hue const white(255); hue const black(0); hue const red4(128); hue const red2(64); hue const red1(32); hue const green4(16); hue const green2(8); hue const green1(1); hue const blue4(4); hue const blue2(2); hue const blue1(1); hue const torquoise(1); inline istream & operator >> (istream & in , hue & shade){ shade = (std::cin == in ? fgw::read() : fgw::read(in)); return in; } // A typedef for the palette elements typedef unsigned char palettecode; typedef hue couleur; struct HueRGB { unsigned char r; unsigned char g; unsigned char b; HueRGB() : r(0), g(0), b(0) {} HueRGB(unsigned char red, unsigned char green, unsigned char blue) : r(red), g(green), b(blue) {} }; /* struct CouleurRGB { f unsigned char r; unsigned char g; unsigned char b; CouleurRGB() : r(0), g(0), b(0) {} CouleurRGB(unsigned char red, unsigned char green, unsigned char blue) : r(red), g(green), b(blue) {} }; */ typedef HueRGB CouleurRGB; int const colours = 0x100; // number of colours in palette int const Xpixels = 512; // pixels across int const Ypixels = 512; // pixels down // plotmode determines the way source and destination hues are combined // during a plot. // enum plotmode { direct, additive, filter, disjoint}; enum plotmode { direct, additif, filtre, disjoint}; class pixelsize { public: pixelsize(int size =1); int size()const {return dim;} bool size(int i){if(i<1 || i >64) return false; dim = i; return true;} private: int dim; }; inline pixelsize::pixelsize(int size):dim(size){if(dim <1) dim = 1;} // Front end. class playpen { public: class exception{ public: enum level{unknown, fatal, error, warning, info}; exception():lev_(unknown), message_("unknown problem"){}; exception(level l,char const * message):lev_(l), message_(message){}; void report()const {cout << message_ << endl;} // Compiler generated copying and destruction are OK. private: level lev_; string message_; }; class raw_pixel_data { int const x_, y_; public: explicit raw_pixel_data(int xval=0, int yval=0):x_(xval), y_(yval) {}; int x() const {return x_;} int y() const {return y_;} }; // 07/06/03 changed to more general name, derived to provide // backward compatibility class origin_data: public raw_pixel_data { public: explicit origin_data(int xval=0, int yval = 0):raw_pixel_data(xval, yval){} }; playpen(hue background = white); ~playpen(); // Playpens are copyable because all instances share the same // representation. But we need a copy ctor to maintain the reference count playpen(playpen const & pp); // Update the physical display. playpen const& display() const; // Plot a pixel. Changes are not visible until next display() call. playpen& plot(int x, int y, hue h); // handle plotting points that are provided as doubles, // the rounding is to avoid problems of conversion from int to double and back again // introducing a rounding error playpen& plot(double x, double y, hue h){return plot(int(x+0.5), int(y+0.5), h);} hue get_hue(int x, int y)const; hue lire_couleur(int x, int y)const{return get_hue(x, y);}; // Set the plotting mode for subsequent calls to plot(). plotmode setplotmode(plotmode pm); playpen& origin(int xval, int yval){xorg = xval; yorg = yval; return *this;} origin_data origin()const {return origin_data(xorg, yorg);} bool scale(int i){return pixsize.size(i);} int scale()const {return pixsize.size();} raw_pixel_data get_raw_xy(int i, int j){return raw_pixel_data(xorg+ i * pixsize.size(), yorg - j * pixsize.size());} typedef origin_data origine_data; // Clear all pixels to the specified hue. Changes is not visible // until the next display() call. playpen& clear(hue h = white); playpen& rgbpalette(); //Francisation playpen& effacer(){return clear(white);}; playpen& tracer(int x, int y, hue h){return plot(x, y, h);} //f playpen const& afficher() const {return display();} //f playpen& tracer(double x, double y, hue h){return plot(int(x+0.5), int(y+0.5), h);} // plotmode mode_tracage(plotmode pm) {return setplotmode(pm);} //f playpen& origine(int xval, int yval){xorg = xval; yorg = yval; return *this;} //f origine_data origine()const {return origin_data(xorg, yorg);} //f bool taille(int i){return pixsize.size(i);} //f int taille() const {return pixsize.size();} //f playpen& effacer(int hue){return clear(hue);} //f // fin francisation // Palette handling: how hues map to a RGB (red, green, blue) // value. Depending on display mode there may not be an exact match // between the RGB value specified and that physically displayed. // Initial palette (when the first playpen object is created) has // entry 255 white and entries 0-215 (inclusive) a standard web // safety palette, including black at entry 0. // Change a palette entry. Change is not visible until the next call // to UpdatePalette(). playpen& setpalettentry(hue, HueRGB const & target); playpen& fixervaleurpalette(couleur coul, CouleurRGB const & cible){return setpalettentry(coul, cible);}; //f playpen& fixervaleurpalette(int coul, CouleurRGB const & cible){ couleur val=coul; return setpalettentry(val, cible);}; //f // Get the RGB value mapped to a specified hue. HueRGB getpalettentry(hue) const; // CouleurRGB lirevaleurpalette(hue) const; CouleurRGB lirevaleurpalette(couleur coul) const {return getpalettentry(coul);}; //f CouleurRGB lirevaleurpalette(int coul) const {return getpalettentry(coul);}; //f // Update the physical palette, possibly changing the display. playpen const & updatepalette() const; playpen const & majpalette() const {return updatepalette();}; //f // Persistence (a.k.a serialization). Ensure stream is opened in // binary (not text) mode (at least for MSVC6 - a bug, I think). // Save all state to binary file. ostream & save(ostream &)const; // Restore all state from binary file. Automatically updates physical // display to reflect changed state. istream & restore(istream &); // Not currently implemented. //ostream & savepalette(ostream&); //istream & restorepalette(ostream&); // GSL: Added. Required by MiniPNG. Ignores plotmode, origin and // scaling. hue getrawpixel(int x, int y) const; void setrawpixel(int x, int y, hue h); couleur lire_pixel_brut(int x, int y) const {return getrawpixel(x,y);}; void ecrire_pixel_brut(int x, int y, couleur coul) {return setrawpixel(x,y, coul);}; private: plotmode pmode; int xorg, yorg; pixelsize pixsize; // There is only one SingletonWindow, used by all playpen objects. static detail::SingletonWindow * graphicswindow; };// class playpen // two utility functions for Playpen + PNG // Purpose: // Load a playpen image from PNG format. // Parameters: // [out] p - The playpen to which the image will be written. // [in, out] stm - The stream from which the PNG data will be read. This // stream must be opened in binary mode. // Exception Safety: // Basic. void LoadPlaypen(playpen& p, std::string filename); inline void OuvrirPlaypen(playpen& p, std::string nom_fichier){LoadPlaypen(p, nom_fichier);} //f // Purpose: // Save a playpen image in PNG format. // Parameters: // [in] p - The playpen from which the image will be read. // [in, out] stm - The stream to which the image will be saved. The // stream must be opened in binary mode. // Exception Safety: // Basic. void SavePlaypen(playpen const & p, std::string filename); inline void EnregistrerPlaypen(playpen const & p, std::string nom_fichier){SavePlaypen(p, nom_fichier);} //f }; // namespace studentgraphics namespace fgw { using namespace studentgraphics; } #endif