Foundation classes for a basic GUI implementing simple widgets and events

Dependents:   TouchScreenGUIDemo

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?

UserRevisionLine numberNew 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 }