ECE4760 - Laser Projector (ipb7, jcc384, pfc38)  1
Raster Laser Projection
rendering.c
Go to the documentation of this file.
1 /* Code copied and slightly adapted from Tahmid's pic32 adaptation
2  * of a TFT screen driver.
3  */
4 
5 /* Code rewritten from Adafruit Arduino library for the TFT
6  * by Syed Tahmid Mahbub
7  * The TFT itself is Adafruit product 1480
8  * Included below is the text header from the original Adafruit library
9  * followed by the code
10  */
11 
12 /*
13  * This is the core graphics library for all our displays, providing a common
14  * set of graphics primitives (points, lines, circles, etc.). It needs to be
15  * paired with a hardware-specific library for each display device we carry
16  * (to handle the lower-level functions).
17  *
18  * Adafruit invests time and resources providing this open source code, please
19  * support Adafruit & open-source hardware by purchasing products from Adafruit!
20  *
21  * Copyright (c) 2013 Adafruit Industries. All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions are met:
25  *
26  * - Redistributions of source code must retain the above copyright notice,
27  * this list of conditions and the following disclaimer.
28  * - Redistributions in binary form must reproduce the above copyright notice,
29  * this list of conditions and the following disclaimer in the documentation
30  * and/or other materials provided with the distribution.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGE.
43  */
44 
45 #include "rendering.h"
46 #include "glcdfont.c"
47 
48 /*******************************/
49 /* LOCAL Macro Definitions */
50 /*******************************/
52 
53 //copy-pastad from tft_ghx.h
54 #define swap(a, b) { short t = a; a = b; b = t; }
55 #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
56 
58 
59 /********************************/
60 /* LOCAL Type(def) Declarations */
61 /********************************/
63 
65 
66 /*******************************/
67 /* LOCAL Variable Definitions */
68 /*******************************/
70 
71 static struct color textcolor;
72 static struct color textbgcolor;
73 static unsigned short cursor_y;
74 static unsigned short cursor_x;
75 static unsigned short textsize;
76 static unsigned short wrap;
77 static unsigned short rotation;
78 
80 
81 /*******************************/
82 /* LOCAL Function Declarations */
83 /*******************************/
85 
87 
88 /*******************************/
89 /* GLOBAL Variable Definitions */
90 /*******************************/
92 
94 
95 /*******************************/
96 /* GLOBAL Function Definitions */
97 /*******************************/
99 
100 void rendering_drawCircle(short x0, short y0, short r,
101  struct color color) {
102  /* Draw a circle outline with center (x0,y0) and radius r, with given color
103  * Parameters:
104  * x0: x-coordinate of center of circle. The top-left of the screen
105  * has x-coordinate 0 and increases to the right
106  * y0: y-coordinate of center of circle. The top-left of the screen
107  * has y-coordinate 0 and increases to the bottom
108  * r: radius of circle
109  * color: 16-bit color value for the circle. Note that the circle
110  * isn't filled. So, this is the color of the outline of the circle
111  * Returns: Nothing
112  */
113  short f = 1 - r;
114  short ddF_x = 1;
115  short ddF_y = -2 * r;
116  short x = 0;
117  short y = r;
118 
119  rendering_drawPixel(x0 , y0+r, color);
120  rendering_drawPixel(x0 , y0-r, color);
121  rendering_drawPixel(x0+r, y0 , color);
122  rendering_drawPixel(x0-r, y0 , color);
123 
124  while (x<y) {
125  if (f >= 0) {
126  y--;
127  ddF_y += 2;
128  f += ddF_y;
129  }
130  x++;
131  ddF_x += 2;
132  f += ddF_x;
133 
134  rendering_drawPixel(x0 + x, y0 + y, color);
135  rendering_drawPixel(x0 - x, y0 + y, color);
136  rendering_drawPixel(x0 + x, y0 - y, color);
137  rendering_drawPixel(x0 - x, y0 - y, color);
138  rendering_drawPixel(x0 + y, y0 + x, color);
139  rendering_drawPixel(x0 - y, y0 + x, color);
140  rendering_drawPixel(x0 + y, y0 - x, color);
141  rendering_drawPixel(x0 - y, y0 - x, color);
142  }
143 }
144 
145 void rendering_drawCircleHelper(short x0, short y0, short r,
146  unsigned char cornername,
147  struct color color) {
148  // Helper function for drawing circles and circular objects
149  short f = 1 - r;
150  short ddF_x = 1;
151  short ddF_y = -2 * r;
152  short x = 0;
153  short y = r;
154 
155  while (x<y) {
156  if (f >= 0) {
157  y--;
158  ddF_y += 2;
159  f += ddF_y;
160  }
161  x++;
162  ddF_x += 2;
163  f += ddF_x;
164  if (cornername & 0x4) {
165  rendering_drawPixel(x0 + x, y0 + y, color);
166  rendering_drawPixel(x0 + y, y0 + x, color);
167  }
168  if (cornername & 0x2) {
169  rendering_drawPixel(x0 + x, y0 - y, color);
170  rendering_drawPixel(x0 + y, y0 - x, color);
171  }
172  if (cornername & 0x8) {
173  rendering_drawPixel(x0 - y, y0 + x, color);
174  rendering_drawPixel(x0 - x, y0 + y, color);
175  }
176  if (cornername & 0x1) {
177  rendering_drawPixel(x0 - y, y0 - x, color);
178  rendering_drawPixel(x0 - x, y0 - y, color);
179  }
180  }
181 }
182 
183 void rendering_fillCircle(short x0, short y0, short r,
184  struct color color) {
185  /* Draw a filled circle with center (x0,y0) and radius r, with given color
186  * Parameters:
187  * x0: x-coordinate of center of circle. The top-left of the screen
188  * has x-coordinate 0 and increases to the right
189  * y0: y-coordinate of center of circle. The top-left of the screen
190  * has y-coordinate 0 and increases to the bottom
191  * r: radius of circle
192  * color: 16-bit color value for the circle
193  * Returns: Nothing
194  */
195  rendering_drawFastVLine(x0, y0-r, 2*r+1, color);
196  rendering_fillCircleHelper(x0, y0, r, 3, 0, color);
197 }
198 
199 void rendering_fillCircleHelper(short x0, short y0, short r,
200  unsigned char cornername, short delta,
201  struct color color) {
202  // Helper function for drawing filled circles
203  short f = 1 - r;
204  short ddF_x = 1;
205  short ddF_y = -2 * r;
206  short x = 0;
207  short y = r;
208 
209  while (x<y) {
210  if (f >= 0) {
211  y--;
212  ddF_y += 2;
213  f += ddF_y;
214  }
215  x++;
216  ddF_x += 2;
217  f += ddF_x;
218 
219  if (cornername & 0x1) {
220  rendering_drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
221  rendering_drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
222  }
223  if (cornername & 0x2) {
224  rendering_drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
225  rendering_drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
226  }
227  }
228 }
229 
230 // Bresenham's algorithm - thx wikpedia
231 void rendering_drawLine(short x0, short y0,
232  short x1, short y1,
233  struct color color) {
234  /* Draw a straight line from (x0,y0) to (x1,y1) with given color
235  * Parameters:
236  * x0: x-coordinate of starting point of line. The x-coordinate of
237  * the top-left of the screen is 0. It increases to the right.
238  * y0: y-coordinate of starting point of line. The y-coordinate of
239  * the top-left of the screen is 0. It increases to the bottom.
240  * x1: x-coordinate of ending point of line. The x-coordinate of
241  * the top-left of the screen is 0. It increases to the right.
242  * y1: y-coordinate of ending point of line. The y-coordinate of
243  * the top-left of the screen is 0. It increases to the bottom.
244  * color: 16-bit color value for line
245  */
246  short steep = abs(y1 - y0) > abs(x1 - x0);
247  if (steep) {
248  swap(x0, y0);
249  swap(x1, y1);
250  }
251 
252  if (x0 > x1) {
253  swap(x0, x1);
254  swap(y0, y1);
255  }
256 
257  short dx, dy;
258  dx = x1 - x0;
259  dy = abs(y1 - y0);
260 
261  short err = dx / 2;
262  short ystep;
263 
264  if (y0 < y1) {
265  ystep = 1;
266  } else {
267  ystep = -1;
268  }
269 
270  for (; x0<=x1; x0++) {
271  if (steep) {
272  rendering_drawPixel(y0, x0, color);
273  } else {
274  rendering_drawPixel(x0, y0, color);
275  }
276  err -= dy;
277  if (err < 0) {
278  y0 += ystep;
279  err += dx;
280  }
281  }
282 }
283 
284 // Draw a rectangle
285 void rendering_drawRect(short x, short y, short w, short h,
286  struct color color) {
287  /* Draw a rectangle outline with top left vertex (x,y), width w
288  * and height h at given color
289  * Parameters:
290  * x: x-coordinate of top-left vertex. The x-coordinate of
291  * the top-left of the screen is 0. It increases to the right.
292  * y: y-coordinate of top-left vertex. The y-coordinate of
293  * the top-left of the screen is 0. It increases to the bottom.
294  * w: width of the rectangle
295  * h: height of the rectangle
296  * color: 16-bit color of the rectangle outline
297  * Returns: Nothing
298  */
299  rendering_drawFastHLine(x, y, w, color);
300  rendering_drawFastHLine(x, y+h-1, w, color);
301  rendering_drawFastVLine(x, y, h, color);
302  rendering_drawFastVLine(x+w-1, y, h, color);
303 }
304 
305 // Draw a rounded rectangle
306 void rendering_drawRoundRect(short x, short y, short w, short h,
307  short r, struct color color) {
308  /* Draw a rounded rectangle outline with top left vertex (x,y), width w,
309  * height h and radius of curvature r at given color
310  * Parameters:
311  * x: x-coordinate of top-left vertex. The x-coordinate of
312  * the top-left of the screen is 0. It increases to the right.
313  * y: y-coordinate of top-left vertex. The y-coordinate of
314  * the top-left of the screen is 0. It increases to the bottom.
315  * w: width of the rectangle
316  * h: height of the rectangle
317  * color: 16-bit color of the rectangle outline
318  * Returns: Nothing
319  */
320  // smarter version
321  rendering_drawFastHLine(x+r , y , w-2*r, color); // Top
322  rendering_drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom
323  rendering_drawFastVLine(x , y+r , h-2*r, color); // Left
324  rendering_drawFastVLine(x+w-1, y+r , h-2*r, color); // Right
325  // draw four corners
326  rendering_drawCircleHelper(x+r , y+r , r, 1, color);
327  rendering_drawCircleHelper(x+w-r-1, y+r , r, 2, color);
328  rendering_drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
329  rendering_drawCircleHelper(x+r , y+h-r-1, r, 8, color);
330 }
331 
332 // Fill a rounded rectangle
333 void rendering_fillRoundRect(short x, short y, short w, short h, short r,
334  struct color color) {
335  // smarter version
336  rendering_fillRect(x+r, y, w-2*r, h, color);
337 
338  // draw four corners
339  rendering_fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
340  rendering_fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color);
341 }
342 
343 // Draw a triangle
344 void rendering_drawTriangle(short x0, short y0, short x1, short y1, short x2,
345  short y2, struct color color) {
346  /* Draw a triangle outline with vertices (x0,y0),(x1,y1),(x2,y2) with given color
347  * Parameters:
348  * x0: x-coordinate of one of the 3 vertices
349  * y0: y-coordinate of one of the 3 vertices
350  * x1: x-coordinate of one of the 3 vertices
351  * y1: y-coordinate of one of the 3 vertices
352  * x2: x-coordinate of one of the 3 vertices
353  * y2: y-coordinate of one of the 3 vertices
354  * color: 16-bit color value for outline
355  * Returns: Nothing
356  */
357  rendering_drawLine(x0, y0, x1, y1, color);
358  rendering_drawLine(x1, y1, x2, y2, color);
359  rendering_drawLine(x2, y2, x0, y0, color);
360 }
361 
362 // Fill a triangle
363 void rendering_fillTriangle (short x0, short y0, short x1, short y1, short x2,
364  short y2, struct color color) {
365  /* Draw a filled triangle with vertices (x0,y0),(x1,y1),(x2,y2) with given color
366  * Parameters:
367  * x0: x-coordinate of one of the 3 vertices
368  * y0: y-coordinate of one of the 3 vertices
369  * x1: x-coordinate of one of the 3 vertices
370  * y1: y-coordinate of one of the 3 vertices
371  * x2: x-coordinate of one of the 3 vertices
372  * y2: y-coordinate of one of the 3 vertices
373  * color: 16-bit color value
374  * Returns: Nothing
375  */
376  short a, b, y, last;
377 
378  // Sort coordinates by Y order (y2 >= y1 >= y0)
379  if (y0 > y1) {
380  swap(y0, y1); swap(x0, x1);
381  }
382  if (y1 > y2) {
383  swap(y2, y1); swap(x2, x1);
384  }
385  if (y0 > y1) {
386  swap(y0, y1); swap(x0, x1);
387  }
388 
389  if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
390  a = b = x0;
391  if(x1 < a) a = x1;
392  else if(x1 > b) b = x1;
393  if(x2 < a) a = x2;
394  else if(x2 > b) b = x2;
395  rendering_drawFastHLine(a, y0, b-a+1, color);
396  return;
397  }
398 
399  short
400  dx01 = x1 - x0,
401  dy01 = y1 - y0,
402  dx02 = x2 - x0,
403  dy02 = y2 - y0,
404  dx12 = x2 - x1,
405  dy12 = y2 - y1,
406  sa = 0,
407  sb = 0;
408 
409  // For upper part of triangle, find scanline crossings for segments
410  // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
411  // is included here (and second loop will be skipped, avoiding a /0
412  // error there), otherwise scanline y1 is skipped here and handled
413  // in the second loop...which also avoids a /0 error here if y0=y1
414  // (flat-topped triangle).
415  if(y1 == y2) last = y1; // Include y1 scanline
416  else last = y1-1; // Skip it
417 
418  for(y=y0; y<=last; y++) {
419  a = x0 + sa / dy01;
420  b = x0 + sb / dy02;
421  sa += dx01;
422  sb += dx02;
423  /* longhand:
424  a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
425  b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
426  */
427  if(a > b) swap(a,b);
428  rendering_drawFastHLine(a, y, b-a+1, color);
429  }
430 
431  // For lower part of triangle, find scanline crossings for segments
432  // 0-2 and 1-2. This loop is skipped if y1=y2.
433  sa = dx12 * (y - y1);
434  sb = dx02 * (y - y0);
435  for(; y<=y2; y++) {
436  a = x1 + sa / dy12;
437  b = x0 + sb / dy02;
438  sa += dx12;
439  sb += dx02;
440  /* longhand:
441  a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
442  b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
443  */
444  if(a > b) swap(a,b);
445  rendering_drawFastHLine(a, y, b-a+1, color);
446  }
447 }
448 
449 void rendering_drawBitmap(short x, short y,
450  const unsigned char *bitmap, short w, short h,
451  struct color color) {
452 
453  short i, j, byteWidth = (w + 7) / 8;
454 
455  for(j=0; j<h; j++) {
456  for(i=0; i<w; i++ ) {
457  if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) {
458  rendering_drawPixel(x+i, y+j, color);
459  }
460  }
461  }
462 }
463 
464 void rendering_write(unsigned char c){
465  if (c == '\n') {
466  cursor_y += textsize*8;
467  cursor_x = 0;
468  } else if (c == '\r') {
469  // skip em
470  } else if (c == '\t'){
471  int new_x = cursor_x + RENDERING_TAB_WIDTH;
472  if (new_x < IMAGE_WIDTH){
473  cursor_x = new_x;
474  }
475  } else {
476  rendering_drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
477  cursor_x += textsize*6;
478  if (wrap && (cursor_x > (IMAGE_WIDTH - textsize*6))) {
479  cursor_y += textsize*8;
480  cursor_x = 0;
481  }
482  }
483 }
484 
485 inline void rendering_writeString(char* str){
486  /* Print text onto screen
487  * Call rendering_setCursor(), rendering_setTextColor(), rendering_setTextSize()
488  * as necessary before printing
489  */
490  while (*str){
491  rendering_write(*str++);
492  }
493 }
494 
495 // Draw a character
496 void rendering_drawChar(short x, short y, unsigned char c,
497  struct color color, struct color bg,
498  unsigned char size) {
499  char i, j;
500  if((x >= IMAGE_WIDTH) || // Clip right
501  (y >= IMAGE_HEIGHT) || // Clip bottom
502  ((x + 6 * size - 1) < 0) || // Clip left
503  ((y + 8 * size - 1) < 0)) // Clip top
504  return;
505 
506  for (i=0; i<6; i++ ) {
507  unsigned char line;
508  if (i == 5)
509  line = 0x0;
510  else
511  line = pgm_read_byte(font+(c*5)+i);
512  for ( j = 0; j<8; j++) {
513  if (line & 0x1) {
514  if (size == 1) // default size
515  rendering_drawPixel(x+i, y+j, color);
516  else { // big size
517  rendering_fillRect(x+(i*size), y+(j*size), size, size, color);
518  }
519  } else if (!color_equal(bg, color)) {
520  if (size == 1) // default size
521  rendering_drawPixel(x+i, y+j, bg);
522  else { // big size
523  rendering_fillRect(x+i*size, y+j*size, size, size, bg);
524  }
525  }
526  line >>= 1;
527  }
528  }
529 }
530 
531 inline void rendering_setCursor(short x, short y) {
532  /* Set cursor for text to be printed
533  * Parameters:
534  * x = x-coordinate of top-left of text starting
535  * y = y-coordinate of top-left of text starting
536  * Returns: Nothing
537  */
538  cursor_x = x;
539  cursor_y = y;
540 }
541 
542 inline void rendering_setTextSize(unsigned char s) {
543  /*Set size of text to be displayed
544  * Parameters:
545  * s = text size (1 being smallest)
546  * Returns: nothing
547  */
548  textsize = (s > 0) ? s : 1;
549 }
550 
551 inline void rendering_setTextColor(struct color c) {
552  // For 'transparent' background, we'll set the bg
553  // to the same as fg instead of using a flag
554  textcolor = textbgcolor = c;
555 }
556 
557 inline void rendering_setTextColor2(struct color c,
558  struct color b) {
559  /* Set color of text to be displayed
560  * Parameters:
561  * c = 16-bit color of text
562  * b = 16-bit color of text background
563  */
564  textcolor = c;
565  textbgcolor = b;
566 }
567 
568 inline void rendering_setTextWrap(char w) {
569  wrap = w;
570 }
571 
572 inline unsigned char rendering_getRotation(void) {
573  /* Returns current roation of screen
574  * 0 = no rotation (0 degree rotation)
575  * 1 = rotate 90 degree clockwise
576  * 2 = rotate 180 degree
577  * 3 = rotate 90 degree anticlockwise
578  */
579  return rotation;
580 }
581 
582 // this function totally replaces the original tft version
583 void rendering_drawPixel(short x, short y,
584  struct color color) {
585  if (x >= IMAGE_WIDTH || y >= IMAGE_HEIGHT || x < 0 || y < 0) {
586  // no-op if pixel is off screen
587  return;
588  } else {
589  projector_set_pixel(color, (unsigned int) x, (unsigned int) y);
590  }
591 }
592 
593 // from tft_master.c, but modified to just call drawPixel
594 void rendering_drawFastVLine(short x, short y, short h,
595  struct color color) {
596  /* Draw a vertical line at location from (x,y) to (x,y+h-1) with color
597  * Parameters:
598  * x: x-coordinate line to draw; top left of screen is x=0
599  * and x increases to the right
600  * y: y-coordinate of starting point of line; top left of screen is y=0
601  * and y increases to the bottom
602  * h: height of line to draw
603  * color: 16-bit color value
604  * Returns: Nothing
605  */
606 
607  // Rudimentary clipping
608  if((x >= IMAGE_WIDTH) || (y >= IMAGE_HEIGHT)) return;
609 
610  // don't go off screen
611  if((y+h-1) >= IMAGE_HEIGHT)
612  h = IMAGE_HEIGHT - y;
613 
614  // draw from bottom to top
615  int current_y;
616  for (current_y = y; current_y < y + h - 1; current_y++) {
617  rendering_drawPixel(x, current_y, color);
618  }
619 }
620 
621 // from tft_master.c, but modified to just call drawPixel
622 void rendering_drawFastHLine(short x, short y, short w,
623  struct color color) {
624  /* Draw a horizontal line at location from (x,y) to (x+w-1,y) with color
625  * Parameters:
626  * x: x-coordinate starting point of line; top left of screen is x=0
627  * and x increases to the right
628  * y: y-coordinate of starting point of line; top left of screen is y=0
629  * and y increases to the bottom
630  * w: width of line to draw
631  * color: 16-bit color value
632  * Returns: Nothing
633  */
634 
635  // Rudimentary clipping
636  if((x >= IMAGE_WIDTH) || (y >= IMAGE_HEIGHT)) {
637  return;
638  }
639 
640  // don't go off edge of screen
641  if((x+w-1) >= IMAGE_WIDTH) {
642  w = IMAGE_WIDTH - x;
643  }
644 
645  // draw from left to right
646  int current_x;
647  for (current_x = x; current_x < x + w - 1; current_x++) {
648  rendering_drawPixel(current_x, y, color);
649  }
650 }
651 
652 // from tft_master.c, but modified to just call drawPixel
653 void rendering_fillRect(short x, short y, short w, short h,
654  struct color color) {
655  /* Draw a filled rectangle with starting top-left vertex (x,y),
656  * width w and height h with given color
657  * Parameters:
658  * x: x-coordinate of top-left vertex; top left of screen is x=0
659  * and x increases to the right
660  * y: y-coordinate of top-left vertex; top left of screen is y=0
661  * and y increases to the bottom
662  * w: width of rectangle
663  * h: height of rectangle
664  * color: 16-bit color value
665  * Returns: Nothing
666  */
667 
668  // rudimentary clipping (drawChar w/big text requires this)
669  if ((x >= IMAGE_WIDTH) || (y >= IMAGE_HEIGHT)) {
670  return;
671  }
672 
673  // don't go off screen horizontally
674  if ((x + w - 1) >= IMAGE_WIDTH) {
675  w = IMAGE_WIDTH - x;
676  }
677  // don't go off screen vertically
678  if ((y + h - 1) >= IMAGE_HEIGHT) {
679  h = IMAGE_HEIGHT - y;
680  }
681 
682  int current_y;
683  // iterate through y first then x because the framebuffer array is laid out by
684  // row then column. This may be good for performance, but the order is
685  // arbitrary anyway.
686  for (current_y = y; current_y < y + h - 1; current_y++) {
687  int current_x;
688  for (current_x = x; current_x < x + w - 1; current_x++) {
689  rendering_drawPixel(current_x, current_y, color);
690  }
691  }
692 }
693 
694 void rendering_drawMinimalCross(short const x, short const y,
695  struct color const color) {
696  rendering_drawPixel(x - 1, y, color); // b
697  rendering_drawPixel(x, y, color); // c X a X
698  rendering_drawPixel(x + 1, y, color); // d b c d
699  rendering_drawPixel(x, y + 1, color); // a X e X
700  rendering_drawPixel(x, y - 1, color); // e
701 }
702 
704 
705 /*******************************/
706 /* ISR Definitions */
707 /*******************************/
709 
711 
712 
713 /*******************************/
714 /* LOCAL Function Definitions */
715 /*******************************/
717 
#define RENDERING_TAB_WIDTH
Definition: parameters.h:60
void rendering_drawLine(short x0, short y0, short x1, short y1, struct color color)
Definition: rendering.c:231
void rendering_drawCircle(short x0, short y0, short r, struct color color)
Definition: rendering.c:100
#define IMAGE_HEIGHT
Definition: parameters.h:18
unsigned char rendering_getRotation(void)
Definition: rendering.c:572
void rendering_write(unsigned char c)
Definition: rendering.c:464
void rendering_setTextColor(struct color c)
Definition: rendering.c:551
Definition: color.h:41
void rendering_setCursor(short x, short y)
Definition: rendering.c:531
void rendering_fillCircle(short x0, short y0, short r, struct color color)
Definition: rendering.c:183
void projector_set_pixel(struct color const color, unsigned int x, unsigned int y)
Set the color of a pixel at the specified location.
Definition: projector.c:205
void rendering_drawRect(short x, short y, short w, short h, struct color color)
Definition: rendering.c:285
#define swap(a, b)
Definition: rendering.c:54
void rendering_fillCircleHelper(short x0, short y0, short r, unsigned char cornername, short delta, struct color color)
Definition: rendering.c:199
bool color_equal(struct color const a, struct color const b)
Return true if a and b represent exactly the same color.
Definition: color.c:71
void rendering_writeString(char *str)
Definition: rendering.c:485
void rendering_setTextSize(unsigned char s)
Definition: rendering.c:542
void rendering_setTextWrap(char w)
Definition: rendering.c:568
void rendering_fillRoundRect(short x, short y, short w, short h, short r, struct color color)
Definition: rendering.c:333
void rendering_drawChar(short x, short y, unsigned char c, struct color color, struct color bg, unsigned char size)
Definition: rendering.c:496
void rendering_drawPixel(short x, short y, struct color color)
Definition: rendering.c:583
void rendering_drawFastHLine(short x, short y, short w, struct color color)
Definition: rendering.c:622
void rendering_drawCircleHelper(short x0, short y0, short r, unsigned char cornername, struct color color)
Definition: rendering.c:145
void rendering_drawFastVLine(short x, short y, short h, struct color color)
Definition: rendering.c:594
void rendering_drawBitmap(short x, short y, const unsigned char *bitmap, short w, short h, struct color color)
Definition: rendering.c:449
void rendering_setTextColor2(struct color c, struct color b)
Definition: rendering.c:557
void rendering_fillRect(short x, short y, short w, short h, struct color color)
Definition: rendering.c:653
#define IMAGE_WIDTH
Definition: parameters.h:19
void rendering_drawTriangle(short x0, short y0, short x1, short y1, short x2, short y2, struct color color)
Definition: rendering.c:344
void rendering_drawRoundRect(short x, short y, short w, short h, short r, struct color color)
Definition: rendering.c:306
void rendering_fillTriangle(short x0, short y0, short x1, short y1, short x2, short y2, struct color color)
Definition: rendering.c:363
#define pgm_read_byte(addr)
Definition: rendering.c:55
void rendering_drawMinimalCross(short const x, short const y, struct color const color)
Draw a 3x3 pixel cross.
Definition: rendering.c:694