A tiny drawing library. include line draw and bitmap-font draw.bitmap-font is from linux-kernel-source.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tinydraw.cpp Source File

tinydraw.cpp

00001 
00002 /**
00003  * @section LICENSE
00004  *
00005  * This source code is "GPLv2" license. 
00006  * The original of the font image is Linux kernel source. 
00007  * Because the Linux kernel license is "GPLv2 with the exception articles",
00008  * this program also applies GPLv2. 
00009  *
00010  * Copyright (C) 2010 tosihisa
00011  *
00012  * @section DESCRIPTION
00013  *
00014  * Tiny library of drawing in framebuffer
00015  *
00016  */
00017 
00018 #include "tinydraw.h"
00019 
00020 TD_COLOR_t *TinyDraw::getVRAMPtr(void) {
00021     return &VRAM[0];
00022 }
00023 
00024 TD_COLOR_t *TinyDraw::getVRAMPtr(TD_POINT_t *pnt) {
00025     int pageNo = pnt->y / 8;
00026     return &(VRAM[(X_MAX * pageNo) + pnt->x]);
00027 }
00028 
00029 void TinyDraw::drawPoint(TD_XY_t x,TD_XY_t y,TD_COLOR_t fcol) {
00030     TD_COLOR_t *byte_ptr;
00031     TD_COLOR_t bitmask = 0x80;
00032     TD_POINT_t pnt;
00033 
00034     pnt.x = x;
00035     pnt.y = y;
00036     byte_ptr = getVRAMPtr(&pnt);
00037     bitmask = 0x01 << (y % 8);
00038 
00039     /* When it is not a transparent shade, it writes it in VRAM. */
00040     if((fcol & COL_TRANS) == 0){
00041         if(fcol != 0x00){
00042             *byte_ptr |= bitmask;        /* write 1 */
00043         } else {
00044             *byte_ptr &= (~bitmask);    /* write 0 */
00045         }
00046     }
00047 }
00048 
00049 void TinyDraw::clear(void) {
00050     int i;
00051     for (i = 0;i < sizeof(VRAM);i++) {
00052         VRAM[i] = 0;
00053     }
00054 }
00055 
00056 char *TinyDraw::getCharImage(int c,const struct font_desc *fontdesc) {
00057     int w;
00058     w = (fontdesc->width > 8) ? 2 : 1;
00059     return ((char *)fontdesc->data) + ((w*fontdesc->height)*(c & 0xff));
00060 }
00061 
00062 /* It corresponds only when the width is below 16dots. */
00063 void TinyDraw::drawChar(TD_POINT_t *pnt,int c,TD_COLOR_PAIR_t *col,const struct font_desc *fontdesc) {
00064     int w,h;
00065     char *imagePtr = getCharImage(c,fontdesc);
00066     unsigned long mask = 0;
00067     unsigned long maskTbl[] = { 0x80,0x8000 };
00068     unsigned short yline;
00069     TD_COLOR_t wcol;
00070 
00071     for (h = 0;h < fontdesc->height;h++) {
00072         mask = maskTbl[ (fontdesc->width - 1) / 8 ];
00073         yline = (unsigned short)(*(imagePtr + 0));
00074         if(fontdesc->width > 8){
00075             yline = yline << 8;
00076             yline |= (unsigned short)(*(imagePtr + 1));
00077         }
00078         for (w = 0;w < fontdesc->width;w++) {
00079             wcol = (yline & mask) ? col->fore : col->back;
00080             drawPoint(pnt->x+w,pnt->y+h,wcol);
00081             mask = mask >> 1;
00082         }
00083         imagePtr += (fontdesc->width > 8) ? 2 : 1;
00084     }
00085 }
00086 
00087 void TinyDraw::drawStr(TD_POINT_t *pnt,char *str,TD_COLOR_PAIR_t *col,const struct font_desc *fontdesc) {
00088     char c;
00089     TD_POINT_t tmp = *pnt;
00090     int i = 0;
00091     for (i = 0;(c = *(str+i)) != (char)('\0');i++) {
00092         drawChar(&tmp,c,col,fontdesc);
00093         tmp.x += fontdesc->width;
00094     }
00095 }
00096 
00097 TD_XY_t TinyDraw::calcAbs(TD_XY_t v) {
00098     return (v < 0) ? (0-v) : v;
00099 }
00100 
00101 TD_XY_t TinyDraw::calcMin(TD_XY_t v1,TD_XY_t v2) {
00102     return (v1 <= v2) ? v1 : v2;
00103 }
00104 
00105 int TinyDraw::checkSign(TD_XY_t v) {
00106     if (v < 0)
00107         return -1;
00108     else if (v == 0)
00109         return 0;
00110     return 1;
00111 }
00112 
00113 void TinyDraw::drawLine(TD_POINT_t *p1,TD_POINT_t *p2,TD_COLOR_PAIR_t *col) {
00114     TD_XY_t d_x;
00115     TD_XY_t d_y;
00116     int s_1;
00117     int s_2;
00118     int i_c = 0;
00119     TD_XY_t tmp;
00120     long e;
00121     TD_XY_t i;
00122     TD_XY_t n_x;
00123     TD_XY_t n_y;
00124 
00125     n_x = p1->x;
00126     n_y = p1->y;
00127     d_x = calcAbs(p2->x - p1->x);
00128     d_y = calcAbs(p2->y - p1->y);
00129     s_1 = checkSign(p2->x - p1->x);
00130     s_2 = checkSign(p2->y - p1->y);
00131 
00132     if (d_x == 0) {
00133         /* vertical */
00134         n_y = calcMin(p1->y,p2->y);
00135         for (i=0;i <= d_y;i++) {
00136             drawPoint(n_x,n_y,col->fore);
00137             n_y++;
00138         }
00139     } else if (d_y == 0) {
00140         /* horizontal */
00141         n_x = calcMin(p1->x,p2->x);
00142         for (i=0;i <= d_x;i++) {
00143             drawPoint(n_x,n_y,col->fore);
00144             n_x++;
00145         }
00146     } else {
00147         i_c = 0;
00148         if (d_y > d_x) {
00149             tmp = d_x;
00150             d_x = d_y;
00151             d_y = tmp;
00152             i_c = 1;
00153         }
00154 
00155         e = 2 * d_y - d_x;
00156         for (i=0;i <= d_x;i++) {
00157             drawPoint(n_x,n_y,col->fore);
00158             while (e>=0) {
00159                 if (i_c) {
00160                     n_x = n_x + s_1;
00161                 } else {
00162                     n_y = n_y + s_2;
00163                 }
00164                 e = e - 2 * d_x;
00165             }
00166             if (i_c) {
00167                 n_y = n_y + s_2;
00168             } else {
00169                 n_x = n_x + s_1;
00170             }
00171             e = e + 2 * d_y;
00172         }
00173     }
00174     /* last point (or p1 == p2 (1dot)) */
00175     drawPoint(p2->x,p2->y,col->fore);
00176 }
00177 
00178 #if 0
00179 void TinyDraw::drawEllipse( int x0, int y0, int r, int a, int b, int col )
00180 {
00181   int x = (int)( (double)r / sqrt( (double)a ) );
00182   int y = 0;
00183   double d = sqrt( (double)a ) * (double)r;
00184   int F = (int)( -2.0 * d ) +     a + 2 * b;
00185   int H = (int)( -4.0 * d ) + 2 * a     + b;
00186 
00187   while ( x >= 0 ) {
00188     pset( x0 + x, y0 + y, col );
00189     pset( x0 - x, y0 + y, col );
00190     pset( x0 + x, y0 - y, col );
00191     pset( x0 - x, y0 - y, col );
00192     if ( F >= 0 ) {
00193       --x;
00194       F -= 4 * a * x;
00195       H -= 4 * a * x - 2 * a;
00196     }
00197     if ( H < 0 ) {
00198       ++y;
00199       F += 4 * b * y + 2 * b;
00200       H += 4 * b * y;
00201     }
00202   }
00203 }
00204 
00205 void TinyDraw::drawCircle( int x0, int y0, int r, unsigned int col )
00206 {
00207   int x = r;
00208   int y = 0;
00209   int F = -2 * r + 3;
00210 
00211   while ( x >= y ) {
00212     pset( x0 + x, y0 + y, col );
00213     pset( x0 - x, y0 + y, col );
00214     pset( x0 + x, y0 - y, col );
00215     pset( x0 - x, y0 - y, col );
00216     pset( x0 + y, y0 + x, col );
00217     pset( x0 - y, y0 + x, col );
00218     pset( x0 + y, y0 - x, col );
00219     pset( x0 - y, y0 - x, col );
00220     if ( F >= 0 ) {
00221       x--;
00222       F -= 4 * x;
00223     }
00224     y++;
00225     F += 4 * y + 2;
00226   }
00227 }
00228 
00229 void TinyDraw::rotatePoint(int p1x,int p1y,int cx,int cy,double deg,int *p2x,int *p2y)
00230 {
00231     double xl1;
00232     double yl1;
00233     double xl2;
00234     double yl2;
00235     double _rad = deg * PI / 180;
00236     double _cos_rad = cos(_rad);
00237     double _sin_rad = sin(_rad);
00238 
00239     xl1 = p1x - cx;
00240     yl1 = p1y - cy;
00241 
00242     xl2 = (_cos_rad*xl1) - (_sin_rad*yl1);
00243     yl2 = (_sin_rad*xl1) - (_cos_rad*yl1);
00244     *p2x = cx + (int)xl2;
00245     *p2y = cy + (int)yl2;
00246 }
00247 #endif