From 9b4dce3403ffdea610044f5df63666b492cee87b Mon Sep 17 00:00:00 2001 From: Edward Blake Date: Fri, 12 Apr 2024 17:07:59 -0400 Subject: [PATCH] wpc_svg_path: Added style sheet support. --- plugins_src/import_export/wpc_svg_path.erl | 1103 +++++++++++++++++++- 1 file changed, 1095 insertions(+), 8 deletions(-) diff --git a/plugins_src/import_export/wpc_svg_path.erl b/plugins_src/import_export/wpc_svg_path.erl index faec26c1f..f56ab9288 100644 --- a/plugins_src/import_export/wpc_svg_path.erl +++ b/plugins_src/import_export/wpc_svg_path.erl @@ -571,7 +571,8 @@ read_file__svg(Name) -> skipping_tag = [], % Currently inside a tag we are skipping units = "px" :: string(), docsz = {100.0,100.0} :: {float(), float()}, - viewbox = {0.0,0.0,100.0,100.0} :: {float(),float(),float(),float()} + viewbox = {0.0,0.0,100.0,100.0} :: {float(),float(),float(),float()}, + e_sty = [] }). -record(path_tag_r, @@ -786,10 +787,15 @@ read_svg_content(Bin_0, FullFilename, ShortFilename) -> EF = {event_fun, fun svg_tok/3}, ES = {event_state, #svgtk{}}, {ok, Bin_1} = svg_change_prolog(Bin_0), - case xmerl_sax_parser:stream(Bin_1, [EF,ES]) of - {ok, #svgtk{list=List,units=DocUnits_S,docsz=DocSz,viewbox=ViewBox}=_Es, _} -> + {Bin_2, StyleTagContents} = extract_styles(Bin_1), + case xmerl_sax_parser:stream(Bin_2, [EF,ES]) of + {ok, #svgtk{list=List,units=DocUnits_S,docsz=DocSz,viewbox=ViewBox,e_sty=ESty}=_Es, _} -> + CurDir = filename:dirname(FullFilename), + ApplStyle_1 = parse_stylesheet_list(StyleTagContents, CurDir), + ApplStyle_2 = get_link_rel_css(ESty, CurDir), + ApplStyle = ApplStyle_1 ++ ApplStyle_2, DocUnits = unit_atom(DocUnits_S), - CommandList_0 = lists:reverse(List), + CommandList_0 = match_css(lists:reverse(List), ApplStyle), {ok, {Definitions, CommandList_1}} = path_definitions(CommandList_0, #document_s{fullfilename=FullFilename,units=DocUnits,docsz=DocSz,viewbox=ViewBox}), @@ -914,7 +920,8 @@ make_viewbox_if_needed(ViewBox, _) -> -svg_tok({startElement, _, LName, _, Attributes_0}=_Ev, _Loc, #svgtk{skipping_tag=SkippingTag,list=List,in_svg_tag=InSVGTag}=State) -> +svg_tok({startElement, _, LName, _, Attributes_0}=_Ev, _Loc, + #svgtk{skipping_tag=SkippingTag,list=List,in_svg_tag=InSVGTag,e_sty=ESty}=State) -> case LName of "svg" -> Wi_He_Units_0 = get_svg_tag_units_from_attrs(Attributes_0), @@ -926,6 +933,11 @@ svg_tok({startElement, _, LName, _, Attributes_0}=_Ev, _Loc, #svgtk{skipping_tag State#svgtk{skipping_tag=["namedview" | SkippingTag]}; "pattern" -> State#svgtk{skipping_tag=["pattern" | SkippingTag]}; + "link" when SkippingTag =:= [] -> + LinkAttrs = [ + {string:to_lower(AttrLName), Val} + || {_,_,AttrLName,Val} <- Attributes_0], + State#svgtk{e_sty=[{linkrel,LinkAttrs} | ESty]}; _ when InSVGTag =:= true andalso SkippingTag =:= [] -> Attributes_1 = [ svg_tok_attr_pair(string:to_lower(LName), string:to_lower(AttrLName), Val) @@ -943,6 +955,8 @@ svg_tok({endElement, _, LName, _}=_Ev, _Loc, #svgtk{skipping_tag=SkippingTag,lis State#svgtk{ skipping_tag = lists:nthtail(1, SkippingTag) }; "pattern" -> State#svgtk{ skipping_tag = lists:nthtail(1, SkippingTag) }; + "link" -> + State; _ when InSVGTag =:= true andalso SkippingTag =:= [] -> State#svgtk{list=[{e, string:to_lower(LName)} |List]}; _ -> @@ -991,6 +1005,9 @@ svg_tok_attr_pair(_LName, _AttrLName, _Val) -> svg_tok_attr_pair_clippath(AttrLName, Val) when AttrLName =:= "id" -> {id, Val}; +svg_tok_attr_pair_clippath(AttrLName, Val) + when AttrLName =:= "class" -> + {class, Val}; svg_tok_attr_pair_clippath(AttrLName, Val) when AttrLName =:= "clippathunits" -> {clipPathUnits, Val}; @@ -999,6 +1016,9 @@ svg_tok_attr_pair_clippath(_AttrLName, _Val) -> svg_tok_attr_pair_mask(AttrLName, Val) when AttrLName =:= "id" -> {id, Val}; +svg_tok_attr_pair_mask(AttrLName, Val) + when AttrLName =:= "class" -> + {class, Val}; svg_tok_attr_pair_mask(AttrLName, Val) when AttrLName =:= "maskunits" -> {clipPathUnits, Val}; @@ -1043,6 +1063,9 @@ svg_tok_attr_pair_image(AttrLName, Val) svg_tok_attr_pair_image(AttrLName, Val) when AttrLName =:= "id" -> {id, Val}; +svg_tok_attr_pair_image(AttrLName, Val) + when AttrLName =:= "class" -> + {class, Val}; svg_tok_attr_pair_image(AttrLName, Val) when AttrLName =:= "preserveAspectRatio" -> {preserve_aspect_ratio, Val}; @@ -1053,6 +1076,9 @@ svg_tok_attr_pair_image(_AttrLName, _Val) -> svg_tok_attr_pair_g(AttrLName, Val) when AttrLName =:= "id" -> {id, Val}; +svg_tok_attr_pair_g(AttrLName, Val) + when AttrLName =:= "class" -> + {class, Val}; svg_tok_attr_pair_g(AttrLName, Val) when AttrLName =:= "label" -> {label, Val}; @@ -1086,6 +1112,8 @@ svg_tok_color_attr("fill-opacity", FVal) -> %% svg_tok_attr_pair_path("id", Val) -> {id, Val}; +svg_tok_attr_pair_path("class", Val) -> + {class, Val}; svg_tok_attr_pair_path(StyleAttr, Val) when StyleAttr =:= "style"; StyleAttr =:= "stroke"; @@ -1105,6 +1133,8 @@ svg_tok_attr_pair_path(_AttrLName, _Val) -> %% svg_tok_attr_pair_polyline("id", Val) -> {id, Val}; +svg_tok_attr_pair_polyline("class", Val) -> + {class, Val}; svg_tok_attr_pair_polyline(StyleAttr, Val) when StyleAttr =:= "style"; StyleAttr =:= "stroke"; @@ -1124,6 +1154,8 @@ svg_tok_attr_pair_polyline(_AttrLName, _Val) -> %% svg_tok_attr_pair_polygon("id", Val) -> {id, Val}; +svg_tok_attr_pair_polygon("class", Val) -> + {class, Val}; svg_tok_attr_pair_polygon(StyleAttr, Val) when StyleAttr =:= "style"; StyleAttr =:= "stroke"; @@ -1149,6 +1181,8 @@ svg_tok_attr_pair_rect(StyleAttr, Val) svg_tok_color_attr(StyleAttr, Val); svg_tok_attr_pair_rect("id", Val) -> {id, Val}; +svg_tok_attr_pair_rect("class", Val) -> + {class, Val}; svg_tok_attr_pair_rect("width", Val) -> Val_1 = parse_float_number_w_unit(Val, 0.0), {width, Val_1}; @@ -1187,6 +1221,8 @@ svg_tok_attr_pair_circle(StyleAttr, Val) svg_tok_color_attr(StyleAttr, Val); svg_tok_attr_pair_circle("id", Val) -> {id, Val}; +svg_tok_attr_pair_circle("class", Val) -> + {class, Val}; svg_tok_attr_pair_circle("cx", Val) -> Val_1 = parse_float_number_w_unit(Val, 0.0), {cx, Val_1}; @@ -1213,6 +1249,8 @@ svg_tok_attr_pair_ellipse(StyleAttr, Val) svg_tok_color_attr(StyleAttr, Val); svg_tok_attr_pair_ellipse("id", Val) -> {id, Val}; +svg_tok_attr_pair_ellipse("class", Val) -> + {class, Val}; svg_tok_attr_pair_ellipse("cx", Val) -> Val_1 = parse_float_number_w_unit(Val, 0.0), {cx, Val_1}; @@ -1340,12 +1378,15 @@ parse_style(A) -> parse_style(A, [], []). parse_style([], SName, List) when length(SName) > 0 -> - parse_style([], [], [{lists:reverse(SName), ""} | List]); + parse_style([], [], [{string:strip(lists:reverse(SName)), ""} | List]); parse_style([], [], List) -> {ok, orddict:from_list(List)}; parse_style([$: | R], SName, List) -> {ok, StyleVal, R_1} = tok_svg_attr(R, [], []), - parse_style(R_1, [], [{lists:reverse(SName), StyleVal} | List]); + parse_style(R_1, [], [{string:strip(lists:reverse(SName)), StyleVal} | List]); +parse_style([A | R], [], List) + when A =:= 32; A =:= 9; A =:= 10; A =:= 13 -> + parse_style(R, [], List); parse_style([A | R], SName, List) when A =/= $: , A =/= $; -> parse_style(R, [A | SName], List). @@ -3587,6 +3628,982 @@ angle_of_line({A1_X,A1_Y}, {A2_X,A2_Y}) -> %%% %%% +%%% +%%% Extract \n", + "\n", + "\n", + "\n", + "\n", + "\n">>, + {SVG_1, StyleList} = extract_styles(A), + {SVG_1, StyleList}. + +-endif(). +