A tiny drawing library. include line draw and bitmap-font draw.bitmap-font is from linux-kernel-source.
tinydraw.cpp
- Committer:
- tosihisa
- Date:
- 2010-11-06
- Revision:
- 4:68c16070d1db
- Parent:
- 1:c2860a9f58b4
File content as of revision 4:68c16070d1db:
/** * @section LICENSE * * This source code is "GPLv2" license. * The original of the font image is Linux kernel source. * Because the Linux kernel license is "GPLv2 with the exception articles", * this program also applies GPLv2. * * Copyright (C) 2010 tosihisa * * @section DESCRIPTION * * Tiny library of drawing in framebuffer * */ #include "tinydraw.h" TD_COLOR_t *TinyDraw::getVRAMPtr(void) { return &VRAM[0]; } TD_COLOR_t *TinyDraw::getVRAMPtr(TD_POINT_t *pnt) { int pageNo = pnt->y / 8; return &(VRAM[(X_MAX * pageNo) + pnt->x]); } void TinyDraw::drawPoint(TD_XY_t x,TD_XY_t y,TD_COLOR_t fcol) { TD_COLOR_t *byte_ptr; TD_COLOR_t bitmask = 0x80; TD_POINT_t pnt; pnt.x = x; pnt.y = y; byte_ptr = getVRAMPtr(&pnt); bitmask = 0x01 << (y % 8); /* When it is not a transparent shade, it writes it in VRAM. */ if((fcol & COL_TRANS) == 0){ if(fcol != 0x00){ *byte_ptr |= bitmask; /* write 1 */ } else { *byte_ptr &= (~bitmask); /* write 0 */ } } } void TinyDraw::clear(void) { int i; for (i = 0;i < sizeof(VRAM);i++) { VRAM[i] = 0; } } char *TinyDraw::getCharImage(int c,const struct font_desc *fontdesc) { int w; w = (fontdesc->width > 8) ? 2 : 1; return ((char *)fontdesc->data) + ((w*fontdesc->height)*(c & 0xff)); } /* It corresponds only when the width is below 16dots. */ void TinyDraw::drawChar(TD_POINT_t *pnt,int c,TD_COLOR_PAIR_t *col,const struct font_desc *fontdesc) { int w,h; char *imagePtr = getCharImage(c,fontdesc); unsigned long mask = 0; unsigned long maskTbl[] = { 0x80,0x8000 }; unsigned short yline; TD_COLOR_t wcol; for (h = 0;h < fontdesc->height;h++) { mask = maskTbl[ (fontdesc->width - 1) / 8 ]; yline = (unsigned short)(*(imagePtr + 0)); if(fontdesc->width > 8){ yline = yline << 8; yline |= (unsigned short)(*(imagePtr + 1)); } for (w = 0;w < fontdesc->width;w++) { wcol = (yline & mask) ? col->fore : col->back; drawPoint(pnt->x+w,pnt->y+h,wcol); mask = mask >> 1; } imagePtr += (fontdesc->width > 8) ? 2 : 1; } } void TinyDraw::drawStr(TD_POINT_t *pnt,char *str,TD_COLOR_PAIR_t *col,const struct font_desc *fontdesc) { char c; TD_POINT_t tmp = *pnt; int i = 0; for (i = 0;(c = *(str+i)) != (char)('\0');i++) { drawChar(&tmp,c,col,fontdesc); tmp.x += fontdesc->width; } } TD_XY_t TinyDraw::calcAbs(TD_XY_t v) { return (v < 0) ? (0-v) : v; } TD_XY_t TinyDraw::calcMin(TD_XY_t v1,TD_XY_t v2) { return (v1 <= v2) ? v1 : v2; } int TinyDraw::checkSign(TD_XY_t v) { if (v < 0) return -1; else if (v == 0) return 0; return 1; } void TinyDraw::drawLine(TD_POINT_t *p1,TD_POINT_t *p2,TD_COLOR_PAIR_t *col) { TD_XY_t d_x; TD_XY_t d_y; int s_1; int s_2; int i_c = 0; TD_XY_t tmp; long e; TD_XY_t i; TD_XY_t n_x; TD_XY_t n_y; n_x = p1->x; n_y = p1->y; d_x = calcAbs(p2->x - p1->x); d_y = calcAbs(p2->y - p1->y); s_1 = checkSign(p2->x - p1->x); s_2 = checkSign(p2->y - p1->y); if (d_x == 0) { /* vertical */ n_y = calcMin(p1->y,p2->y); for (i=0;i <= d_y;i++) { drawPoint(n_x,n_y,col->fore); n_y++; } } else if (d_y == 0) { /* horizontal */ n_x = calcMin(p1->x,p2->x); for (i=0;i <= d_x;i++) { drawPoint(n_x,n_y,col->fore); n_x++; } } else { i_c = 0; if (d_y > d_x) { tmp = d_x; d_x = d_y; d_y = tmp; i_c = 1; } e = 2 * d_y - d_x; for (i=0;i <= d_x;i++) { drawPoint(n_x,n_y,col->fore); while (e>=0) { if (i_c) { n_x = n_x + s_1; } else { n_y = n_y + s_2; } e = e - 2 * d_x; } if (i_c) { n_y = n_y + s_2; } else { n_x = n_x + s_1; } e = e + 2 * d_y; } } /* last point (or p1 == p2 (1dot)) */ drawPoint(p2->x,p2->y,col->fore); } #if 0 void TinyDraw::drawEllipse( int x0, int y0, int r, int a, int b, int col ) { int x = (int)( (double)r / sqrt( (double)a ) ); int y = 0; double d = sqrt( (double)a ) * (double)r; int F = (int)( -2.0 * d ) + a + 2 * b; int H = (int)( -4.0 * d ) + 2 * a + b; while ( x >= 0 ) { pset( x0 + x, y0 + y, col ); pset( x0 - x, y0 + y, col ); pset( x0 + x, y0 - y, col ); pset( x0 - x, y0 - y, col ); if ( F >= 0 ) { --x; F -= 4 * a * x; H -= 4 * a * x - 2 * a; } if ( H < 0 ) { ++y; F += 4 * b * y + 2 * b; H += 4 * b * y; } } } void TinyDraw::drawCircle( int x0, int y0, int r, unsigned int col ) { int x = r; int y = 0; int F = -2 * r + 3; while ( x >= y ) { pset( x0 + x, y0 + y, col ); pset( x0 - x, y0 + y, col ); pset( x0 + x, y0 - y, col ); pset( x0 - x, y0 - y, col ); pset( x0 + y, y0 + x, col ); pset( x0 - y, y0 + x, col ); pset( x0 + y, y0 - x, col ); pset( x0 - y, y0 - x, col ); if ( F >= 0 ) { x--; F -= 4 * x; } y++; F += 4 * y + 2; } } void TinyDraw::rotatePoint(int p1x,int p1y,int cx,int cy,double deg,int *p2x,int *p2y) { double xl1; double yl1; double xl2; double yl2; double _rad = deg * PI / 180; double _cos_rad = cos(_rad); double _sin_rad = sin(_rad); xl1 = p1x - cx; yl1 = p1y - cy; xl2 = (_cos_rad*xl1) - (_sin_rad*yl1); yl2 = (_sin_rad*xl1) - (_cos_rad*yl1); *p2x = cx + (int)xl2; *p2y = cy + (int)yl2; } #endif