diff --git a/crates/typst-pdf/src/krilla.rs b/crates/typst-pdf/src/krilla.rs index ea7cdfe70..a0795e238 100644 --- a/crates/typst-pdf/src/krilla.rs +++ b/crates/typst-pdf/src/krilla.rs @@ -640,7 +640,7 @@ fn write_link( LinkAnnotation::new( rect, Target::Destination(krilla::destination::Destination::Xyz( - XyzDestination::new(page_index, pos.point.as_krilla()), + XyzDestination::new(page_index, pos.point.to_krilla()), )), ) .into(), @@ -665,7 +665,7 @@ pub fn handle_group( convert_path(p, &mut builder); builder.finish() }) - .and_then(|p| p.transform(fc.state().transform.as_krilla())); + .and_then(|p| p.transform(fc.state().transform.to_krilla())); if let Some(clip_path) = &clip_path { surface.push_clip_path(clip_path, &krilla::path::FillRule::NonZero); @@ -726,7 +726,7 @@ pub fn handle_text( let glyphs: &[PdfGlyph] = TransparentWrapper::wrap_slice(t.glyphs.as_slice()); - surface.push_transform(&fc.state().transform.as_krilla()); + surface.push_transform(&fc.state().transform.to_krilla()); surface.fill_glyphs( krilla::geom::Point::from_xy(0.0, 0.0), @@ -771,7 +771,7 @@ pub fn handle_image( surface: &mut Surface, span: Span, ) -> SourceResult<()> { - surface.push_transform(&fc.state().transform.as_krilla()); + surface.push_transform(&fc.state().transform.to_krilla()); match image.kind() { ImageKind::Raster(raster) => { @@ -784,12 +784,12 @@ pub fn handle_image( gc.image_spans.insert(image.clone(), span); } - surface.draw_image(image, size.as_krilla()); + surface.draw_image(image, size.to_krilla()); } ImageKind::Svg(svg) => { surface.draw_svg( svg.tree(), - size.as_krilla(), + size.to_krilla(), SvgSettings { embed_text: !svg.flatten_text(), ..Default::default() @@ -841,7 +841,7 @@ pub fn handle_shape( } } - surface.push_transform(&fc.state().transform.as_krilla()); + surface.push_transform(&fc.state().transform.to_krilla()); if let Some(path) = path_builder.finish() { if let Some(paint) = &shape.fill { diff --git a/crates/typst-pdf/src/paint.rs b/crates/typst-pdf/src/paint.rs index e99fc6451..849091816 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 crate::krilla::{process_frame, FrameContext, GlobalContext, Transforms}; -use crate::util::{AbsExt, FillRuleExt, LineCapExt, LineJoinExt, TransformExt}; +use crate::util::{AbsExt, ColorExt, FillRuleExt, LineCapExt, LineJoinExt, TransformExt}; use krilla::geom::NormalizedF32; use krilla::paint::SpreadMethod; use krilla::surface::Surface; @@ -25,7 +25,7 @@ pub(crate) fn fill( Ok(krilla::path::Fill { paint, - rule: fill_rule_.as_krilla(), + rule: fill_rule_.to_krilla(), opacity: NormalizedF32::new(opacity as f32 / 255.0).unwrap(), }) } @@ -43,8 +43,8 @@ pub(crate) fn stroke( paint, width: stroke.thickness.to_f32(), miter_limit: stroke.miter_limit.get() as f32, - line_join: stroke.join.as_krilla(), - line_cap: stroke.cap.as_krilla(), + line_join: stroke.join.to_krilla(), + line_cap: stroke.cap.to_krilla(), opacity: NormalizedF32::new(opacity as f32 / 255.0).unwrap(), dash: stroke.dash.as_ref().map(|d| dash(d)), }) @@ -57,15 +57,6 @@ fn dash(dash: &DashPattern) -> krilla::path::StrokeDash { } } -fn convert_to_rgb_color(color: &Color) -> (krilla::color::rgb::Color, u8) { - let components = color.to_space(ColorSpace::Srgb).to_vec4_u8(); - ( - krilla::color::rgb::Color::new(components[0], components[1], components[2]) - .into(), - components[3], - ) -} - fn paint( gc: &mut GlobalContext, paint: &Paint, @@ -95,7 +86,7 @@ fn paint( ) } _ => { - let (c, a) = convert_to_rgb_color(c); + let (c, a) = c.to_krilla_rgb(); (c.into(), a) } }; @@ -131,7 +122,7 @@ pub(crate) fn convert_pattern( .unwrap() .pre_concat(transforms.container_transform_chain), } - .as_krilla(); + .to_krilla(); let mut stream_builder = surface.stream_builder(); let mut surface = stream_builder.surface(); @@ -178,7 +169,7 @@ fn convert_gradient( let mut stops: Vec> = vec![]; let mut add_single = |color: &Color, offset: Ratio| { - let (color, opacity) = convert_to_rgb_color(color); + let (color, opacity) = color.to_krilla_rgb(); let opacity = NormalizedF32::new((opacity as f32) / 255.0).unwrap(); let offset = NormalizedF32::new(offset.get() as f32).unwrap(); let stop = krilla::paint::Stop { offset, color, opacity }; @@ -234,7 +225,7 @@ fn convert_gradient( y1, x2, y2, - transform: actual_transform.as_krilla().pre_concat( + transform: actual_transform.to_krilla().pre_concat( krilla::geom::Transform::from_scale(size.x.to_f32(), size.y.to_f32()), ), spread_method: SpreadMethod::Pad, @@ -280,7 +271,7 @@ fn convert_gradient( cx: radial.center.x.get() as f32, cy: radial.center.y.get() as f32, cr: radial.radius.get() as f32, - transform: actual_transform.as_krilla().pre_concat( + transform: actual_transform.to_krilla().pre_concat( krilla::geom::Transform::from_scale(size.x.to_f32(), size.y.to_f32()), ), spread_method: SpreadMethod::Pad, @@ -366,7 +357,7 @@ fn convert_gradient( cy, start_angle: 0.0, end_angle: 360.0, - transform: actual_transform.as_krilla(), + transform: actual_transform.to_krilla(), spread_method: SpreadMethod::Pad, stops: stops.into(), anti_alias: gradient.anti_alias(), diff --git a/crates/typst-pdf/src/util.rs b/crates/typst-pdf/src/util.rs index cfcf13e96..54e3febab 100644 --- a/crates/typst-pdf/src/util.rs +++ b/crates/typst-pdf/src/util.rs @@ -1,64 +1,68 @@ //! Basic utilities for converting typst types to krilla. +use krilla::geom as kg; +use krilla::path as kp; +use krilla::color::rgb as kr; + use typst_library::layout::{Abs, Point, Size, Transform}; use typst_library::text::Font; -use typst_library::visualize::{FillRule, LineCap, LineJoin}; +use typst_library::visualize::{Color, ColorSpace, FillRule, LineCap, LineJoin}; pub(crate) trait SizeExt { - fn as_krilla(&self) -> krilla::geom::Size; + fn to_krilla(&self) -> kg::Size; } impl SizeExt for Size { - fn as_krilla(&self) -> krilla::geom::Size { - krilla::geom::Size::from_wh(self.x.to_f32(), self.y.to_f32()).unwrap() + fn to_krilla(&self) -> kg::Size { + kg::Size::from_wh(self.x.to_f32(), self.y.to_f32()).unwrap() } } pub(crate) trait PointExt { - fn as_krilla(&self) -> krilla::geom::Point; + fn to_krilla(&self) -> kg::Point; } impl PointExt for Point { - fn as_krilla(&self) -> krilla::geom::Point { - krilla::geom::Point::from_xy(self.x.to_f32(), self.y.to_f32()) + fn to_krilla(&self) -> kg::Point { + kg::Point::from_xy(self.x.to_f32(), self.y.to_f32()) } } pub(crate) trait LineCapExt { - fn as_krilla(&self) -> krilla::path::LineCap; + fn to_krilla(&self) -> kp::LineCap; } impl LineCapExt for LineCap { - fn as_krilla(&self) -> krilla::path::LineCap { + fn to_krilla(&self) -> kp::LineCap { match self { - LineCap::Butt => krilla::path::LineCap::Butt, - LineCap::Round => krilla::path::LineCap::Round, - LineCap::Square => krilla::path::LineCap::Square, + LineCap::Butt => kp::LineCap::Butt, + LineCap::Round => kp::LineCap::Round, + LineCap::Square => kp::LineCap::Square, } } } pub(crate) trait LineJoinExt { - fn as_krilla(&self) -> krilla::path::LineJoin; + fn to_krilla(&self) -> kp::LineJoin; } impl LineJoinExt for LineJoin { - fn as_krilla(&self) -> krilla::path::LineJoin { + fn to_krilla(&self) -> kp::LineJoin { match self { - LineJoin::Miter => krilla::path::LineJoin::Miter, - LineJoin::Round => krilla::path::LineJoin::Round, - LineJoin::Bevel => krilla::path::LineJoin::Bevel, + LineJoin::Miter => kp::LineJoin::Miter, + LineJoin::Round => kp::LineJoin::Round, + LineJoin::Bevel => kp::LineJoin::Bevel, } } } pub(crate) trait TransformExt { - fn as_krilla(&self) -> krilla::geom::Transform; + fn to_krilla(&self) -> kg::Transform; } impl TransformExt for Transform { - fn as_krilla(&self) -> krilla::geom::Transform { - krilla::geom::Transform::from_row( + fn to_krilla(&self) -> kg::Transform { + kg::Transform::from_row( self.sx.get() as f32, self.ky.get() as f32, self.kx.get() as f32, @@ -70,14 +74,14 @@ impl TransformExt for Transform { } pub(crate) trait FillRuleExt { - fn as_krilla(&self) -> krilla::path::FillRule; + fn to_krilla(&self) -> kp::FillRule; } impl FillRuleExt for FillRule { - fn as_krilla(&self) -> krilla::path::FillRule { + fn to_krilla(&self) -> kp::FillRule { match self { - FillRule::NonZero => krilla::path::FillRule::NonZero, - FillRule::EvenOdd => krilla::path::FillRule::EvenOdd, + FillRule::NonZero => kp::FillRule::NonZero, + FillRule::EvenOdd => kp::FillRule::EvenOdd, } } } @@ -92,6 +96,22 @@ 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]) + .into(), + components[3], + ) + } +} + /// Display the font family and variant. pub(crate) fn display_font(font: &Font) -> String { let font_family = &font.info().family;