diff --git a/examples/pico_display/demo.cpp b/examples/pico_display/demo.cpp index 86b0801c..a29d9711 100644 --- a/examples/pico_display/demo.cpp +++ b/examples/pico_display/demo.cpp @@ -122,13 +122,44 @@ int main() { if(shape.y >= pico_display.bounds.h) shape.dy *= -1; pico_display.set_pen(shape.pen); - pico_display.circle(point(shape.x, shape.y), shape.r); + pico_display.circle(Point(shape.x, shape.y), shape.r); } float led_step = fmod(i / 20.0f, M_PI * 2.0f); int r = (sin(led_step) * 25.0f) + 25.0f; pico_display.set_led(r, r / 1.2f, r); + + std::vector poly; + poly.push_back(Point(30, 30)); + poly.push_back(Point(50, 35)); + poly.push_back(Point(70, 25)); + poly.push_back(Point(80, 65)); + poly.push_back(Point(50, 85)); + poly.push_back(Point(30, 45)); + + pico_display.set_pen(255, 255, 0); + pico_display.polygon(poly); + + + pico_display.set_pen(0, 255, 255); + pico_display.triangle(Point(50, 50), Point(130, 80), Point(80, 110)); + + pico_display.set_pen(255, 255, 255); + pico_display.line(Point(50, 50), Point(120, 80)); + pico_display.line(Point(20, 20), Point(120, 20)); + pico_display.line(Point(20, 20), Point(20, 120)); + + for(int r = 0; r < 30; r++) { + for(int j = 0; j < 10; j++) { + float rads = ((M_PI * 2) / 30.0f) * float(r); + rads += (float(i) / 100.0f); + rads += (float(j) / 100.0f); + float cx = sin(rads) * 300.0f; + float cy = cos(rads) * 300.0f; + pico_display.line(Point(120, 67), Point(cx + 120, cy + 67)); + } + } /* if(pico_display.is_pressed(pico_display.A)) { pico_display.rectangle(0, 0, 18, 18); diff --git a/examples/pico_explorer/demo.cpp b/examples/pico_explorer/demo.cpp index 71fb7f58..8305e0e5 100644 --- a/examples/pico_explorer/demo.cpp +++ b/examples/pico_explorer/demo.cpp @@ -100,26 +100,26 @@ int main() { if(shape.y >= pico_explorer.bounds.h) shape.dy *= -1; pico_explorer.set_pen(shape.pen); - pico_explorer.circle(point(shape.x, shape.y), shape.r); + pico_explorer.circle(Point(shape.x, shape.y), shape.r); } float rv = pico_explorer.get_adc(pico_explorer.ADC0); pico_explorer.set_pen(255, 255, 255); - pico_explorer.circle(point(rv * 140 + 50, 110), 20); + pico_explorer.circle(Point(rv * 140 + 50, 110), 20); pico_explorer.set_pen(rv * 255, 0, 0); - pico_explorer.circle(point(rv * 140 + 50, 110), 15); + pico_explorer.circle(Point(rv * 140 + 50, 110), 15); float gv = pico_explorer.get_adc(pico_explorer.ADC1); pico_explorer.set_pen(255, 255, 255); - pico_explorer.circle(point(gv * 140 + 50, 160), 20); + pico_explorer.circle(Point(gv * 140 + 50, 160), 20); pico_explorer.set_pen(0, gv * 255, 0); - pico_explorer.circle(point(gv * 140 + 50, 160), 15); + pico_explorer.circle(Point(gv * 140 + 50, 160), 15); float bv = pico_explorer.get_adc(pico_explorer.ADC2); pico_explorer.set_pen(255, 255, 255); - pico_explorer.circle(point(bv * 140 + 50, 210), 20); + pico_explorer.circle(Point(bv * 140 + 50, 210), 20); pico_explorer.set_pen(0, 0, bv * 255); - pico_explorer.circle(point(bv * 140 + 50, 210), 15); + pico_explorer.circle(Point(bv * 140 + 50, 210), 15); pico_explorer.set_motor(pico_explorer.MOTOR1, pico_explorer.FORWARD, bv); pico_explorer.set_motor(pico_explorer.MOTOR2, pico_explorer.FORWARD, rv); @@ -128,32 +128,32 @@ int main() { if(pico_explorer.is_pressed(pico_explorer.A)) { pico_explorer.set_pen(255, 255, 255); - pico_explorer.character('A', point(120, 180), 5); + pico_explorer.character('A', Point(120, 180), 5); } if(pico_explorer.is_pressed(pico_explorer.B)) { pico_explorer.set_pen(255, 255, 255); - pico_explorer.character('B', point(120, 180), 5); + pico_explorer.character('B', Point(120, 180), 5); } if(pico_explorer.is_pressed(pico_explorer.X)) { pico_explorer.set_pen(255, 255, 255); - pico_explorer.character('X', point(120, 180), 5); + pico_explorer.character('X', Point(120, 180), 5); } if(pico_explorer.is_pressed(pico_explorer.Y)) { pico_explorer.set_pen(255, 255, 255); - pico_explorer.character('Y', point(120, 180), 5); + pico_explorer.character('Y', Point(120, 180), 5); } float tyoff = cos(i / 20.0f) * 50.0f - 50.0f; - rect text_box(10, 10, 150, 150); + Rect text_box(10, 10, 150, 150); pico_explorer.set_pen(55, 65, 75); pico_explorer.rectangle(text_box); text_box.deflate(10); pico_explorer.set_clip(text_box); pico_explorer.set_pen(255, 255, 255); - pico_explorer.text("This is a test of some text data that should wrap nicely onto multiple lines which is dead useful like.", point(text_box.x, text_box.y + tyoff), 100); + pico_explorer.text("This is a test of some text data that should wrap nicely onto multiple lines which is dead useful like.", Point(text_box.x, text_box.y + tyoff), 100); float xoff = sin(i / 20.0f) * 50.0f; xoff += 120 - (81 / 2); @@ -168,23 +168,23 @@ int main() { uint8_t b = *src++; pico_explorer.set_pen(r, g, b); - pico_explorer.pixel(point(x + xoff, 68 - y + yoff)); + pico_explorer.pixel(Point(x + xoff, 68 - y + yoff)); } } pico_explorer.remove_clip(); pico_explorer.set_pen(255, 255, 255); - pico_explorer.text("x: " + std::to_string(int(msa301.get_axis(msa301.X, 16) * 100)), point(10, 190), 100); - pico_explorer.text("y: " + std::to_string(int(msa301.get_axis(msa301.Y, 16) * 100)), point(10, 205), 100); - pico_explorer.text("z: " + std::to_string(int(msa301.get_axis(msa301.Z, 16) * 100)), point(10, 220), 100); + pico_explorer.text("x: " + std::to_string(int(msa301.get_axis(msa301.X, 16) * 100)), Point(10, 190), 100); + pico_explorer.text("y: " + std::to_string(int(msa301.get_axis(msa301.Y, 16) * 100)), Point(10, 205), 100); + pico_explorer.text("z: " + std::to_string(int(msa301.get_axis(msa301.Z, 16) * 100)), Point(10, 220), 100); uint16_t xpos = (msa301.get_axis(msa301.X, 16) * 120) + 120; uint16_t ypos = (msa301.get_axis(msa301.Z, 16) * 120) + 120; pico_explorer.set_pen(255, 255, 255); - pico_explorer.circle(point(xpos, ypos), 20); + pico_explorer.circle(Point(xpos, ypos), 20); pico_explorer.set_pen(255, 0, 255); - pico_explorer.circle(point(xpos, ypos), 15); + pico_explorer.circle(Point(xpos, ypos), 15); /* diff --git a/libraries/pico_graphics/pico_graphics.cpp b/libraries/pico_graphics/pico_graphics.cpp index eba9f06d..3b9997cf 100644 --- a/libraries/pico_graphics/pico_graphics.cpp +++ b/libraries/pico_graphics/pico_graphics.cpp @@ -9,35 +9,27 @@ namespace pimoroni { pen = create_pen(r, g, b); } - void PicoGraphics::set_pen(uint16_t p) { + void PicoGraphics::set_pen(Pen p) { pen = p; } - uint16_t PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b) { - uint16_t p = ((r & 0b11111000) << 8) | - ((g & 0b11111100) << 3) | - ((b & 0b11111000) >> 3); - - return __builtin_bswap16(p); - } - - void PicoGraphics::set_clip(const rect &r) { - clip = r; + void PicoGraphics::set_clip(const Rect &r) { + clip = bounds.intersection(r); } void PicoGraphics::remove_clip() { clip = bounds; } - uint16_t* PicoGraphics::ptr(const rect &r) { + Pen* PicoGraphics::ptr(const Rect &r) { return frame_buffer + r.x + r.y * bounds.w; } - uint16_t* PicoGraphics::ptr(const point &p) { + Pen* PicoGraphics::ptr(const Point &p) { return frame_buffer + p.x + p.y * bounds.w; } - uint16_t* PicoGraphics::ptr(int32_t x, int32_t y) { + Pen* PicoGraphics::ptr(int32_t x, int32_t y) { return frame_buffer + x + y * bounds.w; } @@ -45,34 +37,34 @@ namespace pimoroni { rectangle(clip); } - void PicoGraphics::pixel(const point &p) { + void PicoGraphics::pixel(const Point &p) { if(!clip.contains(p)) return; *ptr(p) = pen; } - void PicoGraphics::pixel_span(const point &p, int32_t l) { + void PicoGraphics::pixel_span(const Point &p, int32_t l) { // check if span in bounds if( p.x + l < clip.x || p.x >= clip.x + clip.w || p.y < clip.y || p.y >= clip.y + clip.h) return; // clamp span horizontally - point clipped = p; + Point clipped = p; if(clipped.x < clip.x) {l += clipped.x - clip.x; clipped.x = clip.x;} if(clipped.x + l >= clip.x + clip.w) {l = clip.x + clip.w - clipped.x;} - uint16_t *dest = ptr(clipped); + Pen *dest = ptr(clipped); while(l--) { *dest++ = pen; } } - void PicoGraphics::rectangle(const rect &r) { + void PicoGraphics::rectangle(const Rect &r) { // clip and/or discard depending on rectangle visibility - rect clipped = r.intersection(clip); + Rect clipped = r.intersection(clip); if(clipped.empty()) return; - uint16_t *dest = ptr(clipped); + Pen *dest = ptr(clipped); while(clipped.h--) { // draw span of pixels for this row for(uint32_t i = 0; i < clipped.w; i++) { @@ -84,9 +76,9 @@ namespace pimoroni { } } - void PicoGraphics::circle(const point &p, int32_t radius) { + void PicoGraphics::circle(const Point &p, int32_t radius) { // circle in screen bounds? - rect bounds = rect(p.x - radius, p.y - radius, radius * 2, radius * 2); + Rect bounds = Rect(p.x - radius, p.y - radius, radius * 2, radius * 2); if(!bounds.intersects(clip)) return; int ox = radius, oy = 0, err = -radius; @@ -96,15 +88,15 @@ namespace pimoroni { err += oy; oy++; err += oy; - pixel_span(point(p.x - ox, p.y + last_oy), ox * 2 + 1); + pixel_span(Point(p.x - ox, p.y + last_oy), ox * 2 + 1); if (last_oy != 0) { - pixel_span(point(p.x - ox, p.y - last_oy), ox * 2 + 1); + pixel_span(Point(p.x - ox, p.y - last_oy), ox * 2 + 1); } if(err >= 0 && ox != last_oy) { - pixel_span(point(p.x - last_oy, p.y + ox), last_oy * 2 + 1); + pixel_span(Point(p.x - last_oy, p.y + ox), last_oy * 2 + 1); if (ox != 0) { - pixel_span(point(p.x - last_oy, p.y - ox), last_oy * 2 + 1); + pixel_span(Point(p.x - last_oy, p.y - ox), last_oy * 2 + 1); } err -= ox; ox--; err -= ox; @@ -112,9 +104,9 @@ namespace pimoroni { } } - void PicoGraphics::character(const char c, const point &p, uint8_t scale) { + void PicoGraphics::character(const char c, const Point &p, uint8_t scale) { uint8_t char_index = c - 32; - rect char_bounds(p.x, p.y, character_widths[char_index] * scale, 6 * scale); + Rect char_bounds(p.x, p.y, character_widths[char_index] * scale, 6 * scale); if(!clip.intersects(char_bounds)) return; @@ -122,7 +114,7 @@ namespace pimoroni { for(uint8_t cx = 0; cx < character_widths[char_index]; cx++) { for(uint8_t cy = 0; cy < 6; cy++) { if((1U << cy) & *d) { - rectangle(rect(p.x + (cx * scale), p.y + (cy * scale), scale, scale)); + rectangle(Rect(p.x + (cx * scale), p.y + (cy * scale), scale, scale)); } } @@ -130,7 +122,7 @@ namespace pimoroni { } } - void PicoGraphics::text(const std::string &t, const point &p, int32_t wrap, uint8_t scale) { + void PicoGraphics::text(const std::string &t, const Point &p, int32_t wrap, uint8_t scale) { uint32_t co = 0, lo = 0; // character and line (if wrapping) offset size_t i = 0; @@ -156,7 +148,7 @@ namespace pimoroni { // draw word for(size_t j = i; j < next_space; j++) { - character(t[j], point(p.x + co, p.y + lo), scale); + character(t[j], Point(p.x + co, p.y + lo), scale); co += character_widths[t[j] - 32] * scale; } @@ -166,4 +158,172 @@ namespace pimoroni { } } + int32_t orient2d(Point p1, Point p2, Point p3) { + return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); + } + + bool is_top_left(const Point &p1, const Point &p2) { + return (p1.y == p2.y && p1.x > p2.x) || (p1.y < p2.y); + } + + void PicoGraphics::triangle(Point p1, Point p2, Point p3) { + Rect triangle_bounds( + Point(std::min(p1.x, std::min(p2.x, p3.x)), std::min(p1.y, std::min(p2.y, p3.y))), + Point(std::max(p1.x, std::max(p2.x, p3.x)), std::max(p1.y, std::max(p2.y, p3.y)))); + + // clip extremes to frame buffer size + triangle_bounds = clip.intersection(triangle_bounds); + + // if triangle completely out of bounds then don't bother! + if (triangle_bounds.empty()) { + return; + } + + // fix "winding" of vertices if needed + int32_t winding = orient2d(p1, p2, p3); + if (winding < 0) { + Point t; + t = p1; p1 = p3; p3 = t; + } + + // bias ensures no overdraw between neighbouring triangles + int8_t bias0 = is_top_left(p2, p3) ? 0 : -1; + int8_t bias1 = is_top_left(p3, p1) ? 0 : -1; + int8_t bias2 = is_top_left(p1, p2) ? 0 : -1; + + int32_t a01 = p1.y - p2.y; + int32_t b01 = p2.x - p1.x; + int32_t a12 = p2.y - p3.y; + int32_t b12 = p3.x - p2.x; + int32_t a20 = p3.y - p1.y; + int32_t b20 = p1.x - p3.x; + + Point tl(triangle_bounds.x, triangle_bounds.y); + int32_t w0row = orient2d(p2, p3, tl) + bias0; + int32_t w1row = orient2d(p3, p1, tl) + bias1; + int32_t w2row = orient2d(p1, p2, tl) + bias2; + + for (uint32_t y = 0; y < triangle_bounds.h; y++) { + int32_t w0 = w0row; + int32_t w1 = w1row; + int32_t w2 = w2row; + + Pen *dest = ptr(triangle_bounds.x, triangle_bounds.y + y); + for (uint32_t x = 0; x < triangle_bounds.w; x++) { + if ((w0 | w1 | w2) >= 0) { + *dest = pen; + } + + dest++; + + w0 += a12; + w1 += a20; + w2 += a01; + } + + w0row += b12; + w1row += b20; + w2row += b01; + } + } + + void PicoGraphics::polygon(const std::vector &points) { + static int32_t nodes[64]; // maximum allowed number of nodes per scanline for polygon rendering + + int32_t miny = points[0].y, maxy = points[0].y; + + for (uint16_t i = 1; i < points.size(); i++) { + miny = std::min(miny, points[i].y); + maxy = std::max(maxy, points[i].y); + } + + // for each scanline within the polygon bounds (clipped to clip rect) + Point p; + + for (p.y = std::max(clip.y, miny); p.y <= std::min(clip.y + clip.h, maxy); p.y++) { + uint8_t n = 0; + for (uint16_t i = 0; i < points.size(); i++) { + uint16_t j = (i + 1) % points.size(); + int32_t sy = points[i].y; + int32_t ey = points[j].y; + int32_t fy = p.y; + if ((sy < fy && ey >= fy) || (ey < fy && sy >= fy)) { + int32_t sx = points[i].x; + int32_t ex = points[j].x; + int32_t px = int32_t(sx + float(fy - sy) / float(ey - sy) * float(ex - sx)); + + nodes[n++] = px < clip.x ? clip.x : (px >= clip.x + clip.w ? clip.x + clip.w - 1 : px);// clamp(int32_t(sx + float(fy - sy) / float(ey - sy) * float(ex - sx)), clip.x, clip.x + clip.w); + } + } + + uint16_t i = 0; + while (i < n - 1) { + if (nodes[i] > nodes[i + 1]) { + int32_t s = nodes[i]; nodes[i] = nodes[i + 1]; nodes[i + 1] = s; + if (i) i--; + } + else { + i++; + } + } + + for (uint16_t i = 0; i < n; i += 2) { + pixel_span(Point(nodes[i], p.y), nodes[i + 1] - nodes[i] + 1); + } + } + } + + void PicoGraphics::line(Point p1, Point p2) { + // fast horizontal line + if(p1.y == p2.y) { + int32_t start = std::max(clip.x, std::min(p1.x, p2.x)); + int32_t end = std::min(clip.x + clip.w, std::max(p1.x, p2.x)); + pixel_span(Point(start, p1.y), end - start); + return; + } + + // fast vertical line + if(p1.x == p2.x) { + int32_t start = std::max(clip.y, std::min(p1.y, p2.y)); + int32_t length = std::min(clip.y + clip.h, std::max(p1.y, p2.y)) - start; + Pen *dest = ptr(p1.x, start); + while(length--) { + *dest = pen; + dest += bounds.w; + } + return; + } + + // general purpose line + // lines are either "shallow" or "steep" based on whether the x delta + // is greater than the y delta + int32_t dx = p2.x - p1.x; + int32_t dy = p2.y - p1.y; + bool shallow = std::abs(dx) > std::abs(dy); + if(shallow) { + // shallow version + int32_t s = std::abs(dx); // number of steps + int32_t sx = dx < 0 ? -1 : 1; // x step value + int32_t sy = (dy << 16) / s; // y step value in fixed 16:16 + int32_t x = p1.x; + int32_t y = p1.y << 16; + while(s--) { + pixel(Point(x, y >> 16)); + y += sy; + x += sx; + } + }else{ + // steep version + int32_t s = std::abs(dy); // number of steps + int32_t sy = dy < 0 ? -1 : 1; // x step value + int32_t sx = (dx << 16) / s; // y step value in fixed 16:16 + int32_t y = p1.y; + int32_t x = p1.x << 16; + while(s--) { + pixel(Point(x >> 16, y)); + y += sy; + x += sx; + } + } + } } \ No newline at end of file diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index 545ac9e5..87006bb5 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -3,36 +3,40 @@ #include #include #include +#include // a tiny little graphics library for our Pico products // supports only 16-bit (565) RGB framebuffers namespace pimoroni { - struct rect; + typedef uint16_t Pen; - struct point { + struct Rect; + + struct Point { int32_t x = 0, y = 0; - point() = default; - point(int32_t x, int32_t y) : x(x), y(y) {} + Point() = default; + Point(int32_t x, int32_t y) : x(x), y(y) {} - inline point& operator-= (const point &a) { x -= a.x; y -= a.y; return *this; } - inline point& operator+= (const point &a) { x += a.x; y += a.y; return *this; } + inline Point& operator-= (const Point &a) { x -= a.x; y -= a.y; return *this; } + inline Point& operator+= (const Point &a) { x += a.x; y += a.y; return *this; } - point clamp(const rect &r) const; + Point clamp(const Rect &r) const; }; - struct rect { + struct Rect { int32_t x = 0, y = 0, w = 0, h = 0; - rect() = default; - rect(int32_t x, int32_t y, int32_t w, int32_t h) : x(x), y(y), w(w), h(h) {} + Rect() = default; + Rect(int32_t x, int32_t y, int32_t w, int32_t h) : x(x), y(y), w(w), h(h) {} + Rect(const Point &tl, const Point &br) : x(tl.x), y(tl.y), w(br.x - tl.x), h(br.y - tl.y) {} bool empty() const; - bool contains(const point &p) const; - bool contains(const rect &p) const; - bool intersects(const rect &r) const; - rect intersection(const rect &r) const; + bool contains(const Point &p) const; + bool contains(const Rect &p) const; + bool intersects(const Rect &r) const; + Rect intersection(const Rect &r) const; void inflate(int32_t v); void deflate(int32_t v); @@ -42,34 +46,43 @@ namespace pimoroni { public: uint16_t *frame_buffer; - rect bounds; - rect clip; + Rect bounds; + Rect clip; - uint16_t pen; + Pen pen; public: PicoGraphics(uint16_t width, uint16_t height, uint16_t *frame_buffer) : frame_buffer(frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height) {} void set_pen(uint8_t r, uint8_t g, uint8_t b); - void set_pen(uint16_t p); - uint16_t create_pen(uint8_t r, uint8_t g, uint8_t b); + void set_pen(Pen p); - void set_clip(const rect &r); + constexpr Pen create_pen(uint8_t r, uint8_t g, uint8_t b) { + uint16_t p = ((r & 0b11111000) << 8) | + ((g & 0b11111100) << 3) | + ((b & 0b11111000) >> 3); + + return __builtin_bswap16(p); + }; + + void set_clip(const Rect &r); void remove_clip(); - uint16_t* ptr(const point &p); - uint16_t* ptr(const rect &r); - uint16_t* ptr(int32_t x, int32_t y); + Pen* ptr(const Point &p); + Pen* ptr(const Rect &r); + Pen* ptr(int32_t x, int32_t y); void clear(); - void pixel(const point &p); - void pixel_span(const point &p, int32_t l); - void rectangle(const rect &r); - void circle(const point &p, int32_t r); - void character(const char c, const point &p, uint8_t scale = 2); - void text(const std::string &t, const point &p, int32_t wrap, uint8_t scale = 2); - //void polygon(std::vector); + void pixel(const Point &p); + void pixel_span(const Point &p, int32_t l); + void rectangle(const Rect &r); + void circle(const Point &p, int32_t r); + void character(const char c, const Point &p, uint8_t scale = 2); + void text(const std::string &t, const Point &p, int32_t wrap, uint8_t scale = 2); + void polygon(const std::vector &points); + void triangle(Point p1, Point p2, Point p3); + void line(Point p1, Point p2); }; } \ No newline at end of file diff --git a/libraries/pico_graphics/types.cpp b/libraries/pico_graphics/types.cpp index 838f5556..91d8fb27 100644 --- a/libraries/pico_graphics/types.cpp +++ b/libraries/pico_graphics/types.cpp @@ -5,55 +5,55 @@ namespace pimoroni { - point point::clamp(const rect &r) const { - return point( + Point Point::clamp(const Rect &r) const { + return Point( std::min(std::max(x, r.x), r.x + r.w), std::min(std::max(y, r.y), r.y + r.h) ); } - point operator- (point lhs, const point &rhs) { + Point operator- (Point lhs, const Point &rhs) { lhs -= rhs; return lhs; } - point operator- (const point &rhs) { - return point(-rhs.x, -rhs.y); + Point operator- (const Point &rhs) { + return Point(-rhs.x, -rhs.y); } - point operator+ (point lhs, const point &rhs) { + Point operator+ (Point lhs, const Point &rhs) { lhs += rhs; return lhs; } - bool rect::empty() const { + bool Rect::empty() const { return w <= 0 || h <= 0; } - bool rect::contains(const point &p) const { + bool Rect::contains(const Point &p) const { return p.x >= x && p.y >= y && p.x < x + w && p.y < y + h; } - bool rect::contains(const rect &p) const { + bool Rect::contains(const Rect &p) const { return p.x >= x && p.y >= y && p.x + p.w < x + w && p.y + p.h < y + h; } - bool rect::intersects(const rect &r) const { + bool Rect::intersects(const Rect &r) const { return !(x > r.x + r.w || x + w < r.x || y > r.y + r.h || y + h < r.y); } - rect rect::intersection(const rect &r) const { - return rect(std::max(x, r.x), + Rect Rect::intersection(const Rect &r) const { + return Rect(std::max(x, r.x), std::max(y, r.y), std::min(x + w, r.x + r.w) - std::max(x, r.x), std::min(y + h, r.y + r.h) - std::max(y, r.y)); } - void rect::inflate(int32_t v) { + void Rect::inflate(int32_t v) { x -= v; y -= v; w += v * 2; h += v * 2; } - void rect::deflate(int32_t v) { + void Rect::deflate(int32_t v) { x += v; y += v; w -= v * 2; h -= v * 2; } diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index 79e9c79d..1a51fe13 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -146,7 +146,7 @@ mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) mp_raise_ValueError("b out of range. Expected 0 to 255"); else pen = display->create_pen(r, g, b); - + return mp_obj_new_int(pen); } @@ -158,7 +158,7 @@ mp_obj_t picodisplay_set_clip(mp_uint_t n_args, const mp_obj_t *args) { int w = mp_obj_get_int(args[2]); int h = mp_obj_get_int(args[3]); - rect r(x, y, w, h); + Rect r(x, y, w, h); display->set_clip(r); return mp_const_none; @@ -178,9 +178,9 @@ mp_obj_t picodisplay_pixel(mp_obj_t x_obj, mp_obj_t y_obj) { int x = mp_obj_get_int(x_obj); int y = mp_obj_get_int(y_obj); - point p(x, y); + Point p(x, y); display->pixel(p); - + return mp_const_none; } @@ -189,7 +189,7 @@ mp_obj_t picodisplay_pixel_span(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t l_obj) int y = mp_obj_get_int(y_obj); int l = mp_obj_get_int(l_obj); - point p(x, y); + Point p(x, y); display->pixel_span(p, l); return mp_const_none; @@ -203,7 +203,7 @@ mp_obj_t picodisplay_rectangle(mp_uint_t n_args, const mp_obj_t *args) { int w = mp_obj_get_int(args[2]); int h = mp_obj_get_int(args[3]); - rect r(x, y, w, h); + Rect r(x, y, w, h); display->rectangle(r); return mp_const_none; @@ -214,7 +214,7 @@ mp_obj_t picodisplay_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) { int y = mp_obj_get_int(y_obj); int r = mp_obj_get_int(r_obj); - point p(x, y); + Point p(x, y); display->circle(p, r); return mp_const_none; @@ -225,7 +225,7 @@ mp_obj_t picodisplay_character(mp_uint_t n_args, const mp_obj_t *args) { int x = mp_obj_get_int(args[1]); int y = mp_obj_get_int(args[2]); - point p(x, y); + Point p(x, y); if(n_args == 4) { int scale = mp_obj_get_int(args[3]); display->character((char)c, p, scale); @@ -246,7 +246,7 @@ mp_obj_t picodisplay_text(mp_uint_t n_args, const mp_obj_t *args) { int y = mp_obj_get_int(args[2]); int wrap = mp_obj_get_int(args[3]); - point p(x, y); + Point p(x, y); if(n_args == 5) { int scale = mp_obj_get_int(args[4]); display->text(t, p, wrap, scale);