Skip to content

Commit daa91a6

Browse files
authored
Merge pull request #67 from squix78/fix-rect-drawing-differences
Improving rect drawing
2 parents a2bc976 + dbafddf commit daa91a6

File tree

2 files changed

+68
-22
lines changed

2 files changed

+68
-22
lines changed

OLEDDisplay.cpp

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ void OLEDDisplay::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
125125
void OLEDDisplay::drawRect(int16_t x, int16_t y, int16_t width, int16_t height) {
126126
drawHorizontalLine(x, y, width);
127127
drawVerticalLine(x, y, height);
128-
drawVerticalLine(x + width, y, height);
129-
drawHorizontalLine(x, y + height, width);
128+
drawVerticalLine(x + width - 1, y, height);
129+
drawHorizontalLine(x, y + height - 1, width);
130130
}
131131

132132
void OLEDDisplay::fillRect(int16_t xMove, int16_t yMove, int16_t width, int16_t height) {
133-
for (int16_t i = yMove; i < yMove + height; i++) {
134-
drawHorizontalLine(xMove, i, width);
133+
for (int16_t x = xMove; x < xMove + width; x++) {
134+
drawVerticalLine(x, yMove, height);
135135
}
136136
}
137137

@@ -161,6 +161,46 @@ void OLEDDisplay::drawCircle(int16_t x0, int16_t y0, int16_t radius) {
161161
setPixel(x0, y0 - radius);
162162
}
163163

164+
void OLEDDisplay::drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads) {
165+
int16_t x = 0, y = radius;
166+
int16_t dp = 1 - radius;
167+
while (x < y) {
168+
if (dp < 0)
169+
dp = dp + 2 * (++x) + 3;
170+
else
171+
dp = dp + 2 * (++x) - 2 * (--y) + 5;
172+
if (quads & 0x1) {
173+
setPixel(x0 + x, y0 - y);
174+
setPixel(x0 + y, y0 - x);
175+
}
176+
if (quads & 0x2) {
177+
setPixel(x0 - y, y0 - x);
178+
setPixel(x0 - x, y0 - y);
179+
}
180+
if (quads & 0x4) {
181+
setPixel(x0 - y, y0 + x);
182+
setPixel(x0 - x, y0 + y);
183+
}
184+
if (quads & 0x8) {
185+
setPixel(x0 + x, y0 + y);
186+
setPixel(x0 + y, y0 + x);
187+
}
188+
}
189+
if (quads & 0x1 && quads & 0x8) {
190+
setPixel(x0 + radius, y0);
191+
}
192+
if (quads & 0x4 && quads & 0x8) {
193+
setPixel(x0, y0 + radius);
194+
}
195+
if (quads & 0x2 && quads & 0x4) {
196+
setPixel(x0 - radius, y0);
197+
}
198+
if (quads & 0x1 && quads & 0x2) {
199+
setPixel(x0, y0 - radius);
200+
}
201+
}
202+
203+
164204
void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) {
165205
int16_t x = 0, y = radius;
166206
int16_t dp = 1 - radius;
@@ -215,7 +255,7 @@ void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
215255
}
216256

217257
void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
218-
if (x < 0 || x > DISPLAY_WIDTH) return;
258+
if (x < 0 || x >= DISPLAY_WIDTH) return;
219259

220260
if (y < 0) {
221261
length += y;
@@ -245,9 +285,9 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
245285
}
246286

247287
switch (color) {
248-
case WHITE: *bufferPtr |= drawBit; break;
249-
case BLACK: *bufferPtr &= drawBit; break;
250-
case INVERSE: *bufferPtr ^= drawBit; break;
288+
case WHITE: *bufferPtr |= drawBit; break;
289+
case BLACK: *bufferPtr &= ~drawBit; break;
290+
case INVERSE: *bufferPtr ^= drawBit; break;
251291
}
252292

253293
if (length < yOffset) return;
@@ -280,28 +320,31 @@ void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
280320
if (length > 0) {
281321
drawBit = (1 << (length & 7)) - 1;
282322
switch (color) {
283-
case WHITE: *bufferPtr |= drawBit; break;
284-
case BLACK: *bufferPtr &= drawBit; break;
285-
case INVERSE: *bufferPtr ^= drawBit; break;
323+
case WHITE: *bufferPtr |= drawBit; break;
324+
case BLACK: *bufferPtr &= ~drawBit; break;
325+
case INVERSE: *bufferPtr ^= drawBit; break;
286326
}
287327
}
288328
}
289329

290330
void OLEDDisplay::drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress) {
291331
uint16_t radius = height / 2;
292-
uint16_t innerRadius = radius - 3;
293-
setColor(WHITE);
294-
drawCircle(x + radius, y + radius, radius);
295-
drawRect(x+radius, y, width - 2*radius, height);
296-
drawCircle(x + width - radius, y + radius, radius);
297-
setColor(BLACK);
298-
fillRect(x+radius, y+1, width - 2*radius + 1, height - 1);
332+
uint16_t xRadius = x + radius;
333+
uint16_t yRadius = y + radius;
334+
uint16_t doubleRadius = 2 * radius;
335+
uint16_t innerRadius = radius - 2;
336+
299337
setColor(WHITE);
300-
uint16_t maxProgressWidth = (width - 2 * radius) * progress / 100;
301-
for (uint16_t i = 0; i < maxProgressWidth; i++) {
302-
fillCircle(x + radius + i, y + radius, innerRadius);
303-
}
338+
drawCircleQuads(xRadius, yRadius, radius, 0b00000110);
339+
drawHorizontalLine(xRadius, y, width - doubleRadius + 1);
340+
drawHorizontalLine(xRadius, y + height, width - doubleRadius + 1);
341+
drawCircleQuads(x + width - radius, yRadius, radius, 0b00001001);
342+
343+
uint16_t maxProgressWidth = (width - doubleRadius - 1) * progress / 100;
304344

345+
fillCircle(xRadius, yRadius, innerRadius);
346+
fillRect(xRadius + 1, y + 2, maxProgressWidth, height - 3);
347+
fillCircle(xRadius + maxProgressWidth, yRadius, innerRadius);
305348
}
306349

307350
void OLEDDisplay::drawFastImage(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *image) {

OLEDDisplay.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ class OLEDDisplay : public Print {
138138
// Draw the border of a circle
139139
void drawCircle(int16_t x, int16_t y, int16_t radius);
140140

141+
// Draw all Quadrants specified in the quads bit mask
142+
void drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads);
143+
141144
// Fill circle
142145
void fillCircle(int16_t x, int16_t y, int16_t radius);
143146

0 commit comments

Comments
 (0)