Foundation classes for a basic GUI implementing simple widgets and events
Dependents: TouchScreenGUIDemo
Font/FastFont/FastFontRenderer.cpp@18:d849f3ada858, 2016-05-28 (annotated)
- Committer:
- duncanFrance
- Date:
- Sat May 28 14:50:14 2016 +0000
- Revision:
- 18:d849f3ada858
- Parent:
- 8:a460cabc85ac
Moved the event queue into the EventDispatcher; Improved event handling across Window/Widget
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
duncanFrance | 8:a460cabc85ac | 1 | #include "FastFontRenderer.h" |
duncanFrance | 8:a460cabc85ac | 2 | |
duncanFrance | 8:a460cabc85ac | 3 | FastFontRenderer::FastFontRenderer() : FontRenderer() |
duncanFrance | 8:a460cabc85ac | 4 | { |
duncanFrance | 8:a460cabc85ac | 5 | } |
duncanFrance | 8:a460cabc85ac | 6 | |
duncanFrance | 8:a460cabc85ac | 7 | void FastFontRenderer::putc(const char c, GraphicsDisplay* display, Font* font) |
duncanFrance | 8:a460cabc85ac | 8 | { |
duncanFrance | 8:a460cabc85ac | 9 | FastFont* _font = (FastFont*)font; |
duncanFrance | 8:a460cabc85ac | 10 | uint8_t ch = _font->zoomedHeight(); |
duncanFrance | 8:a460cabc85ac | 11 | |
duncanFrance | 8:a460cabc85ac | 12 | if(c == '\n') { |
duncanFrance | 8:a460cabc85ac | 13 | _cx = _wx0; |
duncanFrance | 8:a460cabc85ac | 14 | _cy += ch; |
duncanFrance | 8:a460cabc85ac | 15 | return; |
duncanFrance | 8:a460cabc85ac | 16 | } |
duncanFrance | 8:a460cabc85ac | 17 | |
duncanFrance | 8:a460cabc85ac | 18 | if(!_font->contains(c)) { |
duncanFrance | 8:a460cabc85ac | 19 | return; |
duncanFrance | 8:a460cabc85ac | 20 | } |
duncanFrance | 8:a460cabc85ac | 21 | |
duncanFrance | 8:a460cabc85ac | 22 | uint8_t cw = _font->zoomedWidthOf(c); |
duncanFrance | 8:a460cabc85ac | 23 | |
duncanFrance | 8:a460cabc85ac | 24 | if((_cx + cw) > _wx1 && !_clip) { |
duncanFrance | 8:a460cabc85ac | 25 | _cx = _wx0; |
duncanFrance | 8:a460cabc85ac | 26 | _cy += ch; |
duncanFrance | 8:a460cabc85ac | 27 | } |
duncanFrance | 8:a460cabc85ac | 28 | |
duncanFrance | 8:a460cabc85ac | 29 | if(cw == 0 || (_cx + cw) > _wx1 || (_cy + ch) > _wy1) { |
duncanFrance | 8:a460cabc85ac | 30 | return; |
duncanFrance | 8:a460cabc85ac | 31 | } |
duncanFrance | 8:a460cabc85ac | 32 | |
duncanFrance | 8:a460cabc85ac | 33 | uint8_t height = _font->height(); |
duncanFrance | 8:a460cabc85ac | 34 | uint8_t width = _font->widthOf(c); |
duncanFrance | 8:a460cabc85ac | 35 | uint8_t zx = _font->zoomX(); |
duncanFrance | 8:a460cabc85ac | 36 | uint8_t zy = _font->zoomY(); |
duncanFrance | 8:a460cabc85ac | 37 | uint8_t bytesPerRow = _font->bytesPerRow(); |
duncanFrance | 8:a460cabc85ac | 38 | uint8_t bytesPerGlyph = _font->totalBytesPerGlyph(); |
duncanFrance | 8:a460cabc85ac | 39 | uint8_t row, z, rowByte, mask, bits; |
duncanFrance | 8:a460cabc85ac | 40 | uint8_t* glyph = _font->glyph(c); |
duncanFrance | 8:a460cabc85ac | 41 | int rowIndex = 0; |
duncanFrance | 8:a460cabc85ac | 42 | int byteIndex, bitsToRender; |
duncanFrance | 8:a460cabc85ac | 43 | |
duncanFrance | 8:a460cabc85ac | 44 | display->window(_cx, _cy, cw + zx, ch); |
duncanFrance | 8:a460cabc85ac | 45 | |
duncanFrance | 8:a460cabc85ac | 46 | for(row=0; row<height; row++) { |
duncanFrance | 8:a460cabc85ac | 47 | // repeat for zoom |
duncanFrance | 8:a460cabc85ac | 48 | for(z=0; z < zy; z++) { |
duncanFrance | 8:a460cabc85ac | 49 | byteIndex = rowIndex; |
duncanFrance | 8:a460cabc85ac | 50 | bitsToRender = width; |
duncanFrance | 8:a460cabc85ac | 51 | for(rowByte = 0; rowByte < bytesPerRow; rowByte++) { |
duncanFrance | 8:a460cabc85ac | 52 | bits = glyph[byteIndex++]; |
duncanFrance | 8:a460cabc85ac | 53 | mask = 0x80; |
duncanFrance | 8:a460cabc85ac | 54 | while(mask != 0 && bitsToRender != 0) { |
duncanFrance | 8:a460cabc85ac | 55 | |
duncanFrance | 8:a460cabc85ac | 56 | if(bits & mask) { |
duncanFrance | 8:a460cabc85ac | 57 | display->window_pushpixel(_foreground, zx); |
duncanFrance | 8:a460cabc85ac | 58 | } else { |
duncanFrance | 8:a460cabc85ac | 59 | display->window_pushpixel(_background, zx); |
duncanFrance | 8:a460cabc85ac | 60 | } |
duncanFrance | 8:a460cabc85ac | 61 | |
duncanFrance | 8:a460cabc85ac | 62 | mask = mask >> 1; |
duncanFrance | 8:a460cabc85ac | 63 | bitsToRender--; |
duncanFrance | 8:a460cabc85ac | 64 | } |
duncanFrance | 8:a460cabc85ac | 65 | } |
duncanFrance | 8:a460cabc85ac | 66 | // Add a one-pixel (zoomed) space |
duncanFrance | 8:a460cabc85ac | 67 | display->window_pushpixel(_background, zx); |
duncanFrance | 8:a460cabc85ac | 68 | } |
duncanFrance | 8:a460cabc85ac | 69 | rowIndex += bytesPerRow; |
duncanFrance | 8:a460cabc85ac | 70 | } |
duncanFrance | 8:a460cabc85ac | 71 | |
duncanFrance | 8:a460cabc85ac | 72 | _cx += cw; |
duncanFrance | 8:a460cabc85ac | 73 | } |
duncanFrance | 8:a460cabc85ac | 74 | |
duncanFrance | 8:a460cabc85ac | 75 | void FastFontRenderer::puts(const char* str, GraphicsDisplay* display, Font* font) |
duncanFrance | 8:a460cabc85ac | 76 | { |
duncanFrance | 8:a460cabc85ac | 77 | |
duncanFrance | 8:a460cabc85ac | 78 | FastFont* _font = (FastFont*)font; |
duncanFrance | 8:a460cabc85ac | 79 | uint8_t cw; |
duncanFrance | 8:a460cabc85ac | 80 | uint8_t ch = _font->zoomedHeight(); |
duncanFrance | 8:a460cabc85ac | 81 | uint8_t height = _font->height(); |
duncanFrance | 8:a460cabc85ac | 82 | uint8_t zoomX = _font->zoomX(); |
duncanFrance | 8:a460cabc85ac | 83 | uint8_t zoomY = _font->zoomY(); |
duncanFrance | 8:a460cabc85ac | 84 | uint8_t bytesPerRow = _font->bytesPerRow(); |
duncanFrance | 8:a460cabc85ac | 85 | uint8_t bytesPerGlyph = _font->totalBytesPerGlyph(); |
duncanFrance | 8:a460cabc85ac | 86 | |
duncanFrance | 8:a460cabc85ac | 87 | // Render the text line by line |
duncanFrance | 8:a460cabc85ac | 88 | // Iterate to build up the length of the first line so we can |
duncanFrance | 8:a460cabc85ac | 89 | // set a clipping window |
duncanFrance | 8:a460cabc85ac | 90 | const char* line = str; |
duncanFrance | 8:a460cabc85ac | 91 | |
duncanFrance | 8:a460cabc85ac | 92 | while(*line != NULL) { |
duncanFrance | 8:a460cabc85ac | 93 | |
duncanFrance | 8:a460cabc85ac | 94 | if((_cy + ch) > _wy1) { |
duncanFrance | 8:a460cabc85ac | 95 | return; |
duncanFrance | 8:a460cabc85ac | 96 | } |
duncanFrance | 8:a460cabc85ac | 97 | |
duncanFrance | 8:a460cabc85ac | 98 | // If the first char is a \n, just increment cy |
duncanFrance | 8:a460cabc85ac | 99 | if(*line == '\n') { |
duncanFrance | 8:a460cabc85ac | 100 | line++; |
duncanFrance | 8:a460cabc85ac | 101 | _cy += ch; |
duncanFrance | 8:a460cabc85ac | 102 | continue; |
duncanFrance | 8:a460cabc85ac | 103 | } |
duncanFrance | 8:a460cabc85ac | 104 | |
duncanFrance | 8:a460cabc85ac | 105 | // Figure out how wide the line is. Clip characters outside the bounding box |
duncanFrance | 8:a460cabc85ac | 106 | int lw = 0; |
duncanFrance | 8:a460cabc85ac | 107 | const char* cur = line; |
duncanFrance | 8:a460cabc85ac | 108 | const char* printable = line; |
duncanFrance | 8:a460cabc85ac | 109 | int nChars = 0; |
duncanFrance | 8:a460cabc85ac | 110 | bool wrapped = false; |
duncanFrance | 8:a460cabc85ac | 111 | |
duncanFrance | 8:a460cabc85ac | 112 | while(*cur != NULL && *cur != '\n') { |
duncanFrance | 8:a460cabc85ac | 113 | |
duncanFrance | 8:a460cabc85ac | 114 | cw = _font->zoomedWidthOf(*cur); |
duncanFrance | 8:a460cabc85ac | 115 | |
duncanFrance | 8:a460cabc85ac | 116 | if((lw + cw) < (_wx1 - _wx0)) { |
duncanFrance | 8:a460cabc85ac | 117 | lw += cw + zoomX; |
duncanFrance | 8:a460cabc85ac | 118 | nChars++; |
duncanFrance | 8:a460cabc85ac | 119 | cur++; |
duncanFrance | 8:a460cabc85ac | 120 | } else { |
duncanFrance | 8:a460cabc85ac | 121 | // dump the rest of the line up to the end or the next newline (clipping) |
duncanFrance | 8:a460cabc85ac | 122 | if(_clip) { |
duncanFrance | 8:a460cabc85ac | 123 | while(*cur != NULL && *cur != '\n') { |
duncanFrance | 8:a460cabc85ac | 124 | cur++; |
duncanFrance | 8:a460cabc85ac | 125 | } |
duncanFrance | 8:a460cabc85ac | 126 | } else { |
duncanFrance | 8:a460cabc85ac | 127 | wrapped = true; |
duncanFrance | 8:a460cabc85ac | 128 | } |
duncanFrance | 8:a460cabc85ac | 129 | break; |
duncanFrance | 8:a460cabc85ac | 130 | } |
duncanFrance | 8:a460cabc85ac | 131 | } |
duncanFrance | 8:a460cabc85ac | 132 | |
duncanFrance | 8:a460cabc85ac | 133 | // Set a wrapping window for the entire line |
duncanFrance | 8:a460cabc85ac | 134 | display->window(_wx0, _cy, lw, ch); |
duncanFrance | 8:a460cabc85ac | 135 | |
duncanFrance | 8:a460cabc85ac | 136 | int rowIndex = 0; |
duncanFrance | 8:a460cabc85ac | 137 | // Do as many lines as a char is pixels high * zoomY |
duncanFrance | 8:a460cabc85ac | 138 | for(int row=0; row<height; row++) { |
duncanFrance | 8:a460cabc85ac | 139 | for(int zy=0; zy<zoomY; zy++) { |
duncanFrance | 8:a460cabc85ac | 140 | for(int i=0; i<nChars; i++) { |
duncanFrance | 8:a460cabc85ac | 141 | // print all the bits in this char for the current row |
duncanFrance | 8:a460cabc85ac | 142 | // taking zoomX into account |
duncanFrance | 8:a460cabc85ac | 143 | char c = printable[i]; |
duncanFrance | 8:a460cabc85ac | 144 | uint8_t* glyph = _font->glyph(c); |
duncanFrance | 8:a460cabc85ac | 145 | uint8_t bitsToRender = _font->widthOf(c); |
duncanFrance | 8:a460cabc85ac | 146 | for(int col=0; col<bytesPerRow; col++) { |
duncanFrance | 8:a460cabc85ac | 147 | uint8_t bits = glyph[rowIndex + col]; |
duncanFrance | 8:a460cabc85ac | 148 | uint8_t mask = 0x80; |
duncanFrance | 8:a460cabc85ac | 149 | while(mask && bitsToRender) { |
duncanFrance | 8:a460cabc85ac | 150 | if(bits & mask) { |
duncanFrance | 8:a460cabc85ac | 151 | display->window_pushpixel(_foreground, zoomX); |
duncanFrance | 8:a460cabc85ac | 152 | } else { |
duncanFrance | 8:a460cabc85ac | 153 | display->window_pushpixel(_background, zoomX); |
duncanFrance | 8:a460cabc85ac | 154 | } |
duncanFrance | 8:a460cabc85ac | 155 | mask = mask >> 1; |
duncanFrance | 8:a460cabc85ac | 156 | bitsToRender--; |
duncanFrance | 8:a460cabc85ac | 157 | } |
duncanFrance | 8:a460cabc85ac | 158 | } |
duncanFrance | 8:a460cabc85ac | 159 | // Add a one-pixel (zoomed) space |
duncanFrance | 8:a460cabc85ac | 160 | display->window_pushpixel(_background, zoomX); |
duncanFrance | 8:a460cabc85ac | 161 | |
duncanFrance | 8:a460cabc85ac | 162 | } |
duncanFrance | 8:a460cabc85ac | 163 | } |
duncanFrance | 8:a460cabc85ac | 164 | rowIndex += bytesPerRow; |
duncanFrance | 8:a460cabc85ac | 165 | } |
duncanFrance | 8:a460cabc85ac | 166 | if(wrapped) _cy += ch; |
duncanFrance | 8:a460cabc85ac | 167 | line = cur; |
duncanFrance | 8:a460cabc85ac | 168 | } |
duncanFrance | 8:a460cabc85ac | 169 | } |