diff --git a/content/src/pattern.rs b/content/src/pattern.rs index a444e8aa..0801acba 100644 --- a/content/src/pattern.rs +++ b/content/src/pattern.rs @@ -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, + pixels_hash: u64, is_opaque: bool, } @@ -65,7 +67,12 @@ impl Image { pub fn new(size: Vector2I, pixels: Vec) -> 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(&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 {