Skip to content

Commit

Permalink
changed fastvhline to point to drawline, added fillScreen, a fake con…
Browse files Browse the repository at this point in the history
…structor and rotation stuff
  • Loading branch information
ladyada committed Mar 16, 2012
1 parent 7ef9c2e commit 17a6c8b
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 18 deletions.
63 changes: 53 additions & 10 deletions Adafruit_GFX.cpp
Expand Up @@ -18,6 +18,18 @@ All text above must be included in any redistribution
#include "glcdfont.c"
#include <avr/pgmspace.h>

void Adafruit_GFX::constructor(uint16_t w, uint16_t h) {
_width = WIDTH = w;
_height = HEIGHT = h;

rotation = 0;
cursor_y = cursor_x = 0;
textsize = 1;
textcolor = 0xFFFF;
textbgcolor = 0x0000;
}


// draw a circle outline
void Adafruit_GFX::drawCircle(uint16_t x0, uint16_t y0, uint16_t r,
uint16_t color) {
Expand Down Expand Up @@ -46,7 +58,6 @@ void Adafruit_GFX::drawCircle(uint16_t x0, uint16_t y0, uint16_t r,
drawPixel(x0 - x, y0 + y, color);
drawPixel(x0 + x, y0 - y, color);
drawPixel(x0 - x, y0 - y, color);

drawPixel(x0 + y, y0 + x, color);
drawPixel(x0 - y, y0 + x, color);
drawPixel(x0 + y, y0 - x, color);
Expand Down Expand Up @@ -175,7 +186,6 @@ void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
void Adafruit_GFX::drawRect(uint16_t x, uint16_t y,
uint16_t w, uint16_t h,
uint16_t color) {
Serial.println('[]');
drawFastHLine(x, y, w, color);
drawFastHLine(x, y+h-1, w, color);
drawFastVLine(x, y, h, color);
Expand All @@ -185,18 +195,14 @@ void Adafruit_GFX::drawRect(uint16_t x, uint16_t y,
void Adafruit_GFX::drawFastVLine(uint16_t x, uint16_t y,
uint16_t h, uint16_t color) {
// stupidest version - update in subclasses if desired!
for (uint16_t j=y; j<y+h; j++) {
drawPixel(x, j, color);
}
drawLine(x, y, x, y+h-1, color);
}


void Adafruit_GFX::drawFastHLine(uint16_t x, uint16_t y,
uint16_t w, uint16_t color) {
// stupidest version - update in subclasses if desired!
for (uint16_t i=x; i<x+w; i++) {
drawPixel(i, y, color);
}
drawLine(x, y, x+w-1, y, color);
}

void Adafruit_GFX::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
Expand All @@ -207,6 +213,11 @@ void Adafruit_GFX::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
}
}


void Adafruit_GFX::fillScreen(uint16_t color) {
fillRect(0, 0, _width, _height, color);
}

// draw a rounded rectangle!
void Adafruit_GFX::drawRoundRect(uint16_t x, uint16_t y, uint16_t w,
uint16_t h, uint16_t r, uint16_t color) {
Expand Down Expand Up @@ -403,6 +414,38 @@ void Adafruit_GFX::setTextColor(uint16_t c) {
}

void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
textcolor = c;
textbgcolor = b;
textcolor = c;
textbgcolor = b;
}

uint8_t Adafruit_GFX::getRotation(void) {
rotation %= 4;
return rotation;
}

void Adafruit_GFX::setRotation(uint8_t x) {
x %= 4; // cant be higher than 3
rotation = x;
switch (x) {
case 0:
case 2:
_width = WIDTH;
_height = HEIGHT;
break;
case 1:
case 3:
_width = HEIGHT;
_height = WIDTH;
break;
}
}


// return the size of the display which depends on the rotation!
uint16_t Adafruit_GFX::width(void) {
return _width;
}

uint16_t Adafruit_GFX::height(void) {
return _height;
}
25 changes: 17 additions & 8 deletions Adafruit_GFX.h
Expand Up @@ -25,20 +25,26 @@ All text above must be included in any redistribution

#define swap(a, b) { int16_t t = a; a = b; b = t; }

class Adafruit_GFX : public Print{
class Adafruit_GFX : public Print {
public:

//Adafruit_GFX();
// i have no idea why we have to formally call the constructor. kinda sux
void constructor(uint16_t w, uint16_t h);

// this must be defined by the subclass
virtual void drawPixel(uint16_t x, uint16_t y, uint16_t color);

// these are 'generic' drawing functions, so we can share them!
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
virtual void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
uint16_t color);
virtual void drawFastVLine(uint16_t x, uint16_t y, uint16_t h, uint16_t color);
virtual void drawFastHLine(uint16_t x, uint16_t y, uint16_t w, uint16_t color);
void drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
virtual void drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
uint16_t color);
void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
virtual void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
uint16_t color);
virtual void fillScreen(uint16_t color);

void drawCircle(uint16_t x0, uint16_t y0, uint16_t r,
uint16_t color);
Expand Down Expand Up @@ -73,15 +79,18 @@ class Adafruit_GFX : public Print{
void setTextColor(uint16_t c, uint16_t bg);
void setTextSize(uint8_t s);

uint16_t height(void);
uint16_t width(void);

// return the size of the display
uint16_t width() { return WIDTH; }
uint16_t height() { return HEIGHT; }
void setRotation(uint8_t r);
uint8_t getRotation(void);

protected:
uint16_t WIDTH, HEIGHT;
uint16_t WIDTH, HEIGHT; // this is the 'raw' display w/h - never changes
uint16_t _width, _height; // dependant on rotation
uint16_t cursor_x, cursor_y, textcolor, textbgcolor;
uint8_t textsize;
uint8_t rotation;
};

#endif

3 comments on commit 17a6c8b

@svgeesus
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why were drawFastVline and drawFastHLine made slower (and "stupider", as the comment says) by replacing the fast, straightforward loop with a call to the bresenham code which (needlessly, here) calculates the slope of the line at each step?

I assume there was some advantage to this commit but I am having a hard time seeing it. Please explain?

@ladyada
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because most screens have an optimized method for drawing straight lines that is hardware dependent, this would be overridden in the subclass.

@PaintYourDragon
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had a look through the code in question, ladyada's right on this one -- each subclass is intended to provide a H/V line function that's genuinely optimized to the specific hardware (the TFTLCD library shows a really good example of this). Simplifying the H/V cases to a loop of drawPixel() calls is a red herring, because that function is performing clipping on every. single. point. along. the. way...that's no optimization at all. The base class is intended to be a minimal framework -- the least code to read, maintain, debug -- just enough to test a new display device by implementing drawPixel(), hence the reduction of the H/V cases to normal line-drawing calls by default. The subclasses can then exploit hardware-specific peculiarities (memory layout, etc.) for more truly optimized graphics primitives that actually deserve the word 'fast' in their names.

"Premature optimization is the root of all evil." -- Donald Knuth

Please sign in to comment.