diff --git a/boot/scene.c b/boot/scene.c index 49dac90ceed..325dd23641f 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -206,12 +206,17 @@ int scene_txt_set_font(struct scene *scn, uint id, const char *font_name, int scene_obj_set_pos(struct scene *scn, uint id, int x, int y) { struct scene_obj *obj; + int w, h; obj = scene_obj_find(scn, id, SCENEOBJT_NONE); if (!obj) return log_msg_ret("find", -ENOENT); + w = obj->bbox.x1 - obj->bbox.x0; + h = obj->bbox.y1 - obj->bbox.y0; obj->bbox.x0 = x; obj->bbox.y0 = y; + obj->bbox.x1 = obj->bbox.x0 + w; + obj->bbox.y1 = obj->bbox.y0 + h; return 0; } @@ -223,8 +228,9 @@ int scene_obj_set_size(struct scene *scn, uint id, int w, int h) obj = scene_obj_find(scn, id, SCENEOBJT_NONE); if (!obj) return log_msg_ret("find", -ENOENT); - obj->bbox.w = w; - obj->bbox.h = h; + obj->bbox.x1 = obj->bbox.x0 + w; + obj->bbox.y1 = obj->bbox.y0 + h; + obj->flags |= SCENEOF_SIZE_VALID; return 0; } @@ -419,8 +425,8 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) if (obj->flags & SCENEOF_POINT) { vidconsole_push_colour(cons, fore, back, &old); video_fill_part(dev, x - theme->menu_inset, y, - x + obj->bbox.w, - y + obj->bbox.h, + obj->bbox.x1, + obj->bbox.y1, vid_priv->colour_bg); } vidconsole_set_cursor_pos(cons, x, y); @@ -765,8 +771,13 @@ int scene_calc_dims(struct scene *scn, bool do_menus) ret = scene_obj_get_hw(scn, obj->id, &width); if (ret < 0) return log_msg_ret("get", ret); - obj->bbox.w = width; - obj->bbox.h = ret; + obj->dims.x = width; + obj->dims.y = ret; + if (!(obj->flags & SCENEOF_SIZE_VALID)) { + obj->bbox.x1 = obj->bbox.x0 + width; + obj->bbox.y1 = obj->bbox.y0 + ret; + obj->flags |= SCENEOF_SIZE_VALID; + } } break; } @@ -917,13 +928,13 @@ int scene_bbox_union(struct scene *scn, uint id, int inset, if (bbox->valid) { bbox->x0 = min(bbox->x0, obj->bbox.x0 - inset); bbox->y0 = min(bbox->y0, obj->bbox.y0); - bbox->x1 = max(bbox->x1, obj->bbox.x0 + obj->bbox.w + inset); - bbox->y1 = max(bbox->y1, obj->bbox.y0 + obj->bbox.h); + bbox->x1 = max(bbox->x1, obj->bbox.x1 + inset); + bbox->y1 = max(bbox->y1, obj->bbox.y1); } else { bbox->x0 = obj->bbox.x0 - inset; bbox->y0 = obj->bbox.y0; - bbox->x1 = obj->bbox.x0 + obj->bbox.w + inset; - bbox->y1 = obj->bbox.y0 + obj->bbox.h; + bbox->x1 = obj->bbox.x1 + inset; + bbox->y1 = obj->bbox.y1; bbox->valid = true; } diff --git a/boot/scene_menu.c b/boot/scene_menu.c index c47c2030527..dbc6793e302 100644 --- a/boot/scene_menu.c +++ b/boot/scene_menu.c @@ -186,8 +186,8 @@ int scene_menu_calc_dims(struct scene_obj_menu *menu) } if (bbox.valid) { - menu->obj.bbox.w = bbox.x1 - bbox.x0; - menu->obj.bbox.h = bbox.y1 - bbox.y0; + menu->obj.dims.x = bbox.x1 - bbox.x0; + menu->obj.dims.y = bbox.y1 - bbox.y0; } return 0; @@ -295,6 +295,9 @@ int scene_menu_arrange(struct scene *scn, struct expo_arrange_info *arr, if (sel_id) menu_point_to_item(menu, sel_id); + menu->obj.bbox.x1 = menu->obj.bbox.x0 + menu->obj.dims.x; + menu->obj.bbox.y1 = menu->obj.bbox.y0 + menu->obj.dims.y; + menu->obj.flags |= SCENEOF_SIZE_VALID; return 0; } diff --git a/boot/scene_textline.c b/boot/scene_textline.c index a513d555ded..f1d6ff7607c 100644 --- a/boot/scene_textline.c +++ b/boot/scene_textline.c @@ -61,7 +61,8 @@ void scene_textline_calc_bbox(struct scene_obj_textline *tline, int scene_textline_calc_dims(struct scene_obj_textline *tline) { - struct scene *scn = tline->obj.scene; + struct scene_obj *obj = &tline->obj; + struct scene *scn = obj->scene; struct vidconsole_bbox bbox; struct scene_obj_txt *txt; int ret; @@ -76,11 +77,16 @@ int scene_textline_calc_dims(struct scene_obj_textline *tline) return log_msg_ret("nom", ret); if (bbox.valid) { - tline->obj.bbox.w = bbox.x1 - bbox.x0; - tline->obj.bbox.h = bbox.y1 - bbox.y0; - - scene_obj_set_size(scn, tline->edit_id, tline->obj.bbox.w, - tline->obj.bbox.h); + obj->dims.x = bbox.x1 - bbox.x0; + obj->dims.y = bbox.y1 - bbox.y0; + if (!(obj->flags & SCENEOF_SIZE_VALID)) { + obj->bbox.x1 = obj->bbox.x0 + obj->dims.x; + obj->bbox.y1 = obj->bbox.y0 + obj->dims.y; + obj->flags |= SCENEOF_SIZE_VALID; + } + scene_obj_set_size(scn, tline->edit_id, + obj->bbox.x1 - obj->bbox.x0, + obj->bbox.y1 - obj->bbox.y0); } return 0; diff --git a/include/expo.h b/include/expo.h index b6de0310071..6f0547a4b38 100644 --- a/include/expo.h +++ b/include/expo.h @@ -9,6 +9,7 @@ #include #include +#include #include struct udevice; @@ -196,14 +197,29 @@ enum scene_obj_t { * * @x0: x position, in pixels from left side * @y0: y position, in pixels from top - * @w: width, in pixels - * @h: height, in pixels + * @x1: x position of right size + * @y1: y position of bottom */ struct scene_obj_bbox { int x0; int y0; - int w; - int h; + int x1; + int y1; +}; + +/** + * struct scene_obj_dims - Dimensions of the object being drawn + * + * Image and text objects have a dimension which can change depending on what + * they contain. For images this stores the size. For text it stores the size as + * rendered on the display + * + * @x: x dimension + * @y: y dimension + */ +struct scene_obj_dims { + int x; + int y; }; /** @@ -213,11 +229,14 @@ struct scene_obj_bbox { * @SCENEOF_POINT: object should be highlighted * @SCENEOF_OPEN: object should be opened (e.g. menu is opened so that an option * can be selected) + * @SCENEOF_SIZE_VALID: object's size (width/height) is valid, so any adjustment + * to x0/y0 should maintain the width/height of the object */ enum scene_obj_flags_t { SCENEOF_HIDE = 1 << 0, SCENEOF_POINT = 1 << 1, SCENEOF_OPEN = 1 << 2, + SCENEOF_SIZE_VALID = BIT(3), }; enum { @@ -232,7 +251,8 @@ enum { * @name: Name of the object (allocated) * @id: ID number of the object * @type: Type of this object - * @bbox: Dimensions for this object + * @bbox: Bounding box for this object + * @dims: Dimensions of the text/image (may be smaller than bbox) * @flags: Flags for this object * @bit_length: Number of bits used for this object in CMOS RAM * @start_bit: Start bit to use for this object in CMOS RAM @@ -244,6 +264,7 @@ struct scene_obj { uint id; enum scene_obj_t type; struct scene_obj_bbox bbox; + struct scene_obj_dims dims; u8 flags; u8 bit_length; u16 start_bit; diff --git a/test/boot/expo.c b/test/boot/expo.c index 9c940825278..94c13e9b71f 100644 --- a/test/boot/expo.c +++ b/test/boot/expo.c @@ -550,39 +550,39 @@ static int expo_render_image(struct unit_test_state *uts) ut_assertnonnull(obj); ut_asserteq(400, obj->bbox.x0); ut_asserteq(100, obj->bbox.y0); - ut_asserteq(126, obj->bbox.w); - ut_asserteq(40, obj->bbox.h); + ut_asserteq(400 + 126, obj->bbox.x1); + ut_asserteq(100 + 40, obj->bbox.y1); /* check dimensions of image */ obj = scene_obj_find(scn, OBJ_LOGO, SCENEOBJT_NONE); ut_assertnonnull(obj); ut_asserteq(50, obj->bbox.x0); ut_asserteq(20, obj->bbox.y0); - ut_asserteq(160, obj->bbox.w); - ut_asserteq(160, obj->bbox.h); + ut_asserteq(50 + 160, obj->bbox.x1); + ut_asserteq(20 + 160, obj->bbox.y1); /* check dimensions of menu labels - both should be the same width */ obj = scene_obj_find(scn, ITEM1_LABEL, SCENEOBJT_NONE); ut_assertnonnull(obj); ut_asserteq(50, obj->bbox.x0); ut_asserteq(436, obj->bbox.y0); - ut_asserteq(29, obj->bbox.w); - ut_asserteq(18, obj->bbox.h); + ut_asserteq(50 + 29, obj->bbox.x1); + ut_asserteq(436 + 18, obj->bbox.y1); obj = scene_obj_find(scn, ITEM2_LABEL, SCENEOBJT_NONE); ut_assertnonnull(obj); ut_asserteq(50, obj->bbox.x0); ut_asserteq(454, obj->bbox.y0); - ut_asserteq(29, obj->bbox.w); - ut_asserteq(18, obj->bbox.h); + ut_asserteq(50 + 29, obj->bbox.x1); + ut_asserteq(454 + 18, obj->bbox.y1); /* check dimensions of menu */ obj = scene_obj_find(scn, OBJ_MENU, SCENEOBJT_NONE); ut_assertnonnull(obj); ut_asserteq(50, obj->bbox.x0); ut_asserteq(400, obj->bbox.y0); - ut_asserteq(160, obj->bbox.w); - ut_asserteq(160, obj->bbox.h); + ut_asserteq(50 + 160, obj->bbox.x1); + ut_asserteq(400 + 160, obj->bbox.y1); /* render it */ expo_set_scene_id(exp, SCENE1);