MHVLib  20111011
An efficiency oriented runtime library for AVR microcontrollers
A:/eclipse/mhvlib/MHV_Display_Monochrome.cpp
Go to the documentation of this file.
00001 /* Copyright (c) 2011, Make, Hack, Void Inc
00002  * All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *  * Redistributions of source code must retain the above copyright
00007  *    notice, this list of conditions and the following disclaimer.
00008  *  * Redistributions in binary form must reproduce the above copyright
00009  *    notice, this list of conditions and the following disclaimer in the
00010  *    documentation and/or other materials provided with the distribution.
00011  *  * Neither the name of the Make, Hack, Void nor the
00012  *    names of its contributors may be used to endorse or promote products
00013  *    derived from this software without specific prior written permission.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00016  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00018  * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00020  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00021  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00022  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00023  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025  */
00026 
00027 #include "MHV_Display_Monochrome.h"
00028 #include <string.h>
00029 #include <math.h>
00030 
00042 MHV_Display_Monochrome::MHV_Display_Monochrome(uint16_t colCount, uint16_t rowCount,
00043                 MHV_RingBuffer *txBuffers) :
00044                         MHV_Device_TX(txBuffers){
00045         _colCount = colCount;
00046         _rowCount = rowCount;
00047 }
00048 
00052 uint16_t MHV_Display_Monochrome::getWidth() {
00053         return _colCount;
00054 }
00055 
00059 uint16_t MHV_Display_Monochrome::getHeight() {
00060         return _rowCount;
00061 }
00062 
00067 void MHV_Display_Monochrome::clear(uint8_t value) {
00068         uint16_t x, y;
00069 
00070         for (x = 0; x < _colCount; ++x) {
00071                 for (y = 0; y < _rowCount; ++y) {
00072                         setPixel(x, y, value);
00073                 }
00074         }
00075 }
00076 
00087 bool MHV_Display_Monochrome::writeChar(const MHV_FONT *font, int16_t *offsetX, int16_t offsetY,
00088                 uint8_t onValue, uint8_t offValue, char character) {
00089         uint8_t c = (uint8_t)character;
00090         if (c < font->firstChar || c >= font->firstChar + font->charCount) {
00091                 c = font->unknown;
00092         }
00093 
00094 // Normalize character to font
00095         c -= font->firstChar;
00096         uint8_t charWidth = pgm_read_byte(font->widths + c);
00097 
00098         const uint8_t *fontChar = font->fontData + pgm_read_word(font->offsets + c);
00099 
00100 // Render each column
00101         bool ret = false;
00102         do {
00103                 int8_t bit = 7;
00104                 uint8_t y = 0;
00105                 uint8_t data = pgm_read_byte(fontChar++);
00106 
00107                 if (*offsetX >= 0) {
00108 // Start at the bottom of the column and work up
00109                         for (; y < font->maxHeight; y++, bit--) {
00110                                 ret = true;
00111 
00112                                 if (data & (1 << bit)) {
00113                                         setPixel(*offsetX, offsetY + y, onValue);
00114                                 } else {
00115                                         setPixel(*offsetX, offsetY + y, offValue);
00116                                 }
00117 
00118 // Support multiple-byte font images - fetch the next byte of data if we exhaust the current one
00119                                 if (-1 == bit && (font->maxHeight - y) > 0) {
00120                                         bit = 7;
00121                                         data = pgm_read_byte(fontChar++);
00122                                 }
00123                         }
00124                 }
00125         } while (++(*offsetX) < (int16_t)_colCount && --charWidth);
00126 
00127         *offsetX += charWidth;
00128 
00129         return ret;
00130 }
00131 
00141 bool MHV_Display_Monochrome::writeSeperator(const MHV_FONT *font, int16_t *offsetX, int16_t offsetY,
00142                 uint8_t onValue, uint8_t offValue) {
00143         bool ret = false;
00144 
00145         if (*offsetX >= 0 && *offsetX < (int16_t)_colCount) {
00146 // Start at the bottom of the column and work up
00147                 uint8_t y = 0;
00148                 uint8_t row;
00149 
00150                 while (y++ < font->maxHeight) {
00151                         row = offsetY + y;
00152                         if (row < _rowCount) {
00153                                 setPixel(*offsetX, row, offValue);
00154                                 ret = true;
00155                         }
00156                 }
00157         }
00158 
00159         (*offsetX)++;
00160         return ret;
00161 }
00162 
00173 bool MHV_Display_Monochrome::writeString(const MHV_FONT *font, int16_t *offsetX, int16_t offsetY,
00174                 uint8_t onValue, uint8_t offValue, const char *string) {
00175         const char *p = string;
00176 
00177         bool ret = false;
00178         while (*p != '\0' && *offsetX < (int16_t)_colCount) {
00179                 ret |= writeChar(font, offsetX, offsetY, onValue, offValue, *p);
00180                 if (*(++p) != '\0') {
00181                         ret |= writeSeperator(font, offsetX, offsetY, onValue, offValue);
00182                 }
00183         }
00184 
00185         return ret;
00186 }
00187 
00199 bool MHV_Display_Monochrome::writeBuffer(const MHV_FONT *font, int16_t *offsetX, int16_t offsetY,
00200                 uint8_t onValue, uint8_t offValue, const char *buffer, uint16_t length) {
00201         bool ret = false;
00202         uint16_t i = 0;
00203         while (i < length && *offsetX < (int16_t)_colCount) {
00204                 ret |= writeChar(font, offsetX, offsetY, onValue, offValue, buffer[i++]);
00205                 if (i != length) {
00206                         ret |= writeSeperator(font, offsetX, offsetY, onValue, offValue);
00207                 }
00208         }
00209 
00210         return ret;
00211 }
00212 
00213 
00224 bool MHV_Display_Monochrome::writeString_P(const MHV_FONT *font, int16_t *offsetX, int16_t offsetY,
00225                 uint8_t onValue, uint8_t offValue, PGM_P string) {
00226         const char *p = string;
00227         char val;
00228 
00229         bool ret = false;
00230         val = pgm_read_byte(p);
00231         while (val != '\0' && *offsetX < (int16_t)_colCount) {
00232                 ret |= writeChar(font, offsetX, offsetY, onValue, offValue, val);
00233                 val = pgm_read_byte(++p);
00234                 if (val != '\0') {
00235                         ret |= writeSeperator(font, offsetX, offsetY, onValue, offValue);
00236                 }
00237         }
00238 
00239         return ret;
00240 }
00241 
00253 bool MHV_Display_Monochrome::writeBuffer_P(const MHV_FONT *font, int16_t *offsetX, int16_t offsetY,
00254                 uint8_t onValue, uint8_t offValue, PGM_P buffer, uint16_t length) {
00255 
00256         bool ret = false;
00257         uint16_t i = 0;
00258         while (i < length && *offsetX < (int16_t)_colCount) {
00259                 ret |= writeChar(font, offsetX, offsetY, onValue, offValue, pgm_read_byte(buffer + i++));
00260                 if (i < length) {
00261                         ret |= writeSeperator(font, offsetX, offsetY, onValue, offValue);
00262                 }
00263         }
00264 
00265         return ret;
00266 }
00267 
00271 void MHV_Display_Monochrome::runTxBuffers() {
00272         _txOffset = _colCount - 1;
00273         moreTX();
00274 }
00275 
00284 bool MHV_Display_Monochrome::txAnimation(const MHV_FONT *font, int16_t offsetY, uint8_t onValue, uint8_t offValue) {
00285         int16_t offsetX = _txOffset--;
00286 
00287         clear(offValue);
00288 
00289         bool ret;
00290         if (_currentTx.progmem) {
00291                 if (_currentTx.isString) {
00292                         ret = writeString_P(font, &offsetX, offsetY, onValue, offValue, _tx);
00293                 } else {
00294                         ret = writeBuffer_P(font, &offsetX, offsetY, onValue, offValue, _tx, _currentTx.length);
00295                 }
00296         } else {
00297                 if (_currentTx.isString) {
00298                         ret = writeString(font, &offsetX, offsetY, onValue, offValue, _tx);
00299                 } else {
00300                         ret = writeBuffer(font, &offsetX, offsetY, onValue, offValue, _tx, _currentTx.length);
00301                 }
00302         }
00303 
00304         if (!ret) {
00305                 _txOffset = _colCount - 1;
00306                 return moreTX();
00307         }
00308 
00309         return true;
00310 }