, &'a mut [u8]>;
+ pub(super) type BorrowedImage<'a, P> = ImageBuffer;
}
#[cfg(all(not(target_arch = "wasm32"), feature = "image"))]
@@ -111,7 +111,14 @@ impl<'a> Buffer<'a> {
}
/// The backend that drawing a bitmap
-pub struct BitMapBackend<'a> {
+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)]
target: Target<'a>,
@@ -123,11 +130,18 @@ pub struct BitMapBackend<'a> {
saved: bool,
}
-impl<'a> BitMapBackend<'a> {
+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 {
Self {
+ _pix: PhantomData,
target: Target::File(path.as_ref()),
size: (w, h),
buffer: Buffer::Owned(vec![0; (3 * w * h) as usize]),
@@ -151,6 +165,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),
@@ -162,6 +177,16 @@ impl<'a> BitMapBackend<'a> {
})
}
+ #[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).
@@ -170,7 +195,8 @@ 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() {
+ 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 = {}",
@@ -181,6 +207,7 @@ impl<'a> BitMapBackend<'a> {
}
Self {
+ _pix: PhantomData,
target: Target::Buffer(PhantomData),
size: (w, h),
buffer: Buffer::Borrowed(buf),
@@ -194,7 +221,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 +385,13 @@ impl<'a> BitMapBackend<'a> {
}
}
-impl<'a> DrawingBackend for BitMapBackend<'a> {
+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) {
@@ -380,7 +413,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 +585,12 @@ impl<'a> DrawingBackend for BitMapBackend<'a> {
}
}
-impl Drop for BitMapBackend<'_> {
+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");
@@ -567,7 +605,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 +633,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 +654,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 +680,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 +712,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 +736,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 +762,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..db8559c5 100644
--- a/src/element/image.rs
+++ b/src/element/image.rs
@@ -48,8 +48,13 @@ 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<
+ #[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)
}
}
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