@@ -206,10 +206,26 @@ static INLINE char* dup_string_val(const _svg_list_builder_state* state, const p
206206 return ret;
207207}
208208
209- static INLINE void set_draw_attr (const _svg_list_builder_state* state, ps_draw_attrs* attrs, int32_t attr_id, const psx_svg_attr* val)
209+ static INLINE ps_draw_attrs* get_current_attrs (_svg_list_builder_state* state)
210+ {
211+ ps_draw_attrs* attrs = state->draw_attrs ;
212+ if (attrs->ref_count == 0 ) {
213+ return attrs;
214+ }
215+
216+ attrs = (ps_draw_attrs*)state->list ->alloc (sizeof (ps_draw_attrs));
217+ // copy attrs
218+ copy_draw_attrs (attrs, state->draw_attrs );
219+ attrs->ref_count = 0 ;
220+ state->draw_attrs = attrs;
221+ return attrs;
222+ }
223+
224+ static INLINE void set_draw_attr (_svg_list_builder_state* state, int32_t attr_id, const psx_svg_attr* val)
210225{
211226 switch (attr_id) {
212227 case SVG_ATTR_FILL : {
228+ ps_draw_attrs* attrs = get_current_attrs (state);
213229 if (val->class_type == SVG_ATTR_VALUE_NONE ) {
214230 attrs->flags &= ~RENDER_FILL ;
215231 return ;
@@ -232,6 +248,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
232248 break ;
233249 }
234250 case SVG_ATTR_FILL_RULE : {
251+ ps_draw_attrs* attrs = get_current_attrs (state);
235252 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
236253 attrs->flags &= ~RENDER_ATTR_FILL_RULE ;
237254 return ;
@@ -241,6 +258,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
241258 break ;
242259 }
243260 case SVG_ATTR_FILL_OPACITY : {
261+ ps_draw_attrs* attrs = get_current_attrs (state);
244262 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
245263 attrs->flags &= ~RENDER_ATTR_FILL_OPACITY ;
246264 return ;
@@ -250,6 +268,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
250268 break ;
251269 }
252270 case SVG_ATTR_STROKE : {
271+ ps_draw_attrs* attrs = get_current_attrs (state);
253272 if (val->class_type == SVG_ATTR_VALUE_NONE ) {
254273 attrs->flags &= ~RENDER_STROKE ;
255274 return ;
@@ -272,6 +291,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
272291 break ;
273292 }
274293 case SVG_ATTR_STROKE_OPACITY : {
294+ ps_draw_attrs* attrs = get_current_attrs (state);
275295 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
276296 attrs->flags &= ~RENDER_ATTR_STROKE_OPACITY ;
277297 return ;
@@ -281,6 +301,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
281301 break ;
282302 }
283303 case SVG_ATTR_STROKE_WIDTH : {
304+ ps_draw_attrs* attrs = get_current_attrs (state);
284305 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
285306 attrs->flags &= ~RENDER_ATTR_STROKE_WIDTH ;
286307 return ;
@@ -290,6 +311,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
290311 break ;
291312 }
292313 case SVG_ATTR_STROKE_LINECAP : {
314+ ps_draw_attrs* attrs = get_current_attrs (state);
293315 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
294316 attrs->flags &= ~RENDER_ATTR_STROKE_LINECAP ;
295317 return ;
@@ -299,6 +321,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
299321 break ;
300322 }
301323 case SVG_ATTR_STROKE_LINEJOIN : {
324+ ps_draw_attrs* attrs = get_current_attrs (state);
302325 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
303326 attrs->flags &= ~RENDER_ATTR_STROKE_LINEJOIN ;
304327 return ;
@@ -308,6 +331,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
308331 break ;
309332 }
310333 case SVG_ATTR_STROKE_MITER_LIMIT : {
334+ ps_draw_attrs* attrs = get_current_attrs (state);
311335 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
312336 attrs->flags &= ~RENDER_ATTR_STROKE_MITER_LIMIT ;
313337 return ;
@@ -317,6 +341,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
317341 break ;
318342 }
319343 case SVG_ATTR_STROKE_DASH_ARRAY : {
344+ ps_draw_attrs* attrs = get_current_attrs (state);
320345 if (val->class_type == SVG_ATTR_VALUE_NONE ) {
321346 attrs->stroke_dash_array = NULL ;
322347 attrs->stroke_dash_num = 0 ;
@@ -341,6 +366,7 @@ static INLINE void set_draw_attr(const _svg_list_builder_state* state, ps_draw_a
341366 break ;
342367 }
343368 case SVG_ATTR_STROKE_DASH_OFFSET : {
369+ ps_draw_attrs* attrs = get_current_attrs (state);
344370 if (val->class_type == SVG_ATTR_VALUE_INHERIT ) {
345371 attrs->flags &= ~RENDER_ATTR_STROKE_DASH_OFFSET ;
346372 return ;
@@ -360,21 +386,6 @@ static INLINE ps_draw_attrs* draw_attrs_create(svg_render_list_impl* list)
360386 return attrs;
361387}
362388
363- static INLINE ps_draw_attrs* get_current_attrs (_svg_list_builder_state* state)
364- {
365- ps_draw_attrs* attrs = state->draw_attrs ;
366- if (attrs->ref_count == 0 ) {
367- return attrs;
368- }
369-
370- attrs = (ps_draw_attrs*)state->list ->alloc (sizeof (ps_draw_attrs));
371- // copy attrs
372- copy_draw_attrs (attrs, state->draw_attrs );
373- attrs->ref_count = 0 ;
374- state->draw_attrs = attrs;
375- return attrs;
376- }
377-
378389enum {
379390 RENDER_NORMAL = 0 ,
380391 RENDER_IN_DEFS = 1 ,
@@ -468,15 +479,8 @@ class render_obj_base : public psx_svg_render_obj
468479 ps_reset_line_dash (ctx);
469480 }
470481 }
471- }
472- }
473482
474- void paint (ps_context* ctx) const
475- {
476- if (m_draw_attrs) {
477- ps_draw_attrs* attrs = m_draw_attrs;
478-
479- if (attrs->flags & RENDER_ATTR_REF_FILL ) {
483+ if (m_draw_attrs->flags & RENDER_ATTR_REF_FILL ) {
480484 render_obj_base* head = m_head;
481485 while (head) {
482486 if (head->id ()) {
@@ -489,7 +493,7 @@ class render_obj_base : public psx_svg_render_obj
489493 }
490494 }
491495
492- if (attrs ->flags & RENDER_ATTR_REF_STROKE ) {
496+ if (m_draw_attrs ->flags & RENDER_ATTR_REF_STROKE ) {
493497 render_obj_base* head = m_head;
494498 while (head) {
495499 if (head->id ()) {
@@ -501,6 +505,13 @@ class render_obj_base : public psx_svg_render_obj
501505 head = head->next ();
502506 }
503507 }
508+ }
509+ }
510+
511+ void paint (ps_context* ctx) const
512+ {
513+ if (m_draw_attrs) {
514+ ps_draw_attrs* attrs = m_draw_attrs;
504515
505516 if (m_global_matrix) {
506517 ps_transform (ctx, m_global_matrix);
@@ -577,8 +588,7 @@ void render_obj_base::set_attr(const psx_svg_attr* attr, _svg_list_builder_state
577588 }
578589 set_matrix ((psx_svg_matrix*)attr->value .val );
579590 } else {
580- ps_draw_attrs* draw_attrs = get_current_attrs (state);
581- set_draw_attr (state, draw_attrs, attr->attr_id , attr);
591+ set_draw_attr (state, attr->attr_id , attr);
582592 }
583593}
584594
@@ -713,8 +723,7 @@ class svg_render_viewport : public render_obj_base
713723 case SVG_ATTR_VIEWPORT_FILL : {
714724 if (attr->class_type == SVG_ATTR_VALUE_INITIAL
715725 && attr->val_type == SVG_ATTR_VALUE_DATA ) {
716- ps_draw_attrs* draw_attrs = get_current_attrs (state);
717- set_draw_attr (state, draw_attrs, SVG_ATTR_FILL , attr);
726+ set_draw_attr (state, SVG_ATTR_FILL , attr);
718727 m_fill = true ;
719728 } else if (attr->class_type == SVG_ATTR_VALUE_NONE ) {
720729 m_fill = false ;
@@ -723,8 +732,7 @@ class svg_render_viewport : public render_obj_base
723732 break ;
724733 case SVG_ATTR_VIEWPORT_FILL_OPACITY : {
725734 if (attr->class_type == SVG_ATTR_VALUE_INITIAL ) {
726- ps_draw_attrs* draw_attrs = get_current_attrs (state);
727- set_draw_attr (state, draw_attrs, SVG_ATTR_FILL_OPACITY , attr);
735+ set_draw_attr (state, SVG_ATTR_FILL_OPACITY , attr);
728736 }
729737 }
730738 break ;
@@ -1031,8 +1039,8 @@ class svg_render_polyline : public render_obj_base
10311039 if (matrix) {
10321040 ps_transform (ctx, matrix);
10331041 }
1034- ps_set_path (ctx, m_path);
10351042
1043+ ps_set_path (ctx, m_path);
10361044 paint (ctx);
10371045 }
10381046
@@ -1136,6 +1144,15 @@ class svg_render_use : public render_obj_base
11361144 }
11371145 }
11381146
1147+ void prepare (ps_context* ctx) const
1148+ {
1149+ render_obj_base::prepare (ctx);
1150+ get_xlink ();
1151+ if (m_linked) {
1152+ m_linked->prepare (ctx);
1153+ }
1154+ }
1155+
11391156 void render (ps_context* ctx, const ps_matrix* matrix)
11401157 {
11411158 ps_translate (ctx, m_x, m_y);
@@ -1147,9 +1164,6 @@ class svg_render_use : public render_obj_base
11471164 get_xlink ();
11481165
11491166 if (m_linked) {
1150- m_linked->prepare (ctx);
1151- prepare (ctx); // FIXME: use other !!!
1152- // FIXME: use with own gradient !!!!!!
11531167 m_linked->render (ctx, NULL );
11541168 }
11551169 }
@@ -1328,7 +1342,7 @@ class svg_render_content : public render_obj_base
13281342 {
13291343 }
13301344
1331- virtual void render_content (ps_context* ctx, ps_path* contents, ps_matrix* offset_matrix, float yoffset, bool rebuild_path)
1345+ virtual void build_content (ps_context* ctx, ps_path* contents, ps_matrix* offset_matrix, float yoffset, bool rebuild_path)
13321346 {
13331347 if (!rebuild_path) {
13341348 return ;
@@ -1403,13 +1417,8 @@ class svg_render_text : public render_obj_base
14031417 this ->svg_render_text ::~svg_render_text ();
14041418 }
14051419
1406- void render (ps_context* ctx, const ps_matrix* matrix)
1420+ void prepare (ps_context* ctx) const
14071421 {
1408- ps_transform (ctx, m_matrix);
1409- if (matrix) {
1410- ps_transform (ctx, matrix);
1411- }
1412-
14131422 ps_font* old_font = ps_set_font (ctx, m_font);
14141423 ps_font_info info;
14151424 ps_get_font_info (ctx, &info);
@@ -1425,14 +1434,28 @@ class svg_render_text : public render_obj_base
14251434 // draw text contents and spans
14261435 for (uint32_t i = 0 ; i < psx_array_size (&m_contents); i++) {
14271436 svg_render_content* content = *(psx_array_get (&m_contents, i, svg_render_content*));
1428- content->render_content (ctx, m_path, mtx, -info.ascent , build_path);
1437+ content->build_content (ctx, m_path, mtx, -info.ascent , build_path);
14291438 }
14301439 ps_matrix_unref (mtx);
14311440
14321441 ps_set_font (ctx, old_font);
1442+ render_obj_base::prepare (ctx);
1443+ }
14331444
1434- ps_set_path (ctx, m_path);
1445+ void render (ps_context* ctx, const ps_matrix* matrix)
1446+ {
1447+ ps_transform (ctx, m_matrix);
1448+ if (matrix) {
1449+ ps_transform (ctx, matrix);
1450+ }
1451+
1452+ // draw text contents and spans
1453+ for (uint32_t i = 0 ; i < psx_array_size (&m_contents); i++) {
1454+ svg_render_content* content = *(psx_array_get (&m_contents, i, svg_render_content*));
1455+ content->render (ctx, NULL );
1456+ }
14351457
1458+ ps_set_path (ctx, m_path);
14361459 paint (ctx);
14371460 }
14381461
@@ -1521,11 +1544,8 @@ class svg_render_tspan : public svg_render_content
15211544 this ->svg_render_tspan ::~svg_render_tspan ();
15221545 }
15231546
1524- virtual void render_content (ps_context* ctx, ps_path*, ps_matrix* offset_matrix, float , bool )
1547+ virtual void build_content (ps_context* ctx, ps_path*, ps_matrix* offset_matrix, float , bool )
15251548 {
1526- ps_save (ctx);
1527- prepare (ctx);
1528-
15291549 ps_font* old_font = ps_set_font (ctx, m_font);
15301550 ps_font_info info;
15311551 ps_get_font_info (ctx, &info);
@@ -1555,9 +1575,13 @@ class svg_render_tspan : public svg_render_content
15551575 }
15561576
15571577 ps_set_font (ctx, old_font);
1578+ }
15581579
1580+ void render (ps_context* ctx, const ps_matrix* matrix)
1581+ {
1582+ ps_save (ctx);
1583+ prepare (ctx);
15591584 ps_set_path (ctx, m_path);
1560-
15611585 paint (ctx);
15621586 ps_restore (ctx);
15631587 }
0 commit comments