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::{paint, AbsExt};
use bytemuck::TransparentWrapper;
@ -26,20 +25,23 @@ use typst_library::visualize::{
#[derive(Debug, Clone)]
struct State {
/// The full transform chain
transform_chain: Transform,
/// The transform of the current item.
transform: Transform,
/// 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.
size: Size,
}
impl State {
/// 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 {
transform_chain,
transform: Transform::identity(),
container_transform: Transform::identity(),
container_transform_chain,
size,
}
}
@ -50,17 +52,19 @@ impl State {
pub fn transform(&mut self, transform: Transform) {
self.transform = self.transform.pre_concat(transform);
self.transform_chain = self.transform_chain.pre_concat(transform);
}
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.
pub fn transforms(&self, size: Size) -> Transforms {
Transforms {
transform: self.transform,
container_transform: self.container_transform,
transform_chain_: self.transform_chain,
transform_: self.transform,
container_transform_chain: self.container_transform_chain,
container_size: self.size,
size,
}
@ -73,7 +77,11 @@ pub(crate) struct FrameContext {
impl FrameContext {
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) {
@ -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)]
#[repr(transparent)]
struct PdfGlyph(Glyph);

View File

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