From 52f3da4910b9c7aefc9dbaff2681874342438bd2 Mon Sep 17 00:00:00 2001 From: ricky han Date: Wed, 30 Oct 2019 11:41:39 -0400 Subject: [PATCH 1/3] generic pixel type for bitmapbackend --- benches/benches/parallel.rs | 12 +++++----- benches/benches/rasterizer.rs | 12 +++++----- src/drawing/backend_impl/bitmap.rs | 36 +++++++++++++++++------------- src/element/image.rs | 4 ++-- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/benches/benches/parallel.rs b/benches/benches/parallel.rs index c7c7321c..a06c51a1 100644 --- a/benches/benches/parallel.rs +++ b/benches/benches/parallel.rs @@ -37,7 +37,7 @@ fn draw_func_1x1_seq(c: &mut Criterion) { let mut buffer = vec![0; (W * H * 3) as usize]; c.bench_function("parallel::draw_func_1x1_seq", |b| { b.iter(|| { - let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area(); + let root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)).into_drawing_area(); root.fill(&WHITE).unwrap(); draw_plot(&root, 2.0); }) @@ -48,7 +48,7 @@ fn draw_func_4x4_seq(c: &mut Criterion) { let mut buffer = vec![0; (W * H * 3) as usize]; c.bench_function("parallel::draw_func_4x4_seq", |b| { b.iter(|| { - let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area(); + let root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)).into_drawing_area(); let areas = root.split_evenly((4, 4)); areas.iter().for_each(|area| draw_plot(&area, 2.0)); }) @@ -59,7 +59,7 @@ fn draw_func_4x4_parallel_and_blit(c: &mut Criterion) { let mut buffer = vec![0; (W * H * 3) as usize]; c.bench_function("parallel::draw_func_4x4_parallel_and_blit", |b| { b.iter(|| { - let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area(); + let root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)).into_drawing_area(); let areas = root.split_evenly((4, 4)); let mut elements: Vec<_> = areas .iter() @@ -83,7 +83,7 @@ fn draw_func_2x1_parallel_and_blit(c: &mut Criterion) { let mut buffer = vec![0; (W * H * 3) as usize]; c.bench_function("parallel::draw_func_2x1_parallel_and_blit", |b| { b.iter(|| { - let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area(); + let root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)).into_drawing_area(); let areas = root.split_evenly((2, 1)); let mut elements: Vec<_> = areas .iter() @@ -107,7 +107,7 @@ fn draw_func_2x1_inplace_parallel(c: &mut Criterion) { let mut buffer = vec![0u8; (W * H * 3) as usize]; c.bench_function("parallel::draw_func_2x1_inplace", |b| { b.iter(|| { - let mut back = BitMapBackend::with_buffer(&mut buffer, (W, H)); + let mut back = BitMapBackend::>::with_buffer(&mut buffer, (W, H)); back.split(&[H / 2]) .into_par_iter() .for_each(|b| draw_plot(&b.into_drawing_area(), 2.0)); @@ -119,7 +119,7 @@ fn draw_func_2x1_seq(c: &mut Criterion) { let mut buffer = vec![0u8; (W * H * 3) as usize]; c.bench_function("parallel::draw_func_2x1_seq", |b| { b.iter(|| { - let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area(); + let root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)).into_drawing_area(); root.split_evenly((2, 1)) .iter_mut() .for_each(|area| draw_plot(area, 2.0)); diff --git a/benches/benches/rasterizer.rs b/benches/benches/rasterizer.rs index 3928cffa..ff800804 100644 --- a/benches/benches/rasterizer.rs +++ b/benches/benches/rasterizer.rs @@ -9,7 +9,7 @@ fn draw_pixel(c: &mut Criterion) { c.bench_function("rasterizer::draw_pixel", |b| { b.iter(|| { - let mut root = BitMapBackend::with_buffer(&mut buffer, (W, H)); + let mut root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)); for x in 0..W / 10 { for y in 0..H / 10 { root.draw_pixel((x as i32, y as i32), &RGBColor(255, 0, 234).to_rgba()) @@ -25,7 +25,7 @@ fn draw_line(c: &mut Criterion) { c.bench_function("rasterizer::draw_line", |b| { b.iter(|| { - let mut root = BitMapBackend::with_buffer(&mut buffer, (W, H)); + let mut root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)); for y in 0..10 { root.draw_line( (0, 0), @@ -43,7 +43,7 @@ fn fill_background(c: &mut Criterion) { c.bench_function("rasterizer::fill_background", |b| { b.iter(|| { - let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area(); + let root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)).into_drawing_area(); root.fill(&WHITE).unwrap(); }) }); @@ -54,7 +54,7 @@ fn fill_circle(c: &mut Criterion) { c.bench_function("rasterizer::fill_circle", |b| { b.iter(|| { - let mut root = BitMapBackend::with_buffer(&mut buffer, (W, H)); + let mut root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)); root.draw_circle((W as i32 / 2, H as i32 / 2), W / 2, &WHITE.to_rgba(), true) .unwrap(); }) @@ -66,7 +66,7 @@ fn fill_background_red(c: &mut Criterion) { c.bench_function("rasterizer::fill_background_red", |b| { b.iter(|| { - let root = BitMapBackend::with_buffer(&mut buffer, (W, H)).into_drawing_area(); + let root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)).into_drawing_area(); root.fill(&RED).unwrap(); }) }); @@ -87,7 +87,7 @@ fn fill_hexagon(c: &mut Criterion) { c.bench_function("rasterizer::fill_hexagon", |b| { b.iter(|| { - let mut root = BitMapBackend::with_buffer(&mut buffer, (W, H)); + let mut root = BitMapBackend::>::with_buffer(&mut buffer, (W, H)); root.fill_polygon(vert.clone(), &RED).unwrap(); }) }); diff --git a/src/drawing/backend_impl/bitmap.rs b/src/drawing/backend_impl/bitmap.rs index 6a883c9e..52d9289f 100644 --- a/src/drawing/backend_impl/bitmap.rs +++ b/src/drawing/backend_impl/bitmap.rs @@ -4,9 +4,9 @@ use std::marker::PhantomData; #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] mod image_encoding_support { - pub(super) use image::{ImageBuffer, ImageError, Rgb}; + pub(super) use image::{ImageBuffer, ImageError, Pixel}; pub(super) use std::path::Path; - pub(super) type BorrowedImage<'a> = ImageBuffer, &'a mut [u8]>; + pub(super) type BorrowedImage<'a, P> = ImageBuffer; } #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] @@ -111,7 +111,8 @@ impl<'a> Buffer<'a> { } /// The backend that drawing a bitmap -pub struct BitMapBackend<'a> { +pub struct BitMapBackend<'a, P: 'static + Pixel> { + _pix: PhantomData

, /// The path to the image #[allow(dead_code)] target: Target<'a>, @@ -123,11 +124,12 @@ pub struct BitMapBackend<'a> { saved: bool, } -impl<'a> BitMapBackend<'a> { +impl<'a, P: 'static + Pixel> BitMapBackend<'a, P> { /// Create a new bitmap backend #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] pub fn new + ?Sized>(path: &'a T, (w, h): (u32, u32)) -> Self { Self { + _pix: PhantomData, target: Target::File(path.as_ref()), size: (w, h), buffer: Buffer::Owned(vec![0; (3 * w * h) as usize]), @@ -151,6 +153,7 @@ impl<'a> BitMapBackend<'a> { frame_delay: u32, ) -> Result { Ok(Self { + _pix: PhantomData, target: Target::Gif(Box::new(gif_support::GifFile::new( path, (w, h), @@ -170,7 +173,7 @@ impl<'a> BitMapBackend<'a> { /// - `buf`: The buffer to operate /// - `dimension`: The size of the image in pixels pub fn with_buffer(buf: &'a mut [u8], (w, h): (u32, u32)) -> Self { - if (w * h * 3) as usize > buf.len() { + if (w * h * P::CHANNEL_COUNT as u32) as usize > buf.len() { // TODO: This doesn't deserve a panic. panic!( "Wrong image size: H = {}, W = {}, BufSize = {}", @@ -181,6 +184,7 @@ impl<'a> BitMapBackend<'a> { } Self { + _pix: PhantomData, target: Target::Buffer(PhantomData), size: (w, h), buffer: Buffer::Borrowed(buf), @@ -194,7 +198,7 @@ impl<'a> BitMapBackend<'a> { /// Split a bitmap backend vertically into several sub drawing area which allows /// multi-threading rendering. - pub fn split(&mut self, area_size: &[u32]) -> Vec { + pub fn split(&mut self, area_size: &[u32]) -> Vec> { let (w, h) = self.get_size(); let buf = self.get_raw_pixel_buffer(); @@ -358,7 +362,7 @@ impl<'a> BitMapBackend<'a> { } } -impl<'a> DrawingBackend for BitMapBackend<'a> { +impl<'a, P: 'static + Pixel> DrawingBackend for BitMapBackend<'a, P> { type ErrorType = BitMapBackendError; fn get_size(&self) -> (u32, u32) { @@ -380,7 +384,7 @@ impl<'a> DrawingBackend for BitMapBackend<'a> { let (w, h) = self.get_size(); match &mut self.target { Target::File(path) => { - if let Some(img) = BorrowedImage::from_raw(w, h, self.buffer.borrow_buffer()) { + if let Some(img) = BorrowedImage::

::from_raw(w, h, self.buffer.borrow_buffer()) { img.save(&path).map_err(|x| { DrawingErrorKind::DrawingError(BitMapBackendError::IOError(x)) })?; @@ -552,7 +556,7 @@ impl<'a> DrawingBackend for BitMapBackend<'a> { } } -impl Drop for BitMapBackend<'_> { +impl> Drop for BitMapBackend<'_, P> { fn drop(&mut self) { if !self.saved { self.present().expect("Unable to save the bitmap"); @@ -567,7 +571,7 @@ fn test_bitmap_backend() { let mut buffer = vec![0; 10 * 10 * 3]; { - let back = BitMapBackend::with_buffer(&mut buffer, (10, 10)); + let back = BitMapBackend::>::with_buffer(&mut buffer, (10, 10)); let area = back.into_drawing_area(); area.fill(&WHITE).unwrap(); @@ -595,7 +599,7 @@ fn test_bitmap_backend_fill_half() { let mut buffer = vec![0; 10 * 10 * 3]; { - let back = BitMapBackend::with_buffer(&mut buffer, (10, 10)); + let back = BitMapBackend::>::with_buffer(&mut buffer, (10, 10)); let area = back.into_drawing_area(); area.draw(&Rectangle::new([(0, 0), (5, 10)], RED.filled())) @@ -616,7 +620,7 @@ fn test_bitmap_backend_fill_half() { let mut buffer = vec![0; 10 * 10 * 3]; { - let back = BitMapBackend::with_buffer(&mut buffer, (10, 10)); + let back = BitMapBackend::>::with_buffer(&mut buffer, (10, 10)); let area = back.into_drawing_area(); area.draw(&Rectangle::new([(0, 0), (10, 5)], RED.filled())) @@ -642,7 +646,7 @@ fn test_bitmap_backend_blend() { let mut buffer = vec![255; 10 * 10 * 3]; { - let back = BitMapBackend::with_buffer(&mut buffer, (10, 10)); + let back = BitMapBackend::>::with_buffer(&mut buffer, (10, 10)); let area = back.into_drawing_area(); area.draw(&Rectangle::new( @@ -674,7 +678,7 @@ fn test_bitmap_backend_split_and_fill() { let mut buffer = vec![255; 10 * 10 * 3]; { - let mut back = BitMapBackend::with_buffer(&mut buffer, (10, 10)); + let mut back = BitMapBackend::>::with_buffer(&mut buffer, (10, 10)); for (sub_backend, color) in back.split(&[5]).into_iter().zip([&RED, &GREEN].iter()) { sub_backend.into_drawing_area().fill(*color).unwrap(); @@ -698,7 +702,7 @@ fn test_draw_rect_out_of_range() { let mut buffer = vec![0; 1099 * 1000 * 3]; { - let mut back = BitMapBackend::with_buffer(&mut buffer, (1000, 1000)); + let mut back = BitMapBackend::>::with_buffer(&mut buffer, (1000, 1000)); back.draw_line((1100, 0), (1100, 999), &RED.to_rgba()) .unwrap(); @@ -724,7 +728,7 @@ fn test_draw_line_out_of_range() { let mut buffer = vec![0; 1000 * 1000 * 3]; { - let mut back = BitMapBackend::with_buffer(&mut buffer, (1000, 1000)); + let mut back = BitMapBackend::>::with_buffer(&mut buffer, (1000, 1000)); back.draw_line((-1000, -1000), (2000, 2000), &WHITE.to_rgba()) .unwrap(); diff --git a/src/element/image.rs b/src/element/image.rs index a867cfc5..3a7d9e47 100644 --- a/src/element/image.rs +++ b/src/element/image.rs @@ -48,8 +48,8 @@ impl<'a, Coord> BitMapElement<'a, Coord> { /// Make the bitmap element as a bitmap backend, so that we can use /// plotters drawing functionality on the bitmap element - pub fn as_bitmap_backend(&mut self) -> BitMapBackend { - BitMapBackend::with_buffer(self.image.to_mut(), self.size) + pub fn as_bitmap_backend>(&mut self) -> BitMapBackend

{ + BitMapBackend::

::with_buffer(self.image.to_mut(), self.size) } } From 673a23d62c09c076ea858086096655cbd1cbf923 Mon Sep 17 00:00:00 2001 From: ricky han Date: Wed, 30 Oct 2019 11:47:47 -0400 Subject: [PATCH 2/3] fix tests --- README.md | 46 ++++++++++---------- doc-template/examples/chart.rs | 2 +- doc-template/examples/composable_elements.rs | 2 +- doc-template/examples/drawing_area.rs | 2 +- doc-template/examples/drawing_backends.rs | 2 +- doc-template/examples/elements.rs | 2 +- doc-template/examples/quick_start.rs | 2 +- examples/animation.rs | 2 +- examples/area-chart.rs | 2 +- examples/blit-bitmap.rs | 2 +- examples/chart.rs | 2 +- examples/console.rs | 2 +- examples/errorbar.rs | 2 +- examples/histogram.rs | 2 +- examples/mandelbrot.rs | 2 +- examples/matshow.rs | 2 +- examples/normal-dist.rs | 2 +- examples/normal-dist2.rs | 2 +- examples/relative_size.rs | 2 +- examples/sierpinski.rs | 4 +- examples/slc-temp.rs | 2 +- examples/snowflake.rs | 2 +- examples/stock.rs | 2 +- examples/two-scales.rs | 2 +- src/element/mod.rs | 6 +-- src/lib.rs | 12 ++--- 26 files changed, 56 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 6f6df1d8..908fa5a0 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ -Plotters is drawing library designed for rendering figures, plots, and charts, in pure rust. Plotters supports various types of back-ends, -including bitmap, vector graph, piston window, GTK/Cairo and WebAssembly. +Plotters is drawing library designed for rendering figures, plots, and charts, in pure rust. Plotters supports various types of back-ends, +including bitmap, vector graph, piston window, GTK/Cairo and WebAssembly. - A new Plotters Developer's Guide is working in progress. The preview version is available at [here](https://plotters-rs.github.io/book). - To try Plotters with interactive Jupyter notebook, or view [here](https://plotters-rs.github.io/plotters-doc-data/evcxr-jupyter-integration.html) for the static HTML version. @@ -147,7 +147,7 @@ And the following code draws a quadratic function. `src/main.rs`, ```rust use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) .caption("y=x^2", ("sans-serif", 50).into_font()) @@ -225,7 +225,7 @@ figure *This tutorial is now working in progress and isn't complete* Thanks to the evcxr, now we have an interactive tutorial for Plotters! -To use the interactive notebook, you must have Jupyter and evcxr installed on your computer. +To use the interactive notebook, you must have Jupyter and evcxr installed on your computer. Follow the instruction on [this page](https://github.com/google/evcxr/tree/master/evcxr_jupyter) below to install it. After that, you should be able to start your Jupyter server locally and load the tutorial! @@ -249,23 +249,23 @@ But Rust is one of the best languages fits the need. Plotting in Rust can be as easy as most of the high-level programming languages. The Rust based plotting library can be very easy to use. -* **Fast** If you need rendering a figure with trillions of data points, -Rust is a good choice. Rust's performance allows you to combine data processing step +* **Fast** If you need rendering a figure with trillions of data points, +Rust is a good choice. Rust's performance allows you to combine data processing step and rendering step into a single application. When plotting in high-level programming languages, -e.g. Javascript or Python, data points must be down-sampled before feeding into the plotting -program because of the performance considerations. Rust is fast enough to do the data processing and visualization -within a single program. You can also integrate the +e.g. Javascript or Python, data points must be down-sampled before feeding into the plotting +program because of the performance considerations. Rust is fast enough to do the data processing and visualization +within a single program. You can also integrate the figure rendering code into your application handling a huge amount of data and visualize it in real-time. -* **WebAssembly Support** Rust is one of few the language with the best WASM support. Plotting in Rust could be +* **WebAssembly Support** Rust is one of few the language with the best WASM support. Plotting in Rust could be very useful for visualization on a web page and would have a huge performance improvement comparing to Javascript. ## Plotting on HTML5 canvas with WASM Backend -Plotters currently supports backend that uses the HTML5 canvas. To use the WASM support, you can simply use +Plotters currently supports backend that uses the HTML5 canvas. To use the WASM support, you can simply use `CanvasBackend` instead of other backend and all other API remains the same! -There's a small demo for Plotters + WASM under `examples/wasm-demo` directory of this repo. +There's a small demo for Plotters + WASM under `examples/wasm-demo` directory of this repo. To play with the deployed version, follow this [link](https://plumberserver.com/plotters-wasm-demo/index.html). @@ -288,7 +288,7 @@ Plotters can use different drawing back-ends, including SVG, BitMap, and even re use plotters::prelude::*; fn main() -> Result<(), Box> { // Create a 800*600 bitmap and start drawing - let mut backend = BitMapBackend::new("plotters-doc-data/1.png", (300, 200)); + let mut backend = BitMapBackend::>::new("plotters-doc-data/1.png", (300, 200)); // And if we want SVG backend // let backend = SVGBackend::new("output.svg", (800, 600)); backend.draw_rect((50, 50), (200, 150), &RED, true)?; @@ -309,7 +309,7 @@ Besides that, the drawing area also allows the customized coordinate system, by use plotters::prelude::*; fn main() -> Result<(), Box> { let root_drawing_area = - BitMapBackend::new("plotters-doc-data/2.png", (300, 200)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/2.png", (300, 200)).into_drawing_area(); // And we can split the drawing area into 3x3 grid let child_drawing_areas = root_drawing_area.split_evenly((3, 3)); // Then we fill the drawing area with different color @@ -335,7 +335,7 @@ To learn more about the element system, please read the [element module document ```rust use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area(); root.fill(&WHITE)?; // Draw an circle on the drawing area root.draw(&Circle::new( @@ -352,7 +352,7 @@ fn main() -> Result<(), Box> { ### Composable Elements Besides the built-in elements, elements can be composed into a logic group we called composed elements. -When composing new elements, the upper-left corner is given in the target coordinate, and a new pixel-based +When composing new elements, the upper-left corner is given in the target coordinate, and a new pixel-based coordinate which has the upper-left corner defined as `(0,0)` is used for further element composition purpose. For example, we can have an element which includes a dot and its coordinate. @@ -361,7 +361,7 @@ For example, we can have an element which includes a dot and its coordinate. use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/4.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/4.png", (640, 480)).into_drawing_area(); root.fill(&RGBColor(240, 200, 200))?; @@ -400,7 +400,7 @@ of the chart context object. ```rust use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area(); root.fill(&WHITE); let root = root.margin(10, 10, 10, 10); // After this point, we should be able to draw construct a chart context @@ -475,7 +475,7 @@ This behavior can also be turned off by setting `default_features = false`. ### List of Features -This is the full list of features that is defined by `Plotters` crate. Use `default_features = false` to disable those default enabled features, and then you should be able to cherry-pick what features you want to include into `Plotters` crate. +This is the full list of features that is defined by `Plotters` crate. Use `default_features = false` to disable those default enabled features, and then you should be able to cherry-pick what features you want to include into `Plotters` crate. | Name | Description | Additional Dependency |Default?| |---------|--------------|--------|------------| @@ -495,12 +495,12 @@ This is the full list of features that is defined by `Plotters` crate. Use `defa The WASM example requires using `wasm32` target to build. Using `cargo build` is likely to use the default target which in most of the case is any of the x86 target. Thus you need add `--target=wasm32-unknown-unknown` in the cargo - parameter list to build it. + parameter list to build it. * How to draw text/circle/point/rectangle/... on the top of chart ? - - As you may realized, Plotters is a drawing library rather than a traditional data plotting library, + + As you may realized, Plotters is a drawing library rather than a traditional data plotting library, you have the freedom to draw anything you want on the drawing area. - Use `DrawingArea::draw` to draw any element on the drawing area. + Use `DrawingArea::draw` to draw any element on the drawing area. diff --git a/doc-template/examples/chart.rs b/doc-template/examples/chart.rs index 76d6b51c..438087b5 100644 --- a/doc-template/examples/chart.rs +++ b/doc-template/examples/chart.rs @@ -1,6 +1,6 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area(); root.fill(&WHITE); let root = root.margin(10, 10, 10, 10); // After this point, we should be able to draw construct a chart context diff --git a/doc-template/examples/composable_elements.rs b/doc-template/examples/composable_elements.rs index 163ca841..c554ad42 100644 --- a/doc-template/examples/composable_elements.rs +++ b/doc-template/examples/composable_elements.rs @@ -1,7 +1,7 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/4.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/4.png", (640, 480)).into_drawing_area(); root.fill(&RGBColor(240, 200, 200))?; diff --git a/doc-template/examples/drawing_area.rs b/doc-template/examples/drawing_area.rs index 68588f0b..61fe8aa6 100644 --- a/doc-template/examples/drawing_area.rs +++ b/doc-template/examples/drawing_area.rs @@ -1,7 +1,7 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { let root_drawing_area = - BitMapBackend::new("plotters-doc-data/2.png", (300, 200)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/2.png", (300, 200)).into_drawing_area(); // And we can split the drawing area into 3x3 grid let child_drawing_areas = root_drawing_area.split_evenly((3, 3)); // Then we fill the drawing area with different color diff --git a/doc-template/examples/drawing_backends.rs b/doc-template/examples/drawing_backends.rs index 7561e6e6..5cf57abf 100644 --- a/doc-template/examples/drawing_backends.rs +++ b/doc-template/examples/drawing_backends.rs @@ -1,7 +1,7 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { // Create a 800*600 bitmap and start drawing - let mut backend = BitMapBackend::new("plotters-doc-data/1.png", (300, 200)); + let mut backend = BitMapBackend::>::new("plotters-doc-data/1.png", (300, 200)); // And if we want SVG backend // let backend = SVGBackend::new("output.svg", (800, 600)); backend.draw_rect((50, 50), (200, 150), &RED, true)?; diff --git a/doc-template/examples/elements.rs b/doc-template/examples/elements.rs index 4f162227..a18e8862 100644 --- a/doc-template/examples/elements.rs +++ b/doc-template/examples/elements.rs @@ -1,6 +1,6 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area(); root.fill(&WHITE)?; // Draw an circle on the drawing area root.draw(&Circle::new( diff --git a/doc-template/examples/quick_start.rs b/doc-template/examples/quick_start.rs index cba9271a..3e0e851c 100644 --- a/doc-template/examples/quick_start.rs +++ b/doc-template/examples/quick_start.rs @@ -1,6 +1,6 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) .caption("y=x^2", ("sans-serif", 50).into_font()) diff --git a/examples/animation.rs b/examples/animation.rs index dd295af4..88d37ff5 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -18,7 +18,7 @@ fn snowflake_iter(points: &[(f64, f64)]) -> Vec<(f64, f64)> { } fn main() -> Result<(), Box> { - let root = BitMapBackend::gif("plotters-doc-data/animation.gif", (800, 600), 1_000)? + let root = BitMapBackend::>::gif("plotters-doc-data/animation.gif", (800, 600), 1_000)? .into_drawing_area(); for i in 0..8 { diff --git a/examples/area-chart.rs b/examples/area-chart.rs index 4c74ffa2..10e96668 100644 --- a/examples/area-chart.rs +++ b/examples/area-chart.rs @@ -17,7 +17,7 @@ fn main() -> Result<(), Box> { }; let root = - BitMapBackend::new("plotters-doc-data/area-chart.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/area-chart.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/blit-bitmap.rs b/examples/blit-bitmap.rs index 294d98ee..5227ba2f 100644 --- a/examples/blit-bitmap.rs +++ b/examples/blit-bitmap.rs @@ -7,7 +7,7 @@ use std::io::BufReader; fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/blit-bitmap.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/blit-bitmap.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) diff --git a/examples/chart.rs b/examples/chart.rs index 2c5bbb57..c564e1be 100644 --- a/examples/chart.rs +++ b/examples/chart.rs @@ -2,7 +2,7 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { let root_area = - BitMapBackend::new("plotters-doc-data/sample.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/sample.png", (1024, 768)).into_drawing_area(); root_area.fill(&WHITE)?; diff --git a/examples/console.rs b/examples/console.rs index 75f2a6b0..44f72c2e 100644 --- a/examples/console.rs +++ b/examples/console.rs @@ -175,7 +175,7 @@ where fn main() -> Result<(), Box> { draw_chart(TextDrawingBackend(vec![PixelState::Empty; 5000]).into_drawing_area())?; - let b = BitMapBackend::new("plotters-doc-data/console-example.png", (1024, 768)) + let b = BitMapBackend::>::new("plotters-doc-data/console-example.png", (1024, 768)) .into_drawing_area(); b.fill(&WHITE)?; draw_chart(b)?; diff --git a/examples/errorbar.rs b/examples/errorbar.rs index 52dd9342..24e38110 100644 --- a/examples/errorbar.rs +++ b/examples/errorbar.rs @@ -12,7 +12,7 @@ fn main() -> Result<(), Box> { let down_sampled = down_sample(&data[..]); let root = - BitMapBackend::new("plotters-doc-data/errorbar.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/errorbar.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/histogram.rs b/examples/histogram.rs index c33363f8..ec7ecfcc 100644 --- a/examples/histogram.rs +++ b/examples/histogram.rs @@ -1,7 +1,7 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/histogram.png", (640, 480)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/histogram.png", (640, 480)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/mandelbrot.rs b/examples/mandelbrot.rs index 81fa6882..f427b477 100644 --- a/examples/mandelbrot.rs +++ b/examples/mandelbrot.rs @@ -3,7 +3,7 @@ use std::ops::Range; fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/mandelbrot.png", (800, 600)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/mandelbrot.png", (800, 600)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/matshow.rs b/examples/matshow.rs index 186fcba5..60637a00 100644 --- a/examples/matshow.rs +++ b/examples/matshow.rs @@ -1,7 +1,7 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/matshow.png", (1024, 768)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/matshow.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/normal-dist.rs b/examples/normal-dist.rs index 6277c33c..454ded65 100644 --- a/examples/normal-dist.rs +++ b/examples/normal-dist.rs @@ -5,7 +5,7 @@ use rand_distr::{Distribution, Normal}; fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/normal-dist.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/normal-dist.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/normal-dist2.rs b/examples/normal-dist2.rs index e4128902..2897a7fe 100644 --- a/examples/normal-dist2.rs +++ b/examples/normal-dist2.rs @@ -16,7 +16,7 @@ fn main() -> Result<(), Box> { }; let root = - BitMapBackend::new("plotters-doc-data/normal-dist2.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/normal-dist2.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/relative_size.rs b/examples/relative_size.rs index a915d8ab..b811c2bc 100644 --- a/examples/relative_size.rs +++ b/examples/relative_size.rs @@ -30,7 +30,7 @@ fn draw_chart(root: &DrawingArea) -> DrawResult<(), fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/relative_size.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/relative_size.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/sierpinski.rs b/examples/sierpinski.rs index 9e685897..a9d19b74 100644 --- a/examples/sierpinski.rs +++ b/examples/sierpinski.rs @@ -3,7 +3,7 @@ use plotters::prelude::*; pub fn sierpinski_carpet( depth: u32, - drawing_area: &DrawingArea, + drawing_area: &DrawingArea>, Shift>, ) -> Result<(), Box> { if depth > 0 { let sub_areas = drawing_area.split_evenly((3, 3)); @@ -21,7 +21,7 @@ pub fn sierpinski_carpet( fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/sierpinski.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/sierpinski.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/slc-temp.rs b/examples/slc-temp.rs index 7a1b509b..93eb4457 100644 --- a/examples/slc-temp.rs +++ b/examples/slc-temp.rs @@ -7,7 +7,7 @@ use std::error::Error; fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/slc-temp.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/slc-temp.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/snowflake.rs b/examples/snowflake.rs index 08e1c7ee..ba69b244 100644 --- a/examples/snowflake.rs +++ b/examples/snowflake.rs @@ -19,7 +19,7 @@ fn snowflake_iter(points: &[(f64, f64)]) -> Vec<(f64, f64)> { fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/snowflake.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/snowflake.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; diff --git a/examples/stock.rs b/examples/stock.rs index 5c5c2b52..c0654d92 100644 --- a/examples/stock.rs +++ b/examples/stock.rs @@ -9,7 +9,7 @@ fn parse_time(t: &str) -> Date { } fn main() -> Result<(), Box> { let data = get_data(); - let root = BitMapBackend::new("plotters-doc-data/stock.png", (1024, 768)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/stock.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; let (to_date, from_date) = ( diff --git a/examples/two-scales.rs b/examples/two-scales.rs index 55cb1cc6..124ecf30 100644 --- a/examples/two-scales.rs +++ b/examples/two-scales.rs @@ -2,7 +2,7 @@ use plotters::prelude::*; fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/twoscale.png", (1024, 768)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/twoscale.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) diff --git a/src/element/mod.rs b/src/element/mod.rs index 17defaec..6111912f 100644 --- a/src/element/mod.rs +++ b/src/element/mod.rs @@ -51,7 +51,7 @@ } fn main() -> Result<(), Box> { - let root = BitMapBackend::new( + let root = BitMapBackend::>::new( "plotters-doc-data/element-0.png", (640, 480) ).into_drawing_area(); @@ -72,7 +72,7 @@ ```rust use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new( + let root = BitMapBackend::>::new( "plotters-doc-data/element-1.png", (640, 480) ).into_drawing_area(); @@ -120,7 +120,7 @@ } fn main() -> Result<(), Box> { let root = - BitMapBackend::new("plotters-doc-data/element-3.png", (640, 480)) + BitMapBackend::>::new("plotters-doc-data/element-3.png", (640, 480)) .into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) diff --git a/src/lib.rs b/src/lib.rs index 45b0b7af..14021be8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -262,7 +262,7 @@ And the following code draws a quadratic function. `src/main.rs`, ```rust use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area(); root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) .caption("y=x^2", ("sans-serif", 50).into_font()) @@ -403,7 +403,7 @@ Plotters can use different drawing back-ends, including SVG, BitMap, and even re use plotters::prelude::*; fn main() -> Result<(), Box> { // Create a 800*600 bitmap and start drawing - let mut backend = BitMapBackend::new("plotters-doc-data/1.png", (300, 200)); + let mut backend = BitMapBackend::>::new("plotters-doc-data/1.png", (300, 200)); // And if we want SVG backend // let backend = SVGBackend::new("output.svg", (800, 600)); backend.draw_rect((50, 50), (200, 150), &RED, true)?; @@ -424,7 +424,7 @@ Besides that, the drawing area also allows the customized coordinate system, by use plotters::prelude::*; fn main() -> Result<(), Box> { let root_drawing_area = - BitMapBackend::new("plotters-doc-data/2.png", (300, 200)).into_drawing_area(); + BitMapBackend::>::new("plotters-doc-data/2.png", (300, 200)).into_drawing_area(); // And we can split the drawing area into 3x3 grid let child_drawing_areas = root_drawing_area.split_evenly((3, 3)); // Then we fill the drawing area with different color @@ -450,7 +450,7 @@ To learn more about the element system, please read the [element module document ```rust use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area(); root.fill(&WHITE)?; // Draw an circle on the drawing area root.draw(&Circle::new( @@ -476,7 +476,7 @@ For example, we can have an element which includes a dot and its coordinate. use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/4.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/4.png", (640, 480)).into_drawing_area(); root.fill(&RGBColor(240, 200, 200))?; @@ -515,7 +515,7 @@ of the chart context object. ```rust use plotters::prelude::*; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area(); + let root = BitMapBackend::>::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area(); root.fill(&WHITE); let root = root.margin(10, 10, 10, 10); // After this point, we should be able to draw construct a chart context From 6448935c99df4da17fa7cc90280d596507bee989 Mon Sep 17 00:00:00 2001 From: ricky han Date: Wed, 30 Oct 2019 12:27:11 -0400 Subject: [PATCH 3/3] fix target_arch="wasm32" --- src/drawing/backend_impl/bitmap.rs | 44 ++++++++++++++++++++++++++---- src/element/image.rs | 7 ++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/drawing/backend_impl/bitmap.rs b/src/drawing/backend_impl/bitmap.rs index 52d9289f..09e98f15 100644 --- a/src/drawing/backend_impl/bitmap.rs +++ b/src/drawing/backend_impl/bitmap.rs @@ -111,7 +111,13 @@ impl<'a> Buffer<'a> { } /// The backend that drawing a bitmap -pub struct BitMapBackend<'a, P: 'static + Pixel> { +pub struct BitMapBackend< + 'a, + #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] + P: 'static + Pixel, + #[cfg(target_arch = "wasm32")] + P: 'static +> { _pix: PhantomData

, /// The path to the image #[allow(dead_code)] @@ -124,7 +130,13 @@ pub struct BitMapBackend<'a, P: 'static + Pixel> { saved: bool, } -impl<'a, P: 'static + Pixel> BitMapBackend<'a, P> { +impl< + 'a, + #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] + P: 'static + Pixel, + #[cfg(target_arch = "wasm32")] + P: 'static +> BitMapBackend<'a, P> { /// Create a new bitmap backend #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] pub fn new + ?Sized>(path: &'a T, (w, h): (u32, u32)) -> Self { @@ -165,6 +177,16 @@ impl<'a, P: 'static + Pixel> BitMapBackend<'a, P> { }) } + #[cfg(target_arch = "wasm32")] + fn get_channel() -> u32 { + 3 + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] + fn get_channel() -> u32 { + P::CHANNEL_COUNT as u32 + } + /// Create a new bitmap backend which only lives in-memory /// /// When this is used, the bitmap backend will write to a user provided [u8] array (or Vec). @@ -173,7 +195,8 @@ impl<'a, P: 'static + Pixel> BitMapBackend<'a, P> { /// - `buf`: The buffer to operate /// - `dimension`: The size of the image in pixels pub fn with_buffer(buf: &'a mut [u8], (w, h): (u32, u32)) -> Self { - if (w * h * P::CHANNEL_COUNT as u32) as usize > buf.len() { + let c = BitMapBackend::

::get_channel(); + if (w * h * c) as usize > buf.len() { // TODO: This doesn't deserve a panic. panic!( "Wrong image size: H = {}, W = {}, BufSize = {}", @@ -362,7 +385,13 @@ impl<'a, P: 'static + Pixel> BitMapBackend<'a, P> { } } -impl<'a, P: 'static + Pixel> DrawingBackend for BitMapBackend<'a, P> { +impl< + 'a, + #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] + P: 'static + Pixel, + #[cfg(target_arch = "wasm32")] + P: 'static +> DrawingBackend for BitMapBackend<'a, P> { type ErrorType = BitMapBackendError; fn get_size(&self) -> (u32, u32) { @@ -556,7 +585,12 @@ impl<'a, P: 'static + Pixel> DrawingBackend for BitMapBackend<'a, P } } -impl> Drop for BitMapBackend<'_, P> { +impl< + #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] + P: 'static + Pixel, + #[cfg(target_arch = "wasm32")] + P: 'static +> Drop for BitMapBackend<'_, P> { fn drop(&mut self) { if !self.saved { self.present().expect("Unable to save the bitmap"); diff --git a/src/element/image.rs b/src/element/image.rs index 3a7d9e47..db8559c5 100644 --- a/src/element/image.rs +++ b/src/element/image.rs @@ -48,7 +48,12 @@ impl<'a, Coord> BitMapElement<'a, Coord> { /// Make the bitmap element as a bitmap backend, so that we can use /// plotters drawing functionality on the bitmap element - pub fn as_bitmap_backend>(&mut self) -> BitMapBackend

{ + pub fn as_bitmap_backend< + #[cfg(all(not(target_arch = "wasm32"), feature = "image"))] + P: 'static + image::Pixel, + #[cfg(target_arch = "wasm32")] + P: 'static + >(&mut self) -> BitMapBackend

{ BitMapBackend::

::with_buffer(self.image.to_mut(), self.size) } }