From a70971a937441ad0d7d11ae8cb0ffbb1884d7f9b Mon Sep 17 00:00:00 2001 From: Michele Bini Date: Thu, 7 Apr 2022 14:11:55 +0200 Subject: [PATCH] hdline-work --- src/CMakeLists.txt | 1 + src/displayapp/icons/analog24_hand.c | 36 + src/displayapp/screens/WatchFaceAnalog24.cpp | 66 +- src/displayapp/screens/WatchFaceAnalog24.h | 2 +- .../analog24-lvgl-hdline-work.diff.txt | 649 ++++++++++++++++++ src/libs/lv_conf.h | 2 +- 6 files changed, 744 insertions(+), 12 deletions(-) create mode 100644 src/displayapp/icons/analog24_hand.c create mode 100644 src/displayapp/screens/analog24-lvgl-hdline-work.diff.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 02d2a2d..0a0abea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -454,6 +454,7 @@ list(APPEND SOURCE_FILES ## Watch faces displayapp/icons/bg_clock.c displayapp/icons/bg_analog24.c + displayapp/icons/analog24_hand.c displayapp/screens/WatchFaceAnalog.cpp displayapp/screens/WatchFaceAnalog24.cpp displayapp/screens/WatchFaceDigital.cpp diff --git a/src/displayapp/icons/analog24_hand.c b/src/displayapp/icons/analog24_hand.c new file mode 100644 index 0000000..0ccac48 --- /dev/null +++ b/src/displayapp/icons/analog24_hand.c @@ -0,0 +1,36 @@ +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif +#ifndef LV_ATTRIBUTE_IMG_ANALOG24_HAND +#define LV_ATTRIBUTE_IMG_ANALOG24_HAND +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_ANALOG24_HAND uint8_t analog24_hand_map[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +const lv_img_dsc_t analog24_hand = { + .header.cf = LV_IMG_CF_ALPHA_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 16, + .header.h = 480, + .data_size = 960, // (480*16/8), + .data = analog24_hand_map, +}; diff --git a/src/displayapp/screens/WatchFaceAnalog24.cpp b/src/displayapp/screens/WatchFaceAnalog24.cpp index 29c1095..29eaf6b 100644 --- a/src/displayapp/screens/WatchFaceAnalog24.cpp +++ b/src/displayapp/screens/WatchFaceAnalog24.cpp @@ -1,6 +1,7 @@ #include "displayapp/screens/WatchFaceAnalog24.h" #include #include +#include #include "displayapp/screens/BatteryIcon.h" #include "displayapp/screens/BleIcon.h" #include "displayapp/screens/Symbols.h" @@ -9,6 +10,8 @@ using namespace Pinetime::Applications::Screens; +// #define USE_HDLINE 1 + LV_IMG_DECLARE(bg_analog24); namespace { @@ -28,17 +31,34 @@ int16_t Sine(int16_t angle) { } int16_t CoordinateXRelocate(int16_t x) { - return (x + LV_HOR_RES / 2); +#ifdef USE_HDLINE + return (x + LV_HOR_RES*2); +#else // USE_HDLINE + return (x + LV_HOR_RES/2); +#endif // USE_HDLINE } int16_t CoordinateYRelocate(int16_t y) { - return std::abs(y - LV_HOR_RES / 2); +#ifdef USE_HDLINE + return std::abs(y - LV_HOR_RES*2); +#else // USE_HDLINE + return std::abs(y - LV_HOR_RES/2); +#endif // USE_HDLINE } lv_point_t CoordinateRelocate(int16_t radius, int16_t angle) { + int16_t a = angle >> 3; + int32_t x1 = CoordinateXRelocate(radius * static_cast(Sine(a)) / LV_TRIG_SCALE); + int32_t y1 = CoordinateYRelocate(radius * static_cast(Cosine(a)) / LV_TRIG_SCALE); + a++; + int32_t x2 = CoordinateXRelocate(radius * static_cast(Sine(a)) / LV_TRIG_SCALE); + int32_t y2 = CoordinateYRelocate(radius * static_cast(Cosine(a)) / LV_TRIG_SCALE); + a = angle & 0x7; + int16_t a0 = 8 - a; + int16_t a1 = a; return lv_point_t{ - .x = CoordinateXRelocate(radius * static_cast(Sine(angle)) / LV_TRIG_SCALE), - .y = CoordinateYRelocate(radius * static_cast(Cosine(angle)) / LV_TRIG_SCALE) + .x = (x1 * a0 + x2 * a1) / 8, + .y = (y1 * a0 + y2 * a1) / 8 }; } @@ -88,7 +108,11 @@ WatchFaceAnalog24::WatchFaceAnalog24(Pinetime::Applications::DisplayApp* app, // Date - Day / Week day +#ifdef USE_HDLINE + hour_body_trace = lv_hdline_create(lv_scr_act(), NULL); +#else // USE_HDLINE hour_body_trace = lv_line_create(lv_scr_act(), NULL); +#endif // USE_HDLINE lv_style_init(&hour_line_style_trace); lv_style_set_line_width(&hour_line_style_trace, LV_STATE_DEFAULT, 3); @@ -139,7 +163,8 @@ WatchFaceAnalog24::~WatchFaceAnalog24() { void WatchFaceAnalog24::UpdateClock() { uint8_t hour = dateTimeController.Hours(); uint8_t minute = dateTimeController.Minutes(); - // second = dateTimeController.Seconds(); + uint8_t second = dateTimeController.Seconds(); + uint16_t msecond = dateTimeController.Milliseconds(); // if (sMinute != minute) { // auto const angle = minute * 6; @@ -153,19 +178,40 @@ void WatchFaceAnalog24::UpdateClock() { // lv_line_set_points(minute_body_trace, minute_point_trace, 2); // } - if (sHour != hour || sMinute != minute) { + if (sHour != hour || sMinute != minute || sSecond != second) { sHour = hour; sMinute = minute; - auto const angle = (hour * 15 + minute / 4); - + sSecond = second; + // auto const angle = 420; + // auto const angle = (368*8) - 420; // (360*8) - 492; // (hour * 120 + minute * 2); + // auto const angle = 492; // (hour * 120 + minute * 2); + // auto const angle = (360*8) - 492; // (hour * 120 + minute * 2); + // auto const angle = hour * 120 + minute * 2; + // auto const angle = hour * 120 + minute * 2 + second / 30; + auto const angle = (hour * 36000 + minute * 600 + second*10 + msecond/100)%(360*8); + + fprintf(stderr, "[[%d]]\n", angle%(360*8)); // hour_point[0] = CoordinateRelocate(30, angle); // hour_point[1] = CoordinateRelocate(HourLength, angle); - hour_point_trace[0] = CoordinateRelocate(-20, angle); - hour_point_trace[1] = CoordinateRelocate(121, angle); + hour_point_trace[0] = CoordinateRelocate(-80, angle); + hour_point_trace[1] = CoordinateRelocate(480, angle); + { + double x = hour_point_trace[1].x; + double y = hour_point_trace[1].y; +#ifdef USE_HDLINE + x /= 4; y /= 4; +#endif + x -= 120; y -= 120; + fprintf(stderr, "Len: %g\n", sqrt(x*x + y*y)); + } // lv_line_set_points(hour_body, hour_point, 2); +#ifdef USE_HDLINE + lv_hdline_set_points(hour_body_trace, hour_point_trace, 2); +#else lv_line_set_points(hour_body_trace, hour_point_trace, 2); +#endif } // if (sSecond != second) { diff --git a/src/displayapp/screens/WatchFaceAnalog24.h b/src/displayapp/screens/WatchFaceAnalog24.h index 0653bcf..6663ed1 100644 --- a/src/displayapp/screens/WatchFaceAnalog24.h +++ b/src/displayapp/screens/WatchFaceAnalog24.h @@ -38,7 +38,7 @@ namespace Pinetime { void Refresh() override; private: - uint8_t sHour, sMinute; // , sSecond; + uint8_t sHour, sMinute, sSecond; Pinetime::Controllers::DateTime::Months month; uint8_t day; diff --git a/src/displayapp/screens/analog24-lvgl-hdline-work.diff.txt b/src/displayapp/screens/analog24-lvgl-hdline-work.diff.txt new file mode 100644 index 0000000..8be9682 --- /dev/null +++ b/src/displayapp/screens/analog24-lvgl-hdline-work.diff.txt @@ -0,0 +1,649 @@ +diff --git a/src/lv_draw/lv_draw_line.c b/src/lv_draw/lv_draw_line.c +index 130c7144..d35d4cbd 100644 +--- a/src/lv_draw/lv_draw_line.c ++++ b/src/lv_draw/lv_draw_line.c +@@ -27,6 +27,9 @@ + LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, + const lv_area_t * clip, + const lv_draw_line_dsc_t * dsc); ++LV_ATTRIBUTE_FAST_MEM static void draw_hdline_skew(const lv_point_t * point1, const lv_point_t * point2, ++ const lv_area_t * clip, ++ const lv_draw_line_dsc_t * dsc); + LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, + const lv_area_t * clip, + const lv_draw_line_dsc_t * dsc); +@@ -112,6 +115,59 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_poin + } + } + ++/** ++ * Draw a line ++ * @param point1 first point of the line ++ * @param point2 second point of the line ++ * @param clip the line will be drawn only in this area ++ * @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable ++ */ ++LV_ATTRIBUTE_FAST_MEM void lv_draw_hdline(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, ++ const lv_draw_line_dsc_t * dsc) ++{ ++ fprintf(stderr, "Here 3\n"); ++ if(dsc->width == 0) return; ++ if(dsc->opa <= LV_OPA_MIN) return; ++ ++ if(point1->x == point2->x && point1->y == point2->y) return; ++ ++ lv_area_t clip_line; ++ uint8_t w = dsc->width; ++ clip_line.x1 = LV_MATH_MIN(point1->x, point2->x); ++ clip_line.x1 /= 4; ++ clip_line.x1 -= w; ++ clip_line.x2 = LV_MATH_MAX(point1->x, point2->x); ++ clip_line.x2 += 3; ++ clip_line.x2 /= 4; ++ clip_line.x2 += w; ++ clip_line.y1 = LV_MATH_MIN(point1->y, point2->y); ++ clip_line.y1 /= 4; ++ clip_line.y1 -= w; ++ clip_line.y2 = LV_MATH_MAX(point1->y, point2->y); ++ clip_line.y2 += 3; ++ clip_line.y2 /= 4; ++ clip_line.y2 += w; ++ bool is_common; ++ is_common = _lv_area_intersect(&clip_line, &clip_line, clip); ++ if(!is_common) return; ++ ++#if 0 ++ lv_point_t pt1 = *point1; ++ lv_point_t pt2 = *point2; ++ ++ pt1.x /= 4; ++ pt1.y /= 4; ++ pt2.x /= 4; ++ pt2.y /= 4; ++ ++ fprintf(stderr, "Here 4\n"); ++ draw_line_skew(&pt1, &pt2, &clip_line, dsc); ++#else ++ draw_hdline_skew(point1, point2, &clip_line, dsc); ++#endif ++} ++ ++ + /********************** + * STATIC FUNCTIONS + **********************/ +@@ -476,3 +532,173 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, cons + lv_draw_mask_remove_id(mask_top_id); + lv_draw_mask_remove_id(mask_bottom_id); + } ++ ++LV_ATTRIBUTE_FAST_MEM static void draw_hdline_skew(const lv_point_t * point1, const lv_point_t * point2, ++ const lv_area_t * clip, ++ const lv_draw_line_dsc_t * dsc) ++{ ++ fprintf(stderr, "Here 5\n"); ++ ++ /*Keep the great y in p1*/ ++ lv_point_t p1; ++ lv_point_t p2; ++ if(point1->y < point2->y) { ++ p1.y = point1->y; ++ p2.y = point2->y; ++ p1.x = point1->x; ++ p2.x = point2->x; ++ } ++ else { ++ p1.y = point2->y; ++ p2.y = point1->y; ++ p1.x = point2->x; ++ p2.x = point1->x; ++ } ++ ++ int32_t xdiff = p2.x - p1.x; ++ int32_t ydiff = p2.y - p1.y; ++ bool flat = LV_MATH_ABS(xdiff) > LV_MATH_ABS(ydiff) ? true : false; ++ ++ static const uint8_t wcorr[] = { ++ 128, 128, 128, 129, 129, 130, 130, 131, ++ 132, 133, 134, 135, 137, 138, 140, 141, ++ 143, 145, 147, 149, 151, 153, 155, 158, ++ 160, 162, 165, 167, 170, 173, 175, 178, ++ 181, ++ }; ++ ++ int32_t w = dsc->width; ++ int32_t wcorr_i = 0; ++ if(flat) wcorr_i = (LV_MATH_ABS(ydiff) << 5) / LV_MATH_ABS(xdiff); ++ else wcorr_i = (LV_MATH_ABS(xdiff) << 5) / LV_MATH_ABS(ydiff); ++ ++ w = (w * wcorr[wcorr_i] + 63) >> 5; /*+ 63 for rounding*/ ++ int32_t w_half0 = w >> 1; ++ int32_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ ++ ++ lv_area_t draw_area = *clip; ++ // draw_area.x1 = LV_MATH_MIN(p1.x, p2.x) - w; ++ // draw_area.x2 = LV_MATH_MAX(p1.x, p2.x) + w; ++ // draw_area.y1 = LV_MATH_MIN(p1.y, p2.y) - w; ++ // draw_area.y2 = LV_MATH_MAX(p1.y, p2.y) + w; ++ ++ // /* Get the union of `coords` and `clip`*/ ++ // /* `clip` is already truncated to the `vdb` size ++ // * in 'lv_refr_area' function */ ++ // bool is_common = _lv_area_intersect(&draw_area, &draw_area, clip); ++ // if(is_common == false) return; ++ ++ lv_draw_mask_line_param_t mask_left_param; ++ lv_draw_mask_line_param_t mask_right_param; ++ lv_draw_mask_line_param_t mask_top_param; ++ lv_draw_mask_line_param_t mask_bottom_param; ++ ++ if(flat) { ++ if(xdiff > 0) { ++ lv_draw_mask_hdline_points_init(&mask_left_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, ++ LV_DRAW_MASK_LINE_SIDE_LEFT); ++ lv_draw_mask_hdline_points_init(&mask_right_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, ++ LV_DRAW_MASK_LINE_SIDE_RIGHT); ++ } ++ else { ++ lv_draw_mask_hdline_points_init(&mask_left_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, ++ LV_DRAW_MASK_LINE_SIDE_LEFT); ++ lv_draw_mask_hdline_points_init(&mask_right_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, ++ LV_DRAW_MASK_LINE_SIDE_RIGHT); ++ } ++ } ++ else { ++ lv_draw_mask_hdline_points_init(&mask_left_param, p1.x + w_half1, p1.y, p2.x + w_half1, p2.y, ++ LV_DRAW_MASK_LINE_SIDE_LEFT); ++ lv_draw_mask_hdline_points_init(&mask_right_param, p1.x - w_half0, p1.y, p2.x - w_half0, p2.y, ++ LV_DRAW_MASK_LINE_SIDE_RIGHT); ++ } ++ ++ /*Use the normal vector for the endings*/ ++ ++ int16_t mask_left_id = lv_draw_mask_add(&mask_left_param, NULL); ++ int16_t mask_right_id = lv_draw_mask_add(&mask_right_param, NULL); ++ int16_t mask_top_id = LV_MASK_ID_INV; ++ int16_t mask_bottom_id = LV_MASK_ID_INV; ++ ++ if(!dsc->raw_end) { ++ lv_draw_mask_hdline_points_init(&mask_top_param, p1.x, p1.y, p1.x - ydiff, p1.y + xdiff, LV_DRAW_MASK_LINE_SIDE_BOTTOM); ++ lv_draw_mask_hdline_points_init(&mask_bottom_param, p2.x, p2.y, p2.x - ydiff, p2.y + xdiff, LV_DRAW_MASK_LINE_SIDE_TOP); ++ mask_top_id = lv_draw_mask_add(&mask_top_param, NULL); ++ mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL); ++ } ++ ++ lv_disp_t * disp = _lv_refr_get_disp_refreshing(); ++ lv_disp_buf_t * vdb = lv_disp_get_buf(disp); ++ ++ const lv_area_t * disp_area = &vdb->area; ++ ++ /*Store the coordinates of the `draw_a` relative to the VDB */ ++ draw_area.x1 -= disp_area->x1; ++ draw_area.y1 -= disp_area->y1; ++ draw_area.x2 -= disp_area->x1; ++ draw_area.y2 -= disp_area->y1; ++ ++ /* The real draw area is around the line. ++ * It's easy to calculate with steep lines, but the area can be very wide with very flat lines. ++ * So deal with it only with steep lines. */ ++ int32_t draw_area_w = lv_area_get_width(&draw_area); ++ ++ /*Draw the background line by line*/ ++ int32_t h; ++ uint32_t hor_res = (uint32_t)lv_disp_get_hor_res(disp); ++ size_t mask_buf_size = LV_MATH_MIN(lv_area_get_size(&draw_area), hor_res); ++ lv_opa_t * mask_buf = _lv_mem_buf_get(mask_buf_size); ++ ++ lv_area_t fill_area; ++ fill_area.x1 = draw_area.x1 + disp_area->x1; ++ fill_area.x2 = draw_area.x2 + disp_area->x1; ++ fill_area.y1 = draw_area.y1 + disp_area->y1; ++ fill_area.y2 = fill_area.y1; ++ ++ int32_t x = vdb->area.x1 + draw_area.x1; ++ ++ uint32_t mask_p = 0; ++ ++ _lv_memset_ff(mask_buf, mask_buf_size); ++ /*Fill the first row with 'color'*/ ++ for(h = draw_area.y1 + disp_area->y1; h <= draw_area.y2 + disp_area->y1; h++) { ++ ++ lv_draw_mask_res_t mask_res = lv_draw_mask_apply(&mask_buf[mask_p], x, h, draw_area_w); ++ if(mask_res == LV_DRAW_MASK_RES_TRANSP) { ++ _lv_memset_00(&mask_buf[mask_p], draw_area_w); ++ } ++ ++ mask_p += draw_area_w; ++ if((uint32_t) mask_p + draw_area_w < mask_buf_size) { ++ fill_area.y2 ++; ++ } ++ else { ++ _lv_blend_fill(&fill_area, clip, ++ dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa, ++ dsc->blend_mode); ++ ++ fill_area.y1 = fill_area.y2 + 1; ++ fill_area.y2 = fill_area.y1; ++ mask_p = 0; ++ _lv_memset_ff(mask_buf, mask_buf_size); ++ } ++ } ++ ++ /*Flush the last part*/ ++ if(fill_area.y1 != fill_area.y2) { ++ fill_area.y2--; ++ _lv_blend_fill(&fill_area, clip, ++ dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa, ++ dsc->blend_mode); ++ ++ } ++ ++ _lv_mem_buf_release(mask_buf); ++ ++ lv_draw_mask_remove_id(mask_left_id); ++ lv_draw_mask_remove_id(mask_right_id); ++ lv_draw_mask_remove_id(mask_top_id); ++ lv_draw_mask_remove_id(mask_bottom_id); ++} ++ +diff --git a/src/lv_draw/lv_draw_line.h b/src/lv_draw/lv_draw_line.h +index 9a1da4e5..6858f48a 100644 +--- a/src/lv_draw/lv_draw_line.h ++++ b/src/lv_draw/lv_draw_line.h +@@ -48,6 +48,8 @@ typedef struct { + */ + LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, + const lv_draw_line_dsc_t * dsc); ++LV_ATTRIBUTE_FAST_MEM void lv_draw_hdline(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, ++ const lv_draw_line_dsc_t * dsc); + + LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc); + +diff --git a/src/lv_draw/lv_draw_mask.c b/src/lv_draw/lv_draw_mask.c +index 7fb01ee0..d925dd1e 100644 +--- a/src/lv_draw/lv_draw_mask.c ++++ b/src/lv_draw/lv_draw_mask.c +@@ -6,6 +6,7 @@ + /********************* + * INCLUDES + *********************/ ++#include + #include "lv_draw_mask.h" + #include "../lv_misc/lv_math.h" + #include "../lv_misc/lv_log.h" +@@ -261,6 +262,197 @@ void lv_draw_mask_line_points_init(lv_draw_mask_line_param_t * param, lv_coord_t + if(param->steep < 0) param->spx = -param->spx; + } + ++void lv_draw_mask_hdline_points_init(lv_draw_mask_line_param_t * param, lv_coord_t p1x, lv_coord_t p1y, lv_coord_t p2x, ++ lv_coord_t p2y, lv_draw_mask_line_side_t side) ++{ ++ fprintf(stderr,"X:%d:%d Y:%d:%d\n",p1x,p2x,p1y,p2y); ++ fprintf(stderr,"X:%d:%d Y:%d:%d\n",p1x&3,p2x&3,p1y&3,p2y&3); ++ // if (!(p1x&3) && !(p1y&3) && !(p2x&3) && !(p2y&3)) { ++ lv_coord_t dx, dy; ++ dx = p2x - p1x; dy = p2y - p1y; ++ // while (dx && dy && !(dx&1) && !(dy&1)) { ++ // dx /= 2; ++ // dy /= 2; ++ // } ++ // p2x = p1x + dx; ++ // p2y = p1y + dy; ++ // r1x = p1x&3; r1y = p1y&3; r2x = p2x&3; r2y = p2y&3; rdx = dx&3; rdy = dy&3; ++ // } ++ if (p1x&3) { ++ lv_coord_t p1xn = p1x - dx; ++ lv_coord_t p1yn = p1y - dy; ++ if (p1xn&3) { ++ p1xn -= dx; ++ p1yn -= dy; ++ if (p1xn&3) { ++ p1xn -= dx; ++ p1yn -= dy; ++ if (p1xn&3) { } else { ++ goto p1xngood; ++ } ++ } else { ++ goto p1xngood; ++ } ++ } else { ++ goto p1xngood; ++ } ++ goto p1xnbad; ++ p1xngood: ++ p1x = p1xn; ++ p1y = p1yn; ++ p1xnbad: ; ++ } ++ if (p2x&3) { ++ lv_coord_t p2xn = p2x + dx; ++ lv_coord_t p2yn = p2y + dy; ++ if (p2xn&3) { ++ p2xn += dx; ++ p2yn += dy; ++ if (p2xn&3) { ++ p2xn += dx; ++ p2yn += dy; ++ if (p2xn&3) { } else { ++ goto p2xngood; ++ } ++ } else { ++ goto p2xngood; ++ } ++ } else { ++ goto p2xngood; ++ } ++ goto p2xnbad; ++ p2xngood: ++ p2x = p2xn; ++ p2y = p2yn; ++ p2xnbad: ; ++ } ++ dx = p2x - p1x; dy = p2y - p1y; ++ if (p1y&3) { ++ lv_coord_t p1xn = p1x - dx; ++ lv_coord_t p1yn = p1y - dy; ++ if (p1yn&3) { ++ p1xn -= dx; ++ p1yn -= dy; ++ if (p1yn&3) { ++ p1xn -= dx; ++ p1yn -= dy; ++ if (p1yn&3) { } else { ++ goto p1yngood; ++ } ++ } else { ++ goto p1yngood; ++ } ++ } else { ++ goto p1yngood; ++ } ++ goto p1ynbad; ++ p1yngood: ++ p1x = p1xn; ++ p1y = p1yn; ++ p1ynbad: ; ++ } ++ if (p2y&3) { ++ lv_coord_t p2xn = p2x + dx; ++ lv_coord_t p2yn = p2y + dy; ++ if (p2yn&3) { ++ p2xn += dx; ++ p2yn += dy; ++ if (p2yn&3) { ++ p2xn += dx; ++ p2yn += dy; ++ if (p2yn&3) { } else { ++ goto p2yngood; ++ } ++ } else { ++ goto p2yngood; ++ } ++ } else { ++ goto p2yngood; ++ } ++ goto p2ynbad; ++ p2yngood: ++ p2x = p2xn; ++ p2y = p2yn; ++ p2ynbad: ; ++ } ++ uint8_t r1x, r1y, r2x, r2y; ++ r1x = p1x&3; r2x = p2x&3; r1y = p1y&3; r2y = p2y&3; ++ dx = p2x - p1x; dy = p2y - p1y; ++ fprintf(stderr,"X:%d:%d Y:%d:%d\n",p1x,p2x,p1y,p2y); ++ fprintf(stderr,"X:%d:%d Y:%d:%d\n",r1x,r2x,r1y,r2y); ++ if (!r1x && !r2x && !r1y && !r2y) { ++ fprintf(stderr, "[ok]\n"); ++ // } else if (1) { ++ // fprintf(stderr, "...\n"); ++ } else if (!r1x && !r2x) { ++ if (r1y == r2y) { ++ if (r1y == 1) { ++ fprintf(stderr, "[Y1]\n"); ++ p1x -= dx; p2x += dx * 2; ++ p1y -= dy; p2y += dy * 2; ++ // p1x -= dx * 2; p2x += dx * 5; ++ // p1y -= dy * 2; p2y += dy * 5; ++ p1y -= 1; p2y += 3; ++ } else if (r1y == 2) { ++ fprintf(stderr, "[Y2]\n"); ++ p1x -= dx * 2; p2x += dx * 2; ++ p1y -= dy * 2; p2y += dy * 2; ++ p1y -= 2; p2y += 2; ++ } else if (r1y == 3) { ++ fprintf(stderr, "[Y3]\n"); ++ p1x -= dx * 2; p2x += dx; ++ p1y -= dy * 2; p2y += dy; ++ // p1x -= dx * 5; p2x += dx * 2; ++ // p1y -= dy * 5; p2y += dy * 2; ++ p1y -= 3; p2y += 1; ++ } ++ } else { ++ fprintf(stderr, "[Y?]\n"); ++ } ++ } else if (!r1y && !r2y) { ++ if (r1x == r2x) { ++ if (r1x == 1) { ++ fprintf(stderr, "[X1]\n"); ++ p1x -= dx; p2x += dx * 2; ++ p1y -= dy; p2y += dy * 2; ++ // p1x -= dx * 2; p2x += dx * 5; ++ // p1y -= dy * 2; p2y += dy * 5; ++ p1x -= 1; p2x += 3; ++ } else if (r1x == 2) { ++ fprintf(stderr, "[X2]\n"); ++ p1x -= dx * 2; p2x += dx * 2; ++ p1y -= dy * 2; p2y += dy * 2; ++ p1x -= 2; p2x += 2; ++ } else if (r1x == 3) { ++ fprintf(stderr, "[X3]\n"); ++ p1x -= dx * 2; p2x += dx; ++ p1y -= dy * 2; p2y += dy; ++ // p1x -= dx * 5; p2x += dx * 2; ++ // p1y -= dy * 5; p2y += dy * 2; ++ p1x -= 3; p2x += 1; ++ } ++ } else { ++ fprintf(stderr, "[X?]\n"); ++ } ++ } else { ++ fprintf(stderr, "[?]\n"); ++ } ++ r1x = p1x&3; r2x = p2x&3; r1y = p1y&3; r2y = p2y&3; ++ dx = p2x - p1x; dy = p2y - p1y; ++ fprintf(stderr,"X:%d:%d Y:%d:%d\n",p1x,p2x,p1y,p2y); ++ fprintf(stderr,"X:%d:%d Y:%d:%d\n",r1x,r2x,r1y,r2y); ++ fprintf(stderr, "\n"); ++ p1x += 2; p1x /= 4; ++ p1y += 2; p1y /= 4; ++ p2x += 2; p2x /= 4; ++ p2y += 2; p2y /= 4; ++ lv_draw_mask_line_points_init( ++ param, ++ p1x, p1y, ++ p2x, p2y, ++ side); ++} ++ + /** + *Initialize a line mask from a point and an angle. + * @param param pointer to a `lv_draw_mask_param_t` to initialize +diff --git a/src/lv_draw/lv_draw_mask.h b/src/lv_draw/lv_draw_mask.h +index adb9a050..4f058ee1 100644 +--- a/src/lv_draw/lv_draw_mask.h ++++ b/src/lv_draw/lv_draw_mask.h +@@ -237,6 +237,9 @@ LV_ATTRIBUTE_FAST_MEM uint8_t lv_draw_mask_get_cnt(void); + void lv_draw_mask_line_points_init(lv_draw_mask_line_param_t * param, lv_coord_t p1x, lv_coord_t p1y, lv_coord_t p2x, + lv_coord_t p2y, lv_draw_mask_line_side_t side); + ++void lv_draw_mask_hdline_points_init(lv_draw_mask_line_param_t * param, lv_coord_t p1x, lv_coord_t p1y, lv_coord_t p2x, ++ lv_coord_t p2y, lv_draw_mask_line_side_t side); ++ + /** + *Initialize a line mask from a point and an angle. + * @param param pointer to a `lv_draw_mask_param_t` to initialize +diff --git a/src/lv_widgets/lv_line.c b/src/lv_widgets/lv_line.c +index c54a0ecf..01ea6dcd 100644 +--- a/src/lv_widgets/lv_line.c ++++ b/src/lv_widgets/lv_line.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + /********************* + * DEFINES +@@ -29,6 +30,7 @@ + /********************** + * STATIC PROTOTYPES + **********************/ ++static lv_design_res_t lv_hdline_design(lv_obj_t * line, const lv_area_t * clip_area, lv_design_mode_t mode); + static lv_design_res_t lv_line_design(lv_obj_t * line, const lv_area_t * clip_area, lv_design_mode_t mode); + static lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param); + +@@ -103,6 +105,28 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy) + return line; + } + ++/** ++ * Create a line objects ++ * @param par pointer to an object, it will be the parent of the new line ++ * @return pointer to the created line ++ */ ++lv_obj_t * lv_hdline_create(lv_obj_t * par, const lv_obj_t * copy) ++{ ++ LV_LOG_TRACE("hdline create started"); ++ ++ /*Create a basic object*/ ++ lv_obj_t * line = lv_line_create(par, copy); ++ LV_ASSERT_MEM(line); ++ if(line == NULL) return NULL; ++ ++ lv_obj_set_design_cb(line, lv_hdline_design); ++ ++ LV_LOG_INFO("hdline created"); ++ ++ return line; ++} ++ ++ + /*===================== + * Setter functions + *====================*/ +@@ -114,6 +138,30 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy) + * so the array can NOT be a local variable which will be destroyed + * @param point_num number of points in 'point_a' + */ ++void lv_hdline_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num) ++{ ++ LV_ASSERT_OBJ(line, LV_OBJX_NAME); ++ ++ lv_line_ext_t * ext = lv_obj_get_ext_attr(line); ++ ext->point_array = point_a; ++ ext->point_num = point_num; ++ ++ if(point_num > 0 && ext->auto_size != 0) { ++ uint16_t i; ++ lv_coord_t xmax = LV_COORD_MIN; ++ lv_coord_t ymax = LV_COORD_MIN; ++ for(i = 0; i < point_num; i++) { ++ xmax = LV_MATH_MAX((point_a[i].x + 3) / 4, xmax); ++ ymax = LV_MATH_MAX((point_a[i].y + 3) / 4, ymax); ++ } ++ ++ lv_style_int_t line_width = lv_obj_get_style_line_width(line, LV_LINE_PART_MAIN); ++ lv_obj_set_size(line, xmax + line_width, ymax + line_width); ++ } ++ ++ lv_obj_invalidate(line); ++} ++ + void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num) + { + LV_ASSERT_OBJ(line, LV_OBJX_NAME); +@@ -267,6 +315,63 @@ static lv_design_res_t lv_line_design(lv_obj_t * line, const lv_area_t * clip_ar + return LV_DESIGN_RES_OK; + } + ++/** ++ * Handle the drawing related tasks of the lines ++ * @param line pointer to an object ++ * @param clip_area the object will be drawn only in this area ++ * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area ++ * (return 'true' if yes) ++ * LV_DESIGN_DRAW: draw the object (always return 'true') ++ * LV_DESIGN_DRAW_POST: drawing after every children are drawn ++ * @param return an element of `lv_design_res_t` ++ */ ++static lv_design_res_t lv_hdline_design(lv_obj_t * line, const lv_area_t * clip_area, lv_design_mode_t mode) ++{ ++ fprintf(stderr, "Here1\n"); ++ /*A line never covers an area*/ ++ if(mode == LV_DESIGN_COVER_CHK) ++ return LV_DESIGN_RES_NOT_COVER; ++ else if(mode == LV_DESIGN_DRAW_MAIN) { ++ lv_line_ext_t * ext = lv_obj_get_ext_attr(line); ++ ++ if(ext->point_num == 0 || ext->point_array == NULL) return false; ++ ++ lv_area_t area; ++ lv_obj_get_coords(line, &area); ++ lv_coord_t x_ofs = area.x1; ++ lv_coord_t y_ofs = area.y1; ++ lv_point_t p1; ++ lv_point_t p2; ++ lv_coord_t h = lv_obj_get_height(line); ++ uint16_t i; ++ ++ lv_draw_line_dsc_t line_dsc; ++ lv_draw_line_dsc_init(&line_dsc); ++ lv_obj_init_draw_line_dsc(line, LV_LINE_PART_MAIN, &line_dsc); ++ ++ /*Read all points and draw the lines*/ ++ for(i = 0; i < ext->point_num - 1; i++) { ++ ++ p1.x = ext->point_array[i].x + x_ofs; ++ p2.x = ext->point_array[i + 1].x + x_ofs; ++ ++ if(ext->y_inv == 0) { ++ p1.y = ext->point_array[i].y + y_ofs; ++ p2.y = ext->point_array[i + 1].y + y_ofs; ++ } ++ else { ++ p1.y = h - ext->point_array[i].y + y_ofs; ++ p2.y = h - ext->point_array[i + 1].y + y_ofs; ++ } ++ fprintf(stderr, "Here2\n"); ++ lv_draw_hdline(&p1, &p2, clip_area, &line_dsc); ++ line_dsc.round_start = 0; /*Draw the rounding only on the end points after the first line*/ ++ } ++ ++ } ++ return LV_DESIGN_RES_OK; ++} ++ + /** + * Signal function of the line + * @param line pointer to a line object +diff --git a/src/lv_widgets/lv_line.h b/src/lv_widgets/lv_line.h +index 1f04aebf..4f737724 100644 +--- a/src/lv_widgets/lv_line.h ++++ b/src/lv_widgets/lv_line.h +@@ -52,6 +52,7 @@ typedef uint8_t lv_line_style_t; + * @return pointer to the created line + */ + lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy); ++lv_obj_t * lv_hdline_create(lv_obj_t * par, const lv_obj_t * copy); + + /*===================== + * Setter functions +@@ -65,6 +66,7 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy); + * @param point_num number of points in 'point_a' + */ + void lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num); ++void lv_hdline_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num); + + /** + * Enable (or disable) the auto-size option. The size of the object will fit to its points. diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 73109c5..71a2ad9 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -173,7 +173,7 @@ typedef void* lv_anim_user_data_t; #define LV_USE_OPA_SCALE 0 /* 1: Use image zoom and rotation*/ -#define LV_USE_IMG_TRANSFORM 0 +#define LV_USE_IMG_TRANSFORM 1 /* 1: Enable object groups (for keyboard/encoder navigation) */ #define LV_USE_GROUP 0 -- 2.19.1