diff --git a/escher/include/escher/view.h b/escher/include/escher/view.h index 3efeb4970..1714a0c7d 100644 --- a/escher/include/escher/view.h +++ b/escher/include/escher/view.h @@ -59,7 +59,7 @@ protected: private: void redraw(KDRect rect); KDPoint absoluteOrigin() const; - KDRect absoluteDrawingArea() const; + KDRect absoluteVisibleFrame() const; bool m_needsRedraw; //TODO: We may want a dynamic size at some point diff --git a/escher/src/view.cpp b/escher/src/view.cpp index fa002dcb2..596e79ec9 100644 --- a/escher/src/view.cpp +++ b/escher/src/view.cpp @@ -47,7 +47,13 @@ void View::redraw(KDRect rect) { } // First, let's draw our own content by calling drawRect - KDSetDrawingArea(absoluteDrawingArea()); + KDPoint absOrigin = absoluteOrigin(); + KDRect absRect = KDRectTranslate(rect, absOrigin); + + KDRect absClippingRect = KDRectIntersection(absoluteVisibleFrame(), absRect); + + KDSetDrawingArea(absOrigin, absoluteVisibleFrame()); + this->drawRect(rect); // Then, let's recursively draw our children over ourself @@ -142,12 +148,12 @@ KDPoint View::absoluteOrigin() const { } } -KDRect View::absoluteDrawingArea() const { +KDRect View::absoluteVisibleFrame() const { if (m_superview == nullptr) { assert(this == (View *)window()); return m_frame; } else { - KDRect parentDrawingArea = m_superview->absoluteDrawingArea(); + KDRect parentDrawingArea = m_superview->absoluteVisibleFrame(); KDRect absoluteFrame = m_frame; absoluteFrame.origin = absoluteOrigin(); diff --git a/kandinsky/include/kandinsky/drawing_area.h b/kandinsky/include/kandinsky/drawing_area.h index 2c37e6926..a8e8bbb60 100644 --- a/kandinsky/include/kandinsky/drawing_area.h +++ b/kandinsky/include/kandinsky/drawing_area.h @@ -7,6 +7,6 @@ * When you set a drawing area (using absolute coordinates), two things happen: * - No drawing will ever happen outside of the specified rect * - All coordinates will then be interpreted as relative to the rect origin */ -void KDSetDrawingArea(KDRect rect); +void KDSetDrawingArea(KDPoint origin, KDRect clippingRect); #endif diff --git a/kandinsky/include/kandinsky/rect.h b/kandinsky/include/kandinsky/rect.h index fe820db85..b879a98f9 100644 --- a/kandinsky/include/kandinsky/rect.h +++ b/kandinsky/include/kandinsky/rect.h @@ -27,6 +27,9 @@ extern KDRect KDRectZero; bool KDRectIntersect(KDRect r1, KDRect r2); KDRect KDRectIntersection(KDRect r1, KDRect r2); +bool KDRectContains(KDRect r, KDPoint p); +KDRect KDRectTranslate(KDRect r, KDPoint p); + void KDFillRect(KDRect rect, KDColor color); void KDDrawRect(KDRect rect, KDColor color); diff --git a/kandinsky/src/drawing_area.c b/kandinsky/src/drawing_area.c index 6b95e00f0..fd67ac75e 100644 --- a/kandinsky/src/drawing_area.c +++ b/kandinsky/src/drawing_area.c @@ -1,13 +1,19 @@ #include #include -KDRect KDDrawingArea = { +KDPoint KDDrawingAreaOrigin = { + .x = 0, + .y = 0 +}; + +KDRect KDDrawingAreaClippingRect = { .x = 0, .y = 0, .width = ION_SCREEN_WIDTH, .height = ION_SCREEN_HEIGHT }; -void KDSetDrawingArea(KDRect rect) { - KDDrawingArea = rect; +void KDSetDrawingArea(KDPoint origin, KDRect clippingRect) { + KDDrawingAreaOrigin = origin; + KDDrawingAreaClippingRect = clippingRect; } diff --git a/kandinsky/src/pixel.c b/kandinsky/src/pixel.c index 1d8189cee..13ab38f2a 100644 --- a/kandinsky/src/pixel.c +++ b/kandinsky/src/pixel.c @@ -1,11 +1,12 @@ #include +#include #include #include #include "private/drawing_area.h" void KDSetPixel(KDPoint p, KDColor c) { - if (p.x >= 0 && p.x < KDDrawingArea.width && - p.y >= 0 && p.y < KDDrawingArea.height) { - ion_set_pixel(p.x+KDDrawingArea.x, p.y+KDDrawingArea.y, c); + KDPoint absolutePoint = KDPointTranslate(p, KDDrawingAreaOrigin); + if (KDRectContains(KDDrawingAreaClippingRect, absolutePoint)) { + ion_set_pixel(absolutePoint.x, absolutePoint.y, c); } } diff --git a/kandinsky/src/private/drawing_area.h b/kandinsky/src/private/drawing_area.h index 27aae1d6a..4392d1aaf 100644 --- a/kandinsky/src/private/drawing_area.h +++ b/kandinsky/src/private/drawing_area.h @@ -1,8 +1,10 @@ #ifndef KANDINSKY_PRIVATE_DRAWING_AREA #define KANDINSKY_PRIVATE_DRAWING_AREA 1 +#include #include -extern KDRect KDDrawingArea; +extern KDPoint KDDrawingAreaOrigin; +extern KDRect KDDrawingAreaClippingRect; #endif diff --git a/kandinsky/src/rect.c b/kandinsky/src/rect.c index f82447dc7..d313c2b3a 100644 --- a/kandinsky/src/rect.c +++ b/kandinsky/src/rect.c @@ -42,13 +42,23 @@ KDRect KDRectIntersection(KDRect r1, KDRect r2) { return intersection; } -void KDFillRect(KDRect rect, KDColor color) { - KDRect rectToBeFilled = { - .x = rect.x + KDDrawingArea.x, - .y = rect.y + KDDrawingArea.y, - .width = min(rect.width, KDDrawingArea.width), - .height = min(rect.height, KDDrawingArea.height) +bool KDRectContains(KDRect r, KDPoint p) { + return (p.x >= r.x && p.x < (r.x+r.width) && p.y >= r.y && p.y < (r.y+r.height)); +} + +KDRect KDRectTranslate(KDRect r, KDPoint p) { + return (KDRect){ + .origin = KDPointTranslate(r.origin, p), + .size = r.size }; +} + +void KDFillRect(KDRect rect, KDColor color) { + KDRect absolutRect = rect; + absolutRect.origin = KDPointTranslate(absolutRect.origin, KDDrawingAreaOrigin); + + KDRect rectToBeFilled = KDRectIntersection(absolutRect, KDDrawingAreaClippingRect); + ion_fill_rect(rectToBeFilled.x, rectToBeFilled.y, rectToBeFilled.width, rectToBeFilled.height, color);