Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions sparse_strips/vello_common/src/filter/color_matrix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2026 the Vello Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! The color matrix filter.

/// Matrix-based color transformation filter.
///
/// The matrix is stored as four rows of five values. Each row computes one output
/// channel (`R`, `G`, `B`, `A`) from the four input channels plus a constant offset.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ColorMatrix {
/// The 4x5 color transformation matrix in row-major order.
pub matrix: [f32; 20],
}

impl ColorMatrix {
/// Create a new color matrix filter.
pub fn new(matrix: [f32; 20]) -> Self {
Self { matrix }
}
}
27 changes: 26 additions & 1 deletion sparse_strips/vello_common/src/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
//! represent a special representation of each filter to be used as the basis for rendering in
//! `vello_hybrid` and `vello_cpu`.

use crate::filter::color_matrix::ColorMatrix;
use crate::filter::drop_shadow::{DropShadow, transform_shadow_params};
use crate::filter::flood::Flood;
use crate::filter::gaussian_blur::{GaussianBlur, transform_blur_params};
use crate::filter::offset::Offset;
use crate::filter_effects::{Filter, FilterPrimitive};
use crate::kurbo::{Affine, Vec2};

pub mod color_matrix;
pub mod drop_shadow;
pub mod flood;
pub mod gaussian_blur;
Expand All @@ -30,6 +32,8 @@ pub enum PreparedFilter {
Offset(Offset),
/// A drop shadow filter.
DropShadow(DropShadow),
/// A color matrix filter.
ColorMatrix(ColorMatrix),
}

impl PreparedFilter {
Expand Down Expand Up @@ -73,8 +77,9 @@ impl PreparedFilter {

Self::Offset(offset)
}
FilterPrimitive::ColorMatrix { matrix } => Self::ColorMatrix(ColorMatrix::new(*matrix)),
_ => {
// Other primitives like Blend, ColorMatrix, ComponentTransfer, etc.
// Other primitives like Blend, ComponentTransfer, etc.
// are not yet implemented
unimplemented!("Other filter primitives not yet implemented");
}
Expand All @@ -92,3 +97,23 @@ fn transform_offset_params(dx: f32, dy: f32, transform: &Affine) -> (f32, f32) {
let transformed_offset = Vec2::new(a * offset.x + c * offset.y, b * offset.x + d * offset.y);
(transformed_offset.x as f32, transformed_offset.y as f32)
}

#[cfg(test)]
mod tests {
use super::*;
use crate::filter_effects::matrices;

#[test]
fn prepares_color_matrix_filter() {
let filter = Filter::from_primitive(FilterPrimitive::ColorMatrix {
matrix: matrices::SEPIA,
});
let prepared = PreparedFilter::new(&filter, &Affine::IDENTITY);

let PreparedFilter::ColorMatrix(color_matrix) = prepared else {
panic!("expected color matrix filter");
};

assert_eq!(color_matrix.matrix, matrices::SEPIA);
}
}
Loading
Loading