@@ -24,17 +24,23 @@ fn make_svg_opacity<C: Color>(color: &C) -> String {
24
24
enum Target < ' a > {
25
25
File ( String , & ' a Path ) ,
26
26
Buffer ( & ' a mut String ) ,
27
+ // TODO: At this point we won't make the breaking change
28
+ // so the u8 buffer is still supported. But in 0.3, we definitely
29
+ // should get rid of this.
30
+ #[ cfg( feature = "deprecated_items" ) ]
31
+ U8Buffer ( String , & ' a mut Vec < u8 > ) ,
27
32
}
28
33
29
34
impl Target < ' _ > {
30
35
fn get_mut ( & mut self ) -> & mut String {
31
36
match self {
32
37
Target :: File ( ref mut buf, _) => buf,
33
38
Target :: Buffer ( buf) => buf,
39
+ #[ cfg( feature = "deprecated_items" ) ]
40
+ Target :: U8Buffer ( ref mut buf, _) => buf,
34
41
}
35
42
}
36
43
}
37
- //use svg::node::element::{Circle, Line, Polygon, Polyline, Rectangle, Text};
38
44
39
45
enum SVGTag {
40
46
SVG ,
@@ -72,6 +78,16 @@ pub struct SVGBackend<'a> {
72
78
}
73
79
74
80
impl < ' a > SVGBackend < ' a > {
81
+ fn escape_and_push ( buf : & mut String , value : & str ) {
82
+ value. chars ( ) . for_each ( |c| match c {
83
+ '<' => buf. push_str ( "<" ) ,
84
+ '>' => buf. push_str ( ">" ) ,
85
+ '&' => buf. push_str ( "&" ) ,
86
+ '"' => buf. push_str ( """ ) ,
87
+ '\'' => buf. push_str ( "'" ) ,
88
+ other => buf. push ( other) ,
89
+ } ) ;
90
+ }
75
91
fn open_tag ( & mut self , tag : SVGTag , attr : & [ ( & str , & str ) ] , close : bool ) {
76
92
let buf = self . target . get_mut ( ) ;
77
93
buf. push_str ( "<" ) ;
@@ -80,14 +96,14 @@ impl<'a> SVGBackend<'a> {
80
96
buf. push_str ( " " ) ;
81
97
buf. push_str ( key) ;
82
98
buf. push_str ( "=\" " ) ;
83
- buf . push_str ( value) ;
99
+ Self :: escape_and_push ( buf , value) ;
84
100
buf. push_str ( "\" " ) ;
85
101
}
86
102
if close {
87
103
buf. push_str ( "/>\n " ) ;
88
104
} else {
89
105
self . tag_stack . push ( tag) ;
90
- buf. push_str ( ">" ) ;
106
+ buf. push_str ( ">\n " ) ;
91
107
}
92
108
}
93
109
@@ -127,8 +143,26 @@ impl<'a> SVGBackend<'a> {
127
143
ret
128
144
}
129
145
130
- /// Create a new SVG drawing backend and store the document into a u8 buffer
131
- pub fn with_buffer ( buf : & ' a mut String , size : ( u32 , u32 ) ) -> Self {
146
+ /// Create a new SVG drawing backend and store the document into a u8 vector
147
+ #[ cfg( feature = "deprecated_items" ) ]
148
+ #[ deprecated(
149
+ note = "This will be replaced by `with_string`, consider use `with_string` to avoid breaking change in the future"
150
+ ) ]
151
+ pub fn with_buffer ( buf : & ' a mut Vec < u8 > , size : ( u32 , u32 ) ) -> Self {
152
+ let mut ret = Self {
153
+ target : Target :: U8Buffer ( String :: default ( ) , buf) ,
154
+ size,
155
+ tag_stack : vec ! [ ] ,
156
+ saved : false ,
157
+ } ;
158
+
159
+ ret. init_svg_file ( size) ;
160
+
161
+ ret
162
+ }
163
+
164
+ /// Create a new SVG drawing backend and store the document into a String buffer
165
+ pub fn with_string ( buf : & ' a mut String , size : ( u32 , u32 ) ) -> Self {
132
166
let mut ret = Self {
133
167
target : Target :: Buffer ( buf) ,
134
168
size,
@@ -165,6 +199,11 @@ impl<'a> DrawingBackend for SVGBackend<'a> {
165
199
. map_err ( DrawingErrorKind :: DrawingError ) ?;
166
200
}
167
201
Target :: Buffer ( _) => { }
202
+ #[ cfg( feature = "deprecated_items" ) ]
203
+ Target :: U8Buffer ( ref actual, ref mut target) => {
204
+ target. clear ( ) ;
205
+ target. extend_from_slice ( actual. as_bytes ( ) ) ;
206
+ }
168
207
}
169
208
self . saved = true ;
170
209
}
@@ -429,7 +468,8 @@ impl<'a> DrawingBackend for SVGBackend<'a> {
429
468
false ,
430
469
) ;
431
470
432
- self . target . get_mut ( ) . push_str ( text) ;
471
+ Self :: escape_and_push ( self . target . get_mut ( ) , text) ;
472
+ self . target . get_mut ( ) . push_str ( "\n " ) ;
433
473
434
474
self . close_tag ( ) ;
435
475
@@ -554,9 +594,9 @@ mod test {
554
594
}
555
595
556
596
fn draw_mesh_with_custom_ticks ( tick_size : i32 , test_name : & str ) {
557
- let mut buffer : String = Default :: default ( ) ;
597
+ let mut content : String = Default :: default ( ) ;
558
598
{
559
- let root = SVGBackend :: with_buffer ( & mut buffer , ( 500 , 500 ) ) . into_drawing_area ( ) ;
599
+ let root = SVGBackend :: with_string ( & mut content , ( 500 , 500 ) ) . into_drawing_area ( ) ;
560
600
561
601
let mut chart = ChartBuilder :: on ( & root)
562
602
. caption ( "This is a test" , ( "sans-serif" , 20 ) )
@@ -571,7 +611,6 @@ mod test {
571
611
. unwrap ( ) ;
572
612
}
573
613
574
- let content = buffer;
575
614
checked_save_file ( test_name, & content) ;
576
615
577
616
assert ! ( content. contains( "This is a test" ) ) ;
@@ -589,9 +628,9 @@ mod test {
589
628
590
629
#[ test]
591
630
fn test_text_alignments ( ) {
592
- let mut buffer : String = Default :: default ( ) ;
631
+ let mut content : String = Default :: default ( ) ;
593
632
{
594
- let mut root = SVGBackend :: with_buffer ( & mut buffer , ( 500 , 500 ) ) ;
633
+ let mut root = SVGBackend :: with_string ( & mut content , ( 500 , 500 ) ) ;
595
634
596
635
let style = TextStyle :: from ( ( "sans-serif" , 20 ) . into_font ( ) )
597
636
. pos ( Pos :: new ( HPos :: Right , VPos :: Top ) ) ;
@@ -604,7 +643,6 @@ mod test {
604
643
root. draw_text ( "left-align" , & style, ( 150 , 200 ) ) . unwrap ( ) ;
605
644
}
606
645
607
- let content = buffer;
608
646
checked_save_file ( "test_text_alignments" , & content) ;
609
647
610
648
for svg_line in content. split ( "</text>" ) {
@@ -624,9 +662,9 @@ mod test {
624
662
625
663
#[ test]
626
664
fn test_text_draw ( ) {
627
- let mut buffer : String = Default :: default ( ) ;
665
+ let mut content : String = Default :: default ( ) ;
628
666
{
629
- let root = SVGBackend :: with_buffer ( & mut buffer , ( 1500 , 800 ) ) . into_drawing_area ( ) ;
667
+ let root = SVGBackend :: with_string ( & mut content , ( 1500 , 800 ) ) . into_drawing_area ( ) ;
630
668
let root = root
631
669
. titled ( "Image Title" , ( "sans-serif" , 60 ) . into_font ( ) )
632
670
. unwrap ( ) ;
@@ -676,7 +714,6 @@ mod test {
676
714
}
677
715
}
678
716
679
- let content = buffer;
680
717
checked_save_file ( "test_text_draw" , & content) ;
681
718
682
719
assert_eq ! ( content. matches( "dog" ) . count( ) , 36 ) ;
@@ -686,10 +723,10 @@ mod test {
686
723
687
724
#[ test]
688
725
fn test_text_clipping ( ) {
689
- let mut buffer : String = Default :: default ( ) ;
726
+ let mut content : String = Default :: default ( ) ;
690
727
{
691
728
let ( width, height) = ( 500_i32 , 500_i32 ) ;
692
- let root = SVGBackend :: with_buffer ( & mut buffer , ( width as u32 , height as u32 ) )
729
+ let root = SVGBackend :: with_string ( & mut content , ( width as u32 , height as u32 ) )
693
730
. into_drawing_area ( ) ;
694
731
695
732
let style = TextStyle :: from ( ( "sans-serif" , 20 ) . into_font ( ) )
@@ -711,16 +748,15 @@ mod test {
711
748
. unwrap ( ) ;
712
749
}
713
750
714
- let content = buffer;
715
751
checked_save_file ( "test_text_clipping" , & content) ;
716
752
}
717
753
718
754
#[ test]
719
755
fn test_series_labels ( ) {
720
- let mut buffer = String :: default ( ) ;
756
+ let mut content = String :: default ( ) ;
721
757
{
722
758
let ( width, height) = ( 500 , 500 ) ;
723
- let root = SVGBackend :: with_buffer ( & mut buffer , ( width, height) ) . into_drawing_area ( ) ;
759
+ let root = SVGBackend :: with_string ( & mut content , ( width, height) ) . into_drawing_area ( ) ;
724
760
725
761
let mut chart = ChartBuilder :: on ( & root)
726
762
. caption ( "All series label positions" , ( "sans-serif" , 20 ) )
@@ -770,16 +806,15 @@ mod test {
770
806
}
771
807
}
772
808
773
- let content = buffer;
774
809
checked_save_file ( "test_series_labels" , & content) ;
775
810
}
776
811
777
812
#[ test]
778
813
fn test_draw_pixel_alphas ( ) {
779
- let mut buffer = String :: default ( ) ;
814
+ let mut content = String :: default ( ) ;
780
815
{
781
816
let ( width, height) = ( 100_i32 , 100_i32 ) ;
782
- let root = SVGBackend :: with_buffer ( & mut buffer , ( width as u32 , height as u32 ) )
817
+ let root = SVGBackend :: with_string ( & mut content , ( width as u32 , height as u32 ) )
783
818
. into_drawing_area ( ) ;
784
819
root. fill ( & WHITE ) . unwrap ( ) ;
785
820
@@ -790,7 +825,6 @@ mod test {
790
825
}
791
826
}
792
827
793
- let content = buffer;
794
828
checked_save_file ( "test_draw_pixel_alphas" , & content) ;
795
829
}
796
830
}
0 commit comments