From 01fd27c7474c70b75d0568dfedd2400c956859ef Mon Sep 17 00:00:00 2001 From: Laurenz Stampfl <47084093+LaurenzV@users.noreply.github.com> Date: Sat, 14 Dec 2024 22:37:59 +0100 Subject: [PATCH] Add support for patterns --- crates/typst-pdf/src/content_old.rs | 2 +- crates/typst-pdf/src/image.rs | 4 +- crates/typst-pdf/src/krilla.rs | 289 ++++++++++++++++---------- crates/typst-pdf/src/lib.rs | 4 +- crates/typst-pdf/src/paint.rs | 184 ++++++++++------ crates/typst-pdf/src/primitive.rs | 2 +- crates/typst-pdf/src/resources_old.rs | 2 +- 7 files changed, 302 insertions(+), 185 deletions(-) diff --git a/crates/typst-pdf/src/content_old.rs b/crates/typst-pdf/src/content_old.rs index ca28cebbe..ff5dfc37d 100644 --- a/crates/typst-pdf/src/content_old.rs +++ b/crates/typst-pdf/src/content_old.rs @@ -25,8 +25,8 @@ use typst_library::visualize::{ use typst_syntax::Span; use typst_utils::{Deferred, Numeric, SliceExt}; -use crate::color_old::PaintEncode; use crate::color_font::ColorFontMap; +use crate::color_old::PaintEncode; use crate::extg_old::ExtGState; use crate::image_old::deferred_image; use crate::resources_old::Resources; diff --git a/crates/typst-pdf/src/image.rs b/crates/typst-pdf/src/image.rs index eba257f3d..bc3023d4c 100644 --- a/crates/typst-pdf/src/image.rs +++ b/crates/typst-pdf/src/image.rs @@ -29,8 +29,8 @@ impl PdfImage { impl Hash for PdfImage { fn hash(&self, state: &mut H) { - /// `alpha_channel` and `actual_dynamic` are generated from the underlying `RasterImage`, - /// so this is enough. Since `raster` is prehashed, this is also very cheap. + // `alpha_channel` and `actual_dynamic` are generated from the underlying `RasterImage`, + // so this is enough. Since `raster` is prehashed, this is also very cheap. self.raster.hash(state); } } diff --git a/crates/typst-pdf/src/krilla.rs b/crates/typst-pdf/src/krilla.rs index 94eb67efc..fabc5afef 100644 --- a/crates/typst-pdf/src/krilla.rs +++ b/crates/typst-pdf/src/krilla.rs @@ -1,11 +1,12 @@ +use crate::content_old::Transforms; +use crate::primitive::{PointExt, SizeExt, TransformExt}; use crate::{paint, AbsExt}; use bytemuck::TransparentWrapper; -use image::{GenericImageView}; +use image::GenericImageView; use krilla::action::{Action, LinkAction}; use krilla::annotation::{LinkAnnotation, Target}; use krilla::destination::XyzDestination; use krilla::font::{GlyphId, GlyphUnits}; -use krilla::geom::{Point, Transform}; use krilla::path::PathBuilder; use krilla::surface::Surface; use krilla::validation::Validator; @@ -16,49 +17,51 @@ use std::hash::{Hash, Hasher}; use std::ops::Range; use std::sync::Arc; use svg2pdf::usvg::Rect; -use typst_library::layout::{Abs, Frame, FrameItem, GroupItem, PagedDocument, Size}; +use typst_library::layout::{ + Abs, Frame, FrameItem, GroupItem, PagedDocument, Point, Size, Transform, +}; use typst_library::model::Destination; use typst_library::text::{Font, Glyph, TextItem}; -use typst_library::visualize::{FillRule, Geometry, Image, ImageKind, Paint, Path, PathItem, Shape}; -use crate::content_old::Transforms; -use crate::primitive::{PointExt, SizeExt, TransformExt}; +use typst_library::visualize::{ + FillRule, Geometry, Image, ImageKind, Paint, Path, PathItem, Shape, +}; #[derive(Debug, Clone)] struct State { /// The transform of the current item. - transform: typst_library::layout::Transform, + transform: Transform, /// The transform of first hard frame in the hierarchy. - container_transform: typst_library::layout::Transform, + container_transform: Transform, /// The size of the first hard frame in the hierarchy. size: Size, } impl State { /// Creates a new, clean state for a given `size`. - pub fn new(size: Size) -> Self { + fn new(size: Size) -> Self { Self { - transform: typst_library::layout::Transform::identity(), - container_transform: typst_library::layout::Transform::identity(), + transform: Transform::identity(), + container_transform: Transform::identity(), size, } } - pub fn transform(&mut self, transform: typst_library::layout::Transform) { - self.transform = self.transform.pre_concat(transform); - if self.container_transform.is_identity() { - self.container_transform = self.transform; - } + pub fn size(&mut self, size: Size) { + self.size = size; } - fn group_transform(&mut self, transform: typst_library::layout::Transform) { - self.container_transform = - self.container_transform.pre_concat(transform); + pub fn transform(&mut self, transform: Transform) { + self.transform = self.transform.pre_concat(transform); + } + + fn set_container_transform(&mut self) { + self.container_transform = self.transform; } /// Creates the [`Transforms`] structure for the current item. - pub fn transforms(&self, size: Size, pos: typst_library::layout::Point) -> Transforms { + pub fn transforms(&self, size: Size) -> Transforms { Transforms { - transform: self.transform.pre_concat(typst_library::layout::Transform::translate(pos.x, pos.y)), + transform: self.transform, container_transform: self.container_transform, container_size: self.size, size, @@ -66,15 +69,13 @@ impl State { } } -struct FrameContext { - states: Vec +pub(crate) struct FrameContext { + states: Vec, } impl FrameContext { pub fn new(size: Size) -> Self { - Self { - states: vec![State::new(size)], - } + Self { states: vec![State::new(size)] } } pub fn push(&mut self) { @@ -89,7 +90,7 @@ impl FrameContext { self.states.last().unwrap() } - pub fn state_mut(&mut self) -> &State { + pub fn state_mut(&mut self) -> &mut State { self.states.last_mut().unwrap() } } @@ -126,17 +127,12 @@ impl krilla::font::Glyph for PdfGlyph { pub struct GlobalContext { fonts: HashMap, - cur_transform: typst_library::layout::Transform, annotations: Vec, } impl GlobalContext { pub fn new() -> Self { - Self { - fonts: Default::default(), - cur_transform: typst_library::layout::Transform::identity(), - annotations: vec![], - } + Self { fonts: Default::default(), annotations: vec![] } } } @@ -165,7 +161,15 @@ pub fn pdf(typst_document: &PagedDocument) -> Vec { ); let mut page = document.start_page_with(settings); let mut surface = page.surface(); - process_frame(&typst_page.frame, &mut surface, &mut context); + let mut fc = FrameContext::new(typst_page.frame.size()); + // println!("{:?}", &typst_page.frame); + process_frame( + &mut fc, + &typst_page.frame, + typst_page.fill_or_transparent(), + &mut surface, + &mut context, + ); surface.finish(); let annotations = std::mem::take(&mut context.annotations); @@ -183,47 +187,66 @@ pub fn finish(document: krilla::Document) -> Vec { document.finish().unwrap() } -pub fn process_frame(frame: &Frame, fill: Option, surface: &mut Surface, gc: &mut GlobalContext) { - let mut fc = FrameContext::new(frame.size()); +pub fn process_frame( + fc: &mut FrameContext, + frame: &Frame, + fill: Option, + surface: &mut Surface, + gc: &mut GlobalContext, +) { + fc.push(); + + if frame.kind().is_hard() { + fc.state_mut().set_container_transform(); + fc.state_mut().size(frame.size()); + } + + if let Some(fill) = fill { + let shape = Geometry::Rect(frame.size()).filled(fill); + handle_shape(fc, &shape, surface, gc); + } for (point, item) in frame.items() { - surface.push_transform(&Transform::from_translate( - point.x.to_f32(), - point.y.to_f32(), - )); - + fc.push(); + fc.state_mut().transform(Transform::translate(point.x, point.y)); match item { - FrameItem::Group(g) => handle_group(g, surface, gc), - FrameItem::Text(t) => handle_text(t, surface, gc), - FrameItem::Shape(s, _) => handle_shape(s, surface), + FrameItem::Group(g) => handle_group(fc, g, surface, gc), + FrameItem::Text(t) => handle_text(fc, t, surface, gc), + FrameItem::Shape(s, _) => handle_shape(fc, s, surface, gc), FrameItem::Image(image, size, span) => { - handle_image(image, *size, surface, gc) + handle_image(fc, image, *size, surface) } - FrameItem::Link(d, s) => handle_link(*point, d, *s, gc, surface), + FrameItem::Link(d, s) => {} FrameItem::Tag(_) => {} } - surface.pop(); + fc.pop(); } + + fc.pop(); } pub fn handle_group( + fc: &mut FrameContext, group: &GroupItem, surface: &mut Surface, context: &mut GlobalContext, ) { - let old = context.cur_transform; - context.cur_transform = context.cur_transform.pre_concat(group.transform); + fc.push(); + fc.state_mut().transform(group.transform); - surface.push_transform(&group.transform.as_krilla()); - process_frame(&group.frame, surface, context); + process_frame(fc, &group.frame, None, surface, context); - context.cur_transform = old; - surface.pop(); + fc.pop(); } -pub fn handle_text(t: &TextItem, surface: &mut Surface, context: &mut GlobalContext) { - let font = context +pub fn handle_text( + fc: &mut FrameContext, + t: &TextItem, + surface: &mut Surface, + gc: &mut GlobalContext, +) { + let font = gc .fonts .entry(t.font.clone()) .or_insert_with(|| { @@ -232,14 +255,23 @@ pub fn handle_text(t: &TextItem, surface: &mut Surface, context: &mut GlobalCont .unwrap() }) .clone(); - let fill = paint::fill(&t.fill, FillRule::NonZero); + let fill = paint::fill( + gc, + &t.fill, + FillRule::NonZero, + true, + surface, + fc.state().transforms(Size::zero()), + ); let text = t.text.as_str(); let size = t.size; let glyphs: &[PdfGlyph] = TransparentWrapper::wrap_slice(t.glyphs.as_slice()); + surface.push_transform(&fc.state().transform.as_krilla()); + surface.fill_glyphs( - Point::from_xy(0.0, 0.0), + krilla::geom::Point::from_xy(0.0, 0.0), fill, &glyphs, font.clone(), @@ -249,9 +281,13 @@ pub fn handle_text(t: &TextItem, surface: &mut Surface, context: &mut GlobalCont false, ); - if let Some(stroke) = t.stroke.as_ref().map(paint::stroke) { + if let Some(stroke) = t + .stroke + .as_ref() + .map(|s| paint::stroke(gc, s, true, surface, fc.state().transforms(Size::zero()))) + { surface.stroke_glyphs( - Point::from_xy(0.0, 0.0), + krilla::geom::Point::from_xy(0.0, 0.0), stroke, &glyphs, font.clone(), @@ -261,14 +297,18 @@ pub fn handle_text(t: &TextItem, surface: &mut Surface, context: &mut GlobalCont true, ); } + + surface.pop(); } pub fn handle_image( + fc: &mut FrameContext, image: &Image, size: Size, surface: &mut Surface, - _: &mut GlobalContext, ) { + surface.push_transform(&fc.state().transform.as_krilla()); + match image.kind() { ImageKind::Raster(raster) => { // TODO: Don't unwrap @@ -276,12 +316,26 @@ pub fn handle_image( surface.draw_image(image, size.as_krilla()); } ImageKind::Svg(svg) => { - surface.draw_svg(svg.tree(), size.as_krilla(), SvgSettings::default()); + surface.draw_svg( + svg.tree(), + size.as_krilla(), + SvgSettings { + embed_text: !svg.flatten_text(), + ..Default::default() + }, + ); } } + + surface.pop(); } -pub fn handle_shape(fc: &FrameContext, pos: Point, shape: &Shape, surface: &mut Surface) { +pub fn handle_shape( + fc: &mut FrameContext, + shape: &Shape, + surface: &mut Surface, + gc: &mut GlobalContext, +) { let mut path_builder = PathBuilder::new(); match &shape.geometry { @@ -300,11 +354,17 @@ pub fn handle_shape(fc: &FrameContext, pos: Point, shape: &Shape, surface: &mut } surface.push_transform(&fc.state().transform.as_krilla()); - surface.push_transform(&Transform::from_translate(pos.x, pos.y)); if let Some(path) = path_builder.finish() { if let Some(paint) = &shape.fill { - let fill = paint::fill(paint, shape.fill_rule); + let fill = paint::fill( + gc, + &paint, + shape.fill_rule, + false, + surface, + fc.state().transforms(Size::zero()), + ); surface.fill_path(&path, fill); } @@ -317,13 +377,18 @@ pub fn handle_shape(fc: &FrameContext, pos: Point, shape: &Shape, surface: &mut }); if let Some(stroke) = &stroke { - let stroke = paint::stroke(stroke); + let stroke = paint::stroke( + gc, + stroke, + false, + surface, + fc.state().transforms(Size::zero()), + ); surface.stroke_path(&path, stroke); } } surface.pop(); - surface.pop(); } pub fn convert_path(path: &Path, builder: &mut PathBuilder) { @@ -344,49 +409,49 @@ pub fn convert_path(path: &Path, builder: &mut PathBuilder) { } } -fn handle_link( - pos: typst_library::layout::Point, - dest: &Destination, - size: typst_library::layout::Size, - ctx: &mut GlobalContext, - surface: &mut Surface, -) { - let mut min_x = Abs::inf(); - let mut min_y = Abs::inf(); - let mut max_x = -Abs::inf(); - let mut max_y = -Abs::inf(); - - // Compute the bounding box of the transformed link. - for point in [ - pos, - pos + typst_library::layout::Point::with_x(size.x), - pos + typst_library::layout::Point::with_y(size.y), - pos + size.to_point(), - ] { - let t = point.transform(ctx.cur_transform); - min_x.set_min(t.x); - min_y.set_min(t.y); - max_x.set_max(t.x); - max_y.set_max(t.y); - } - - let x1 = min_x.to_f32(); - let x2 = max_x.to_f32(); - let y1 = min_y.to_f32(); - let y2 = max_y.to_f32(); - let rect = krilla::geom::Rect::from_ltrb(x1, y1, x2, y2).unwrap(); - - let target = match dest { - Destination::Url(u) => { - Target::Action(Action::Link(LinkAction::new(u.to_string()))) - } - Destination::Position(p) => { - Target::Destination(krilla::destination::Destination::Xyz( - XyzDestination::new(p.page.get() - 1, p.point.as_krilla()), - )) - } - Destination::Location(_) => return, - }; - - ctx.annotations.push(LinkAnnotation::new(rect, target).into()); -} +// fn handle_link( +// pos: typst_library::layout::Point, +// dest: &Destination, +// size: typst_library::layout::Size, +// ctx: &mut GlobalContext, +// surface: &mut Surface, +// ) { +// let mut min_x = Abs::inf(); +// let mut min_y = Abs::inf(); +// let mut max_x = -Abs::inf(); +// let mut max_y = -Abs::inf(); +// +// // Compute the bounding box of the transformed link. +// for point in [ +// pos, +// pos + Point::with_x(size.x), +// pos + Point::with_y(size.y), +// pos + size.to_point(), +// ] { +// let t = point.transform(ctx.cur_transform); +// min_x.set_min(t.x); +// min_y.set_min(t.y); +// max_x.set_max(t.x); +// max_y.set_max(t.y); +// } +// +// let x1 = min_x.to_f32(); +// let x2 = max_x.to_f32(); +// let y1 = min_y.to_f32(); +// let y2 = max_y.to_f32(); +// let rect = krilla::geom::Rect::from_ltrb(x1, y1, x2, y2).unwrap(); +// +// let target = match dest { +// Destination::Url(u) => { +// Target::Action(Action::Link(LinkAction::new(u.to_string()))) +// } +// Destination::Position(p) => { +// Target::Destination(krilla::destination::Destination::Xyz( +// XyzDestination::new(p.page.get() - 1, p.point.as_krilla()), +// )) +// } +// Destination::Location(_) => return, +// }; +// +// ctx.annotations.push(LinkAnnotation::new(rect, target).into()); +// } diff --git a/crates/typst-pdf/src/lib.rs b/crates/typst-pdf/src/lib.rs index a990cbee2..614d8236b 100644 --- a/crates/typst-pdf/src/lib.rs +++ b/crates/typst-pdf/src/lib.rs @@ -1,8 +1,8 @@ //! Exporting of Typst documents into PDFs. mod catalog_old; -mod color_old; mod color_font; +mod color_old; mod content_old; mod extg_old; mod font_old; @@ -35,8 +35,8 @@ use typst_syntax::Span; use typst_utils::Deferred; use crate::catalog_old::write_catalog; -use crate::color_old::{alloc_color_functions_refs, ColorFunctionRefs}; use crate::color_font::{write_color_fonts, ColorFontSlice}; +use crate::color_old::{alloc_color_functions_refs, ColorFunctionRefs}; use crate::extg_old::{write_graphic_states, ExtGState}; use crate::font_old::write_fonts; use crate::gradient_old::{write_gradients, PdfGradient}; diff --git a/crates/typst-pdf/src/paint.rs b/crates/typst-pdf/src/paint.rs index 41fa48502..66594f315 100644 --- a/crates/typst-pdf/src/paint.rs +++ b/crates/typst-pdf/src/paint.rs @@ -1,19 +1,29 @@ //! Convert paint types from typst to krilla. -use std::num::NonZeroUsize; +use crate::content_old::Transforms; +use crate::krilla::{process_frame, FrameContext, GlobalContext}; +use crate::primitive::{FillRuleExt, LineCapExt, LineJoinExt, TransformExt}; +use crate::AbsExt; use krilla::geom::NormalizedF32; use krilla::page::{NumberingStyle, PageLabel}; -use typst_library::layout::{Abs, Angle, Quadrant, Ratio, Transform}; +use krilla::surface::Surface; +use std::num::NonZeroUsize; +use typst_library::layout::Abs; use typst_library::model::Numbering; -use typst_library::visualize::{ColorSpace, DashPattern, FillRule, FixedStroke, Gradient, Paint, RelativeTo}; +use typst_library::visualize::{ + ColorSpace, DashPattern, FillRule, FixedStroke, Paint, Pattern, RelativeTo, +}; use typst_utils::Numeric; -use crate::{content_old, AbsExt}; -use crate::content_old::Transforms; -use crate::gradient_old::PdfGradient; -use crate::primitive::{FillRuleExt, LineCapExt, LineJoinExt}; -pub(crate) fn fill(paint_: &Paint, fill_rule_: FillRule) -> krilla::path::Fill { - let (paint, opacity) = paint(paint_); +pub(crate) fn fill( + gc: &mut GlobalContext, + paint_: &Paint, + fill_rule_: FillRule, + on_text: bool, + surface: &mut Surface, + transforms: Transforms, +) -> krilla::path::Fill { + let (paint, opacity) = paint(gc, paint_, on_text, surface, transforms); krilla::path::Fill { paint, @@ -22,8 +32,14 @@ pub(crate) fn fill(paint_: &Paint, fill_rule_: FillRule) -> krilla::path::Fill { } } -pub(crate) fn stroke(stroke: &FixedStroke) -> krilla::path::Stroke { - let (paint, opacity) = paint(&stroke.paint); +pub(crate) fn stroke( + fc: &mut GlobalContext, + stroke: &FixedStroke, + on_text: bool, + surface: &mut Surface, + transforms: Transforms, +) -> krilla::path::Stroke { + let (paint, opacity) = paint(fc, &stroke.paint, on_text, surface, transforms); krilla::path::Stroke { paint, width: stroke.thickness.to_f32(), @@ -42,7 +58,13 @@ fn dash(dash: &DashPattern) -> krilla::path::StrokeDash { } } -fn paint(paint: &Paint) -> (krilla::paint::Paint, u8) { +fn paint( + gc: &mut GlobalContext, + paint: &Paint, + on_text: bool, + surface: &mut Surface, + transforms: Transforms, +) -> (krilla::paint::Paint, u8) { match paint { Paint::Solid(c) => { let components = c.to_space(ColorSpace::Srgb).to_vec4_u8(); @@ -57,7 +79,7 @@ fn paint(paint: &Paint) -> (krilla::paint::Paint, u8) { ) } Paint::Gradient(_) => (krilla::color::rgb::Color::black().into(), 255), - Paint::Pattern(_) => (krilla::color::rgb::Color::black().into(), 255), + Paint::Pattern(p) => convert_pattern(gc, p, on_text, surface, transforms), } } @@ -80,8 +102,8 @@ impl PageLabelExt for PageLabel { // If there is a suffix, we cannot use the common style optimisation, // since PDF does not provide a suffix field. let style = if pat.suffix.is_empty() { - use typst_library::model::NumberingKind as Kind; use krilla::page::NumberingStyle as Style; + use typst_library::model::NumberingKind as Kind; match kind { Kind::Arabic => Some(Style::Arabic), Kind::LowerRoman => Some(Style::LowerRoman), @@ -116,13 +138,13 @@ impl PageLabelExt for PageLabel { } } -// TODO: Anti-aliasing - -fn convert_gradient( - gradient: &Gradient, +pub(crate) fn convert_pattern( + gc: &mut GlobalContext, + pattern: &Pattern, on_text: bool, + surface: &mut Surface, mut transforms: Transforms, -) -> usize { +) -> (krilla::paint::Paint, u8) { // Edge cases for strokes. if transforms.size.x.is_zero() { transforms.size.x = Abs::pt(1.0); @@ -131,52 +153,82 @@ fn convert_gradient( if transforms.size.y.is_zero() { transforms.size.y = Abs::pt(1.0); } - let size = match gradient.unwrap_relative(on_text) { - RelativeTo::Self_ => transforms.size, - RelativeTo::Parent => transforms.container_size, - }; - let rotation = gradient.angle().unwrap_or_else(Angle::zero); - - let transform = match gradient.unwrap_relative(on_text) { - RelativeTo::Self_ => transforms.transform, - RelativeTo::Parent => transforms.container_transform, - }; - - let scale_offset = match gradient { - Gradient::Conic(_) => 4.0_f64, - _ => 1.0, - }; - - let transform = transform - .pre_concat(Transform::translate( - offset_x * scale_offset, - offset_y * scale_offset, - )) - .pre_concat(Transform::scale( - Ratio::new(size.x.to_pt() * scale_offset), - Ratio::new(size.y.to_pt() * scale_offset), - )); - - let angle = Gradient::correct_aspect_ratio(rotation, size.aspect_ratio()); - - match &gradient { - Gradient::Linear(_) => { - let (mut sin, mut cos) = (angle.sin(), angle.cos()); - - // Scale to edges of unit square. - let factor = cos.abs() + sin.abs(); - sin *= factor; - cos *= factor; - - let (x1, y1, x2, y2): (f64, f64, f64, f64) = match angle.quadrant() { - Quadrant::First => (0.0, 0.0, cos, sin), - Quadrant::Second => (1.0, 0.0, cos + 1.0, sin), - Quadrant::Third => (1.0, 1.0, cos + 1.0, sin + 1.0), - Quadrant::Fourth => (0.0, 1.0, cos, sin + 1.0), - }; + let transform = surface.ctm().invert().unwrap().pre_concat( + match pattern.unwrap_relative(on_text) { + RelativeTo::Self_ => transforms.transform, + RelativeTo::Parent => transforms.container_transform, } - Gradient::Radial(_) => {} - Gradient::Conic(_) => {} - } -} \ No newline at end of file + .as_krilla(), + ); + + let mut stream_builder = surface.stream_builder(); + let mut surface = stream_builder.surface(); + let mut fc = FrameContext::new(pattern.frame().size()); + process_frame(&mut fc, pattern.frame(), None, &mut surface, gc); + surface.finish(); + let stream = stream_builder.finish(); + let pattern = krilla::paint::Pattern { + stream, + transform, + width: (pattern.size().x + pattern.spacing().x).to_pt() as _, + height: (pattern.size().y + pattern.spacing().y).to_pt() as _, + }; + + (pattern.into(), 255) +} + +// TODO: Anti-aliasing + +// fn convert_gradient( +// gradient: &Gradient, +// on_text: bool, +// mut transforms: Transforms, +// ) -> usize { +// // Edge cases for strokes. +// if transforms.size.x.is_zero() { +// transforms.size.x = Abs::pt(1.0); +// } +// +// if transforms.size.y.is_zero() { +// transforms.size.y = Abs::pt(1.0); +// } +// let size = match gradient.unwrap_relative(on_text) { +// RelativeTo::Self_ => transforms.size, +// RelativeTo::Parent => transforms.container_size, +// }; +// +// let rotation = gradient.angle().unwrap_or_else(Angle::zero); +// +// let transform = match gradient.unwrap_relative(on_text) { +// RelativeTo::Self_ => transforms.transform, +// RelativeTo::Parent => transforms.container_transform, +// }; +// +// let scale_offset = match gradient { +// Gradient::Conic(_) => 4.0_f64, +// _ => 1.0, +// }; +// +// let angle = Gradient::correct_aspect_ratio(rotation, size.aspect_ratio()); +// +// match &gradient { +// Gradient::Linear(_) => { +// let (mut sin, mut cos) = (angle.sin(), angle.cos()); +// +// // Scale to edges of unit square. +// let factor = cos.abs() + sin.abs(); +// sin *= factor; +// cos *= factor; +// +// let (x1, y1, x2, y2): (f64, f64, f64, f64) = match angle.quadrant() { +// Quadrant::First => (0.0, 0.0, cos, sin), +// Quadrant::Second => (1.0, 0.0, cos + 1.0, sin), +// Quadrant::Third => (1.0, 1.0, cos + 1.0, sin + 1.0), +// Quadrant::Fourth => (0.0, 1.0, cos, sin + 1.0), +// }; +// } +// Gradient::Radial(_) => {} +// Gradient::Conic(_) => {} +// } +// } diff --git a/crates/typst-pdf/src/primitive.rs b/crates/typst-pdf/src/primitive.rs index ae48d51bc..bd2770332 100644 --- a/crates/typst-pdf/src/primitive.rs +++ b/crates/typst-pdf/src/primitive.rs @@ -81,4 +81,4 @@ impl FillRuleExt for FillRule { FillRule::EvenOdd => krilla::path::FillRule::EvenOdd, } } -} \ No newline at end of file +} diff --git a/crates/typst-pdf/src/resources_old.rs b/crates/typst-pdf/src/resources_old.rs index 22e7e0f5b..4345fd6f1 100644 --- a/crates/typst-pdf/src/resources_old.rs +++ b/crates/typst-pdf/src/resources_old.rs @@ -18,8 +18,8 @@ use typst_library::visualize::Image; use typst_syntax::Span; use typst_utils::Deferred; -use crate::color_old::ColorSpaces; use crate::color_font::ColorFontMap; +use crate::color_old::ColorSpaces; use crate::extg_old::ExtGState; use crate::gradient_old::PdfGradient; use crate::image_old::EncodedImage;