7 #ifndef BMPTK_GRAPHICS_H
8 #define BMPTK_GRAPHICS_H
56 static int sign(
short int x ){
57 return ( x > 0 ) - (x < 0); }
60 static bool is_within(
short int x,
short int m ){
61 return (( x >= 0 ) && ( x < m )) || (( x <= 0 ) && ( x > m )); }
75 vector(
short int x,
short int y ): x( x ), y( y ) {}
78 short int x_get()
const {
return x; }
81 short int y_get()
const {
return y; }
85 return vector( x + p.x, y + p.y ); }
89 return vector( x += p.x, y += p.y ); }
97 return vector( x - p.x, y - p.y ); }
101 return vector( x -= p.x, y -= p.y ); }
105 return vector( - x, - y ); }
109 return vector( x / n, y / n ); }
120 return vector( x * n, y * n ); }
131 return vector( x * rhs.x, y * rhs.y ); }
135 return ( x == p.x ) && ( y == p.y ); }
139 return ! ( *
this == p ); }
148 return vector( sign( x ), sign( y )); }
160 ( y >= 0 ) ? y : -y );
188 return is_within( x, p.x ) && is_within( y, p.y ); }
223 std::ostream &
operator<< ( std::ostream &
s,
const vector p );
261 static int clip(
int x ){
262 return ( x < 0 ) ? 0 : ( x > 0xFF ? 0xFF : x ); }
278 color(
int r,
int g,
int b,
bool t = 0 ):
279 transp( t ), r( clip( r )), g( clip( g )), b( clip( b ))
281 if( t ){ r = g = b = 0; }
289 r( clip( ( rgb & 0xFF0000 ) >> 16 )),
290 g( clip( ( rgb & 0x00FF00 ) >> 8 )),
291 b( clip( ( rgb & 0x0000FF ) >> 0 )){}
296 ((
unsigned int)( r & 0xF8 ) >> 3 )
297 | ((
unsigned int)( g & 0xF8 ) << 2 )
298 | ((
unsigned int)( b & 0xF8 ) << 7 )
331 transp && c.transp ); }
335 r = clip( r + (
int)c.r );
336 g = clip( g + (
int)c.g );
337 b = clip( b + (
int)c.b );
338 transp = transp && c.transp;
344 return color( r, g, b, transp ); }
352 transp && c.transp ); }
356 r = clip( r - (
int)c.r );
357 g = clip( g - (
int)c.g );
358 b = clip( b - (
int)c.b );
359 transp = transp && c.transp;
373 return color( r / n, g / n, b / n, transp ); }
385 return color( r * n, g * n, b * n, transp ); }
397 return transp ? c.transp :
398 ( ! c.transp ) && ( r == c.r ) && ( g == c.g ) && ( b == c.b ); }
402 return ! ( *
this == c ); }
410 transp && c.transp ); }
446 std::ostream &
operator << ( std::ostream &
s,
const color c );
519 const char * event_type_name(
const event_type e );
525 std::ostream &
operator<<( std::ostream &
s,
const event_type &e );
564 location( p ), e( e ) {}
580 std::ostream &
operator<<( std::ostream &
s,
const event &e );
651 unsigned int width = 1
684 virtual void draw()
const = 0;
746 return p.is_within(
size ); }
890 if( ! pixel( p ).is_transparent() ){
891 f.
write( p, pixel( p ));
1011 frame &f1, &f2, &f3, &f4;
1013 static frame & frame_dummy_ref(){
1024 frame &f3 = frame_dummy_ref(),
1025 frame &f4 = frame_dummy_ref()
1083 static color default_filter(
color c ){
return c; }
1108 writer( f, p, filter( c ), bg );
1171 const unsigned int scale;
1215 unsigned int scale = 1,
1219 frame( direction.abs() ),
1221 top_left( top_left ),
1222 bottom_right( top_left + direction - direction.direction() ),
1239 for(
unsigned int x = 0; x < scale; x++ ){
1240 for(
unsigned int y = 0; y < scale; y++ ){
1283 const color fg = color::black(),
1290 color::transparent(),
1350 void operator=(
const rectangle & rhs );
1383 const color fg = color::black(),
1384 const color bg = color::transparent(),
1388 drawable( frame, position, fg, bg, width ),
1420 void circle_draw_pixel(
1438 unsigned int radius,
1439 const color fg = color::black(),
1440 const color bg = color::transparent(),
1441 unsigned int width = 1
1443 drawable( frame, position, fg, bg, width ), radius( radius ){}
1475 const vector position = vector::origin() )
const = 0;
1507 virtual color checked_read(
const vector p )
const = 0;
1519 return p.is_within( size ); }
1528 const vector position = vector::origin() )
const;
1537 return checked_read( p );
1539 return color::transparent();
1564 const unsigned char *data;
1604 const unsigned char *data;
1611 bool bool_read(
const vector p )
const;
1624 const unsigned char *data
1629 fg = color::black();
1630 bg = color::white();
1637 return bool_read( p ) ? fg : bg; }
1671 fixed( fixed ), proportional( ! fixed ), font_char_size( char_size ){}
1677 virtual bool has(
char c )
const = 0;
1680 virtual bool read(
char c,
const vector p )
const = 0;
1686 virtual vector char_size(
char c )
const = 0;
1731 const color fg = color::black(),
1732 const color bg = color::transparent()
1743 return f.
read( c, p ) ? fg : bg; }
1801 const unsigned char *data
1803 font( fixed, char_size ),
1810 if( ( c <
' ' ) || ( c >= 127 ) )
return false;
1811 return start[ (int) c - 32 ] >= 0;
1815 vector char_size(
char c )
const;
1818 bool read(
char c,
const vector p )
const;
1850 const inline_font & font_default();
1917 unsigned int scale = 1,
1918 vector spacing = vector::origin(),
1921 color fg = color::black(),
1922 color bg = color::transparent()
1930 top_left_margin( top_left_margin ),
1931 bottom_right_margin( bottom_right_margin ),
1943 spacing( fmt.spacing ),
1944 top_left_margin( fmt.top_left_margin ),
1945 bottom_right_margin( fmt.bottom_right_margin ),
1952 std::ostream &
operator<<( std::ostream &s,
const format &f );
1998 void draw( frame &f,
const vector position = vector::origin() )
const;
2003 class frame_console_stringbuf :
public std::streambuf {
2009 void print(
char c );
2010 std::streamsize xsputn (
const char * s, std::streamsize n );
2014 frame_console_stringbuf( frame &fr, format fm ):
2035 frame_console_stringbuf buf;
2068 class sheet_base :
public drawable {
2070 const char * buffer;
2078 template<
unsigned int charsize >
class sheet :
public sheet_base {
2079 char buffer[ charsize + 1 ];
2081 sheet( ): sheet_base( , ){}
2094 widget * children, * next_child;
2096 const widget *toplevel, *parent;
2100 widget( widget * toplevel, widget * parent, frame *f ):
2101 children( 0 ), next_child( 0 ),
2102 toplevel( toplevel ), parent( parent ),
2103 inner( f ), changed( 1 )
2106 widget( widget * parent, frame *f ):
2107 children( 0 ), next_child( 0 ),
2108 toplevel( parent->toplevel ), parent( parent ),
2109 inner( f ), changed( 1 )
2111 parent->add(
this ); }
2113 void add( widget * w ){
2114 w->next_child = children;
2117 void redraw(
bool forced = 0 ){
2124 for( widget *w = children; w != 0; w = w->next_child ){
2125 w->redraw( changed );
2130 virtual void handle(
const event &e ){
2131 for( widget *w = children; w != 0; w = w->next_child ){
2132 event ew( w->inner->translate(
2134 e.event_type_get() );
2135 if( ew.location_get().is_within( w->inner->size_get() )){
2141 virtual void draw(
void ){};
2152 class wframe :
public widget {
2164 const vector &origin = vector( 0, 0 ),
2165 const color &bg = color::red(),
2166 const relief border = relief_raised
2168 widget( &parent, &subf ),
2169 subf( *parent.inner, origin, origin + size ),
2176 void handle(
const event &e ){
2180 border = flip( border );
2197 class wpaint :
public widget {
2209 const vector origin = vector( 0, 0 ),
2210 const color &bg = color::red(),
2211 const color &fg = color::blue()
2213 widget( &parent, &subf ),
2214 subf( *parent.inner, origin, origin + size ),
2220 void handle(
const event &e ){
2222 inner->write( e.location_get(), fg );
2241 class wtoplevel :
public widget {
2245 wtoplevel( frame &f,
const color &bg ):
2246 widget( this, this, &f ), bg( bg ) {}
2248 virtual event event_get(
void ) = 0;
2251 inner->clear( bg ); }
2260 #endif // #ifdef BMPTK_GRAPHICS_H