MHVLib
20111011
An efficiency oriented runtime library for AVR microcontrollers
|
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 }