1 /** 2 * @file lv_svg.h 3 * 4 */ 5 6 #ifndef LV_SVG_H 7 #define LV_SVG_H 8 9 /********************* 10 * INCLUDES 11 *********************/ 12 #include "../../lv_conf_internal.h" 13 #if LV_USE_SVG 14 15 #include "../../misc/lv_array.h" 16 #include "../../misc/lv_tree.h" 17 /********************* 18 * DEFINES 19 *********************/ 20 21 /********************** 22 * TYPEDEFS 23 **********************/ 24 enum { 25 LV_SVG_TAG_INVALID = -1, 26 LV_SVG_TAG_CONTENT, 27 LV_SVG_TAG_SVG, 28 LV_SVG_TAG_USE, 29 LV_SVG_TAG_G, 30 LV_SVG_TAG_PATH, 31 LV_SVG_TAG_RECT, 32 LV_SVG_TAG_CIRCLE, 33 LV_SVG_TAG_ELLIPSE, 34 LV_SVG_TAG_LINE, 35 LV_SVG_TAG_POLYLINE, 36 LV_SVG_TAG_POLYGON, 37 LV_SVG_TAG_SOLID_COLOR, 38 LV_SVG_TAG_LINEAR_GRADIENT, 39 LV_SVG_TAG_RADIAL_GRADIENT, 40 LV_SVG_TAG_STOP, 41 LV_SVG_TAG_DEFS, 42 LV_SVG_TAG_IMAGE, 43 #if LV_USE_SVG_ANIMATION 44 LV_SVG_TAG_MPATH, 45 LV_SVG_TAG_SET, 46 LV_SVG_TAG_ANIMATE, 47 LV_SVG_TAG_ANIMATE_COLOR, 48 LV_SVG_TAG_ANIMATE_TRANSFORM, 49 LV_SVG_TAG_ANIMATE_MOTION, 50 #endif 51 LV_SVG_TAG_TEXT, 52 LV_SVG_TAG_TSPAN, 53 LV_SVG_TAG_TEXT_AREA, 54 }; 55 typedef int8_t lv_svg_tag_t; 56 57 enum { 58 LV_SVG_ATTR_INVALID = 0, 59 LV_SVG_ATTR_ID, 60 LV_SVG_ATTR_XML_ID, 61 LV_SVG_ATTR_VERSION, 62 LV_SVG_ATTR_BASE_PROFILE, 63 LV_SVG_ATTR_VIEWBOX, 64 LV_SVG_ATTR_PRESERVE_ASPECT_RATIO, 65 LV_SVG_ATTR_VIEWPORT_FILL, 66 LV_SVG_ATTR_VIEWPORT_FILL_OPACITY, 67 LV_SVG_ATTR_DISPLAY, 68 LV_SVG_ATTR_VISIBILITY, 69 LV_SVG_ATTR_X, 70 LV_SVG_ATTR_Y, 71 LV_SVG_ATTR_WIDTH, 72 LV_SVG_ATTR_HEIGHT, 73 LV_SVG_ATTR_RX, 74 LV_SVG_ATTR_RY, 75 LV_SVG_ATTR_CX, 76 LV_SVG_ATTR_CY, 77 LV_SVG_ATTR_R, 78 LV_SVG_ATTR_X1, 79 LV_SVG_ATTR_Y1, 80 LV_SVG_ATTR_X2, 81 LV_SVG_ATTR_Y2, 82 LV_SVG_ATTR_POINTS, 83 LV_SVG_ATTR_D, 84 LV_SVG_ATTR_PATH_LENGTH, 85 LV_SVG_ATTR_XLINK_HREF, 86 LV_SVG_ATTR_FILL, 87 LV_SVG_ATTR_FILL_RULE, 88 LV_SVG_ATTR_FILL_OPACITY, 89 LV_SVG_ATTR_STROKE, 90 LV_SVG_ATTR_STROKE_WIDTH, 91 LV_SVG_ATTR_STROKE_LINECAP, 92 LV_SVG_ATTR_STROKE_LINEJOIN, 93 LV_SVG_ATTR_STROKE_MITER_LIMIT, 94 LV_SVG_ATTR_STROKE_DASH_ARRAY, 95 LV_SVG_ATTR_STROKE_DASH_OFFSET, 96 LV_SVG_ATTR_STROKE_OPACITY, 97 LV_SVG_ATTR_OPACITY, 98 LV_SVG_ATTR_SOLID_COLOR, 99 LV_SVG_ATTR_SOLID_OPACITY, 100 LV_SVG_ATTR_GRADIENT_UNITS, 101 LV_SVG_ATTR_GRADIENT_STOP_OFFSET, 102 LV_SVG_ATTR_GRADIENT_STOP_COLOR, 103 LV_SVG_ATTR_GRADIENT_STOP_OPACITY, 104 LV_SVG_ATTR_FONT_FAMILY, 105 LV_SVG_ATTR_FONT_STYLE, 106 LV_SVG_ATTR_FONT_VARIANT, 107 LV_SVG_ATTR_FONT_WEIGHT, 108 LV_SVG_ATTR_FONT_SIZE, 109 LV_SVG_ATTR_TRANSFORM, 110 LV_SVG_ATTR_TEXT_ANCHOR, 111 #if LV_USE_SVG_ANIMATION 112 LV_SVG_ATTR_ATTRIBUTE_NAME, 113 LV_SVG_ATTR_ATTRIBUTE_TYPE, 114 LV_SVG_ATTR_BEGIN, 115 LV_SVG_ATTR_END, 116 LV_SVG_ATTR_DUR, 117 LV_SVG_ATTR_MIN, 118 LV_SVG_ATTR_MAX, 119 LV_SVG_ATTR_RESTART, 120 LV_SVG_ATTR_REPEAT_COUNT, 121 LV_SVG_ATTR_REPEAT_DUR, 122 LV_SVG_ATTR_CALC_MODE, 123 LV_SVG_ATTR_VALUES, 124 LV_SVG_ATTR_KEY_TIMES, 125 LV_SVG_ATTR_KEY_SPLINES, 126 LV_SVG_ATTR_KEY_POINTS, 127 LV_SVG_ATTR_FROM, 128 LV_SVG_ATTR_TO, 129 LV_SVG_ATTR_BY, 130 LV_SVG_ATTR_ADDITIVE, 131 LV_SVG_ATTR_ACCUMULATE, 132 LV_SVG_ATTR_PATH, 133 LV_SVG_ATTR_ROTATE, 134 LV_SVG_ATTR_TRANSFORM_TYPE, 135 #endif 136 }; 137 typedef uint8_t lv_svg_attr_type_t; 138 139 enum { 140 LV_SVG_TRANSFORM_TYPE_MATRIX = 1, 141 LV_SVG_TRANSFORM_TYPE_TRANSLATE, 142 LV_SVG_TRANSFORM_TYPE_ROTATE, 143 LV_SVG_TRANSFORM_TYPE_SCALE, 144 LV_SVG_TRANSFORM_TYPE_SKEW_X, 145 LV_SVG_TRANSFORM_TYPE_SKEW_Y, 146 }; 147 typedef uint8_t lv_svg_transform_type_t; 148 149 #if LV_USE_SVG_ANIMATION 150 enum { 151 LV_SVG_ANIM_REMOVE = 0, 152 LV_SVG_ANIM_FREEZE, 153 }; 154 155 enum { 156 LV_SVG_ANIM_RESTART_ALWAYS = 0, 157 LV_SVG_ANIM_RESTART_WHEN_NOT_ACTIVE, 158 LV_SVG_ANIM_RESTART_NEVER, 159 }; 160 161 enum { 162 LV_SVG_ANIM_CALC_MODE_LINEAR = 0, 163 LV_SVG_ANIM_CALC_MODE_PACED, 164 LV_SVG_ANIM_CALC_MODE_SPLINE, 165 LV_SVG_ANIM_CALC_MODE_DISCRETE, 166 }; 167 168 enum { 169 LV_SVG_ANIM_ADDITIVE_REPLACE = 0, 170 LV_SVG_ANIM_ADDITIVE_SUM, 171 }; 172 173 enum { 174 LV_SVG_ANIM_ACCUMULATE_NONE = 0, 175 LV_SVG_ANIM_ACCUMULATE_SUM, 176 }; 177 #endif 178 179 enum { 180 LV_SVG_ASPECT_RATIO_NONE = 0, 181 LV_SVG_ASPECT_RATIO_XMIN_YMIN = (1 << 1), 182 LV_SVG_ASPECT_RATIO_XMID_YMIN = (2 << 1), 183 LV_SVG_ASPECT_RATIO_XMAX_YMIN = (3 << 1), 184 LV_SVG_ASPECT_RATIO_XMIN_YMID = (4 << 1), 185 LV_SVG_ASPECT_RATIO_XMID_YMID = (5 << 1), 186 LV_SVG_ASPECT_RATIO_XMAX_YMID = (6 << 1), 187 LV_SVG_ASPECT_RATIO_XMIN_YMAX = (7 << 1), 188 LV_SVG_ASPECT_RATIO_XMID_YMAX = (8 << 1), 189 LV_SVG_ASPECT_RATIO_XMAX_YMAX = (9 << 1), 190 }; 191 192 enum { 193 LV_SVG_ASPECT_RATIO_OPT_MEET = 0, 194 LV_SVG_ASPECT_RATIO_OPT_SLICE, 195 }; 196 typedef uint32_t lv_svg_aspect_ratio_t; 197 198 typedef struct { 199 float x; 200 float y; 201 } lv_svg_point_t; 202 203 typedef struct { 204 float m[3][3]; 205 } lv_svg_matrix_t; 206 207 typedef uint32_t lv_svg_color_t; 208 209 enum { 210 LV_SVG_FILL_NONZERO = 0, 211 LV_SVG_FILL_EVENODD, 212 }; 213 typedef uint8_t lv_svg_fill_rule_t; 214 215 enum { 216 LV_SVG_LINE_CAP_BUTT = 0, 217 LV_SVG_LINE_CAP_SQUARE, 218 LV_SVG_LINE_CAP_ROUND, 219 }; 220 typedef uint8_t lv_svg_line_cap_t; 221 222 enum { 223 LV_SVG_LINE_JOIN_MITER = 0, 224 LV_SVG_LINE_JOIN_BEVEL, 225 LV_SVG_LINE_JOIN_ROUND, 226 }; 227 typedef uint8_t lv_svg_line_join_t; 228 229 enum { 230 LV_SVG_GRADIENT_UNITS_OBJECT = 0, 231 LV_SVG_GRADIENT_UNITS_USER_SPACE, 232 }; 233 typedef uint8_t lv_svg_gradient_units_t; 234 235 typedef union { 236 int32_t ival; 237 uint32_t uval; 238 float fval; 239 char * sval; 240 void * val; 241 } lv_svg_attr_value_t; 242 243 /* 244 * to simplify list buffer management, allocate enough memory for all data and length. 245 * | size | data[0] | data[1] | data[2] | ... | 246 */ 247 typedef struct { 248 uint32_t length; 249 uint8_t data[1]; 250 } lv_svg_attr_values_list_t; 251 252 /* https://www.w3.org/TR/SVGTiny12/svgudomidl.html */ 253 enum { 254 LV_SVG_PATH_CMD_MOVE_TO = 77, 255 LV_SVG_PATH_CMD_LINE_TO = 76, 256 LV_SVG_PATH_CMD_CURVE_TO = 67, 257 LV_SVG_PATH_CMD_QUAD_TO = 81, 258 LV_SVG_PATH_CMD_CLOSE = 90, 259 }; 260 261 /* 262 * to simplify list buffer management, allocate enough memory for all path data and cmd. 263 * | cmd | data[0] | data[1] | data[2] | ... | 264 */ 265 typedef struct { 266 uint32_t cmd; 267 uint8_t data[1]; 268 } lv_svg_attr_path_value_t; 269 270 enum { 271 LV_SVG_ATTR_VALUE_DATA = 0, 272 LV_SVG_ATTR_VALUE_PTR, 273 }; 274 typedef uint8_t lv_svg_attr_value_type_t; 275 276 enum { 277 LV_SVG_ATTR_VALUE_NONE = 0, 278 LV_SVG_ATTR_VALUE_INITIAL, 279 LV_SVG_ATTR_VALUE_INHERIT, 280 }; 281 typedef uint8_t lv_svg_attr_value_class_t; 282 283 typedef struct { 284 lv_svg_attr_type_t id; 285 lv_svg_attr_value_type_t val_type; 286 lv_svg_attr_value_class_t class_type; 287 lv_svg_attr_value_t value; 288 } lv_svg_attr_t; 289 290 struct _lv_svg_render_obj; 291 292 typedef struct { 293 lv_tree_node_t base; 294 char * xml_id; /* xml_id or content */ 295 lv_svg_tag_t type; 296 lv_array_t attrs; 297 struct _lv_svg_render_obj * render_obj; 298 } lv_svg_node_t; 299 300 /********************** 301 * GLOBAL PROTOTYPES 302 **********************/ 303 304 /** 305 * @brief Loading SVG data and creating the DOM tree 306 * @param svg_data pointer to the SVG data 307 * @param data_len the SVG data length 308 */ 309 lv_svg_node_t * lv_svg_load_data(const char * svg_data, uint32_t data_len); 310 311 /** 312 * @brief Create an SVG DOM node 313 * @param parent pointer to the parent node 314 * @return true: an new SVG DOM node, false: NULL 315 */ 316 lv_svg_node_t * lv_svg_node_create(lv_svg_node_t * parent); 317 318 /** 319 * @brief Delete an SVG DOM subtree 320 * @param node pointer to an SVG DOM subtree 321 */ 322 void lv_svg_node_delete(lv_svg_node_t * node); 323 324 /********************** 325 * MACROS 326 **********************/ 327 #define LV_SVG_NODE_CHILD(n, i) \ 328 ((lv_svg_node_t *)(LV_TREE_NODE((n))->children[i])) 329 330 #define LV_SVG_NODE(n) ((lv_svg_node_t*)(n)) 331 332 #endif /*LV_USE_SVG*/ 333 334 #endif /*LV_SVG_H*/ 335