This commit is contained in:
Laurenz Stampfl 2025-03-18 11:29:22 +01:00
parent a330866ad2
commit 78901fb248
2 changed files with 43 additions and 34 deletions

View File

@ -1,7 +1,7 @@
//! Convert paint types from typst to krilla. //! Convert paint types from typst to krilla.
use krilla::geom::NormalizedF32; use krilla::geom::NormalizedF32;
use krilla::graphics::color::{cmyk, luma, rgb}; use krilla::graphics::color::{self, cmyk, luma, rgb};
use krilla::graphics::paint::{ use krilla::graphics::paint::{
Fill, LinearGradient, Pattern, RadialGradient, SpreadMethod, Stop, Stroke, Fill, LinearGradient, Pattern, RadialGradient, SpreadMethod, Stop, Stroke,
StrokeDash, SweepGradient, StrokeDash, SweepGradient,
@ -16,7 +16,7 @@ use typst_library::visualize::{
use typst_utils::Numeric; use typst_utils::Numeric;
use crate::convert::{handle_frame, FrameContext, GlobalContext, State}; use crate::convert::{handle_frame, FrameContext, GlobalContext, State};
use crate::util::{AbsExt, ColorExt, FillRuleExt, LineCapExt, LineJoinExt, TransformExt}; use crate::util::{AbsExt, FillRuleExt, LineCapExt, LineJoinExt, TransformExt};
pub(crate) fn convert_fill( pub(crate) fn convert_fill(
gc: &mut GlobalContext, gc: &mut GlobalContext,
@ -76,38 +76,51 @@ fn convert_paint(
} }
match paint { match paint {
Paint::Solid(c) => Ok(convert_solid(c)), Paint::Solid(c) => {
let (c, a) = convert_solid(c);
Ok((c.into(), a))
},
Paint::Gradient(g) => Ok(convert_gradient(g, on_text, state, size)), Paint::Gradient(g) => Ok(convert_gradient(g, on_text, state, size)),
Paint::Tiling(p) => convert_pattern(gc, p, on_text, surface, state), Paint::Tiling(p) => convert_pattern(gc, p, on_text, surface, state),
} }
} }
fn convert_solid(color: &Color) -> (krilla::graphics::paint::Paint, u8) { fn convert_solid(color: &Color) -> (color::Color, u8) {
match color.space() { match color.space() {
ColorSpace::D65Gray => { ColorSpace::D65Gray => {
let components = color.to_vec4_u8(); let (c, a) = convert_luma(color);
(luma::Color::new(components[0]).into(), components[3]) (c.into(), a)
} }
ColorSpace::Cmyk => { ColorSpace::Cmyk => {
let components = color.to_vec4_u8(); (convert_cmyk(color).into(), 255)
( }
// Convert all other colors in different colors spaces into RGB
_ => {
let (c, a) = convert_rgb(color);
(c.into(), a)
}
}
}
fn convert_cmyk(color: &Color) -> cmyk::Color {
let components = color.to_space(ColorSpace::Cmyk).to_vec4_u8();
cmyk::Color::new( cmyk::Color::new(
components[0], components[0],
components[1], components[1],
components[2], components[2],
components[3], components[3],
) )
.into(),
// Typst doesn't support alpha on CMYK colors.
255,
)
}
// Convert all other colors in different colors spaces into RGB
_ => {
let (c, a) = color.to_krilla_rgb();
(c.into(), a)
} }
fn convert_rgb(color: &Color) -> (rgb::Color, u8) {
let components = color.to_space(ColorSpace::Srgb).to_vec4_u8();
(rgb::Color::new(components[0], components[1], components[2]), components[3])
} }
fn convert_luma(color: &Color) -> (luma::Color, u8) {
let components = color.to_space(ColorSpace::D65Gray).to_vec4_u8();
(luma::Color::new(components[0]), components[3])
} }
fn convert_pattern( fn convert_pattern(
@ -243,11 +256,19 @@ fn convert_gradient(
} }
} }
fn convert_gradient_stops(gradient: &Gradient) -> Vec<Stop<rgb::Color>> { fn convert_gradient_stops(gradient: &Gradient) -> Vec<Stop> {
let mut stops: Vec<Stop<rgb::Color>> = vec![]; let mut stops= vec![];
let use_cmyk = gradient.stops().iter().all(|s| s.color.space() == ColorSpace::Cmyk);
let mut add_single = |color: &Color, offset: Ratio| { let mut add_single = |color: &Color, offset: Ratio| {
let (color, opacity) = color.to_krilla_rgb(); let (color, opacity) = if use_cmyk {
(convert_cmyk(color).into(), 255)
} else {
let (c, a) = convert_rgb(color);
(c.into(), a)
};
let opacity = NormalizedF32::new((opacity as f32) / 255.0).unwrap(); let opacity = NormalizedF32::new((opacity as f32) / 255.0).unwrap();
let offset = NormalizedF32::new(offset.get() as f32).unwrap(); let offset = NormalizedF32::new(offset.get() as f32).unwrap();
let stop = Stop { offset, color, opacity }; let stop = Stop { offset, color, opacity };

View File

@ -98,18 +98,6 @@ impl AbsExt for Abs {
} }
} }
pub(crate) trait ColorExt {
fn to_krilla_rgb(&self) -> (kr::Color, u8);
}
impl ColorExt for Color {
/// Convert a color into a krilla RGB color and an alpha value.
fn to_krilla_rgb(&self) -> (kr::Color, u8) {
let components = self.to_space(ColorSpace::Srgb).to_vec4_u8();
(kr::Color::new(components[0], components[1], components[2]), components[3])
}
}
/// Display the font family and variant of a font. /// Display the font family and variant of a font.
pub(crate) fn display_font(font: &Font) -> String { pub(crate) fn display_font(font: &Font) -> String {
let font_family = &font.info().family; let font_family = &font.info().family;