A simple yet powerful library for controlling graphical displays. Multiple display controllers are supported using inheritance.

Dependents:   mbed_rifletool Hexi_Bubble_Game Hexi_Catch-the-dot_Game Hexi_Acceleromagnetic_Synth

NOTE: This library is in beta right now. As far as I know, everything here works, but there are many features that are lacking so far. Most notably containers, button handling, and display drivers other than the SSD1306.

Committer:
neilt6
Date:
Tue May 27 21:41:28 2014 +0000
Revision:
3:a8f72d4864e6
Parent:
1:f7003ec66a51
Syntax improvements

Who changed what in which revision?

UserRevisionLine numberNew contents of line
neilt6 0:b876cf091464 1 /* NeatGUI Library
neilt6 0:b876cf091464 2 * Copyright (c) 2013 Neil Thiessen
neilt6 0:b876cf091464 3 *
neilt6 0:b876cf091464 4 * Licensed under the Apache License, Version 2.0 (the "License");
neilt6 0:b876cf091464 5 * you may not use this file except in compliance with the License.
neilt6 0:b876cf091464 6 * You may obtain a copy of the License at
neilt6 0:b876cf091464 7 *
neilt6 0:b876cf091464 8 * http://www.apache.org/licenses/LICENSE-2.0
neilt6 0:b876cf091464 9 *
neilt6 0:b876cf091464 10 * Unless required by applicable law or agreed to in writing, software
neilt6 0:b876cf091464 11 * distributed under the License is distributed on an "AS IS" BASIS,
neilt6 0:b876cf091464 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
neilt6 0:b876cf091464 13 * See the License for the specific language governing permissions and
neilt6 0:b876cf091464 14 * limitations under the License.
neilt6 0:b876cf091464 15 */
neilt6 0:b876cf091464 16
neilt6 0:b876cf091464 17 #include "Canvas.h"
neilt6 0:b876cf091464 18
neilt6 0:b876cf091464 19 Canvas::Canvas(int w, int h)
neilt6 0:b876cf091464 20 {
neilt6 0:b876cf091464 21 m_Width = w;
neilt6 0:b876cf091464 22 m_Height = h;
neilt6 0:b876cf091464 23 }
neilt6 0:b876cf091464 24
neilt6 0:b876cf091464 25 void Canvas::clear(unsigned int c)
neilt6 0:b876cf091464 26 {
neilt6 0:b876cf091464 27 fillRect(0, 0, m_Width, m_Height, c);
neilt6 0:b876cf091464 28 }
neilt6 0:b876cf091464 29
neilt6 0:b876cf091464 30 void Canvas::drawLine(int x0, int y0, int x1, int y1, unsigned int c)
neilt6 0:b876cf091464 31 {
neilt6 0:b876cf091464 32 int steep = abs(y1 - y0) > abs(x1 - x0);
neilt6 0:b876cf091464 33 if (steep) {
neilt6 0:b876cf091464 34 int temp = x0;
neilt6 0:b876cf091464 35 x0 = y0;
neilt6 0:b876cf091464 36 y0 = temp;
neilt6 0:b876cf091464 37
neilt6 0:b876cf091464 38 temp = x1;
neilt6 0:b876cf091464 39 x1 = y1;
neilt6 0:b876cf091464 40 y1 = temp;
neilt6 0:b876cf091464 41 }
neilt6 0:b876cf091464 42
neilt6 0:b876cf091464 43 if (x0 > x1) {
neilt6 0:b876cf091464 44 int temp = x0;
neilt6 0:b876cf091464 45 x0 = x1;
neilt6 0:b876cf091464 46 x1 = temp;
neilt6 0:b876cf091464 47
neilt6 0:b876cf091464 48 temp = y0;
neilt6 0:b876cf091464 49 y0 = y1;
neilt6 0:b876cf091464 50 y1 = temp;
neilt6 0:b876cf091464 51 }
neilt6 0:b876cf091464 52
neilt6 0:b876cf091464 53 int dx, dy;
neilt6 0:b876cf091464 54 dx = x1 - x0;
neilt6 0:b876cf091464 55 dy = abs(y1 - y0);
neilt6 0:b876cf091464 56
neilt6 0:b876cf091464 57 int err = dx / 2;
neilt6 0:b876cf091464 58 int ystep;
neilt6 0:b876cf091464 59
neilt6 0:b876cf091464 60 if (y0 < y1) {
neilt6 0:b876cf091464 61 ystep = 1;
neilt6 0:b876cf091464 62 } else {
neilt6 0:b876cf091464 63 ystep = -1;
neilt6 0:b876cf091464 64 }
neilt6 0:b876cf091464 65
neilt6 0:b876cf091464 66 for (; x0 <= x1; x0++) {
neilt6 0:b876cf091464 67 if (steep) {
neilt6 0:b876cf091464 68 drawPixel(y0, x0, c);
neilt6 0:b876cf091464 69 } else {
neilt6 0:b876cf091464 70 drawPixel(x0, y0, c);
neilt6 0:b876cf091464 71 }
neilt6 0:b876cf091464 72 err -= dy;
neilt6 0:b876cf091464 73 if (err < 0) {
neilt6 0:b876cf091464 74 y0 += ystep;
neilt6 0:b876cf091464 75 err += dx;
neilt6 0:b876cf091464 76 }
neilt6 0:b876cf091464 77 }
neilt6 0:b876cf091464 78 }
neilt6 0:b876cf091464 79
neilt6 0:b876cf091464 80 void Canvas::drawHLine(int x, int y, int w, unsigned int c)
neilt6 0:b876cf091464 81 {
neilt6 0:b876cf091464 82 drawLine(x, y, x + w - 1, y, c);
neilt6 0:b876cf091464 83 }
neilt6 0:b876cf091464 84
neilt6 0:b876cf091464 85 void Canvas::drawVLine(int x, int y, int h, unsigned int c)
neilt6 0:b876cf091464 86 {
neilt6 0:b876cf091464 87 drawLine(x, y, x, y + h - 1, c);
neilt6 0:b876cf091464 88 }
neilt6 0:b876cf091464 89
neilt6 0:b876cf091464 90 void Canvas::drawRect(int x, int y, int w, int h, unsigned int c)
neilt6 0:b876cf091464 91 {
neilt6 0:b876cf091464 92 drawHLine(x, y, w, c);
neilt6 0:b876cf091464 93 drawHLine(x, y + h - 1, w, c);
neilt6 0:b876cf091464 94 drawVLine(x, y, h, c);
neilt6 0:b876cf091464 95 drawVLine(x + w - 1, y, h, c);
neilt6 0:b876cf091464 96 }
neilt6 0:b876cf091464 97
neilt6 0:b876cf091464 98 void Canvas::fillRect(int x, int y, int w, int h, unsigned int c)
neilt6 0:b876cf091464 99 {
neilt6 0:b876cf091464 100 for (int i = x; i < x + w; i++) {
neilt6 0:b876cf091464 101 drawVLine(i, y, h, c);
neilt6 0:b876cf091464 102 }
neilt6 0:b876cf091464 103 }
neilt6 0:b876cf091464 104
neilt6 0:b876cf091464 105 void Canvas::drawTriangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int c)
neilt6 0:b876cf091464 106 {
neilt6 0:b876cf091464 107 drawLine(x0, y0, x1, y1, c);
neilt6 0:b876cf091464 108 drawLine(x1, y1, x2, y2, c);
neilt6 0:b876cf091464 109 drawLine(x2, y2, x0, y0, c);
neilt6 0:b876cf091464 110 }
neilt6 0:b876cf091464 111
neilt6 0:b876cf091464 112 void Canvas::fillTriangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int c)
neilt6 0:b876cf091464 113 {
neilt6 0:b876cf091464 114 int a, b, y, last;
neilt6 0:b876cf091464 115
neilt6 0:b876cf091464 116 //Sort coordinates by Y order (y2 >= y1 >= y0)
neilt6 0:b876cf091464 117 if (y0 > y1) {
neilt6 0:b876cf091464 118 int temp = y0;
neilt6 0:b876cf091464 119 y0 = y1;
neilt6 0:b876cf091464 120 y1 = temp;
neilt6 0:b876cf091464 121
neilt6 0:b876cf091464 122 temp = x0;
neilt6 0:b876cf091464 123 x0 = x1;
neilt6 0:b876cf091464 124 x1 = temp;
neilt6 0:b876cf091464 125 }
neilt6 0:b876cf091464 126 if (y1 > y2) {
neilt6 0:b876cf091464 127 int temp = y1;
neilt6 0:b876cf091464 128 x1 = y2;
neilt6 0:b876cf091464 129 y2 = temp;
neilt6 0:b876cf091464 130
neilt6 0:b876cf091464 131 temp = x1;
neilt6 0:b876cf091464 132 x1 = x2;
neilt6 0:b876cf091464 133 x2 = temp;
neilt6 0:b876cf091464 134 }
neilt6 0:b876cf091464 135 if (y0 > y1) {
neilt6 0:b876cf091464 136 int temp = y0;
neilt6 0:b876cf091464 137 y0 = y1;
neilt6 0:b876cf091464 138 y1 = temp;
neilt6 0:b876cf091464 139
neilt6 0:b876cf091464 140 temp = x0;
neilt6 0:b876cf091464 141 x0 = x1;
neilt6 0:b876cf091464 142 x1 = temp;
neilt6 0:b876cf091464 143 }
neilt6 0:b876cf091464 144
neilt6 0:b876cf091464 145 //Handle awkward all-on-same-line case as its own thing
neilt6 0:b876cf091464 146 if(y0 == y2) {
neilt6 0:b876cf091464 147 a = b = x0;
neilt6 0:b876cf091464 148 if(x1 < a)
neilt6 0:b876cf091464 149 a = x1;
neilt6 0:b876cf091464 150 else if(x1 > b)
neilt6 0:b876cf091464 151 b = x1;
neilt6 0:b876cf091464 152 if(x2 < a)
neilt6 0:b876cf091464 153 a = x2;
neilt6 0:b876cf091464 154 else if(x2 > b)
neilt6 0:b876cf091464 155 b = x2;
neilt6 0:b876cf091464 156
neilt6 0:b876cf091464 157 drawHLine(a, y0, b - a + 1, c);
neilt6 0:b876cf091464 158
neilt6 0:b876cf091464 159 return;
neilt6 0:b876cf091464 160 }
neilt6 0:b876cf091464 161
neilt6 0:b876cf091464 162 int dx01 = x1 - x0;
neilt6 0:b876cf091464 163 int dy01 = y1 - y0;
neilt6 0:b876cf091464 164 int dx02 = x2 - x0;
neilt6 0:b876cf091464 165 int dy02 = y2 - y0;
neilt6 0:b876cf091464 166 int dx12 = x2 - x1;
neilt6 0:b876cf091464 167 int dy12 = y2 - y1;
neilt6 0:b876cf091464 168 int sa = 0;
neilt6 0:b876cf091464 169 int sb = 0;
neilt6 0:b876cf091464 170
neilt6 0:b876cf091464 171 //For upper part of triangle, find scanline crossings for segments
neilt6 0:b876cf091464 172 //0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
neilt6 0:b876cf091464 173 //is included here (and second loop will be skipped, avoiding a /0
neilt6 0:b876cf091464 174 //error there), otherwise scanline y1 is skipped here and handled
neilt6 0:b876cf091464 175 //in the second loop...which also avoids a /0 error here if y0=y1
neilt6 0:b876cf091464 176 //(flat-topped triangle).
neilt6 0:b876cf091464 177 if(y1 == y2)
neilt6 0:b876cf091464 178 last = y1; //Include y1 scanline
neilt6 0:b876cf091464 179 else
neilt6 0:b876cf091464 180 last = y1 - 1; //Skip it
neilt6 0:b876cf091464 181
neilt6 0:b876cf091464 182 for(y = y0; y <= last; y++) {
neilt6 0:b876cf091464 183 a = x0 + sa / dy01;
neilt6 0:b876cf091464 184 b = x0 + sb / dy02;
neilt6 0:b876cf091464 185 sa += dx01;
neilt6 0:b876cf091464 186 sb += dx02;
neilt6 0:b876cf091464 187
neilt6 0:b876cf091464 188 if(a > b) {
neilt6 0:b876cf091464 189 int temp = a;
neilt6 0:b876cf091464 190 a = b;
neilt6 0:b876cf091464 191 b = temp;
neilt6 0:b876cf091464 192 }
neilt6 0:b876cf091464 193 drawHLine(a, y, b - a + 1, c);
neilt6 0:b876cf091464 194 }
neilt6 0:b876cf091464 195
neilt6 0:b876cf091464 196 //For lower part of triangle, find scanline crossings for segments
neilt6 0:b876cf091464 197 //0-2 and 1-2. This loop is skipped if y1=y2.
neilt6 0:b876cf091464 198 sa = dx12 * (y - y1);
neilt6 0:b876cf091464 199 sb = dx02 * (y - y0);
neilt6 0:b876cf091464 200 for(; y <= y2; y++) {
neilt6 0:b876cf091464 201 a = x1 + sa / dy12;
neilt6 0:b876cf091464 202 b = x0 + sb / dy02;
neilt6 0:b876cf091464 203 sa += dx12;
neilt6 0:b876cf091464 204 sb += dx02;
neilt6 0:b876cf091464 205
neilt6 0:b876cf091464 206 if(a > b) {
neilt6 0:b876cf091464 207 int temp = a;
neilt6 0:b876cf091464 208 a = b;
neilt6 0:b876cf091464 209 b = temp;
neilt6 0:b876cf091464 210 }
neilt6 0:b876cf091464 211 drawHLine(a, y, b - a + 1, c);
neilt6 0:b876cf091464 212 }
neilt6 0:b876cf091464 213 }
neilt6 0:b876cf091464 214
neilt6 0:b876cf091464 215 void Canvas::drawCircle(int x, int y, int r, unsigned int c)
neilt6 0:b876cf091464 216 {
neilt6 0:b876cf091464 217 int f = 1 - r;
neilt6 0:b876cf091464 218 int ddF_x = 1;
neilt6 0:b876cf091464 219 int ddF_y = -2 * r;
neilt6 0:b876cf091464 220 int i = 0;
neilt6 0:b876cf091464 221 int j = r;
neilt6 0:b876cf091464 222
neilt6 0:b876cf091464 223 drawPixel(x, y + r, c);
neilt6 0:b876cf091464 224 drawPixel(x, y - r, c);
neilt6 0:b876cf091464 225 drawPixel(x + r, y, c);
neilt6 0:b876cf091464 226 drawPixel(x - r, y, c);
neilt6 0:b876cf091464 227
neilt6 0:b876cf091464 228 while(i < j) {
neilt6 0:b876cf091464 229 if(f >= 0) {
neilt6 0:b876cf091464 230 j--;
neilt6 0:b876cf091464 231 ddF_y += 2;
neilt6 0:b876cf091464 232 f += ddF_y;
neilt6 0:b876cf091464 233 }
neilt6 0:b876cf091464 234 i++;
neilt6 0:b876cf091464 235 ddF_x += 2;
neilt6 0:b876cf091464 236 f += ddF_x;
neilt6 0:b876cf091464 237 drawPixel(x + i, y + j, c);
neilt6 0:b876cf091464 238 drawPixel(x - i, y + j, c);
neilt6 0:b876cf091464 239 drawPixel(x + i, y - j, c);
neilt6 0:b876cf091464 240 drawPixel(x - i, y - j, c);
neilt6 0:b876cf091464 241 drawPixel(x + j, y + i, c);
neilt6 0:b876cf091464 242 drawPixel(x - j, y + i, c);
neilt6 0:b876cf091464 243 drawPixel(x + j, y - i, c);
neilt6 0:b876cf091464 244 drawPixel(x - j, y - i, c);
neilt6 0:b876cf091464 245 }
neilt6 0:b876cf091464 246 }
neilt6 0:b876cf091464 247
neilt6 0:b876cf091464 248 void Canvas::fillCircle(int x, int y, int r, unsigned int c)
neilt6 0:b876cf091464 249 {
neilt6 0:b876cf091464 250 drawVLine(x, y - r, 2 * r + 1, c);
neilt6 0:b876cf091464 251 fillCircleHelper(x, y, r, 3, 0, c);
neilt6 0:b876cf091464 252 }
neilt6 0:b876cf091464 253
neilt6 0:b876cf091464 254 void Canvas::drawRoundRect(int x, int y, int w, int h, int r, unsigned int c)
neilt6 0:b876cf091464 255 {
neilt6 0:b876cf091464 256 //Draw the four lines
neilt6 0:b876cf091464 257 drawHLine(x + r, y, w - 2 * r, c); //Top
neilt6 0:b876cf091464 258 drawHLine(x + r, y + h - 1, w - 2 * r, c); //Bottom
neilt6 0:b876cf091464 259 drawVLine(x, y + r, h - 2 * r, c); //Left
neilt6 0:b876cf091464 260 drawVLine(x + w - 1, y + r, h - 2 * r, c); //Right
neilt6 0:b876cf091464 261
neilt6 0:b876cf091464 262 //Draw the four corners
neilt6 0:b876cf091464 263 drawCircleHelper(x + r, y + r, r, 1, c);
neilt6 0:b876cf091464 264 drawCircleHelper(x + w - r - 1, y + r, r, 2, c);
neilt6 0:b876cf091464 265 drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, c);
neilt6 0:b876cf091464 266 drawCircleHelper(x + r, y + h - r - 1, r, 8, c);
neilt6 0:b876cf091464 267 }
neilt6 0:b876cf091464 268
neilt6 0:b876cf091464 269 void Canvas::fillRoundRect(int x, int y, int w, int h, int r, unsigned int c)
neilt6 0:b876cf091464 270 {
neilt6 0:b876cf091464 271 //Draw the body
neilt6 0:b876cf091464 272 fillRect(x + r, y, w - 2 * r, h, c);
neilt6 0:b876cf091464 273
neilt6 0:b876cf091464 274 //Draw the four corners
neilt6 0:b876cf091464 275 fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, c);
neilt6 0:b876cf091464 276 fillCircleHelper(x+r, y + r, r, 2, h - 2 * r - 1, c);
neilt6 0:b876cf091464 277 }
neilt6 0:b876cf091464 278
neilt6 1:f7003ec66a51 279 void Canvas::drawImage(Image* img, int x, int y)
neilt6 0:b876cf091464 280 {
neilt6 0:b876cf091464 281 for (int j = 0; j < img->height(); j++) {
neilt6 0:b876cf091464 282 for (int i = 0; i < img->width(); i++) {
neilt6 0:b876cf091464 283 drawPixel(i + x, j + y, img->pixel(i, j));
neilt6 0:b876cf091464 284 }
neilt6 0:b876cf091464 285 }
neilt6 0:b876cf091464 286 }
neilt6 0:b876cf091464 287
neilt6 1:f7003ec66a51 288 int Canvas::drawChar(char c, Font* fnt, int x, int y)
neilt6 0:b876cf091464 289 {
neilt6 0:b876cf091464 290 //Get the character glyph
neilt6 0:b876cf091464 291 BitmapImage glyph = fnt->glyph(c);
neilt6 0:b876cf091464 292
neilt6 0:b876cf091464 293 //Draw the character glyph
neilt6 0:b876cf091464 294 drawImage(&glyph, x, y);
neilt6 0:b876cf091464 295
neilt6 0:b876cf091464 296 //Return the width of the glyph
neilt6 0:b876cf091464 297 return glyph.width();
neilt6 0:b876cf091464 298 }
neilt6 0:b876cf091464 299
neilt6 1:f7003ec66a51 300 void Canvas::drawString(const char* str, Font* fnt, int x, int y)
neilt6 0:b876cf091464 301 {
neilt6 0:b876cf091464 302 int cursX = 0;
neilt6 0:b876cf091464 303 int cursY = 0;
neilt6 0:b876cf091464 304
neilt6 0:b876cf091464 305 while(*str != NULL) {
neilt6 0:b876cf091464 306 //Check for a new line character
neilt6 0:b876cf091464 307 if (*str == '\n') {
neilt6 0:b876cf091464 308 //Go to a new line
neilt6 0:b876cf091464 309 cursX = 0;
neilt6 0:b876cf091464 310 cursY += fnt->height();
neilt6 0:b876cf091464 311
neilt6 0:b876cf091464 312 //We're done for this character
neilt6 0:b876cf091464 313 str++;
neilt6 0:b876cf091464 314 continue;
neilt6 0:b876cf091464 315 }
neilt6 0:b876cf091464 316
neilt6 0:b876cf091464 317 //Check for a carriage return character
neilt6 0:b876cf091464 318 if (*str == '\r') {
neilt6 0:b876cf091464 319 //Ignore it, we're done for this character
neilt6 0:b876cf091464 320 str++;
neilt6 0:b876cf091464 321 continue;
neilt6 0:b876cf091464 322 }
neilt6 0:b876cf091464 323
neilt6 0:b876cf091464 324 //Draw the character
neilt6 0:b876cf091464 325 cursX += drawChar(*str++, fnt, x + cursX, y + cursY);
neilt6 0:b876cf091464 326 }
neilt6 0:b876cf091464 327 }
neilt6 0:b876cf091464 328
neilt6 1:f7003ec66a51 329 void Canvas::drawString(const char* str, Font* fnt, int x, int y, int w, int h)
neilt6 0:b876cf091464 330 {
neilt6 0:b876cf091464 331 int cursX = 0;
neilt6 0:b876cf091464 332 int cursY = 0;
neilt6 0:b876cf091464 333
neilt6 0:b876cf091464 334 while(*str != NULL) {
neilt6 0:b876cf091464 335 //Check for a new line character
neilt6 0:b876cf091464 336 if (*str == '\n') {
neilt6 0:b876cf091464 337 //Check if we can fit another line
neilt6 0:b876cf091464 338 if ((cursY + 2 * fnt->height()) < h) {
neilt6 0:b876cf091464 339 //Yes we can
neilt6 0:b876cf091464 340 cursX = 0;
neilt6 0:b876cf091464 341 cursY += fnt->height();
neilt6 0:b876cf091464 342
neilt6 0:b876cf091464 343 //We're done for this character
neilt6 0:b876cf091464 344 str++;
neilt6 0:b876cf091464 345 continue;
neilt6 0:b876cf091464 346 } else {
neilt6 0:b876cf091464 347 //Nope, we can't print any more so return
neilt6 0:b876cf091464 348 return;
neilt6 0:b876cf091464 349 }
neilt6 0:b876cf091464 350 }
neilt6 0:b876cf091464 351
neilt6 0:b876cf091464 352 //Check for a carriage return character
neilt6 0:b876cf091464 353 if (*str == '\r') {
neilt6 0:b876cf091464 354 //Ignore it, we're done for this character
neilt6 0:b876cf091464 355 str++;
neilt6 0:b876cf091464 356 continue;
neilt6 0:b876cf091464 357 }
neilt6 0:b876cf091464 358
neilt6 0:b876cf091464 359 //Check for entire words first
neilt6 0:b876cf091464 360 if ((*str > ' ') && (*str <= 0x7E)) {
neilt6 0:b876cf091464 361 //Draw entire word on canvas with correct wrapping
neilt6 0:b876cf091464 362 //int i = 0;
neilt6 0:b876cf091464 363 int wlen;
neilt6 0:b876cf091464 364
neilt6 0:b876cf091464 365 //Determine the length of the next word
neilt6 0:b876cf091464 366 wlen = fnt->measureWord(str);
neilt6 0:b876cf091464 367
neilt6 0:b876cf091464 368 //Will the length of the next word exceed the margins?
neilt6 0:b876cf091464 369 if ((wlen + cursX) > w) {
neilt6 0:b876cf091464 370 //Only do a newline if the word will fit on it
neilt6 0:b876cf091464 371 if (wlen <= w) {
neilt6 0:b876cf091464 372 //Check if we can fit another line
neilt6 0:b876cf091464 373 if ((cursY + 2 * fnt->height()) < h) {
neilt6 0:b876cf091464 374 //Yes we can
neilt6 0:b876cf091464 375 cursX = 0;
neilt6 0:b876cf091464 376 cursY += fnt->height();
neilt6 0:b876cf091464 377 } else {
neilt6 0:b876cf091464 378 //Nope, we can't print any more so return
neilt6 0:b876cf091464 379 return;
neilt6 0:b876cf091464 380 }
neilt6 0:b876cf091464 381 }
neilt6 0:b876cf091464 382 }
neilt6 0:b876cf091464 383
neilt6 0:b876cf091464 384 //Put just the word characters on the display up to the next non-whitespace character or the end of the string
neilt6 0:b876cf091464 385 while ((*str > ' ') && (*str <= 0x7E)) {
neilt6 0:b876cf091464 386 //Check if the character will fit on the screen
neilt6 0:b876cf091464 387 if ((fnt->glyph(*str).width() + cursX) > w) {
neilt6 0:b876cf091464 388 //Check if we can fit another line
neilt6 0:b876cf091464 389 if ((cursY + 2 * fnt->height()) < h) {
neilt6 0:b876cf091464 390 //Yes we can
neilt6 0:b876cf091464 391 cursX = 0;
neilt6 0:b876cf091464 392 cursY += fnt->height();
neilt6 0:b876cf091464 393 } else {
neilt6 0:b876cf091464 394 //Nope, we can't print any more so return
neilt6 0:b876cf091464 395 return;
neilt6 0:b876cf091464 396 }
neilt6 0:b876cf091464 397 }
neilt6 0:b876cf091464 398
neilt6 0:b876cf091464 399 //Draw the character
neilt6 0:b876cf091464 400 cursX += drawChar(*str++, fnt, x + cursX, y + cursY);
neilt6 0:b876cf091464 401 }
neilt6 0:b876cf091464 402 } else {
neilt6 0:b876cf091464 403 //Check if the character will fit on the screen
neilt6 0:b876cf091464 404 if ((fnt->glyph(*str).width() + cursX) > w) {
neilt6 0:b876cf091464 405 //Check if we can fit another line
neilt6 0:b876cf091464 406 if ((cursY + 2 * fnt->height()) < h) {
neilt6 0:b876cf091464 407 //Yes we can
neilt6 0:b876cf091464 408 cursX = 0;
neilt6 0:b876cf091464 409 cursY += fnt->height();
neilt6 0:b876cf091464 410 } else {
neilt6 0:b876cf091464 411 //Nope, we can't print any more so return
neilt6 0:b876cf091464 412 return;
neilt6 0:b876cf091464 413 }
neilt6 0:b876cf091464 414 }
neilt6 0:b876cf091464 415
neilt6 0:b876cf091464 416 //Draw the character
neilt6 0:b876cf091464 417 cursX += drawChar(*str++, fnt, x + cursX, y + cursY);
neilt6 0:b876cf091464 418 }
neilt6 0:b876cf091464 419 }
neilt6 0:b876cf091464 420 }
neilt6 0:b876cf091464 421
neilt6 1:f7003ec66a51 422 int Canvas::width()
neilt6 0:b876cf091464 423 {
neilt6 0:b876cf091464 424 return m_Width;
neilt6 0:b876cf091464 425 }
neilt6 0:b876cf091464 426
neilt6 1:f7003ec66a51 427 int Canvas::height()
neilt6 0:b876cf091464 428 {
neilt6 0:b876cf091464 429 return m_Height;
neilt6 0:b876cf091464 430 }
neilt6 0:b876cf091464 431
neilt6 0:b876cf091464 432 void Canvas::drawCircleHelper(int x, int y, int r, unsigned int corner, unsigned int c)
neilt6 0:b876cf091464 433 {
neilt6 0:b876cf091464 434 int f = 1 - r;
neilt6 0:b876cf091464 435 int ddF_x = 1;
neilt6 0:b876cf091464 436 int ddF_y = -2 * r;
neilt6 0:b876cf091464 437 int i = 0;
neilt6 0:b876cf091464 438 int j = r;
neilt6 0:b876cf091464 439
neilt6 0:b876cf091464 440 while (i < j) {
neilt6 0:b876cf091464 441 if (f >= 0) {
neilt6 0:b876cf091464 442 j--;
neilt6 0:b876cf091464 443 ddF_y += 2;
neilt6 0:b876cf091464 444 f += ddF_y;
neilt6 0:b876cf091464 445 }
neilt6 0:b876cf091464 446 i++;
neilt6 0:b876cf091464 447 ddF_x += 2;
neilt6 0:b876cf091464 448 f += ddF_x;
neilt6 0:b876cf091464 449 if (corner & 0x4) {
neilt6 0:b876cf091464 450 drawPixel(x + i, y + j, c);
neilt6 0:b876cf091464 451 drawPixel(x + j, y + i, c);
neilt6 0:b876cf091464 452 }
neilt6 0:b876cf091464 453 if (corner & 0x2) {
neilt6 0:b876cf091464 454 drawPixel(x + i, y - j, c);
neilt6 0:b876cf091464 455 drawPixel(x + j, y - i, c);
neilt6 0:b876cf091464 456 }
neilt6 0:b876cf091464 457 if (corner & 0x8) {
neilt6 0:b876cf091464 458 drawPixel(x - j, y + i, c);
neilt6 0:b876cf091464 459 drawPixel(x - i, y + j, c);
neilt6 0:b876cf091464 460 }
neilt6 0:b876cf091464 461 if (corner & 0x1) {
neilt6 0:b876cf091464 462 drawPixel(x - j, y - i, c);
neilt6 0:b876cf091464 463 drawPixel(x - i, y - j, c);
neilt6 0:b876cf091464 464 }
neilt6 0:b876cf091464 465 }
neilt6 0:b876cf091464 466 }
neilt6 0:b876cf091464 467
neilt6 0:b876cf091464 468 void Canvas::fillCircleHelper(int x, int y, int r, unsigned int corner, int delta, unsigned int c)
neilt6 0:b876cf091464 469 {
neilt6 0:b876cf091464 470 int f = 1 - r;
neilt6 0:b876cf091464 471 int ddF_x = 1;
neilt6 0:b876cf091464 472 int ddF_y = -2 * r;
neilt6 0:b876cf091464 473 int i = 0;
neilt6 0:b876cf091464 474 int j = r;
neilt6 0:b876cf091464 475
neilt6 0:b876cf091464 476 while (i < j) {
neilt6 0:b876cf091464 477 if (f >= 0) {
neilt6 0:b876cf091464 478 j--;
neilt6 0:b876cf091464 479 ddF_y += 2;
neilt6 0:b876cf091464 480 f += ddF_y;
neilt6 0:b876cf091464 481 }
neilt6 0:b876cf091464 482 i++;
neilt6 0:b876cf091464 483 ddF_x += 2;
neilt6 0:b876cf091464 484 f += ddF_x;
neilt6 0:b876cf091464 485
neilt6 0:b876cf091464 486 if (corner & 0x1) {
neilt6 0:b876cf091464 487 drawVLine(x + i, y - j, 2 * j + 1 + delta, c);
neilt6 0:b876cf091464 488 drawVLine(x + j, y - i, 2 * i + 1 + delta, c);
neilt6 0:b876cf091464 489 }
neilt6 0:b876cf091464 490 if (corner & 0x2) {
neilt6 0:b876cf091464 491 drawVLine(x - i, y - j, 2 * j + 1 + delta, c);
neilt6 0:b876cf091464 492 drawVLine(x - j, y - i, 2 * i + 1 + delta, c);
neilt6 0:b876cf091464 493 }
neilt6 0:b876cf091464 494 }
neilt6 0:b876cf091464 495 }