el h / SimpleGUI

Fork of SimpleGUI by Duncan McIntyre

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FastFontRenderer.cpp Source File

FastFontRenderer.cpp

00001 #include "FastFontRenderer.h"
00002 
00003 FastFontRenderer::FastFontRenderer() : FontRenderer()
00004 {
00005 }
00006 
00007 void FastFontRenderer::putc(const char  c, GraphicsDisplay* display, Font* font)
00008 {
00009     FastFont* _font = (FastFont*)font;
00010     uint8_t ch = _font->zoomedHeight();
00011 
00012     if(c == '\n') {
00013         _cx = _wx0;
00014         _cy += ch;
00015         return;
00016     }
00017 
00018     if(!_font->contains(c)) {
00019         return;
00020     }
00021 
00022     uint8_t cw = _font->zoomedWidthOf(c);
00023     
00024     if((_cx + cw) > _wx1 && !_clip) {
00025         _cx = _wx0;
00026         _cy += ch;
00027     }
00028 
00029     if(cw == 0 || (_cx + cw) > _wx1 || (_cy + ch) > _wy1) {
00030         return;
00031     }
00032 
00033     uint8_t height = _font->height();
00034     uint8_t width = _font->widthOf(c);
00035     uint8_t zx = _font->zoomX();
00036     uint8_t zy = _font->zoomY();
00037     uint8_t bytesPerRow = _font->bytesPerRow();
00038     uint8_t bytesPerGlyph = _font->totalBytesPerGlyph();
00039     uint8_t row, z, rowByte, mask, bits;
00040     uint8_t* glyph = _font->glyph(c);
00041     int rowIndex = 0;
00042     int byteIndex, bitsToRender;
00043 
00044     display->window(_cx, _cy, cw + zx, ch);
00045 
00046     for(row=0; row<height; row++) {
00047         // repeat for zoom
00048         for(z=0; z < zy; z++) {
00049             byteIndex = rowIndex;
00050             bitsToRender = width;
00051             for(rowByte = 0; rowByte < bytesPerRow; rowByte++) {
00052                 bits = glyph[byteIndex++];
00053                 mask = 0x80;
00054                 while(mask != 0 && bitsToRender != 0) {
00055 
00056                     if(bits & mask) {
00057                         display->window_pushpixel(_foreground, zx);
00058                     } else {
00059                         display->window_pushpixel(_background, zx);
00060                     }
00061 
00062                     mask = mask >> 1;
00063                     bitsToRender--;
00064                 }
00065             }
00066             // Add a one-pixel (zoomed) space
00067             display->window_pushpixel(_background, zx);
00068         }
00069         rowIndex += bytesPerRow;
00070     }
00071 
00072     _cx += cw;
00073 }
00074 
00075 void FastFontRenderer::puts(const char* str, GraphicsDisplay* display, Font* font)
00076 {
00077 
00078     FastFont* _font = (FastFont*)font;
00079     uint8_t cw;
00080     uint8_t ch = _font->zoomedHeight();
00081     uint8_t height = _font->height();
00082     uint8_t zoomX = _font->zoomX();
00083     uint8_t zoomY = _font->zoomY();
00084     uint8_t bytesPerRow = _font->bytesPerRow();
00085     uint8_t bytesPerGlyph = _font->totalBytesPerGlyph();
00086 
00087     // Render the text line by line
00088     // Iterate to build up the length of the first line so we can
00089     // set a clipping window
00090     const char* line = str;
00091 
00092     while(*line != NULL) {
00093         
00094         if((_cy + ch) > _wy1) {
00095             return;
00096         }
00097         
00098         // If the first char is a \n, just increment cy
00099         if(*line == '\n') {
00100             line++;
00101             _cy += ch;
00102             continue;
00103         }
00104         
00105         // Figure out how wide the line is. Clip characters outside the bounding box
00106         int lw = 0;
00107         const char* cur = line;
00108         const char* printable = line;
00109         int nChars = 0;
00110         bool wrapped = false;
00111 
00112         while(*cur != NULL && *cur != '\n') {
00113 
00114             cw = _font->zoomedWidthOf(*cur);
00115 
00116             if((lw + cw) < (_wx1 - _wx0)) {
00117                 lw += cw + zoomX;
00118                 nChars++;
00119                 cur++;
00120             } else {
00121                 // dump the rest of the line up to the end or the next newline (clipping)
00122                 if(_clip) {
00123                     while(*cur != NULL && *cur != '\n') {
00124                         cur++;
00125                     }
00126                 } else {
00127                     wrapped = true;
00128                 }
00129                 break;
00130             }
00131         }
00132 
00133         // Set a wrapping window for the entire line
00134         display->window(_wx0, _cy, lw, ch);
00135 
00136         int rowIndex = 0;
00137         // Do as many lines as a char is pixels high * zoomY
00138         for(int row=0; row<height; row++) {
00139             for(int zy=0; zy<zoomY; zy++) {
00140                 for(int i=0; i<nChars; i++) {
00141                     // print all the bits in this char for the current row
00142                     // taking zoomX into account
00143                     char c = printable[i];
00144                     uint8_t* glyph = _font->glyph(c);
00145                     uint8_t bitsToRender = _font->widthOf(c);
00146                     for(int col=0; col<bytesPerRow; col++) {
00147                         uint8_t bits = glyph[rowIndex + col];
00148                         uint8_t mask = 0x80;
00149                         while(mask && bitsToRender) {
00150                             if(bits & mask) {
00151                                 display->window_pushpixel(_foreground, zoomX);
00152                             } else {
00153                                 display->window_pushpixel(_background, zoomX);
00154                             }
00155                             mask = mask >> 1;
00156                             bitsToRender--;
00157                         }
00158                     }
00159                     // Add a one-pixel (zoomed) space
00160                     display->window_pushpixel(_background, zoomX);
00161 
00162                 }
00163             }
00164             rowIndex += bytesPerRow;
00165         }
00166        if(wrapped) _cy += ch;
00167         line = cur;
00168     }
00169 }