fix missmatched pattern text issue

This commit is contained in:
Laurenz Stampfl 2024-12-15 19:29:58 +01:00
parent 4c6dd8cd89
commit 1d135ddd90
2 changed files with 41 additions and 22 deletions

View File

@ -1,4 +1,3 @@
use crate::content_old::Transforms;
use crate::primitive::{PointExt, SizeExt, TransformExt}; use crate::primitive::{PointExt, SizeExt, TransformExt};
use crate::{paint, AbsExt}; use crate::{paint, AbsExt};
use bytemuck::TransparentWrapper; use bytemuck::TransparentWrapper;
@ -26,20 +25,23 @@ use typst_library::visualize::{
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct State { struct State {
/// The full transform chain
transform_chain: Transform,
/// The transform of the current item. /// The transform of the current item.
transform: Transform, transform: Transform,
/// The transform of first hard frame in the hierarchy. /// The transform of first hard frame in the hierarchy.
container_transform: Transform, container_transform_chain: Transform,
/// The size of the first hard frame in the hierarchy. /// The size of the first hard frame in the hierarchy.
size: Size, size: Size,
} }
impl State { impl State {
/// Creates a new, clean state for a given `size`. /// Creates a new, clean state for a given `size`.
fn new(size: Size) -> Self { fn new(size: Size, transform_chain: Transform, container_transform_chain: Transform) -> Self {
Self { Self {
transform_chain,
transform: Transform::identity(), transform: Transform::identity(),
container_transform: Transform::identity(), container_transform_chain,
size, size,
} }
} }
@ -50,17 +52,19 @@ impl State {
pub fn transform(&mut self, transform: Transform) { pub fn transform(&mut self, transform: Transform) {
self.transform = self.transform.pre_concat(transform); self.transform = self.transform.pre_concat(transform);
self.transform_chain = self.transform_chain.pre_concat(transform);
} }
fn set_container_transform(&mut self) { fn set_container_transform(&mut self) {
self.container_transform = self.transform; self.container_transform_chain = self.transform_chain;
} }
/// Creates the [`Transforms`] structure for the current item. /// Creates the [`Transforms`] structure for the current item.
pub fn transforms(&self, size: Size) -> Transforms { pub fn transforms(&self, size: Size) -> Transforms {
Transforms { Transforms {
transform: self.transform, transform_chain_: self.transform_chain,
container_transform: self.container_transform, transform_: self.transform,
container_transform_chain: self.container_transform_chain,
container_size: self.size, container_size: self.size,
size, size,
} }
@ -73,7 +77,11 @@ pub(crate) struct FrameContext {
impl FrameContext { impl FrameContext {
pub fn new(size: Size) -> Self { pub fn new(size: Size) -> Self {
Self { states: vec![State::new(size)] } Self { states: vec![State::new(size, Transform::identity(), Transform::identity())] }
}
pub fn derive_new(&self, size: Size) -> Self {
Self { states: vec![State::new(size, self.state().transform_chain, self.state().container_transform_chain)] }
} }
pub fn push(&mut self) { pub fn push(&mut self) {
@ -93,6 +101,21 @@ impl FrameContext {
} }
} }
/// Subset of the state used to calculate the transform of gradients and patterns.
#[derive(Debug, Clone, Copy)]
pub(super) struct Transforms {
/// The full transform chain.
pub transform_chain_: Transform,
/// The transform of the current item.
pub transform_: Transform,
/// The transform of first hard frame in the hierarchy.
pub container_transform_chain: Transform,
/// The size of the first hard frame in the hierarchy.
pub container_size: Size,
/// The size of the item.
pub size: Size,
}
#[derive(TransparentWrapper)] #[derive(TransparentWrapper)]
#[repr(transparent)] #[repr(transparent)]
struct PdfGlyph(Glyph); struct PdfGlyph(Glyph);

View File

@ -1,7 +1,6 @@
//! Convert paint types from typst to krilla. //! Convert paint types from typst to krilla.
use crate::content_old::Transforms; use crate::krilla::{process_frame, FrameContext, GlobalContext, Transforms};
use crate::krilla::{process_frame, FrameContext, GlobalContext};
use crate::primitive::{FillRuleExt, LineCapExt, LineJoinExt, TransformExt}; use crate::primitive::{FillRuleExt, LineCapExt, LineJoinExt, TransformExt};
use crate::AbsExt; use crate::AbsExt;
use krilla::geom::NormalizedF32; use krilla::geom::NormalizedF32;
@ -157,13 +156,10 @@ pub(crate) fn convert_pattern(
transforms.size.y = Abs::pt(1.0); transforms.size.y = Abs::pt(1.0);
} }
let transform = surface.ctm().invert().unwrap().pre_concat( let transform = match pattern.unwrap_relative(on_text) {
match pattern.unwrap_relative(on_text) { RelativeTo::Self_ => Transform::identity(),
RelativeTo::Self_ => transforms.transform, RelativeTo::Parent => transforms.transform_chain_.invert().unwrap().pre_concat(transforms.container_transform_chain)
RelativeTo::Parent => transforms.container_transform, }.as_krilla();
}
.as_krilla(),
);
let mut stream_builder = surface.stream_builder(); let mut stream_builder = surface.stream_builder();
let mut surface = stream_builder.surface(); let mut surface = stream_builder.surface();
@ -201,8 +197,8 @@ fn convert_gradient(
let rotation = gradient.angle().unwrap_or_else(Angle::zero); let rotation = gradient.angle().unwrap_or_else(Angle::zero);
let transform = match gradient.unwrap_relative(on_text) { let transform = match gradient.unwrap_relative(on_text) {
RelativeTo::Self_ => transforms.transform, RelativeTo::Self_ => transforms.transform_chain_,
RelativeTo::Parent => transforms.container_transform, RelativeTo::Parent => transforms.container_transform_chain,
}; };
let angle = rotation; let angle = rotation;
@ -220,7 +216,7 @@ fn convert_gradient(
match &gradient { match &gradient {
Gradient::Linear(linear) => { Gradient::Linear(linear) => {
let actual_transform = let actual_transform =
transforms.transform.invert().unwrap().pre_concat(transform); transforms.transform_chain_.invert().unwrap().pre_concat(transform);
if let Some((c, t)) = linear.stops.first() { if let Some((c, t)) = linear.stops.first() {
add_single(c, *t); add_single(c, *t);
@ -280,7 +276,7 @@ fn convert_gradient(
} }
Gradient::Radial(radial) => { Gradient::Radial(radial) => {
let actual_transform = let actual_transform =
transforms.transform.invert().unwrap().pre_concat(transform); transforms.transform_chain_.invert().unwrap().pre_concat(transform);
if let Some((c, t)) = radial.stops.first() { if let Some((c, t)) = radial.stops.first() {
add_single(c, *t); add_single(c, *t);
@ -331,7 +327,7 @@ fn convert_gradient(
let cx = size.x.to_f32() * conic.center.x.get() as f32; let cx = size.x.to_f32() * conic.center.x.get() as f32;
let cy = size.y.to_f32() * conic.center.y.get() as f32; let cy = size.y.to_f32() * conic.center.y.get() as f32;
let actual_transform = transforms let actual_transform = transforms
.transform .transform_chain_
.invert() .invert()
.unwrap() .unwrap()
.pre_concat(transform) .pre_concat(transform)