diff --git a/src/widgets/chart/lv_chart.c b/src/widgets/chart/lv_chart.c index dcc0b73b69..af1b913b96 100644 --- a/src/widgets/chart/lv_chart.c +++ b/src/widgets/chart/lv_chart.c @@ -11,6 +11,7 @@ #include "../../draw/lv_draw_private.h" #include "../../core/lv_obj_private.h" #include "../../core/lv_obj_class_private.h" +#include "../../core/lv_obj_draw_private.h" #if LV_USE_CHART != 0 #include "../../misc/lv_assert.h" @@ -807,15 +808,29 @@ static void lv_chart_event(const lv_obj_class_t * class_p, lv_event_t * e) } else if(code == LV_EVENT_DRAW_MAIN) { lv_layer_t * layer = lv_event_get_layer(e); - draw_div_lines(obj, layer); - if(lv_ll_is_empty(&chart->series_ll) == false) { - if(chart->type == LV_CHART_TYPE_LINE) draw_series_line(obj, layer); - else if(chart->type == LV_CHART_TYPE_BAR) draw_series_bar(obj, layer); - else if(chart->type == LV_CHART_TYPE_SCATTER) draw_series_scatter(obj, layer); + lv_area_t ext_coords; + lv_obj_get_coords(obj, &ext_coords); + int32_t ext_draw_size = lv_obj_get_ext_draw_size(obj); + lv_area_increase(&ext_coords, ext_draw_size, ext_draw_size); + + lv_area_t clip_area; + if(lv_area_intersect(&clip_area, &ext_coords, &layer->_clip_area)) { + const lv_area_t clip_area_ori = layer->_clip_area; + layer->_clip_area = clip_area; + + draw_div_lines(obj, layer); + + if(lv_ll_is_empty(&chart->series_ll) == false) { + if(chart->type == LV_CHART_TYPE_LINE) draw_series_line(obj, layer); + else if(chart->type == LV_CHART_TYPE_BAR) draw_series_bar(obj, layer); + else if(chart->type == LV_CHART_TYPE_SCATTER) draw_series_scatter(obj, layer); + } + + draw_cursors(obj, layer); + + layer->_clip_area = clip_area_ori; } - - draw_cursors(obj, layer); } } @@ -823,13 +838,6 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) { lv_chart_t * chart = (lv_chart_t *)obj; - lv_area_t series_clip_area; - bool mask_ret = lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); - if(mask_ret == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = series_clip_area; - int16_t i; int16_t i_start; int16_t i_end; @@ -892,18 +900,10 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) lv_draw_line(layer, &line_dsc); } } - - layer->_clip_area = clip_area_ori; } static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) { - lv_area_t clip_area; - if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_t * chart = (lv_chart_t *)obj; if(chart->point_cnt < 2) return; @@ -917,10 +917,6 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) int32_t y_ofs = obj->coords.y1 + pad_top - lv_obj_get_scroll_top(obj); lv_chart_series_t * ser; - lv_area_t series_clip_area; - bool mask_ret = lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); - if(mask_ret == false) return; - lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); line_dsc.base.layer = layer; @@ -976,7 +972,7 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) line_dsc.p1.x = line_dsc.p2.x; line_dsc.p1.y = line_dsc.p2.y; - if(line_dsc.p1.x > clip_area_ori.x2 + point_w + 1) break; + if(line_dsc.p1.x > layer->_clip_area.x2 + point_w + 1) break; line_dsc.p2.x = (lv_value_precise_t)((w * i) / (chart->point_cnt - 1)) + x_ofs; p_act = (start_point + i) % chart->point_cnt; @@ -985,7 +981,7 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) y_tmp = y_tmp / (chart->ymax[ser->y_axis_sec] - chart->ymin[ser->y_axis_sec]); line_dsc.p2.y = h - y_tmp + y_ofs; - if(line_dsc.p2.x < clip_area_ori.x1 - point_w - 1) { + if(line_dsc.p2.x < layer->_clip_area.x1 - point_w - 1) { p_prev = p_act; continue; } @@ -1052,19 +1048,10 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) line_dsc.base.id1--; } } - - layer->_clip_area = clip_area_ori; } static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) { - - lv_area_t clip_area; - if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_t * chart = (lv_chart_t *)obj; uint32_t i; @@ -1174,18 +1161,11 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) } line_dsc.base.id1++; point_dsc_default.base.id1++; - layer->_clip_area = clip_area_ori; } } static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) { - lv_area_t clip_area; - if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_t * chart = (lv_chart_t *)obj; uint32_t i; @@ -1243,11 +1223,11 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) col_a.x2 = col_a.x1 + col_w - 1; x_act += col_w + ser_gap; - if(col_a.x2 < clip_area.x1) { + if(col_a.x2 < layer->_clip_area.x1) { col_dsc.base.id1++; continue; } - if(col_a.x1 > clip_area.x2) break; + if(col_a.x1 > layer->_clip_area.x2) break; col_dsc.bg_color = ser->color; @@ -1262,7 +1242,6 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) col_dsc.base.id1++; } } - layer->_clip_area = clip_area_ori; } static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) @@ -1272,12 +1251,6 @@ static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) lv_chart_t * chart = (lv_chart_t *)obj; if(lv_ll_is_empty(&chart->cursor_ll)) return; - lv_area_t clip_area; - if(!lv_area_intersect(&clip_area, &layer->_clip_area, &obj->coords)) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_cursor_t * cursor; lv_draw_line_dsc_t line_dsc_ori; @@ -1361,8 +1334,6 @@ static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) line_dsc_ori.base.id1++; point_dsc_ori.base.id1++; } - - layer->_clip_area = clip_area_ori; } /**