38 m_dx(dx>0?dx:window.dx()) ,
39 m_dy(dy>0?dy:window.dy()) ,
41 m_client_side(!server_side) ,
44 m_pixmap(m_window.windowDisplay(),m_window,m_dx,m_dy) ,
45 m_image(m_window.windowDisplay(),m_window,m_dx,m_dy) ,
46 m_context(m_window.windowDisplay(),m_window) ,
52 G_ASSERT( colours == 0 || colours == 16 || colours == 256 ) ;
56 m_window.
install( *m_colour_map.get() ) ;
81 return std::make_pair( m_aspect_top , m_aspect_bottom ) ;
86 G_ASSERT( m_colours != 0 && static_cast<int>(n) < m_colours ) ;
92 return m_colours == 0 ?
Gr::Colour() : colour(0U) ;
97 return m_colours == 0 ?
Gr::Colour(255,255,255) : (m_colours==16?colour(1U):colour(255U)) ;
105 void operator()(
int x ,
int y ,
bool b )
107 m_canvas.point( x + m_x , m_canvas.dy() - ( y + m_y ) , b ? m_c : m_b ) ;
119 out o( *
this , x , y , c , black() ) ;
123 unsigned long GX::Canvas::pixel(
const Gr::Colour & c_in )
const
125 return pixel( c_in , m_stereo_mode ) ;
128 unsigned long GX::Canvas::pixel(
const Gr::Colour & c_in , Canvas::Stereo stereo_mode )
const
131 if( stereo_mode == Canvas::left )
136 c = m_colours == 0 ? red_0 : ( m_colours == 16 ? red_16 : red_256 ) ;
138 else if( stereo_mode == Canvas::right )
143 c = m_colours == 0 ? green_0 : ( m_colours == 16 ? green_16 : green_256 ) ;
146 G_ASSERT( (m_colour_map.get()==
nullptr) == (m_colours==0) ) ;
147 if( m_colours != 0 && ( c.
g() || c.
b() ) )
148 G_WARNING_ONCE(
"GX::Canvas::pixel: invalid colour: green and blue components ignored" ) ;
150 return m_colour_map.get() ? m_colour_map->get(c.
r()) : c.
cc() ;
156 m_stereo_mode != Canvas::left && m_stereo_mode != Canvas::right &&
157 m_colour_map.get() ==
nullptr &&
158 m_client_side && m_image.fastable() ;
165 bool pixel_or = m_stereo_mode == Canvas::left || m_stereo_mode == Canvas::right ;
166 m_image.drawPoint( x , m_dy-1-y , pixel(c) , pixel_or ) ;
170 m_context.setForeground( pixel(c) ) ;
171 m_pixmap.drawPoint( m_context , x , m_dy-1-y ) ;
179 bool pixel_or = m_stereo_mode == Canvas::left || m_stereo_mode == Canvas::right ;
180 m_image.drawLine( x0 , m_dy-1-y0 , x1 , m_dy-1-y1 , pixel(c) , pixel_or ) ;
184 m_context.setForeground( pixel(c) ) ;
185 m_pixmap.drawLine( m_context , x0 , m_dy-1-y0 , x1 , m_dy-1-y1 ) ;
192 m_image.drawLineAcross( x_first , x_last , m_dy-1-y , pixel(c) ) ;
194 line( x_first , y , x_last , y , c ) ;
200 m_image.drawLineDown( x , m_dy-1-y_first , m_dy-1-y_last , pixel(c) ) ;
202 line( x , y_first , x , y_last , c ) ;
207 unsigned long pixel = 0UL ;
210 pixel = m_image.readPoint( x , m_dy-1-y ) ;
214 G_WARNING(
"Canvas::readPoint: slow implementation" ) ;
215 unique_ptr<GX::Image> image_ptr ;
216 m_pixmap.readImage( image_ptr ) ;
217 pixel = image_ptr.get()->
readPoint( x , m_dy-1-y ) ;
220 G_ASSERT( (m_colour_map.get()==
nullptr) == (m_colours==0) ) ;
221 if( m_colour_map.get() != nullptr )
223 G_ASSERT( m_colour_map->size() ==
static_cast<unsigned int>(m_colours) ) ;
224 pixel %= m_colour_map->size() ;
225 return Gr::Colour( m_colour_map->find(pixel) , 0U , 0U ) ;
229 Gr::Colour::cc_t cc = pixel ;
238 m_image.clear( to_white ) ;
242 unsigned long pixel = to_white ? white().cc() : black().cc() ;
243 m_context.setForeground( pixel ) ;
244 m_pixmap.drawRectangle( m_context , 0 , 0 , m_dx , m_dy ) ;
251 m_image.blit( m_window , 0 , 0 , m_dx , m_dy , 0 , 0 ) ;
253 m_pixmap.blit( m_window , 0 , 0 , m_dx , m_dy , 0 , 0 ) ;
258 m_stereo_mode = mode ;
Gr::Colour colour(unsigned int n) const
Returns a colour from the palette.
A window class that is-a GX::Drawable and a GX::EventHandler.
value_t r() const
Returns the red value.
void install(GX::ColourMap &)
Installs a colourmap.
void point(int x, int y, Gr::Colour c)
Draws a single pixel.
void lineDown(int x, int y_first, int y_last, const Gr::Colour &c)
Draws a vertical line.
Canvas(GX::Window &, int dx=0, int dy=0, int colours=0, bool server_side=false)
Constructor.
void clear(bool white=false)
Clears the canvas to black (or white).
void blit()
Blits the canvas contents to the window.
void lineAcross(int y, int x_first, int x_last, const Gr::Colour &c)
Draws a horizontal line.
A simple rgb colour structure.
std::pair< unsigned int, unsigned int > aspect() const
Returns the canvas aspect ratio as a fraction (normally about 0.7).
A colourmap class that provides pixel values for a set of mapped colours.
static Colour from(cc_t cc)
Creates a colour from a combined-component value.
int colours() const
Returns the number of colours, as passed in to the ctor.
bool fastable() const
Returns true if fastpoint() can be used rather than point().
GX::Display & windowDisplay()
Returns a reference to the display as passed in to the ctor.
value_t g() const
Returns the green value.
Gr::Colour white() const
Returns white.
int dx() const
Returns the canvas width in pixels.
static bool enabled()
Returns true if test features are enabled.
Gr::Colour readPoint(int x, int y) const
Reads a pixel.
void line(int x0, int y0, int x1, int y1, Gr::Colour c)
Draws a line.
void text(const std::string &s, int x, int y, Gr::Colour c)
Draws a single-line text string at the given position.
A drawing surface that is embedded in a window.
static void output(const std::string &s, Tout &out_functor)
Calls an (x,y,bool) functor for all the glyph points corresponding to the given line of text...
value_t b() const
Returns the blue value.
cc_t cc() const
Returns a combined-component value that incorporates the r(), g() and b() values. ...
unsigned long readPoint(int x, int y) const
Reads a pixel value at a point.
int dy() const
Returns the canvas height in pixels.
Gr::Colour black() const
Returns black.
void stereo(Stereo mode=normal)
Sets the left/right stereo mode for subsequent line() and point() drawing operations.