work fine

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Microduino_Matrix.cpp Source File

Microduino_Matrix.cpp

00001 // 本作品采用知识共享 署名-非商业性使用-相同方式共享 3.0 未本地化版本 许可协议进行许可
00002 // 访问 http://creativecommons.org/licenses/by-nc-sa/3.0/ 查看该许可协议
00003 // ==============
00004 
00005 // 版权所有:
00006 // @老潘orz  wasdpkj@hotmail.com
00007 // ==============
00008 
00009 // Microduino-IDE
00010 // ==============
00011 // Microduino Getting start:
00012 // http://www.microduino.cc/download/
00013 
00014 // Microduino IDE Support:
00015 // https://github.com/wasdpkj/Microduino-IDE-Support/
00016 
00017 // ==============
00018 // Microduino wiki:
00019 // http://wiki.microduino.cc
00020 
00021 // ==============
00022 // E-mail:
00023 // Kejia Pan
00024 // pankejia@microduino.cc
00025 
00026 // ==============
00027 // Weibo:
00028 // @老潘orz
00029 
00030 #include "Microduino_Matrix.h"
00031 #include "Fonts.h"
00032 
00033 extern Serial pc;
00034 
00035 #define read16(Y,Z)  (uint16_t)((uint8_t)pgm_read_byte((Y) + (Z++)) | ((uint8_t)pgm_read_byte((Y) + (Z++)) << 8))
00036 #define read32(Y,Z) (uint32_t)((uint8_t)pgm_read_byte((Y) + (Z++)) | ((uint8_t)pgm_read_byte((Y) + (Z++)) << 8) | ((uint8_t)pgm_read_byte((Y) + (Z++)) << 16) | ((uint8_t)pgm_read_byte((Y) + (Z++)) << 24))
00037 #define BUFFPIXEL (MatrixPix_X * 8 * 3)
00038 
00039 Matrix::Matrix(uint8_t (*_addr)[8])
00040 {
00041     //  uint8_t (*p)[10]=_addr;
00042     uint8_t _x = 0, _y = 0;
00043     for (uint8_t a = 0; a < 8; a++) { //判断第一层
00044         if (_addr[0][a] == 0) {
00045 
00046             break;  //NULL,结束当前层判断
00047         } else {
00048             _x = a + 1;
00049             for (uint8_t b = 0; b < 8; b++) { //判断第二层
00050                 if (_addr[b][a] == 0) {
00051                     break;  //NULL,结束当前层判断
00052                 } else {
00053                     _y = b + 1;
00054                 }
00055             }
00056         }
00057     }
00058 
00059     this->_numX = _x;
00060     this->_numY = _y;
00061 
00062     this->_matrixNum = this->_numX * this->_numY;
00063     led = new LedControl[this->_matrixNum];
00064 
00065     this->cursor_y = 0;
00066     this->cursor_x = 0;
00067 
00068     uint8_t _p[64];
00069     for (int a = 0; a < this->_numY; a++) {
00070         for (int b = 0; b < this->_numX ; b++) {
00071             uint8_t _s = b + a * this->_numX ;
00072             _p[_s] = _addr[a][b];
00073         }
00074     }
00075     setDeviceAddr(_p);
00076 
00077     clearFastMode();
00078     clearColor();
00079     setFontMode(true);
00080 }
00081 
00082 uint8_t Matrix::getDeviceAddr(uint8_t _a)
00083 {
00084     return led[_a].getDeviceAddr();
00085 }
00086 
00087 void Matrix::setDeviceAddr(uint8_t* _addr)
00088 {
00089     for (int a = 0; a < getMatrixNum(); a++)
00090         led[a].setDeviceAddr(_addr[a]);
00091 }
00092 
00093 void Matrix::clearDisplay()
00094 {
00095     for (int a = 0; a < getMatrixNum(); a++)
00096         led[a].clearDisplay();
00097 }
00098 
00099 void Matrix::setLedColor(uint8_t _row, uint8_t _col, uint8_t _value_r, uint8_t _value_g, uint8_t _value_b)
00100 {
00101     if((_col > (getHeight() * 8 - 1)) || (_row > (getWidth() * 8 - 1)))
00102         return;
00103     int16_t _s = (_row / 8) + (_col / 8) * getWidth();
00104     led[_s].setLedColor(_row % 8, _col % 8, _value_r, _value_g, _value_b);
00105 }
00106 
00107 void Matrix::setLedColorFast(uint8_t _row, uint8_t _col, uint8_t _value_r, uint8_t _value_g, uint8_t _value_b)
00108 {
00109     if((_col > (getHeight() * 8 - 1)) || (_row > (getWidth() * 8 - 1)))
00110         return;
00111     int16_t _s = (_row / 8) + (_col / 8) * getWidth();
00112     led[_s].setLedColorFast(_row % 8, _col % 8, _value_r, _value_g, _value_b);
00113 }
00114 
00115 void Matrix::setLed(uint8_t _row, uint8_t _col, bool _state)
00116 {
00117     if((_col > (getHeight() * 8 - 1)) || (_row > (getWidth() * 8 - 1)))
00118         return;
00119     int16_t _s = (_row / 8) + (_col / 8) * getWidth();
00120     led[_s].setLed(_row % 8, _col % 8, _state);
00121 }
00122 
00123 void Matrix::setCursor(int16_t _x, int16_t _y)
00124 {
00125     this->cursor_x = _x;
00126     this->cursor_y = _y;
00127 
00128     for (int _y = 0; _y < getHeight(); _y++) {
00129         for (int _x = 0; _x < getWidth(); _x++) {
00130             uint8_t _s = _x + _y * getWidth();
00131             led[_s].setCursor(-(8 * _x) + this->cursor_x, -(8 * _y) + this->cursor_y);
00132         }
00133     }
00134 }
00135 
00136 void Matrix::setFastMode()
00137 {
00138     //  runFun(&setFastMode);
00139     //  this->Fast_mode = true;
00140     for (int a = 0; a < getMatrixNum(); a++)
00141         led[a].setFastMode();
00142 }
00143 
00144 void Matrix::clearFastMode()
00145 {
00146     //  this->Fast_mode = false;
00147     for (int a = 0; a < getMatrixNum(); a++)
00148         led[a].clearFastMode();
00149 }
00150 
00151 void Matrix::setFontMode(bool _Mode)
00152 {
00153     for (int a = 0; a < getMatrixNum(); a++)
00154         led[a].setFontMode(_Mode);
00155 }
00156 
00157 void Matrix::setColor(uint8_t value_r, uint8_t value_g, uint8_t value_b)
00158 {
00159     for (int a = 0; a < getMatrixNum(); a++)
00160         led[a].setColor(value_r, value_g, value_b);
00161 }
00162 
00163 void Matrix::clearColor()
00164 {
00165     for (int a = 0; a < getMatrixNum(); a++)
00166         led[a].clearColor();
00167 }
00168 
00169 void Matrix::drawLine(int8_t x1, int8_t y1, int8_t x2, int8_t y2)
00170 {
00171     uint8_t tmp;
00172     uint8_t x, y;
00173     uint8_t dx, dy;
00174     int8_t err;
00175     int8_t ystep;
00176 
00177     uint8_t swapxy = 0;
00178 
00179     /* no BBX intersection check at the moment, should be added... */
00180 
00181     if ( x1 > x2 ) dx = x1 - x2;
00182     else dx = x2 - x1;
00183     if ( y1 > y2 ) dy = y1 - y2;
00184     else dy = y2 - y1;
00185 
00186     if ( dy > dx ) {
00187         swapxy = 1;
00188         tmp = dx;
00189         dx = dy;
00190         dy = tmp;
00191         tmp = x1;
00192         x1 = y1;
00193         y1 = tmp;
00194         tmp = x2;
00195         x2 = y2;
00196         y2 = tmp;
00197     }
00198     if ( x1 > x2 ) {
00199         tmp = x1;
00200         x1 = x2;
00201         x2 = tmp;
00202         tmp = y1;
00203         y1 = y2;
00204         y2 = tmp;
00205     }
00206     err = dx >> 1;
00207     if ( y2 > y1 ) ystep = 1;
00208     else ystep = -1;
00209     y = y1;
00210     for ( x = x1; x <= x2; x++ ) {
00211         if ( swapxy == 0 )
00212             setLed(x, y, 1);
00213         else
00214             setLed(y, x, 1);
00215         err -= (uint8_t)dy;
00216         if ( err < 0 ) {
00217             y += (uint8_t)ystep;
00218             err += (uint8_t)dx;
00219         }
00220     }
00221 }
00222 
00223 void Matrix::drawCircle_section(int8_t x, int8_t y, int8_t x0, int8_t y0, uint8_t option)
00224 {
00225     /* upper right */
00226     if ( option & U8G_DRAW_UPPER_RIGHT ) {
00227         setLed(x0 + x, y0 - y, 1);
00228         setLed(x0 + y, y0 - x, 1);
00229     }
00230 
00231     /* upper left */
00232     if ( option & U8G_DRAW_UPPER_LEFT ) {
00233         setLed(x0 - x, y0 - y, 1);
00234         setLed(x0 - y, y0 - x, 1);
00235     }
00236 
00237     /* lower right */
00238     if ( option & U8G_DRAW_LOWER_RIGHT ) {
00239         setLed(x0 + x, y0 + y, 1);
00240         setLed(x0 + y, y0 + x, 1);
00241     }
00242 
00243     /* lower left */
00244     if ( option & U8G_DRAW_LOWER_LEFT ) {
00245         setLed(x0 - x, y0 + y, 1);
00246         setLed(x0 - y, y0 + x, 1);
00247     }
00248 }
00249 
00250 void Matrix::drawVLine(int8_t x, int8_t y, int8_t w)
00251 {
00252     if(w<=0)
00253         return;
00254 
00255     while (w--) {
00256         setLed(x, y + w, 1);
00257     }
00258 }
00259 
00260 void Matrix::drawHLine(int8_t x, int8_t y, int8_t h)
00261 {
00262     if(h<=0)
00263         return;
00264 
00265     while (h--) {
00266         setLed(x + h, y, 1);
00267     }
00268 }
00269 
00270 void Matrix::drawDisc_section(int8_t x, int8_t y, int8_t x0, int8_t y0, uint8_t option)
00271 {
00272     /* upper right */
00273     if ( option & U8G_DRAW_UPPER_RIGHT ) {
00274         drawVLine(x0 + x, y0 - y, y + 1);
00275         drawVLine(x0 + y, y0 - x, x + 1);
00276     }
00277 
00278     /* upper left */
00279     if ( option & U8G_DRAW_UPPER_LEFT ) {
00280         drawVLine(x0 - x, y0 - y, y + 1);
00281         drawVLine(x0 - y, y0 - x, x + 1);
00282     }
00283 
00284     /* lower right */
00285     if ( option & U8G_DRAW_LOWER_RIGHT ) {
00286         drawVLine(x0 + x, y0, y + 1);
00287         drawVLine(x0 + y, y0, x + 1);
00288     }
00289 
00290     /* lower left */
00291     if ( option & U8G_DRAW_LOWER_LEFT ) {
00292         drawVLine(x0 - x, y0, y + 1);
00293         drawVLine(x0 - y, y0, x + 1);
00294     }
00295 }
00296 
00297 void Matrix::drawCircle(int8_t x0, int8_t y0, int8_t rad, int8_t option)
00298 {
00299     if(rad<=0)
00300         return;
00301 
00302     int8_t f;
00303     int8_t ddF_x;
00304     int8_t ddF_y;
00305     uint8_t x;
00306     uint8_t y;
00307 
00308     f = 1;
00309     f -= rad;
00310     ddF_x = 1;
00311     ddF_y = 0;
00312     ddF_y -= rad;
00313     ddF_y *= 2;
00314     x = 0;
00315     y = rad;
00316 
00317     drawCircle_section(x, y, x0, y0, option);
00318 
00319     while ( x < y ) {
00320         if (f >= 0) {
00321             y--;
00322             ddF_y += 2;
00323             f += ddF_y;
00324         }
00325         x++;
00326         ddF_x += 2;
00327         f += ddF_x;
00328 
00329         drawCircle_section(x, y, x0, y0, option);
00330     }
00331 }
00332 
00333 void Matrix::drawDisc(int8_t x0, int8_t y0, int8_t rad, int8_t option)
00334 {
00335     if(rad<=0)
00336         return;
00337 
00338     int8_t f;
00339     int8_t ddF_x;
00340     int8_t ddF_y;
00341     uint8_t x;
00342     uint8_t y;
00343 
00344     f = 1;
00345     f -= rad;
00346     ddF_x = 1;
00347     ddF_y = 0;
00348     ddF_y -= rad;
00349     ddF_y *= 2;
00350     x = 0;
00351     y = rad;
00352 
00353     drawDisc_section(x, y, x0, y0, option);
00354 
00355     while ( x < y ) {
00356         if (f >= 0) {
00357             y--;
00358             ddF_y += 2;
00359             f += ddF_y;
00360         }
00361         x++;
00362         ddF_x += 2;
00363         f += ddF_x;
00364 
00365         drawDisc_section(x, y, x0, y0, option);
00366     }
00367 }
00368 
00369 void Matrix::drawFrame(int8_t x, int8_t y, int8_t w, int8_t h)
00370 {
00371     if(h<=0 || w<=0)
00372         return;
00373 
00374     int8_t xtmp = x;
00375 
00376     drawHLine(x, y, w);
00377     drawVLine(x, y, h);
00378     x+=w;
00379     x--;
00380     drawVLine(x, y, h);
00381     y+=h;
00382     y--;
00383     drawHLine(xtmp, y, w);
00384 }
00385 
00386 void Matrix::drawRFrame(int8_t x, int8_t y, int8_t w, int8_t h, uint8_t r)
00387 {
00388     if(h<3 || w<3)
00389         return;
00390 
00391     if(r>(w-2)/2 || r>(h-2)/2)
00392         r = min((h-2)/2,(w-2)/2);
00393 
00394     int8_t xl, yu;
00395     xl = x;
00396     xl += r;
00397     yu = y;
00398     yu += r;
00399 
00400     {
00401         int8_t yl, xr;
00402 
00403         xr = x;
00404         xr += w;
00405         xr -= r;
00406         xr -= 1;
00407 
00408         yl = y;
00409         yl += h;
00410         yl -= r;
00411         yl -= 1;
00412 
00413         drawCircle(xl, yu, r, U8G_DRAW_UPPER_LEFT);
00414         drawCircle(xr, yu, r, U8G_DRAW_UPPER_RIGHT);
00415         drawCircle(xl, yl, r, U8G_DRAW_LOWER_LEFT);
00416         drawCircle(xr, yl, r, U8G_DRAW_LOWER_RIGHT);
00417     }
00418 
00419     {
00420         int8_t ww, hh;
00421 
00422         ww = w;
00423         ww -= r;
00424         ww -= r;
00425         ww -= 2;
00426         hh = h;
00427         hh -= r;
00428         hh -= r;
00429         hh -= 2;
00430 
00431         xl++;
00432         yu++;
00433         h--;
00434         w--;
00435         drawHLine(xl, y, ww);
00436         drawHLine(xl, y+h, ww);
00437         drawVLine(x, yu, hh);
00438         drawVLine(x+w, yu, hh);
00439     }
00440 }
00441 
00442 void Matrix::drawBox(int8_t x, int8_t y, int8_t w, int8_t h)
00443 {
00444     if(h<=0 || w<=0)
00445         return;
00446 
00447     do {
00448         drawHLine(x, y, w);
00449         y++;
00450         h--;
00451     } while( h != 0 );
00452 }
00453 
00454 void Matrix::drawRBox(int8_t x, int8_t y, int8_t w, int8_t h, uint8_t r)
00455 {
00456     if(h<3 || w<3)
00457         return;
00458 
00459     if(r>(w-2)/2 || r>(h-2)/2)
00460         r=min((h-2)/2,(w-2)/2);
00461 
00462     int8_t xl, yu;
00463     int8_t yl, xr;
00464 
00465 
00466     xl = x;
00467     xl += r;
00468     yu = y;
00469     yu += r;
00470 
00471     xr = x;
00472     xr += w;
00473     xr -= r;
00474     xr -= 1;
00475 
00476     yl = y;
00477     yl += h;
00478     yl -= r;
00479     yl -= 1;
00480 
00481     drawDisc(xl, yu, r, U8G_DRAW_UPPER_LEFT);
00482     drawDisc(xr, yu, r, U8G_DRAW_UPPER_RIGHT);
00483     drawDisc(xl, yl, r, U8G_DRAW_LOWER_LEFT);
00484     drawDisc(xr, yl, r, U8G_DRAW_LOWER_RIGHT);
00485 
00486     {
00487         int8_t ww, hh;
00488 
00489         ww = w;
00490         ww -= r;
00491         ww -= r;
00492         ww -= 2;
00493         hh = h;
00494         hh -= r;
00495         hh -= r;
00496         hh -= 2;
00497 
00498         xl++;
00499         yu++;
00500         h--;
00501         drawBox(xl, y, ww, r+1);
00502         drawBox(xl, yl, ww, r+1);
00503         // drawHLine(xl, y+h, ww);
00504         drawBox(x, yu, w, hh);
00505         // drawVLine(x+w, yu, hh);
00506     }
00507 }
00508 
00509 void Matrix::drawBMP(int16_t x, int16_t y, int16_t w, int16_t h,const uint8_t *bitmap)
00510 {
00511     int16_t i, j, byteWidth = (w + 7) / 8;
00512 
00513     for(j=0; j<h; j++) {
00514         for(i=0; i<w; i++ ) {
00515 #if 0
00516             if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> ((h-i-1) & 7))) {
00517                 setLed(x+i, y+j, 1);
00518             }
00519 #else
00520             if (bitmap[j * byteWidth + i / 8] & (128 >> ((h-i-1) & 7))) {
00521                 setLed(x+i, y+j, 1);
00522             }
00523 #endif
00524         }
00525     }
00526 }
00527 
00528 #if 0
00529 bool Matrix::drawBMP(int16_t x, int16_t y, const uint8_t *bitmap)
00530 {
00531     uint32_t _dataNum = 0;
00532     uint8_t  _dataBuffer[BUFFPIXEL]; //pixel buffer (R+G+B per pixel)
00533 
00534     //Parse BMP header
00535     if (read16((uint8_t*)bitmap, _dataNum) == 0x4D42) { //BMP signature
00536         (void)read32((uint8_t*)bitmap, _dataNum); //File size
00537         (void)read32((uint8_t*)bitmap, _dataNum); //Read & ignore creator bytes
00538         uint32_t bmpImageoffset = read32((uint8_t*)bitmap, _dataNum); //Start of image data in file
00539         //Read DIB header
00540         (void)read32((uint8_t*)bitmap, _dataNum);  //Header size
00541         int bmpWidth  = read32((uint8_t*)bitmap, _dataNum),
00542             bmpHeight = read32((uint8_t*)bitmap, _dataNum);
00543 
00544         bool  flip = true;      //BMP is stored bottom-to-top
00545         //If bmpHeight is negative, image is in top-down order.
00546         if (bmpHeight < 0) {
00547             bmpHeight = -bmpHeight;
00548             flip = false;
00549         }
00550 
00551         if (read16((uint8_t*)bitmap, _dataNum) == 1) { //# planes -- must be '1'
00552             uint8_t bmpDepth = read16((uint8_t*)bitmap, _dataNum); //Bit depth (currently must be 24)
00553             if ((bmpDepth == 24) && (read32((uint8_t*)bitmap, _dataNum) == 0)) { //0 = uncompressed
00554                 //BMP rows are padded (if needed) to 4-byte boundary
00555                 uint32_t rowSize = (bmpWidth * 3 + 3) & ~3; //Not always = bmpWidth; may have padding
00556 
00557                 //Crop area to be loaded
00558                 int w = bmpWidth,
00559                     h = bmpHeight;
00560 
00561                 if ((x + w - 1) >= (getWidth() * 8)) w = (getWidth() * 8)  - x;
00562                 if ((y + h - 1) >= (getHeight() * 8)) h = (getHeight() * 8) - y;
00563 
00564                 for (int row = 0; row < h; row++) { //For each scanline...
00565                     uint32_t pos = bmpImageoffset + (flip ? (bmpHeight - 1 - row) : row) * rowSize ;
00566                     uint8_t  buffidx = sizeof(_dataBuffer); //Current position in _dataBuffer
00567                     for (int col = 0; col < w; col++) { //For each pixel...
00568                         //Time to read more pixel data?
00569                         if (buffidx >= sizeof(_dataBuffer)) { //Indeed
00570                             buffidx = 0; //Set index to beginning
00571                             for (int a = 0; a < BUFFPIXEL; a++) {
00572                                 _dataBuffer[a] = pgm_read_byte((uint8_t*)bitmap + (pos + a));
00573                             }
00574                         }
00575 
00576                         uint8_t _b = _dataBuffer[buffidx++],
00577                                 _g = _dataBuffer[buffidx++],
00578                                 _r = _dataBuffer[buffidx++];
00579                         setLedColor(col + x, row + y, _r, _g, _b);
00580                     } //end pixel
00581                 } //end scanline
00582             } //end goodBmp
00583             else {
00584                 return false;
00585             }
00586         }//end planes
00587         else {
00588             return false;
00589         }
00590     }//end sianatrue
00591     else {
00592         return false;
00593     }
00594     return true;
00595 }
00596 #else
00597 uint8_t  _dataBuffer[BUFFPIXEL]; //pixel buffer (R+G+B per pixel)
00598 bool Matrix::drawBMP(int16_t x, int16_t y, const uint8_t *bitmap)
00599 {
00600     uint32_t _dataNum = 0;
00601     uint32_t tempData = 0;
00602     
00603     pc.printf("Enter drawBMP()\r\n");
00604     //Parse BMP header
00605     //if (read16((uint8_t*)bitmap, _dataNum) == 0x4D42) { //BMP signature
00606     if ((bitmap[_dataNum++] == 0x42) && (bitmap[_dataNum++] == 0x4D)) { //BMP signature
00607         pc.printf("Enter if\r\n");
00608         //(void)read32((uint8_t*)bitmap, _dataNum); //File size
00609         _dataNum += 4;  //File size
00610         //(void)read32((uint8_t*)bitmap, _dataNum); //Read & ignore creator bytes
00611         _dataNum += 4; //Read & ignore creator bytes
00612         //uint32_t bmpImageoffset = read32((uint8_t*)bitmap, _dataNum); //Start of image data in file
00613         uint32_t bmpImageoffset = bitmap[_dataNum] | bitmap[_dataNum+1]<<8 | bitmap[_dataNum+2]<< 16 | bitmap[_dataNum+3] << 24; //Start of image data in file
00614         _dataNum += 4;
00615         pc.printf("bmpImageoffset = %u\r\n", bmpImageoffset);
00616         //Read DIB header
00617         //(void)read32((uint8_t*)bitmap, _dataNum);  //Header size
00618         _dataNum += 4;  //Header size
00619         //int bmpWidth  = read32((uint8_t*)bitmap, _dataNum);
00620         int bmpWidth  = bitmap[_dataNum] | bitmap[_dataNum+1]<<8 | bitmap[_dataNum+2]<< 16 | bitmap[_dataNum+3] << 24;
00621         _dataNum += 4;
00622         //int bmpHeight = read32((uint8_t*)bitmap, _dataNum);
00623         int bmpHeight = bitmap[_dataNum] | bitmap[_dataNum+1]<<8 | bitmap[_dataNum+2]<< 16 | bitmap[_dataNum+3] << 24;
00624         _dataNum += 4;
00625 
00626         bool  flip = true;      //BMP is stored bottom-to-top
00627         //If bmpHeight is negative, image is in top-down order.
00628         if (bmpHeight < 0) {
00629             bmpHeight = -bmpHeight;
00630             flip = false;
00631         }
00632 
00633         //if (read16((uint8_t*)bitmap, _dataNum) == 1) { //# planes -- must be '1'
00634         if ((bitmap[_dataNum] | bitmap[_dataNum+1]<<8) == 1) { //# planes -- must be '1'
00635             _dataNum += 2;
00636             //uint8_t bmpDepth = read16((uint8_t*)bitmap, _dataNum); //Bit depth (currently must be 24)
00637             uint8_t bmpDepth = bitmap[_dataNum] | bitmap[_dataNum+1]<<8; //Bit depth (currently must be 24)
00638             _dataNum += 2;
00639             tempData = bitmap[_dataNum] | bitmap[_dataNum+1]<<8 | bitmap[_dataNum+2]<< 16 | bitmap[_dataNum+3] << 24;
00640             _dataNum += 4;
00641             //if ((bmpDepth == 24) && (read32((uint8_t*)bitmap, _dataNum) == 0)) { //0 = uncompressed
00642             if ((bmpDepth == 24) && (tempData == 0)) { //0 = uncompressed
00643                 //BMP rows are padded (if needed) to 4-byte boundary
00644                 uint32_t rowSize = (bmpWidth * 3 + 3) & ~3; //Not always = bmpWidth; may have padding
00645 
00646                 //Crop area to be loaded
00647                 int w = bmpWidth,
00648                     h = bmpHeight;
00649 
00650                 if ((x + w - 1) >= (getWidth() * 8)) w = (getWidth() * 8)  - x;
00651                 if ((y + h - 1) >= (getHeight() * 8)) h = (getHeight() * 8) - y;
00652 
00653                 for (int row = 0; row < h; row++) { //For each scanline...
00654                     uint32_t pos = bmpImageoffset + (flip ? (bmpHeight - 1 - row) : row) * rowSize ;
00655                     uint8_t  buffidx = sizeof(_dataBuffer); //Current position in _dataBuffer
00656                     for (int col = 0; col < w; col++) { //For each pixel...
00657                         //Time to read more pixel data?
00658                         if (buffidx >= sizeof(_dataBuffer)) { //Indeed
00659                             buffidx = 0; //Set index to beginning
00660                             for (int a = 0; a < BUFFPIXEL; a++) {
00661                                 _dataBuffer[a] = pgm_read_byte((uint8_t*)bitmap + (pos + a));
00662                             }
00663                         }
00664 
00665                         uint8_t _b = _dataBuffer[buffidx++],
00666                                 _g = _dataBuffer[buffidx++],
00667                                 _r = _dataBuffer[buffidx++];
00668                         setLedColor(col + x, row + y, _r, _g, _b);
00669                     } //end pixel
00670                 } //end scanline
00671             } //end goodBmp
00672             else {
00673                 return false;
00674             }
00675         }//end planes
00676         else {
00677             return false;
00678         }
00679     }//end sianatrue
00680     else {
00681         return false;
00682     }
00683     return true;
00684 }
00685 #endif
00686 
00687 void Matrix::writeString(char* _c, bool _m, uint16_t _t, int16_t _xy)
00688 {
00689     setFontMode(_m);
00690     int c1 = (_m ? getWidth() : getHeight()) * 8;
00691     int c2 = -(_m ? getStringWidth(_c) : getStringHeight(_c))  - c1;
00692     for (int a = c1; a > c2; a--) {
00693         setCursor((_m ? a : _xy), (_m ? _xy : a));
00694         print(_c);
00695         wait_ms(_t);
00696 #ifdef WDT
00697         //wdt_reset();
00698 #endif
00699     }
00700 }
00701 
00702 size_t Matrix::write(uint8_t c)
00703 {
00704     if (CharToInt(c) > 94 || CharToInt(c) < 0)
00705         return 0;
00706 
00707     for (int a = 0; a < getMatrixNum(); a++)
00708         led[a].write(c);
00709 
00710     return 1;
00711     /* void Matrix::print(char* _c) {
00712       for (int a = 0; a < this->_matrixNum; a++)
00713         led[a].print(_c);
00714       } */
00715 }
00716 
00717 int16_t Matrix::getStringWidth(char * _String)
00718 {
00719     //    return (uint32_t)(offset + millis() / 1000);
00720     int _leng = 0;
00721     int _Width = 0;
00722     while (_String[_leng] != NULL) {
00723 #if 0
00724         _Width += 1 + pgm_read_byte(alphabetBitmap[(_String[_leng] - 32)] + FONE_SIZE_X);
00725 #else
00726         //_Width += (1 + alphabetBitmap[((int)_String[_leng] - 32)] + FONE_SIZE_X);
00727         _Width += 1 + FONE_SIZE_X;
00728 #endif
00729         _leng++;
00730     }
00731     return _Width;
00732 }
00733 
00734 int16_t Matrix::getStringHeight(char* _String)
00735 {
00736     //    return (uint32_t)(offset + millis() / 1000);
00737     int _leng = 0;
00738     int _Height = 0;
00739     while (_String[_leng] != NULL) {
00740         _Height += 1 + FONE_SIZE_Y;
00741         _leng++;
00742     }
00743     return _Height;
00744 }
00745 
00746 int16_t Matrix::getMatrixNum()
00747 {
00748     return this->_matrixNum;
00749 }
00750 
00751 int16_t Matrix::getWidth()
00752 {
00753     return this->_numX;
00754 }
00755 
00756 int16_t Matrix::getHeight()
00757 {
00758     return this->_numY;
00759 }