#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum HintingMode {
#[default]
None,
Normal,
Full,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SubpixelMode {
#[default]
None,
Horizontal,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum LcdFilterKernel {
Box,
Triangle,
#[default]
FreeType5Tap,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct RasterOptions {
pub hinting_mode: HintingMode,
pub subpixel_mode: SubpixelMode,
pub lcd_filter: LcdFilterKernel,
pub gamma_correction: bool,
pub stem_darkening: bool,
}
impl Default for RasterOptions {
fn default() -> Self {
Self {
hinting_mode: HintingMode::None,
subpixel_mode: SubpixelMode::None,
lcd_filter: LcdFilterKernel::FreeType5Tap,
gamma_correction: true,
stem_darkening: false,
}
}
}
impl RasterOptions {
pub fn builder() -> RasterOptionsBuilder {
RasterOptionsBuilder::default()
}
pub fn lcd() -> Self {
Self {
subpixel_mode: SubpixelMode::Horizontal,
..Self::default()
}
}
}
#[derive(Debug, Clone, Default)]
pub struct RasterOptionsBuilder(RasterOptions);
impl RasterOptionsBuilder {
pub fn hinting(mut self, mode: HintingMode) -> Self {
self.0.hinting_mode = mode;
self
}
pub fn subpixel(mut self, mode: SubpixelMode) -> Self {
self.0.subpixel_mode = mode;
self
}
pub fn filter(mut self, kernel: LcdFilterKernel) -> Self {
self.0.lcd_filter = kernel;
self
}
pub fn gamma(mut self, enabled: bool) -> Self {
self.0.gamma_correction = enabled;
self
}
pub fn stem_darkening(mut self, enabled: bool) -> Self {
self.0.stem_darkening = enabled;
self
}
pub fn build(self) -> RasterOptions {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_options_build_without_panic() {
let opts = RasterOptions::default();
assert_eq!(opts.hinting_mode, HintingMode::None);
assert_eq!(opts.subpixel_mode, SubpixelMode::None);
assert_eq!(opts.lcd_filter, LcdFilterKernel::FreeType5Tap);
assert!(opts.gamma_correction);
assert!(!opts.stem_darkening);
}
#[test]
fn builder_sets_all_fields() {
let opts = RasterOptions::builder()
.hinting(HintingMode::Full)
.subpixel(SubpixelMode::Horizontal)
.filter(LcdFilterKernel::Triangle)
.gamma(false)
.stem_darkening(true)
.build();
assert_eq!(opts.hinting_mode, HintingMode::Full);
assert_eq!(opts.subpixel_mode, SubpixelMode::Horizontal);
assert_eq!(opts.lcd_filter, LcdFilterKernel::Triangle);
assert!(!opts.gamma_correction);
assert!(opts.stem_darkening);
}
#[test]
fn lcd_constructor_enables_horizontal() {
let opts = RasterOptions::lcd();
assert_eq!(opts.subpixel_mode, SubpixelMode::Horizontal);
assert!(
opts.gamma_correction,
"LCD mode should keep gamma correction"
);
}
}