From 8e4b1666bba74408fb903680c3701d58d9a33a77 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Tue, 5 Jul 2016 13:32:47 +0200 Subject: [PATCH] Kandinsky: KDFillRect takes a pattern, always Change-Id: I32113345d742f21c0e238c1707bcee0116694d6f --- apps/graph/graph/cursor_view.cpp | 3 ++- apps/graph/graph/graph_view.cpp | 5 +++-- apps/graph/list/function_cell.cpp | 2 +- escher/src/scroll_view_indicator.cpp | 4 ++-- escher/src/solid_color_view.cpp | 2 +- escher/src/tab_view.cpp | 3 ++- ion/include/ion/screen.h | 10 ++------- ion/src/device/display/display.c | 9 ++++++--- ion/src/simulator/init.cpp | 11 +++++----- kandinsky/include/kandinsky/context.h | 4 +++- kandinsky/include/kandinsky/rect.h | 3 ++- kandinsky/src/rect.c | 29 ++++++++++++++++++++++++--- 12 files changed, 55 insertions(+), 30 deletions(-) diff --git a/apps/graph/graph/cursor_view.cpp b/apps/graph/graph/cursor_view.cpp index f635c3185..e3174a32f 100644 --- a/apps/graph/graph/cursor_view.cpp +++ b/apps/graph/graph/cursor_view.cpp @@ -1,5 +1,6 @@ #include "cursor_view.h" void CursorView::drawRect(KDRect rect) const { - KDFillRect(rect, KDColorRed); + KDColor cursorColor = KDColorRed; + KDFillRect(rect, &cursorColor, 1); } diff --git a/apps/graph/graph/graph_view.cpp b/apps/graph/graph/graph_view.cpp index dc4f2a531..3ea307193 100644 --- a/apps/graph/graph/graph_view.cpp +++ b/apps/graph/graph/graph_view.cpp @@ -40,7 +40,8 @@ void GraphView::layoutSubviews() { } void GraphView::drawRect(KDRect rect) const { - KDFillRect(rect, KDColorWhite); + KDColor backgroundColor = KDColorWhite; + KDFillRect(rect, &backgroundColor, 1); drawGrid(rect); drawAxes(rect); drawFunction(rect); @@ -62,7 +63,7 @@ void GraphView::drawLine(KDRect rect, Axis axis, float coordinate, KDColor color lineRect.height = rect.height; break; } - KDFillRect(lineRect, color); + KDFillRect(lineRect, &color, 1); } void GraphView::drawAxes(KDRect rect) const { diff --git a/apps/graph/list/function_cell.cpp b/apps/graph/list/function_cell.cpp index a602ba137..f9f19e28b 100644 --- a/apps/graph/list/function_cell.cpp +++ b/apps/graph/list/function_cell.cpp @@ -10,7 +10,7 @@ FunctionCell::FunctionCell() : void FunctionCell::drawRect(KDRect rect) const { KDColor background = m_even ? KDColorRGB(0xEE, 0xEE, 0xEE) : KDColorRGB(0x77,0x77,0x77); - KDFillRect(rect, background); + KDFillRect(rect, &background, 1); KDDrawString(m_message, KDPointZero, m_focused); } diff --git a/escher/src/scroll_view_indicator.cpp b/escher/src/scroll_view_indicator.cpp index 0b693288f..e3df94114 100644 --- a/escher/src/scroll_view_indicator.cpp +++ b/escher/src/scroll_view_indicator.cpp @@ -15,7 +15,7 @@ ScrollViewIndicator::ScrollViewIndicator(ScrollViewIndicator::Direction directio } void ScrollViewIndicator::drawRect(KDRect rect) const { - KDFillRect(bounds(), k_backgroundColor); + KDFillRect(bounds(), &k_backgroundColor, 1); KDRect indicatorFrame; if (m_direction == Direction::Horizontal) { indicatorFrame.x = m_start*m_frame.width; @@ -29,7 +29,7 @@ void ScrollViewIndicator::drawRect(KDRect rect) const { indicatorFrame.width = m_frame.width; indicatorFrame.height = (m_end-m_start)*m_frame.height; } - KDFillRect(indicatorFrame, k_indicatorColor); + KDFillRect(indicatorFrame, &k_indicatorColor, 1); } void ScrollViewIndicator::setStart(float start) { diff --git a/escher/src/solid_color_view.cpp b/escher/src/solid_color_view.cpp index 9c0506c9a..cf8101154 100644 --- a/escher/src/solid_color_view.cpp +++ b/escher/src/solid_color_view.cpp @@ -7,7 +7,7 @@ SolidColorView::SolidColorView(KDColor color) : } void SolidColorView::drawRect(KDRect rect) const { - KDFillRect(rect, m_color); + KDFillRect(rect, &m_color, 1); } #if ESCHER_VIEW_LOGGING diff --git a/escher/src/tab_view.cpp b/escher/src/tab_view.cpp index 64897b2e1..679c5372c 100644 --- a/escher/src/tab_view.cpp +++ b/escher/src/tab_view.cpp @@ -12,7 +12,8 @@ TabView::TabView() : } void TabView::drawRect(KDRect rect) const { - KDFillRect(rect, KDColorRGB(0xb5, 0x1d, 0xab)); + KDColor backgroundColor = KDColorRGB(0xb5, 0x1d, 0xab); + KDFillRect(rect, &backgroundColor, 1); } void TabView::addTabNamed(const char * name) { diff --git a/ion/include/ion/screen.h b/ion/include/ion/screen.h index b4cd3d4b8..c00e26029 100644 --- a/ion/include/ion/screen.h +++ b/ion/include/ion/screen.h @@ -12,6 +12,7 @@ * which results in a very consequent speedup (up to ~10x faster). */ #include +#include /* ION manipulates RGB565 colors */ typedef uint16_t ion_color_t; @@ -23,14 +24,7 @@ void ion_set_pixel(uint16_t x, uint16_t y, ion_color_t color); void ion_fill_rect( uint16_t x, uint16_t y, uint16_t width, uint16_t height, - ion_color_t color -); - -/* Fill a rect with a color buffer */ -void ion_fill_rect_from_buffer( - uint16_t x, uint16_t y, - uint16_t width, uint16_t height, - ion_color_t * buffer + ion_color_t * pattern, size_t patternSize ); #define ION_SCREEN_WIDTH 320 diff --git a/ion/src/device/display/display.c b/ion/src/device/display/display.c index 7e42d83b5..a53f6bc2d 100644 --- a/ion/src/device/display/display.c +++ b/ion/src/device/display/display.c @@ -48,11 +48,14 @@ void ion_set_pixel(uint16_t x, uint16_t y, ion_color_t color) { void ion_fill_rect( uint16_t x, uint16_t y, uint16_t width, uint16_t height, - ion_color_t color) + ion_color_t * pattern, size_t patternSize) { st7789_set_drawing_area(&sDisplayController, x, y, width, height); - for (int i=0; i 0) { + int32_t blockSize = remainingSize > patternSize ? patternSize : remainingSize; + st7789_push_pixels(&sDisplayController, pattern, blockSize); + remainingSize -= blockSize; } } diff --git a/ion/src/simulator/init.cpp b/ion/src/simulator/init.cpp index 9923f250f..1645b6f5b 100644 --- a/ion/src/simulator/init.cpp +++ b/ion/src/simulator/init.cpp @@ -3,6 +3,7 @@ extern "C" { #include #include #include +#include #include "init.h" } #include @@ -33,6 +34,8 @@ void init_platform() { window->end(); window->show(); + + KDCurrentContext->fillRect = NULL; } void ion_set_pixel(uint16_t x, uint16_t y, ion_color_t color) { @@ -50,13 +53,9 @@ void ion_set_pixel(uint16_t x, uint16_t y, ion_color_t color) { void ion_fill_rect( uint16_t x, uint16_t y, uint16_t width, uint16_t height, - ion_color_t color) + ion_color_t * pattern, size_t patternSize) { - for (int16_t i = x; i<(x+width); i++) { - for (int16_t j = y; j<(y+height); j++) { - ion_set_pixel(i, j, color); - } - } + assert(false); } bool ion_key_down(ion_key_t key) { diff --git a/kandinsky/include/kandinsky/context.h b/kandinsky/include/kandinsky/context.h index a55406063..7780a2c4d 100644 --- a/kandinsky/include/kandinsky/context.h +++ b/kandinsky/include/kandinsky/context.h @@ -6,9 +6,11 @@ typedef struct { void (*setPixel)(KDCoordinate x, KDCoordinate y, KDColor color); + // fillRect can be left NULL. + // In that case, Kandinsky will fall back to using setPixel only void (*fillRect)(KDCoordinate x, KDCoordinate y, KDCoordinate width, KDCoordinate height, - KDColor color); + KDColor * pattern, size_t patternSize); KDPoint origin; KDRect clippingRect; } KDContext; diff --git a/kandinsky/include/kandinsky/rect.h b/kandinsky/include/kandinsky/rect.h index e5573aff8..a77118359 100644 --- a/kandinsky/include/kandinsky/rect.h +++ b/kandinsky/include/kandinsky/rect.h @@ -2,6 +2,7 @@ #define KANDINSKY_RECT_H #include +#include #include #include @@ -33,7 +34,7 @@ KDRect KDRectUnion(KDRect r1, KDRect r2); bool KDRectContains(KDRect r, KDPoint p); KDRect KDRectTranslate(KDRect r, KDPoint p); -void KDFillRect(KDRect rect, KDColor color); +void KDFillRect(KDRect rect, const KDColor * pattern, size_t patternSize); void KDDrawRect(KDRect rect, KDColor color); #endif diff --git a/kandinsky/src/rect.c b/kandinsky/src/rect.c index 2d9992491..dfe2ab72c 100644 --- a/kandinsky/src/rect.c +++ b/kandinsky/src/rect.c @@ -2,6 +2,7 @@ #include #include #include +#include KDRect KDRectZero = {.x = 0, .y = 0, .width = 0, .height = 0}; @@ -100,15 +101,37 @@ KDRect KDRectTranslate(KDRect r, KDPoint p) { }; } -void KDFillRect(KDRect rect, KDColor color) { +void KDPerPixelFillRect(KDCoordinate x, KDCoordinate y, + KDCoordinate width, KDCoordinate height, + KDColor * pattern, size_t patternSize) { + size_t offset = 0; + for (KDCoordinate j=0; jsetPixel(x+i, y+j, pattern[offset++]); + if (offset >= patternSize) { + offset = 0; + } + } + } +} + +void KDFillRect(KDRect rect, const KDColor * pattern, size_t patternSize) { + assert(patternSize >= 1); KDRect absolutRect = rect; absolutRect.origin = KDPointTranslate(absolutRect.origin, KDCurrentContext->origin); KDRect rectToBeFilled = KDRectIntersection(absolutRect, KDCurrentContext->clippingRect); - KDCurrentContext->fillRect(rectToBeFilled.x, rectToBeFilled.y, + void (*fillRectFunction)(KDCoordinate x, KDCoordinate y, + KDCoordinate width, KDCoordinate height, + KDColor * pattern, size_t patternSize) = KDCurrentContext->fillRect; + if (fillRectFunction == NULL) { + fillRectFunction = KDPerPixelFillRect; + } + + fillRectFunction(rectToBeFilled.x, rectToBeFilled.y, rectToBeFilled.width, rectToBeFilled.height, - color); + pattern, patternSize); } void KDDrawRect(KDRect rect, KDColor color) {