From 78901fb248d9b36aa92e9424732021484b0e4437 Mon Sep 17 00:00:00 2001 From: Laurenz Stampfl Date: Tue, 18 Mar 2025 11:29:22 +0100 Subject: [PATCH] more --- crates/typst-pdf/src/paint.rs | 65 +++++++++++++++++++++++------------ crates/typst-pdf/src/util.rs | 12 ------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/crates/typst-pdf/src/paint.rs b/crates/typst-pdf/src/paint.rs index 353c2210f..7d488b60a 100644 --- a/crates/typst-pdf/src/paint.rs +++ b/crates/typst-pdf/src/paint.rs @@ -1,7 +1,7 @@ //! Convert paint types from typst to krilla. use krilla::geom::NormalizedF32; -use krilla::graphics::color::{cmyk, luma, rgb}; +use krilla::graphics::color::{self, cmyk, luma, rgb}; use krilla::graphics::paint::{ Fill, LinearGradient, Pattern, RadialGradient, SpreadMethod, Stop, Stroke, StrokeDash, SweepGradient, @@ -16,7 +16,7 @@ use typst_library::visualize::{ use typst_utils::Numeric; 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( gc: &mut GlobalContext, @@ -76,40 +76,53 @@ fn convert_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::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() { ColorSpace::D65Gray => { - let components = color.to_vec4_u8(); - (luma::Color::new(components[0]).into(), components[3]) + let (c, a) = convert_luma(color); + (c.into(), a) } ColorSpace::Cmyk => { - let components = color.to_vec4_u8(); - ( - cmyk::Color::new( - components[0], - components[1], - components[2], - components[3], - ) - .into(), - // Typst doesn't support alpha on CMYK colors. - 255, - ) + (convert_cmyk(color).into(), 255) } // Convert all other colors in different colors spaces into RGB _ => { - let (c, a) = color.to_krilla_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( + components[0], + components[1], + components[2], + components[3], + ) +} + +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( gc: &mut GlobalContext, pattern: &Tiling, @@ -243,11 +256,19 @@ fn convert_gradient( } } -fn convert_gradient_stops(gradient: &Gradient) -> Vec> { - let mut stops: Vec> = vec![]; +fn convert_gradient_stops(gradient: &Gradient) -> 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 (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 offset = NormalizedF32::new(offset.get() as f32).unwrap(); let stop = Stop { offset, color, opacity }; diff --git a/crates/typst-pdf/src/util.rs b/crates/typst-pdf/src/util.rs index 5e1c5dcfb..ff6fc07fb 100644 --- a/crates/typst-pdf/src/util.rs +++ b/crates/typst-pdf/src/util.rs @@ -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. pub(crate) fn display_font(font: &Font) -> String { let font_family = &font.info().family;