LCOV - code coverage report
Current view: top level - pencil/source/draw - draw_stereotype_icon.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.67.0_covts Lines: 34.7 % 193 67
Test Date: 2025-11-06 17:22:08 Functions: 50.0 % 2 1

            Line data    Source code
       1              : /* File: draw_stereotype_icon.c; Copyright and License: see below */
       2              : 
       3              : #include "draw_svg_path_data.h"
       4              : #include "draw/draw_stereotype_icon.h"
       5              : #include "layout/layout_visible_set.h"
       6              : #include "u8/u8_trace.h"
       7              : #include "utf8stringbuf/utf8stringbuf.h"
       8              : #include <stdio.h>
       9              : #include <stdlib.h>
      10              : #include <assert.h>
      11              : 
      12              : const double DRAW_STEREOTYPE_ICON_WIDTH_TO_HEIGHT = 1.0;
      13              : 
      14            0 : u8_error_t draw_stereotype_icon_draw ( const draw_stereotype_icon_t *this_,
      15              :                                         const char *stereotype,
      16              :                                         const data_profile_part_t *profile,
      17              :                                         const GdkRGBA *default_color,
      18              :                                         u8_error_info_t *out_err_info,
      19              :                                         const geometry_rectangle_t *bounds,
      20              :                                         cairo_t *cr )
      21              : {
      22            0 :     U8_TRACE_BEGIN();
      23            0 :     assert( NULL != stereotype );
      24            0 :     assert( NULL != profile );
      25            0 :     assert( NULL != out_err_info );
      26            0 :     assert( NULL != bounds );
      27            0 :     assert( NULL != cr );
      28            0 :     u8_error_t result = U8_ERROR_NONE;
      29            0 :     u8_error_info_init_void( out_err_info );
      30              : 
      31            0 :     const utf8stringview_t stereotype_view = UTF8STRINGVIEW_STR(stereotype);
      32              :     const data_classifier_t *const optional_stereotype
      33            0 :         = data_profile_part_get_stereotype_by_name_const( profile, &stereotype_view );
      34            0 :     if ( optional_stereotype != NULL )
      35              :     {
      36            0 :         U8_TRACE_INFO_STR( "stereotype", stereotype );
      37            0 :         const char *const drawing_directives = data_classifier_get_description_const( optional_stereotype );
      38              :         geometry_rectangle_t io_view_rect;
      39            0 :         geometry_rectangle_init_empty( &io_view_rect );
      40            0 :         result |= draw_stereotype_icon_private_parse_svg_xml( this_,
      41              :                                                                false,  /* draw */
      42              :                                                                drawing_directives,
      43              :                                                                &io_view_rect,
      44              :                                                                default_color,
      45              :                                                                out_err_info,
      46              :                                                                bounds,
      47              :                                                                cr
      48              :                                                              );
      49            0 :         if ( result == U8_ERROR_NONE )
      50              :         {
      51              :             /* make view rect quadratic */
      52            0 :             const double view_width = geometry_rectangle_get_width( &io_view_rect );
      53            0 :             const double view_height = geometry_rectangle_get_height( &io_view_rect );
      54            0 :             if ( view_width > view_height)
      55              :             {
      56            0 :                 geometry_rectangle_set_top( &io_view_rect, geometry_rectangle_get_top( &io_view_rect ) - 0.5*(view_width-view_height) );
      57            0 :                 geometry_rectangle_set_height( &io_view_rect, view_width );
      58              :             }
      59              :             else
      60              :             {
      61            0 :                 geometry_rectangle_set_left( &io_view_rect, geometry_rectangle_get_left( &io_view_rect ) - 0.5*(view_height-view_width) );
      62            0 :                 geometry_rectangle_set_width( &io_view_rect, view_height );
      63              :             }
      64            0 :             result |= draw_stereotype_icon_private_parse_svg_xml( this_,
      65              :                                                                    true,  /* draw */
      66              :                                                                    drawing_directives,
      67              :                                                                    &io_view_rect,
      68              :                                                                    default_color,
      69              :                                                                    out_err_info,
      70              :                                                                    bounds,
      71              :                                                                    cr
      72              :                                                                  );
      73              :         }
      74              : 
      75            0 :         geometry_rectangle_destroy( &io_view_rect );
      76              :     }
      77              :     else
      78              :     {
      79            0 :         result = U8_ERROR_NOT_FOUND;
      80              :     }
      81              : 
      82            0 :     U8_TRACE_END_ERR(result);
      83            0 :     return result;
      84              : }
      85              : 
      86              : /*! \brief states of parsing svg, the xml parts */
      87              : enum draw_stereotype_icon_xml_enum {
      88              :     DRAW_STEREOTYPE_ICON_XML_OUTSIDE_PATH,  /*!< nothing passed yet */
      89              :     DRAW_STEREOTYPE_ICON_XML_TAG_STARTED,  /*!< XML tag start passed */
      90              :     DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG,  /*!< XML token path passed */
      91              :     DRAW_STEREOTYPE_ICON_XML_D_ATTR,  /*!< XML attribute d: name passed */
      92              :     DRAW_STEREOTYPE_ICON_XML_D_DEF,  /*!< XML attribute d: assignment passed */
      93              :     DRAW_STEREOTYPE_ICON_XML_FILL_ATTR,  /*!< XML attribute fill: name passed, see svg spec 13.2. Specifying paint */
      94              :     DRAW_STEREOTYPE_ICON_XML_FILL_DEF,  /*!< XML attribute fill: assignment passed */
      95              :     DRAW_STEREOTYPE_ICON_XML_FILL_VALUE,  /*!< XML attribute fill: single or double quotes passed */
      96              :     DRAW_STEREOTYPE_ICON_XML_STROKE_ATTR,  /*!< XML attribute stroke: name passed, see svg spec 13.2. Specifying paint */
      97              :     DRAW_STEREOTYPE_ICON_XML_STROKE_DEF,  /*!< XML attribute stroke: assignment passed */
      98              :     DRAW_STEREOTYPE_ICON_XML_STROKE_VALUE,  /*!< XML attribute stroke: single or double quotes passed */
      99              :     DRAW_STEREOTYPE_ICON_XML_INSIDE_SGLQ_VALUE,  /*!< single-quoted XML attribute-value of any other attribute-name */
     100              :     DRAW_STEREOTYPE_ICON_XML_INSIDE_DBLQ_VALUE,  /*!< double-quoted XML attribute-value of any other attribute-name */
     101              : };
     102              : 
     103           29 : u8_error_t draw_stereotype_icon_private_parse_svg_xml ( const draw_stereotype_icon_t *this_,
     104              :                                                          bool draw,
     105              :                                                          const char *drawing_directives,
     106              :                                                          geometry_rectangle_t *io_view_rect,
     107              :                                                          const GdkRGBA *default_color,
     108              :                                                          u8_error_info_t *out_err_info,
     109              :                                                          const geometry_rectangle_t *target_bounds,
     110              :                                                          cairo_t *cr )
     111              : {
     112           29 :     U8_TRACE_BEGIN();
     113           29 :     assert( NULL != drawing_directives );
     114           29 :     assert( NULL != io_view_rect );
     115           29 :     assert( NULL != out_err_info );
     116           29 :     assert( NULL != target_bounds );
     117           29 :     assert( ( ! draw ) || ( NULL != cr ) );
     118           29 :     u8_error_t result = U8_ERROR_NONE;
     119              : 
     120              :     /* states while parsing: */
     121           29 :     enum draw_stereotype_icon_xml_enum parser_state = DRAW_STEREOTYPE_ICON_XML_OUTSIDE_PATH;
     122           29 :     uint_fast16_t path_count = 0;
     123           29 :     GdkRGBA stroke_color = *default_color;
     124           29 :     GdkRGBA fill_color = { .red = 1.0, .green = 1.0, .blue = 1.0, .alpha = 0.0 };
     125              :     char xml_attr_value_buf[64]; /* max 4 floating point numbers and rgba(%,%,%,%) string around */
     126           29 :     utf8stringbuf_t xml_attr_value = UTF8STRINGBUF(xml_attr_value_buf);
     127              : 
     128           29 :     const utf8stringview_t drawing_directives_view = UTF8STRINGVIEW_STR( drawing_directives );
     129              :     utf8stringviewtokenizer_t tok_iterator;
     130           29 :     utf8stringviewtokenizer_init( &tok_iterator, &drawing_directives_view, UTF8STRINGVIEWTOKENMODE_TEXT );
     131          214 :     while( utf8stringviewtokenizer_has_next( &tok_iterator ) && ( result == U8_ERROR_NONE ) )
     132              :     {
     133          185 :         const utf8stringview_t tok = utf8stringviewtokenizer_next( &tok_iterator );
     134          185 :         assert( utf8stringview_get_length( &tok ) > 0 );  /* otherwise this would not be a token */
     135              :         /* U8_TRACE_INFO_VIEW( "token:", tok ); */
     136              : 
     137          185 :         switch ( parser_state )
     138              :         {
     139           31 :             case DRAW_STEREOTYPE_ICON_XML_OUTSIDE_PATH:
     140              :             {
     141           31 :                 if ( utf8stringview_equals_str( &tok, "<" ) )
     142              :                 {
     143           28 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_TAG_STARTED;
     144              :                 }
     145              :             }
     146           31 :             break;
     147              : 
     148           28 :             case DRAW_STEREOTYPE_ICON_XML_TAG_STARTED:
     149              :             {
     150           28 :                 if ( utf8stringview_equals_str( &tok, "path" ) )
     151              :                 {
     152              :                     /* for each new path, reset the colors to defaults */
     153           28 :                     stroke_color = *default_color;
     154           28 :                     fill_color = (GdkRGBA) { .red = 1.0, .green = 1.0, .blue = 1.0, .alpha = 0.0 };
     155           28 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     156              :                 }
     157              :                 else
     158              :                 {
     159              :                     /* no error, accept anythig here: */
     160              :                     /* not a path tag, back to ouside state */
     161              :                     /* TODO accept a namespace for the path maybe? */
     162            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_OUTSIDE_PATH;
     163              :                 }
     164              :             }
     165           28 :             break;
     166              : 
     167           70 :             case DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG:
     168              :             {
     169           70 :                 if ( utf8stringview_equals_str( &tok, "d" ) )
     170              :                 {
     171           28 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_D_ATTR;
     172              :                 }
     173           42 :                 else if ( utf8stringview_equals_str( &tok, "stroke" ) )
     174              :                 {
     175            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_STROKE_ATTR;
     176              :                 }
     177           42 :                 else if ( utf8stringview_equals_str( &tok, "fill" ) )
     178              :                 {
     179            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_FILL_ATTR;
     180              :                 }
     181           42 :                 else if ( utf8stringview_equals_str( &tok, "\'" ) )
     182              :                 {
     183            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_SGLQ_VALUE;
     184              :                 }
     185           42 :                 else if ( utf8stringview_equals_str( &tok, "\"" ) )
     186              :                 {
     187            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_DBLQ_VALUE;
     188              :                 }
     189           42 :                 else if ( utf8stringview_equals_str( &tok, "/" ) )
     190              :                 {
     191              :                     /* ignore */
     192              :                 }
     193           21 :                 else if ( utf8stringview_equals_str( &tok, ">" ) )
     194              :                 {
     195           21 :                     if ( draw )
     196              :                     {
     197            0 :                         assert( NULL != cr );
     198              :                         /* fill and stroke */
     199            0 :                         if ( fill_color.alpha > 0.01 )
     200              :                         {
     201            0 :                             if ( stroke_color.alpha > 0.01 )
     202              :                             {
     203            0 :                                 cairo_set_source_rgba( cr, fill_color.red, fill_color.green, fill_color.blue, fill_color.alpha );
     204            0 :                                 cairo_fill_preserve( cr );
     205            0 :                                 cairo_set_source_rgba( cr, stroke_color.red, stroke_color.green, stroke_color.blue, stroke_color.alpha );
     206            0 :                                 cairo_stroke( cr );
     207              :                             }
     208              :                             else
     209              :                             {
     210            0 :                                 cairo_set_source_rgba( cr, fill_color.red, fill_color.green, fill_color.blue, fill_color.alpha );
     211            0 :                                 cairo_fill( cr );
     212              :                             }
     213              :                         }
     214              :                         else
     215              :                         {
     216            0 :                             cairo_set_source_rgba( cr, stroke_color.red, stroke_color.green, stroke_color.blue, stroke_color.alpha );
     217            0 :                             cairo_stroke( cr );
     218              :                         }
     219              :                     }
     220              :                     /* end of path tag */
     221           21 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_OUTSIDE_PATH;
     222              :                 }
     223              :             }
     224           70 :             break;
     225              : 
     226           28 :             case DRAW_STEREOTYPE_ICON_XML_D_ATTR:
     227              :             {
     228           28 :                 if ( utf8stringview_equals_str( &tok, "=" ) )
     229              :                 {
     230           28 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_D_DEF;
     231              :                 }
     232              :                 else
     233              :                 {
     234              :                     /* this is an error */
     235              :                     /* TODO the tokenizer may have split a token, e.g. d:pre-d-post */
     236              :                     /* A possible fix is to implement a token mode for XML-NM-Tokens */
     237            0 :                     result |= U8_ERROR_PARSER_STRUCTURE;
     238            0 :                     u8_error_info_init_line( out_err_info,
     239              :                                              U8_ERROR_PARSER_STRUCTURE,
     240            0 :                                              utf8stringviewtokenizer_get_line( &tok_iterator )
     241              :                                            );
     242              : 
     243              :                     /* not a d attribute, back to inside path state */
     244            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     245              :                 }
     246              :             }
     247           28 :             break;
     248              : 
     249           28 :             case DRAW_STEREOTYPE_ICON_XML_D_DEF:
     250              :             {
     251           28 :                 if (( utf8stringview_equals_str( &tok, "\"" ) )||( utf8stringview_equals_str( &tok, "\'" ) ))
     252           28 :                 {
     253              :                     /* process draw commands in sub statemachine */
     254           28 :                     utf8stringviewtokenizer_set_mode( &tok_iterator, UTF8STRINGVIEWTOKENMODE_FLOAT_ONLY );
     255              :                     draw_svg_path_data_t svg_path_data;
     256           28 :                     draw_svg_path_data_init( &svg_path_data );
     257           28 :                     if ( draw )
     258              :                     {
     259            0 :                         result |= draw_svg_path_data_draw( &svg_path_data,
     260              :                                                            &tok_iterator,
     261              :                                                            io_view_rect,
     262              :                                                            out_err_info,
     263              :                                                            target_bounds,
     264              :                                                            cr
     265              :                                                          );
     266              :                     }
     267              :                     else
     268              :                     {
     269              :                         geometry_rectangle_t path_view_rect;
     270           28 :                         geometry_rectangle_init_empty( &path_view_rect );
     271           28 :                         result |= draw_svg_path_data_parse_bounds( &svg_path_data,
     272              :                                                                    &tok_iterator,
     273              :                                                                    &path_view_rect,
     274              :                                                                    out_err_info
     275              :                                                                  );
     276           28 :                         if ( path_count == 0 )
     277              :                         {
     278           28 :                             geometry_rectangle_replace( io_view_rect, &path_view_rect );
     279              :                         }
     280              :                         else
     281              :                         {
     282            0 :                             geometry_rectangle_init_by_bounds( io_view_rect, io_view_rect, &path_view_rect );
     283              :                         }
     284           28 :                         geometry_rectangle_destroy( &path_view_rect );
     285              :                     }
     286           28 :                     draw_svg_path_data_destroy( &svg_path_data );
     287           28 :                     utf8stringviewtokenizer_set_mode( &tok_iterator, UTF8STRINGVIEWTOKENMODE_TEXT );
     288           28 :                     path_count ++;
     289              :                 }
     290              :                 else
     291              :                 {
     292              :                     /* this is an error */
     293            0 :                     result |= U8_ERROR_PARSER_STRUCTURE;
     294            0 :                     u8_error_info_init_line( out_err_info,
     295              :                                              U8_ERROR_PARSER_STRUCTURE,
     296            0 :                                              utf8stringviewtokenizer_get_line( &tok_iterator )
     297              :                                            );
     298              :                 }
     299              :                 /* back to inside path state */
     300           28 :                 parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     301              :             }
     302           28 :             break;
     303              : 
     304            0 :             case DRAW_STEREOTYPE_ICON_XML_STROKE_ATTR:
     305              :             {
     306            0 :                 if ( utf8stringview_equals_str( &tok, "=" ) )
     307              :                 {
     308            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_STROKE_DEF;
     309              :                 }
     310              :                 else
     311              :                 {
     312              :                     /* this is an error */
     313              :                     /* TODO the tokenizer may have split a token, e.g. stroke:pre-stroke-post */
     314              :                     /* A possible fix is to implement a token mode for XML-NM-Tokens */
     315            0 :                     result |= U8_ERROR_PARSER_STRUCTURE;
     316            0 :                     u8_error_info_init_line( out_err_info,
     317              :                                              U8_ERROR_PARSER_STRUCTURE,
     318            0 :                                              utf8stringviewtokenizer_get_line( &tok_iterator )
     319              :                                            );
     320              : 
     321              :                     /* not a stroke attribute, back to inside path state */
     322            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     323              :                 }
     324              :             }
     325            0 :             break;
     326              : 
     327            0 :             case DRAW_STEREOTYPE_ICON_XML_STROKE_DEF:
     328              :             {
     329            0 :                 if (( utf8stringview_equals_str( &tok, "\"" ) )||( utf8stringview_equals_str( &tok, "\'" ) ))
     330              :                 {
     331              :                     /* end of the value of another, ignored tag */
     332            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_STROKE_VALUE;
     333            0 :                     utf8stringbuf_clear( &xml_attr_value );
     334              :                 }
     335              :                 else
     336              :                 {
     337              :                     /* this is an error */
     338            0 :                     result |= U8_ERROR_PARSER_STRUCTURE;
     339            0 :                     u8_error_info_init_line( out_err_info,
     340              :                                              U8_ERROR_PARSER_STRUCTURE,
     341            0 :                                              utf8stringviewtokenizer_get_line( &tok_iterator )
     342              :                                            );
     343              : 
     344              :                     /* not a stroke attribute, back to inside path state */
     345            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     346              :                 }
     347              :             }
     348            0 :             break;
     349              : 
     350            0 :             case DRAW_STEREOTYPE_ICON_XML_STROKE_VALUE:
     351              :             {
     352            0 :                 if (( utf8stringview_equals_str( &tok, "\"" ) )||( utf8stringview_equals_str( &tok, "\'" ) ))
     353              :                 {
     354              :                     /* parse the color */
     355            0 :                     if ( utf8stringbuf_equals_str( &xml_attr_value, "none" ) )
     356              :                     {
     357            0 :                         stroke_color = (GdkRGBA) { .red = 1.0, .green = 1.0, .blue = 1.0, .alpha = 0.0 };
     358              :                     }
     359              :                     else
     360              :                     {
     361            0 :                         U8_TRACE_INFO_STR( "stroke:", utf8stringbuf_get_string( &xml_attr_value ) );
     362            0 :                         const gboolean success = gdk_rgba_parse( &stroke_color, utf8stringbuf_get_string( &xml_attr_value ) );
     363            0 :                         if ( ! success )
     364              :                         {
     365            0 :                             result |= U8_ERROR_PARSER_STRUCTURE;
     366            0 :                             u8_error_info_init_line( out_err_info,
     367              :                                                      U8_ERROR_PARSER_STRUCTURE,
     368            0 :                                                      utf8stringviewtokenizer_get_line( &tok_iterator )
     369              :                                                    );
     370              :                         }
     371              :                     }
     372              :                     /* end of the value of fill tag */
     373            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     374              :                 }
     375              :                 else
     376              :                 {
     377            0 :                     utf8stringbuf_append_view( &xml_attr_value, &tok );
     378              :                 }
     379              :             }
     380            0 :             break;
     381              : 
     382            0 :             case DRAW_STEREOTYPE_ICON_XML_FILL_ATTR:
     383              :             {
     384            0 :                 if ( utf8stringview_equals_str( &tok, "=" ) )
     385              :                 {
     386            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_FILL_DEF;
     387              :                 }
     388              :                 else
     389              :                 {
     390              :                     /* this is an error */
     391              :                     /* TODO the tokenizer may have split a token, e.g. fill:pre-fill-post */
     392              :                     /* A possible fix is to implement a token mode for XML-NM-Tokens */
     393            0 :                     result |= U8_ERROR_PARSER_STRUCTURE;
     394            0 :                     u8_error_info_init_line( out_err_info,
     395              :                                              U8_ERROR_PARSER_STRUCTURE,
     396            0 :                                              utf8stringviewtokenizer_get_line( &tok_iterator )
     397              :                                            );
     398              : 
     399              :                     /* not a fill attribute, back to inside path state */
     400            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     401              :                 }
     402              :             }
     403            0 :             break;
     404              : 
     405            0 :             case DRAW_STEREOTYPE_ICON_XML_FILL_DEF:
     406              :             {
     407            0 :                 if (( utf8stringview_equals_str( &tok, "\"" ) )||( utf8stringview_equals_str( &tok, "\'" ) ))
     408              :                 {
     409              :                     /* end of the value of another, ignored tag */
     410            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_FILL_VALUE;
     411            0 :                     utf8stringbuf_clear( &xml_attr_value );
     412              :                 }
     413              :                 else
     414              :                 {
     415              :                     /* this is an error */
     416            0 :                     result |= U8_ERROR_PARSER_STRUCTURE;
     417            0 :                     u8_error_info_init_line( out_err_info,
     418              :                                              U8_ERROR_PARSER_STRUCTURE,
     419            0 :                                              utf8stringviewtokenizer_get_line( &tok_iterator )
     420              :                                            );
     421              : 
     422              :                     /* not a stroke attribute, back to inside path state */
     423            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     424              :                 }
     425              :             }
     426            0 :             break;
     427              : 
     428            0 :             case DRAW_STEREOTYPE_ICON_XML_FILL_VALUE:
     429              :             {
     430            0 :                 if (( utf8stringview_equals_str( &tok, "\"" ) )||( utf8stringview_equals_str( &tok, "\'" ) ))
     431              :                 {
     432              :                     /* parse the color */
     433            0 :                     if ( utf8stringbuf_equals_str( &xml_attr_value, "none" ) )
     434              :                     {
     435            0 :                         fill_color = (GdkRGBA) { .red = 1.0, .green = 1.0, .blue = 1.0, .alpha = 0.0 };
     436              :                     }
     437              :                     else
     438              :                     {
     439            0 :                         U8_TRACE_INFO_STR( "fill:", utf8stringbuf_get_string( &xml_attr_value ) );
     440            0 :                         const gboolean success = gdk_rgba_parse( &fill_color, utf8stringbuf_get_string( &xml_attr_value ) );
     441            0 :                         if ( ! success )
     442              :                         {
     443            0 :                             result |= U8_ERROR_PARSER_STRUCTURE;
     444            0 :                             u8_error_info_init_line( out_err_info,
     445              :                                                      U8_ERROR_PARSER_STRUCTURE,
     446            0 :                                                      utf8stringviewtokenizer_get_line( &tok_iterator )
     447              :                                                    );
     448              :                         }
     449              :                     }
     450              :                     /* end of the value of fill tag */
     451            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     452              :                 }
     453              :                 else
     454              :                 {
     455            0 :                     utf8stringbuf_append_view( &xml_attr_value, &tok );
     456              :                 }
     457              :             }
     458            0 :             break;
     459              : 
     460            0 :             case DRAW_STEREOTYPE_ICON_XML_INSIDE_SGLQ_VALUE:
     461              :             {
     462            0 :                 if ( utf8stringview_equals_str( &tok, "\'" ) )
     463              :                 {
     464              :                     /* end of the value of another, ignored tag */
     465            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     466              :                 }
     467              :                 /*
     468              :                 else
     469              :                 {
     470              :                     U8_TRACE_INFO_VIEW( "other single-quoted:", tok );
     471              :                 }
     472              :                 */
     473              :             }
     474            0 :             break;
     475              : 
     476            0 :             case DRAW_STEREOTYPE_ICON_XML_INSIDE_DBLQ_VALUE:
     477              :             {
     478            0 :                 if ( utf8stringview_equals_str( &tok, "\"" ) )
     479              :                 {
     480              :                     /* end of the value of another, ignored tag */
     481            0 :                     parser_state = DRAW_STEREOTYPE_ICON_XML_INSIDE_PATH_TAG;
     482              :                 }
     483              :                 /*
     484              :                 else
     485              :                 {
     486              :                     U8_TRACE_INFO_VIEW( "other double-quoted:", tok );
     487              :                 }
     488              :                 */
     489              :             }
     490            0 :             break;
     491              :         }
     492              :     }
     493              : 
     494              :     /* report error on unfinished drawing */
     495           29 :     if (( result == U8_ERROR_NONE )&&( parser_state != DRAW_STEREOTYPE_ICON_XML_OUTSIDE_PATH ))
     496              :     {
     497            0 :         result |= U8_ERROR_PARSER_STRUCTURE;
     498              :         /* if no other error encountered yet, report this one: */
     499            0 :         if ( ! u8_error_info_is_error( out_err_info ) )
     500              :         {
     501            0 :             u8_error_info_init_line( out_err_info,
     502              :                                      U8_ERROR_PARSER_STRUCTURE,
     503            0 :                                      utf8stringviewtokenizer_get_line( &tok_iterator )
     504              :                                    );
     505              :         }
     506              :     }
     507              : 
     508              :     /* check if anything was drawn at all */
     509           29 :     if ( path_count == 0 )
     510              :     {
     511            1 :         result |= U8_ERROR_NOT_FOUND;
     512              :     }
     513              : 
     514           29 :     utf8stringviewtokenizer_destroy( &tok_iterator );
     515           29 :     U8_TRACE_END_ERR(result);
     516           29 :     return result;
     517              : }
     518              : 
     519              : 
     520              : /*
     521              : Copyright 2023-2025 Andreas Warnke
     522              :     http://www.apache.org/licenses/LICENSE-2.0
     523              : 
     524              : Licensed under the Apache License, Version 2.0 (the "License");
     525              : you may not use this file except in compliance with the License.
     526              : You may obtain a copy of the License at
     527              : 
     528              : 
     529              : Unless required by applicable law or agreed to in writing, software
     530              : distributed under the License is distributed on an "AS IS" BASIS,
     531              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     532              : See the License for the specific language governing permissions and
     533              : limitations under the License.
     534              : */
        

Generated by: LCOV version 2.0-1