源码
//color/gradient_source.rs
use super::spread::*;
use super::super::matrix::generic::*;
use super::super::matrix::point::*;
pub struct GradientSource {
matrix: Matrix2D<Fixed>,
lut: [u32; 256],
}
impl GradientSource {
// 泛型化的 radial_gradient_eval
pub fn radial_gradient_eval<S: Spread>(&self, x: u16, y: u16) -> u32 {
let p = Point(x as i32,y as i32)*self.matrix;
let px = p.x as f32;
let py = p.y as f32;
let mut distance = (px * px + py * py).sqrt() as i32;
distance >>= 8;
self.lut[S::apply(distance) as usize]
}
// 泛型化的 linear_gradient_eval
pub fn linear_gradient_eval<S: SpreadBehavior>(&self, x: u16, y: u16) -> u32 {
let p = Point(x,y)*self.matrix;
let lx = p.x >> 8;
self.lut[S::apply(lx) as usize]
}
}
代码分析
这段代码定义了一个GradientSource结构体,用于处理渐变效果的计算。它提供了径向渐变和线性渐变的评估方法。
结构体定义
pub struct GradientSource {
matrix: Matrix2D<Fixed>, // 2D变换矩阵
lut: [u32; 256], // 256个元素的查找表(LUT)
}
matrix: 一个2D变换矩阵,用于坐标变换
lut: 一个包含256个u32值的查找表,存储颜色或渐变值
方法实现
- 径向渐变评估 (radial_gradient_eval)
pub fn radial_gradient_eval<S: Spread>(&self, x: u16, y: u16) -> u32 {
let p = Point(x as i32,y as i32)*self.matrix; // 应用变换矩阵
let px = p.x as f32;
let py = p.y as f32;
let mut distance = (px * px + py * py).sqrt() as i32; // 计算到原点的距离
distance >>= 8; // 右移8位,相当于除以256
self.lut[S::apply(distance) as usize] // 使用Spread特性处理距离并查找颜色
}
这个方法:
将输入坐标(x,y)转换为i32并应用变换矩阵
计算变换后点到原点的欧几里得距离
将距离值右移8位(相当于除以256)
使用Spread特性处理距离值
从查找表中返回对应的颜色值
线性渐变评估 (linear_gradient_eval)
pub fn linear_gradient_eval<S: SpreadBehavior>(&self, x: u16, y: u16) -> u32 {
let p = Point(x,y)*self.matrix; // 应用变换矩阵
let lx = p.x >> 8; // 只使用x坐标,右移8位
self.lut[S::apply(lx) as usize] // 使用SpreadBehavior特性处理x值并查找颜色
}
这个方法:
将输入坐标(x,y)应用变换矩阵
只使用变换后的x坐标,并右移8位
使用SpreadBehavior特性处理x值
从查找表中返回对应的颜色值
特性约束
radial_gradient_eval要求泛型参数S实现Spread特性
linear_gradient_eval要求泛型参数S实现SpreadBehavior特性
这些特性可能定义了如何处理渐变边界(如重复、反射或夹紧等行为)。
用途
这段代码用于图形渲染中实现渐变效果,通过查找表(LUT)和矩阵变换来高效计算任意位置的渐变颜色值。