24
24
* TYPEDEFS
25
25
**********************/
26
26
27
+
28
+ /**
29
+ * Since the key-value data structure of lv_cache is integrated, the kv data structure
30
+ * will be saved at the same time when the cache is successfully created.
31
+ * In order to pursue efficiency during the matching process, the primary key (lv) used for matching
32
+ * will not dup the dash_pattern secondary pointer, so when the creation is successful, dash_pattern needs
33
+ * to be dup to the child key (vg), so type is added here to distinguish where the real data of dash_pattern exists.
34
+ */
35
+ typedef enum {
36
+ DASH_PATTERN_TYPE_LV ,
37
+ DASH_PATTERN_TYPE_VG
38
+ } dash_pattern_type_t ;
39
+
27
40
typedef struct {
28
- /* stroke path */
29
- lv_vg_lite_path_t * path ;
30
-
31
- /* stroke parameters */
32
- float width ;
33
- lv_vector_stroke_cap_t cap ;
34
- lv_vector_stroke_join_t join ;
35
- uint16_t miter_limit ;
36
- lv_array_t dash_pattern ;
41
+ dash_pattern_type_t dash_pattern_type ;
42
+
43
+ struct {
44
+ /* path data */
45
+ lv_vg_lite_path_t * path ;
46
+
47
+ /* stroke parameters */
48
+ float width ;
49
+ lv_vector_stroke_cap_t cap ;
50
+ lv_vector_stroke_join_t join ;
51
+ uint16_t miter_limit ;
52
+ lv_array_t dash_pattern ;
53
+ } lv ;
54
+
55
+ struct {
56
+ /* stroke path */
57
+ lv_vg_lite_path_t * path ;
58
+
59
+ /* dash pattern, for comparison only */
60
+ lv_array_t dash_pattern ;
61
+ } vg ;
37
62
} stroke_item_t ;
38
63
39
64
/**********************
@@ -124,21 +149,21 @@ lv_cache_entry_t * lv_vg_lite_stroke_get(struct _lv_draw_vg_lite_unit_t * unit,
124
149
/* prepare search key */
125
150
stroke_item_t search_key ;
126
151
lv_memzero (& search_key , sizeof (search_key ));
127
- search_key .cap = dsc -> cap ;
128
- search_key .join = dsc -> join ;
129
- search_key .width = dsc -> width ;
130
- search_key .miter_limit = dsc -> miter_limit ;
152
+ search_key .lv . cap = dsc -> cap ;
153
+ search_key .lv . join = dsc -> join ;
154
+ search_key .lv . width = dsc -> width ;
155
+ search_key .lv . miter_limit = dsc -> miter_limit ;
131
156
132
157
/* A one-time read-only array that only copies the pointer but not the content */
133
- search_key .dash_pattern = dsc -> dash_pattern ;
134
- search_key .path = path ;
158
+ search_key .lv . dash_pattern = dsc -> dash_pattern ;
159
+ search_key .lv . path = path ;
135
160
136
- lv_cache_entry_t * cache_node_entry = lv_cache_acquire (unit -> stroke_cache , & search_key , & search_key );
161
+ lv_cache_entry_t * cache_node_entry = lv_cache_acquire (unit -> stroke_cache , & search_key , NULL );
137
162
if (cache_node_entry ) {
138
163
return cache_node_entry ;
139
164
}
140
165
141
- cache_node_entry = lv_cache_acquire_or_create (unit -> stroke_cache , & search_key , & search_key );
166
+ cache_node_entry = lv_cache_acquire_or_create (unit -> stroke_cache , & search_key , NULL );
142
167
if (cache_node_entry == NULL ) {
143
168
LV_LOG_ERROR ("stroke cache creating failed" );
144
169
return NULL ;
@@ -153,7 +178,13 @@ struct _lv_vg_lite_path_t * lv_vg_lite_stroke_get_path(lv_cache_entry_t * cache_
153
178
154
179
stroke_item_t * stroke_item = lv_cache_entry_get_data (cache_entry );
155
180
LV_ASSERT_NULL (stroke_item );
156
- return stroke_item -> path ;
181
+
182
+ if (lv_array_size (& stroke_item -> vg .dash_pattern )) {
183
+ /* check if dash pattern must be duped */
184
+ LV_ASSERT (stroke_item -> dash_pattern_type == DASH_PATTERN_TYPE_VG );
185
+ }
186
+
187
+ return stroke_item -> vg .path ;
157
188
}
158
189
159
190
void lv_vg_lite_stroke_drop (struct _lv_draw_vg_lite_unit_t * unit ,
@@ -170,43 +201,49 @@ void lv_vg_lite_stroke_drop(struct _lv_draw_vg_lite_unit_t * unit,
170
201
171
202
static bool stroke_create_cb (stroke_item_t * item , void * user_data )
172
203
{
204
+ LV_UNUSED (user_data );
173
205
LV_ASSERT_NULL (item );
174
206
175
- stroke_item_t * src = user_data ;
176
- LV_ASSERT_NULL (src );
177
-
178
- lv_memzero (item , sizeof (stroke_item_t ));
207
+ /* Check if stroke width is valid */
208
+ if (item -> lv .width <= 0 ) {
209
+ LV_LOG_WARN ("stroke width error: %f" , item -> lv .width );
210
+ return false;
211
+ }
179
212
180
- /* copy path */
181
- item -> path = lv_vg_lite_path_create (VG_LITE_FP32 );
182
- lv_vg_lite_path_append_path (item -> path , src -> path );
213
+ /* Reset the dash pattern type */
214
+ item -> dash_pattern_type = DASH_PATTERN_TYPE_LV ;
183
215
184
- /* copy parameters */
185
- item -> cap = src -> cap ;
186
- item -> join = src -> join ;
187
- item -> width = src -> width ;
188
- item -> miter_limit = src -> miter_limit ;
216
+ /* dup the path */
217
+ item -> vg .path = lv_vg_lite_path_create (VG_LITE_FP32 );
218
+ lv_vg_lite_path_append_path (item -> vg .path , item -> lv .path );
189
219
190
- /* copy dash pattern */
191
- uint32_t size = lv_array_size (& src -> dash_pattern );
220
+ /* dup the dash pattern */
221
+ vg_lite_float_t * vg_dash_pattern = NULL ;
222
+ const uint32_t size = lv_array_size (& item -> lv .dash_pattern );
192
223
if (size ) {
193
- lv_array_init (& item -> dash_pattern , size , sizeof (float ));
194
- lv_array_copy (& item -> dash_pattern , & src -> dash_pattern );
224
+ /* Only support float dash pattern */
225
+ LV_ASSERT (item -> lv .dash_pattern .element_size == sizeof (float ));
226
+ lv_array_init (& item -> vg .dash_pattern , size , sizeof (float ));
227
+ lv_array_copy (& item -> vg .dash_pattern , & item -> lv .dash_pattern );
228
+
229
+ /* mark dash pattern has been duped */
230
+ item -> dash_pattern_type = DASH_PATTERN_TYPE_VG ;
231
+ vg_dash_pattern = lv_array_front (& item -> vg .dash_pattern );
195
232
}
196
233
197
234
/* update parameters */
198
- vg_lite_path_t * vg_path = lv_vg_lite_path_get_path (item -> path );
235
+ vg_lite_path_t * vg_path = lv_vg_lite_path_get_path (item -> vg . path );
199
236
LV_VG_LITE_CHECK_ERROR (vg_lite_set_path_type (vg_path , VG_LITE_DRAW_STROKE_PATH ));
200
237
201
238
vg_lite_error_t error = vg_lite_set_stroke (
202
239
vg_path ,
203
- lv_stroke_cap_to_vg (item -> cap ),
204
- lv_stroke_join_to_vg (item -> join ),
205
- item -> width ,
206
- item -> miter_limit ,
207
- lv_array_front ( & item -> dash_pattern ) ,
240
+ lv_stroke_cap_to_vg (item -> lv . cap ),
241
+ lv_stroke_join_to_vg (item -> lv . join ),
242
+ item -> lv . width ,
243
+ item -> lv . miter_limit ,
244
+ vg_dash_pattern ,
208
245
size ,
209
- item -> width / 2 ,
246
+ item -> lv . width / 2 ,
210
247
0 );
211
248
212
249
if (error != VG_LITE_SUCCESS ) {
@@ -242,68 +279,104 @@ static void stroke_free_cb(stroke_item_t * item, void * user_data)
242
279
LV_UNUSED (user_data );
243
280
LV_ASSERT_NULL (item );
244
281
245
- lv_array_deinit (& item -> dash_pattern );
246
- lv_vg_lite_path_destroy (item -> path );
247
- lv_memzero (item , sizeof (stroke_item_t ));
282
+ if (item -> vg .path ) {
283
+ lv_vg_lite_path_destroy (item -> vg .path );
284
+ item -> vg .path = NULL ;
285
+ }
286
+
287
+ if (item -> dash_pattern_type == DASH_PATTERN_TYPE_VG ) {
288
+ lv_array_deinit (& item -> vg .dash_pattern );
289
+ item -> dash_pattern_type = DASH_PATTERN_TYPE_LV ;
290
+ }
248
291
}
249
292
250
- static lv_cache_compare_res_t path_compare (const vg_lite_path_t * lhs , const vg_lite_path_t * rhs )
293
+ static lv_cache_compare_res_t dash_pattern_compare (const stroke_item_t * lhs , const stroke_item_t * rhs )
251
294
{
252
- LV_ASSERT (lhs -> format == VG_LITE_FP32 );
253
- LV_ASSERT (rhs -> format == VG_LITE_FP32 );
295
+ /* Select the dash pattern to compare */
296
+ const lv_array_t * lhs_dash_pattern = lhs -> dash_pattern_type == DASH_PATTERN_TYPE_LV ?
297
+ & lhs -> lv .dash_pattern :
298
+ & lhs -> vg .dash_pattern ;
299
+ const lv_array_t * rhs_dash_pattern = rhs -> dash_pattern_type == DASH_PATTERN_TYPE_LV ?
300
+ & rhs -> lv .dash_pattern :
301
+ & rhs -> vg .dash_pattern ;
302
+
303
+ const uint32_t lhs_dash_pattern_size = lv_array_size (lhs_dash_pattern );
304
+ const uint32_t rhs_dash_pattern_size = lv_array_size (rhs_dash_pattern );
305
+
306
+ if (lhs_dash_pattern_size != rhs_dash_pattern_size ) {
307
+ return lhs_dash_pattern_size > rhs_dash_pattern_size ? 1 : -1 ;
308
+ }
254
309
255
- if (lhs -> path_length != rhs -> path_length ) {
256
- return lhs -> path_length > rhs -> path_length ? 1 : -1 ;
310
+ if (lhs_dash_pattern_size == 0 && rhs_dash_pattern_size == 0 ) {
311
+ return 0 ;
257
312
}
258
313
259
- int cmp_res = lv_memcmp (lhs -> path , rhs -> path , lhs -> path_length );
314
+ /* Both dash pattern has the same size, compare them */
315
+ LV_ASSERT (lhs_dash_pattern -> element_size == sizeof (float ));
316
+ LV_ASSERT (rhs_dash_pattern -> element_size == sizeof (float ));
317
+
318
+ /* compare dash pattern data */
319
+ int cmp_res = lv_memcmp (
320
+ lv_array_front (lhs_dash_pattern ),
321
+ lv_array_front (rhs_dash_pattern ),
322
+ lhs_dash_pattern_size * sizeof (float ));
323
+
260
324
if (cmp_res != 0 ) {
261
325
return cmp_res > 0 ? 1 : -1 ;
262
326
}
263
327
264
328
return 0 ;
265
329
}
266
330
267
- static lv_cache_compare_res_t stroke_compare_cb (const stroke_item_t * lhs , const stroke_item_t * rhs )
331
+ static lv_cache_compare_res_t path_compare (const stroke_item_t * lhs , const stroke_item_t * rhs )
268
332
{
269
- if (lhs -> width != lhs -> width ) {
270
- return lhs -> width > lhs -> width ? 1 : -1 ;
333
+ /* Give priority to using dup vg.path */
334
+ const vg_lite_path_t * lhs_path = lhs -> vg .path ?
335
+ lv_vg_lite_path_get_path (lhs -> vg .path ) :
336
+ lv_vg_lite_path_get_path (lhs -> lv .path );
337
+ const vg_lite_path_t * rhs_path = rhs -> vg .path ?
338
+ lv_vg_lite_path_get_path (rhs -> vg .path ) :
339
+ lv_vg_lite_path_get_path (rhs -> lv .path );
340
+
341
+ LV_ASSERT (lhs_path -> format == VG_LITE_FP32 );
342
+ LV_ASSERT (rhs_path -> format == VG_LITE_FP32 );
343
+
344
+ if (lhs_path -> path_length != rhs_path -> path_length ) {
345
+ return lhs_path -> path_length > rhs_path -> path_length ? 1 : -1 ;
271
346
}
272
347
273
- if (lhs -> cap != rhs -> cap ) {
274
- return lhs -> cap > rhs -> cap ? 1 : -1 ;
348
+ int cmp_res = lv_memcmp (lhs_path -> path , rhs_path -> path , lhs_path -> path_length );
349
+ if (cmp_res != 0 ) {
350
+ return cmp_res > 0 ? 1 : -1 ;
275
351
}
276
352
277
- if (lhs -> join != rhs -> join ) {
278
- return lhs -> join > rhs -> join ? 1 : -1 ;
279
- }
353
+ return 0 ;
354
+ }
280
355
281
- if (lhs -> miter_limit != rhs -> miter_limit ) {
282
- return lhs -> miter_limit > rhs -> miter_limit ? 1 : -1 ;
356
+ static lv_cache_compare_res_t stroke_compare_cb (const stroke_item_t * lhs , const stroke_item_t * rhs )
357
+ {
358
+ if (lhs -> lv .width != rhs -> lv .width ) {
359
+ return lhs -> lv .width > rhs -> lv .width ? 1 : -1 ;
283
360
}
284
361
285
- uint32_t lhs_dash_pattern_size = lv_array_size (& lhs -> dash_pattern );
286
- uint32_t rhs_dash_pattern_size = lv_array_size (& rhs -> dash_pattern );
287
-
288
- if (lhs_dash_pattern_size != rhs_dash_pattern_size ) {
289
- return lhs_dash_pattern_size > rhs_dash_pattern_size ? 1 : -1 ;
362
+ if (lhs -> lv .cap != rhs -> lv .cap ) {
363
+ return lhs -> lv .cap > rhs -> lv .cap ? 1 : -1 ;
290
364
}
291
365
292
- if (lhs_dash_pattern_size > 0 && rhs_dash_pattern_size > 0 ) {
293
- LV_ASSERT ( lhs -> dash_pattern . element_size == sizeof ( float )) ;
294
- LV_ASSERT ( rhs -> dash_pattern . element_size == sizeof ( float ));
366
+ if (lhs -> lv . join != rhs -> lv . join ) {
367
+ return lhs -> lv . join > rhs -> lv . join ? 1 : -1 ;
368
+ }
295
369
296
- const float * lhs_dash_pattern = lv_array_front (& lhs -> dash_pattern );
297
- const float * rhs_dash_pattern = lv_array_front (& rhs -> dash_pattern );
370
+ if (lhs -> lv .miter_limit != rhs -> lv .miter_limit ) {
371
+ return lhs -> lv .miter_limit > rhs -> lv .miter_limit ? 1 : -1 ;
372
+ }
298
373
299
- /* compare dash pattern */
300
- int cmp_res = lv_memcmp (lhs_dash_pattern , rhs_dash_pattern , lhs_dash_pattern_size * sizeof (float ));
301
- if (cmp_res != 0 ) {
302
- return cmp_res > 0 ? 1 : -1 ;
303
- }
374
+ lv_cache_compare_res_t dash_pattern_res = dash_pattern_compare (lhs , rhs );
375
+ if (dash_pattern_res != 0 ) {
376
+ return dash_pattern_res ;
304
377
}
305
378
306
- return path_compare (lv_vg_lite_path_get_path ( lhs -> path ), lv_vg_lite_path_get_path ( rhs -> path ) );
379
+ return path_compare (lhs , rhs );
307
380
}
308
381
309
382
#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/
0 commit comments