summaryrefslogtreecommitdiff
path: root/work-patches/hdline-work.patch
diff options
context:
space:
mode:
authorMichele Bini <michele.bini@gmail.com>2022-04-07 12:12:02 (GMT)
committerMichele Bini <michele.bini@gmail.com>2022-04-10 07:36:52 (GMT)
commitc21518adfc7df5478a5e51d77e1b6915dfc470dd (patch)
treea7688a68f1743a6e499987cb4ba0516adb6fed94 /work-patches/hdline-work.patch
parentf67d92a56cd2246a11c18a4a58b808222cb9d744 (diff)
work-patches/hdline-work.patch
Diffstat (limited to 'work-patches/hdline-work.patch')
-rw-r--r--work-patches/hdline-work.patch882
1 files changed, 882 insertions, 0 deletions
diff --git a/work-patches/hdline-work.patch b/work-patches/hdline-work.patch
new file mode 100644
index 0000000..947e42d
--- /dev/null
+++ b/work-patches/hdline-work.patch
@@ -0,0 +1,882 @@
+From a70971a937441ad0d7d11ae8cb0ffbb1884d7f9b Mon Sep 17 00:00:00 2001
+From: Michele Bini <michele.bini@gmail.com>
+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 <cmath>
+ #include <lvgl/lvgl.h>
++#include <stdio.h>
+ #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<int32_t>(Sine(a)) / LV_TRIG_SCALE);
++ int32_t y1 = CoordinateYRelocate(radius * static_cast<int32_t>(Cosine(a)) / LV_TRIG_SCALE);
++ a++;
++ int32_t x2 = CoordinateXRelocate(radius * static_cast<int32_t>(Sine(a)) / LV_TRIG_SCALE);
++ int32_t y2 = CoordinateYRelocate(radius * static_cast<int32_t>(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<int32_t>(Sine(angle)) / LV_TRIG_SCALE),
+- .y = CoordinateYRelocate(radius * static_cast<int32_t>(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 <stdio.h>
++ #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 <stdbool.h>
++ #include <stdint.h>
++ #include <string.h>
+++#include <stdio.h>
++
++ /*********************
++ * 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
+