Cache image hashes.
@@ -15,6 +15,7 @@ use crate::util;
use pathfinder_color::{self as color, ColorU};
use pathfinder_geometry::transform2d::Transform2F;
use pathfinder_geometry::vector::Vector2I;
+use std::collections::hash_map::DefaultHasher;
use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
@@ -38,10 +39,11 @@ pub enum PatternSource {
/// RGBA, non-premultiplied.
// FIXME(pcwalton): Hash the pixel contents so that we don't have to compare every pixel!
// TODO(pcwalton): Should the pixels be premultiplied?
-#[derive(Clone, PartialEq, Eq, Hash)]
+#[derive(Clone, PartialEq, Eq)]
pub struct Image {
size: Vector2I,
pixels: Vec<ColorU>,
+ pixels_hash: u64,
is_opaque: bool,
}
@@ -65,7 +67,12 @@ impl Image {
pub fn new(size: Vector2I, pixels: Vec<ColorU>) -> Image {
assert_eq!(size.x() as usize * size.y() as usize, pixels.len());
let is_opaque = pixels.iter().all(|pixel| pixel.is_opaque());
- Image { size, pixels, is_opaque }
+
+ let mut pixels_hasher = DefaultHasher::new();
+ pixels.hash(&mut pixels_hasher);
+ let pixels_hash = pixels_hasher.finish();
+
+ Image { size, pixels, pixels_hash, is_opaque }
}
#[cfg(feature = "pf-image")]
@@ -111,6 +118,14 @@ impl Debug for Image {
}
}
+impl Hash for Image {
+ fn hash<H>(&self, hasher: &mut H) where H: Hasher {
+ self.size.hash(hasher);
+ self.pixels_hash.hash(hasher);
+ self.is_opaque.hash(hasher);
+ }
+}
+
impl Eq for Pattern {}
impl Hash for Pattern {
