Skip to content

Commit bbf8047

Browse files
committed
Deprecated the SVGBackend::with_buffer
1 parent c3c591a commit bbf8047

File tree

3 files changed

+61
-25
lines changed

3 files changed

+61
-25
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
- Faster bitmap blending algorithm, which is 5x faster than the original one.
1515
- Text alignment improvement, now we can suggest the invariant point by giving `TextAlignment` to the text style (Thanks to @nauld)
16+
- More controls on features, allows opt in and out series types
17+
- Remove dependency to svg crate, since it doesn't provide more feature than a plain string.
1618

1719
## Plotters 0.2.11 (2019-10-27)
1820

src/drawing/backend_impl/svg.rs

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,23 @@ fn make_svg_opacity<C: Color>(color: &C) -> String {
2424
enum Target<'a> {
2525
File(String, &'a Path),
2626
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>),
2732
}
2833

2934
impl Target<'_> {
3035
fn get_mut(&mut self) -> &mut String {
3136
match self {
3237
Target::File(ref mut buf, _) => buf,
3338
Target::Buffer(buf) => buf,
39+
#[cfg(feature = "deprecated_items")]
40+
Target::U8Buffer(ref mut buf, _) => buf,
3441
}
3542
}
3643
}
37-
//use svg::node::element::{Circle, Line, Polygon, Polyline, Rectangle, Text};
3844

3945
enum SVGTag {
4046
SVG,
@@ -72,6 +78,16 @@ pub struct SVGBackend<'a> {
7278
}
7379

7480
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("&lt;"),
84+
'>' => buf.push_str("&gt;"),
85+
'&' => buf.push_str("&amp;"),
86+
'"' => buf.push_str("&quot;"),
87+
'\'' => buf.push_str("&apos;"),
88+
other => buf.push(other),
89+
});
90+
}
7591
fn open_tag(&mut self, tag: SVGTag, attr: &[(&str, &str)], close: bool) {
7692
let buf = self.target.get_mut();
7793
buf.push_str("<");
@@ -80,14 +96,14 @@ impl<'a> SVGBackend<'a> {
8096
buf.push_str(" ");
8197
buf.push_str(key);
8298
buf.push_str("=\"");
83-
buf.push_str(value);
99+
Self::escape_and_push(buf, value);
84100
buf.push_str("\"");
85101
}
86102
if close {
87103
buf.push_str("/>\n");
88104
} else {
89105
self.tag_stack.push(tag);
90-
buf.push_str(">");
106+
buf.push_str(">\n");
91107
}
92108
}
93109

@@ -127,8 +143,26 @@ impl<'a> SVGBackend<'a> {
127143
ret
128144
}
129145

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 {
132166
let mut ret = Self {
133167
target: Target::Buffer(buf),
134168
size,
@@ -165,6 +199,11 @@ impl<'a> DrawingBackend for SVGBackend<'a> {
165199
.map_err(DrawingErrorKind::DrawingError)?;
166200
}
167201
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+
}
168207
}
169208
self.saved = true;
170209
}
@@ -429,7 +468,8 @@ impl<'a> DrawingBackend for SVGBackend<'a> {
429468
false,
430469
);
431470

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");
433473

434474
self.close_tag();
435475

@@ -554,9 +594,9 @@ mod test {
554594
}
555595

556596
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();
558598
{
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();
560600

561601
let mut chart = ChartBuilder::on(&root)
562602
.caption("This is a test", ("sans-serif", 20))
@@ -571,7 +611,6 @@ mod test {
571611
.unwrap();
572612
}
573613

574-
let content = buffer;
575614
checked_save_file(test_name, &content);
576615

577616
assert!(content.contains("This is a test"));
@@ -589,9 +628,9 @@ mod test {
589628

590629
#[test]
591630
fn test_text_alignments() {
592-
let mut buffer: String = Default::default();
631+
let mut content: String = Default::default();
593632
{
594-
let mut root = SVGBackend::with_buffer(&mut buffer, (500, 500));
633+
let mut root = SVGBackend::with_string(&mut content, (500, 500));
595634

596635
let style = TextStyle::from(("sans-serif", 20).into_font())
597636
.pos(Pos::new(HPos::Right, VPos::Top));
@@ -604,7 +643,6 @@ mod test {
604643
root.draw_text("left-align", &style, (150, 200)).unwrap();
605644
}
606645

607-
let content = buffer;
608646
checked_save_file("test_text_alignments", &content);
609647

610648
for svg_line in content.split("</text>") {
@@ -624,9 +662,9 @@ mod test {
624662

625663
#[test]
626664
fn test_text_draw() {
627-
let mut buffer: String = Default::default();
665+
let mut content: String = Default::default();
628666
{
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();
630668
let root = root
631669
.titled("Image Title", ("sans-serif", 60).into_font())
632670
.unwrap();
@@ -676,7 +714,6 @@ mod test {
676714
}
677715
}
678716

679-
let content = buffer;
680717
checked_save_file("test_text_draw", &content);
681718

682719
assert_eq!(content.matches("dog").count(), 36);
@@ -686,10 +723,10 @@ mod test {
686723

687724
#[test]
688725
fn test_text_clipping() {
689-
let mut buffer: String = Default::default();
726+
let mut content: String = Default::default();
690727
{
691728
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))
693730
.into_drawing_area();
694731

695732
let style = TextStyle::from(("sans-serif", 20).into_font())
@@ -711,16 +748,15 @@ mod test {
711748
.unwrap();
712749
}
713750

714-
let content = buffer;
715751
checked_save_file("test_text_clipping", &content);
716752
}
717753

718754
#[test]
719755
fn test_series_labels() {
720-
let mut buffer = String::default();
756+
let mut content = String::default();
721757
{
722758
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();
724760

725761
let mut chart = ChartBuilder::on(&root)
726762
.caption("All series label positions", ("sans-serif", 20))
@@ -770,16 +806,15 @@ mod test {
770806
}
771807
}
772808

773-
let content = buffer;
774809
checked_save_file("test_series_labels", &content);
775810
}
776811

777812
#[test]
778813
fn test_draw_pixel_alphas() {
779-
let mut buffer = String::default();
814+
let mut content = String::default();
780815
{
781816
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))
783818
.into_drawing_area();
784819
root.fill(&WHITE).unwrap();
785820

@@ -790,7 +825,6 @@ mod test {
790825
}
791826
}
792827

793-
let content = buffer;
794828
checked_save_file("test_draw_pixel_alphas", &content);
795829
}
796830
}

src/evcxr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn evcxr_figure<
3434
draw: Draw,
3535
) -> SVGWrapper {
3636
let mut buffer = "".to_string();
37-
let root = SVGBackend::with_buffer(&mut buffer, size).into_drawing_area();
37+
let root = SVGBackend::with_string(&mut buffer, size).into_drawing_area();
3838
draw(root).expect("Drawing failure");
3939
SVGWrapper(buffer, "".to_string())
4040
}

0 commit comments

Comments
 (0)