File indexing completed on 2026-04-09 07:49:31
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <cassert>
0024 #include <cstring>
0025 #include <cstdlib>
0026 #include <cstdio>
0027
0028 struct scanvas
0029 {
0030 bool verbose ;
0031 unsigned width ;
0032 unsigned height ;
0033 unsigned xscale ;
0034 unsigned yscale ;
0035 unsigned nx ;
0036 unsigned ny ;
0037 char* c ;
0038
0039 scanvas( unsigned width, unsigned height, unsigned xscale=8, unsigned yscale=4 );
0040 void resize(unsigned width, unsigned height);
0041 void clear();
0042 void drawtest();
0043
0044 void drawf( int ix, int iy, int dx, int dy, float val , const char* fmt="%7.2f" );
0045 void draw( int ix, int iy, int dx, int dy, int val);
0046 void drawch( int ix, int iy, int dx, int dy, char ch);
0047 void draw( int ix, int iy, int dx, int dy, const char* txt);
0048 void _draw( int ix, int iy, int dx, int dy, const char* txt);
0049
0050 void print(const char* msg=nullptr) const ;
0051 const char* desc() const ;
0052 };
0053
0054
0055 inline scanvas::scanvas(unsigned width_, unsigned height_, unsigned xscale_, unsigned yscale_)
0056 :
0057 verbose(getenv("VERBOSE")!=nullptr),
0058 xscale(xscale_),
0059 yscale(yscale_),
0060 nx(0),
0061 ny(0),
0062 c(nullptr)
0063 {
0064 resize(width_, height_);
0065 }
0066
0067 inline void scanvas::resize(unsigned width_, unsigned height_)
0068 {
0069 width = width_ ;
0070 height = height_ ;
0071 nx = width*xscale+1 ;
0072 ny = height*yscale ;
0073 if(verbose)
0074 printf("scanvas::resize width %d height %d nx %d ny %d nx*ny %d xscale %d yscale %d \n", width, height, nx, ny, nx*ny, xscale, yscale );
0075 delete [] c ;
0076 c = new char[nx*ny+1] ;
0077 clear();
0078 }
0079
0080 inline void scanvas::clear()
0081 {
0082 for(unsigned y=0 ; y < ny ; y++) for(unsigned x=0 ; x < nx ; x++) c[y*nx+x] = ' ' ;
0083 for(unsigned y=0 ; y < ny ; y++) c[y*nx+nx-1] = '\n' ;
0084 c[nx*ny] = '\0' ;
0085 }
0086
0087 inline void scanvas::drawtest()
0088 {
0089 for(int ix=0 ; ix < int(width) ; ix++ )
0090 for(int iy=0 ; iy < int(height) ; iy++ )
0091 {
0092 for(int dx=0 ; dx < int(xscale) ; dx++)
0093 for(int dy=0 ; dy < int(yscale) ; dy++)
0094 {
0095 draw(ix,iy,dx,dy, dx);
0096 }
0097 }
0098 }
0099
0100
0101
0102 inline void scanvas::drawf(int ix, int iy, int dx, int dy, float val, const char* fmt )
0103 {
0104 char tmp[16] ;
0105 int rc = sprintf(tmp, fmt, val );
0106 bool expect = rc == int(strlen(tmp)) ;
0107 assert( expect );
0108 if(!expect) exit(EXIT_FAILURE) ;
0109
0110 bool expect_xscale = xscale > 7 ;
0111 if(!expect_xscale) printf("scanvas::_draw expect_xscale when drawing floats an xscale of at least 8 is needed xscale %d \n", xscale) ;
0112
0113
0114 _draw(ix, iy, dx, dy, tmp);
0115 }
0116
0117 inline void scanvas::draw(int ix, int iy, int dx, int dy, int val)
0118 {
0119 char tmp[16] ;
0120 int rc = sprintf(tmp, "%d", val );
0121 bool expect = rc == int(strlen(tmp)) ;
0122 assert( expect );
0123 if(!expect) exit(EXIT_FAILURE) ;
0124
0125 _draw(ix, iy, dx, dy, tmp);
0126 }
0127
0128 inline void scanvas::drawch(int ix, int iy, int dx, int dy, char ch)
0129 {
0130 char tmp[2];
0131 tmp[0] = ch ;
0132 tmp[1] = '\0' ;
0133 _draw(ix, iy, dx, dy, tmp);
0134 }
0135 inline void scanvas::draw(int ix, int iy, int dx, int dy, const char* txt)
0136 {
0137 _draw(ix, iy, dx, dy, txt);
0138 }
0139
0140 inline void scanvas::_draw(int ix, int iy, int dx, int dy, const char* txt)
0141 {
0142 if( ix < 0 ) ix += width ;
0143 if( iy < 0 ) iy += height ;
0144 if( dx < 0 ) dx += xscale ;
0145 if( dy < 0 ) dy += yscale ;
0146
0147 bool expect_ix = ix >= 0 && ix < int(width) ;
0148 bool expect_iy = iy >= 0 && iy < int(height) ;
0149 bool expect_dx = dx >= 0 && dx < int(xscale) ;
0150 bool expect_dy = dy >= 0 && dy < int(yscale) ;
0151
0152 bool expect = expect_ix && expect_iy && expect_dx && expect_dy ;
0153
0154 if(!expect) printf("scanvas::_draw ix %d width %d iy %d height %d dx %d xscale %d dy %d yscale %d \n", ix, width, iy, height, dx, xscale, dy, yscale );
0155 if(!expect) return ;
0156
0157
0158
0159
0160
0161 int x = ix*xscale + dx ;
0162 int y = iy*yscale + dy ;
0163 int l = strlen(txt) ;
0164
0165 bool expect_x = x + l < int(nx) ;
0166 bool expect_y = y < int(ny) ;
0167
0168 if(!expect_x) printf("scanvas::_draw expect_x ERROR out of range ix %d xscale %d dx %d x %d l %d x+l %d nx %d txt [%s] \n", ix, xscale, dx, x, l, x+l, nx, txt );
0169 if(!expect_y) printf("scanvas::_draw expect_y ERROR out of range y %d ny %d \n", y, ny );
0170
0171
0172
0173
0174 if(!expect_x) return ;
0175 if(!expect_y) return ;
0176
0177
0178
0179 int offset = y*nx + x ;
0180 bool expect_offset = offset >= 0 && offset + l < int(nx*ny) ;
0181
0182 if(!expect_offset) printf("scanvas::_draw error out of range offset+l %d nx*ny %d \n", offset+l, nx*ny ) ;
0183
0184
0185
0186 if(!expect_offset) return ;
0187
0188
0189 memcpy( c + offset , txt, l );
0190 }
0191
0192 inline void scanvas::print(const char* msg) const
0193 {
0194 if(msg) printf("%s\n", msg);
0195 if(verbose)
0196 printf("\n[\n%s]\n",c);
0197 else
0198 printf("\n%s",c);
0199 }
0200
0201 inline const char* scanvas::desc() const
0202 {
0203 char msg[200] ;
0204 snprintf(msg, 200, "scanvas::desc width %d height %d xscale %d yscale %d nx %d ny %d", width, height, xscale, yscale, nx, ny );
0205 return strdup(msg);
0206 }
0207