diff options
| author | Sébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com> | 2023-10-03 19:31:02 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-03 19:31:02 +0200 |
| commit | a4e357fb37d76d32d06ad8cc21e47bb2cc064cfd (patch) | |
| tree | 52e118513218d961cc5e8c713575049cd75a2e95 /crates/typst-library/src | |
| parent | 6b1233e127d815b38fea9ab909dd4081cdf76ca2 (diff) | |
Gradient Part 2 - Linear gradients (#2279)
Diffstat (limited to 'crates/typst-library/src')
26 files changed, 50 insertions, 36 deletions
diff --git a/crates/typst-library/src/layout/columns.rs b/crates/typst-library/src/layout/columns.rs index 961bedc5..bf111506 100644 --- a/crates/typst-library/src/layout/columns.rs +++ b/crates/typst-library/src/layout/columns.rs @@ -100,7 +100,7 @@ impl Layout for ColumnsElem { // case, the frame is first created with zero height and then // resized. let height = if regions.expand.y { region.y } else { Abs::zero() }; - let mut output = Frame::new(Size::new(regions.size.x, height)); + let mut output = Frame::hard(Size::new(regions.size.x, height)); let mut cursor = Abs::zero(); for _ in 0..columns { diff --git a/crates/typst-library/src/layout/container.rs b/crates/typst-library/src/layout/container.rs index e966398f..28a56103 100644 --- a/crates/typst-library/src/layout/container.rs +++ b/crates/typst-library/src/layout/container.rs @@ -164,6 +164,7 @@ impl Layout for BoxElem { // Apply metadata. frame.meta(styles, false); + frame.set_kind(FrameKind::Hard); Ok(Fragment::frame(frame)) } @@ -440,6 +441,7 @@ impl Layout for BlockElem { // Apply metadata. for frame in &mut frames { + frame.set_kind(FrameKind::Hard); frame.meta(styles, false); } diff --git a/crates/typst-library/src/layout/flow.rs b/crates/typst-library/src/layout/flow.rs index 796b1ac8..432ab5e8 100644 --- a/crates/typst-library/src/layout/flow.rs +++ b/crates/typst-library/src/layout/flow.rs @@ -55,7 +55,7 @@ impl Layout for FlowElem { let layoutable = child.with::<dyn Layout>().unwrap(); layouter.layout_single(vt, layoutable, styles)?; } else if child.is::<MetaElem>() { - let mut frame = Frame::new(Size::zero()); + let mut frame = Frame::soft(Size::zero()); frame.meta(styles, true); layouter.items.push(FlowItem::Frame { frame, @@ -484,7 +484,7 @@ impl<'a> FlowLayouter<'a> { size.y = self.initial.y; } - let mut output = Frame::new(size); + let mut output = Frame::soft(size); let mut ruler = FixedAlign::Start; let mut float_top_offset = Abs::zero(); let mut offset = float_top_height; diff --git a/crates/typst-library/src/layout/grid.rs b/crates/typst-library/src/layout/grid.rs index 06962524..134bdc7c 100644 --- a/crates/typst-library/src/layout/grid.rs +++ b/crates/typst-library/src/layout/grid.rs @@ -563,7 +563,7 @@ impl<'a> GridLayouter<'a> { height: Abs, y: usize, ) -> SourceResult<Frame> { - let mut output = Frame::new(Size::new(self.width, height)); + let mut output = Frame::soft(Size::new(self.width, height)); let mut pos = Point::zero(); for (x, &rcol) in self.rcols.iter().enumerate() { @@ -593,7 +593,7 @@ impl<'a> GridLayouter<'a> { // Prepare frames. let mut outputs: Vec<_> = heights .iter() - .map(|&h| Frame::new(Size::new(self.width, h))) + .map(|&h| Frame::soft(Size::new(self.width, h))) .collect(); // Prepare regions. @@ -647,7 +647,7 @@ impl<'a> GridLayouter<'a> { } // The frame for the region. - let mut output = Frame::new(size); + let mut output = Frame::soft(size); let mut pos = Point::zero(); let mut rrows = vec![]; diff --git a/crates/typst-library/src/layout/page.rs b/crates/typst-library/src/layout/page.rs index 9ec69f58..b2efed19 100644 --- a/crates/typst-library/src/layout/page.rs +++ b/crates/typst-library/src/layout/page.rs @@ -381,7 +381,7 @@ impl PageElem { if extend_to.is_some_and(|p| p.matches(page_counter.physical().get())) { // Insert empty page after the current pages. let size = area.map(Abs::is_finite).select(area, Size::zero()); - frames.push(Frame::new(size)); + frames.push(Frame::hard(size)); } let fill = self.fill(styles); diff --git a/crates/typst-library/src/layout/par.rs b/crates/typst-library/src/layout/par.rs index e41d3547..f126df76 100644 --- a/crates/typst-library/src/layout/par.rs +++ b/crates/typst-library/src/layout/par.rs @@ -714,7 +714,7 @@ fn prepare<'a>( } } Segment::Meta => { - let mut frame = Frame::new(Size::zero()); + let mut frame = Frame::soft(Size::zero()); frame.meta(styles, true); items.push(Item::Meta(frame)); } @@ -1521,7 +1521,7 @@ fn commit( } let size = Size::new(width, top + bottom); - let mut output = Frame::new(size); + let mut output = Frame::soft(size); output.set_baseline(top); // Construct the line's frame. diff --git a/crates/typst-library/src/layout/repeat.rs b/crates/typst-library/src/layout/repeat.rs index 41dede51..6b30dd50 100644 --- a/crates/typst-library/src/layout/repeat.rs +++ b/crates/typst-library/src/layout/repeat.rs @@ -54,7 +54,7 @@ impl Layout for RepeatElem { bail!(self.span(), "repeat with no size restrictions"); } - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); if piece.has_baseline() { frame.set_baseline(piece.baseline()); } diff --git a/crates/typst-library/src/layout/stack.rs b/crates/typst-library/src/layout/stack.rs index d3fcba8d..398341b2 100644 --- a/crates/typst-library/src/layout/stack.rs +++ b/crates/typst-library/src/layout/stack.rs @@ -254,7 +254,7 @@ impl<'a> StackLayouter<'a> { size.set(self.axis, full); } - let mut output = Frame::new(size); + let mut output = Frame::hard(size); let mut cursor = Abs::zero(); let mut ruler: FixedAlign = self.dir.start().into(); diff --git a/crates/typst-library/src/math/accent.rs b/crates/typst-library/src/math/accent.rs index c92f9585..a542111b 100644 --- a/crates/typst-library/src/math/accent.rs +++ b/crates/typst-library/src/math/accent.rs @@ -88,7 +88,7 @@ impl LayoutMath for AccentElem { let base_ascent = base.ascent(); let baseline = base_pos.y + base.ascent(); - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); frame.set_baseline(baseline); frame.push_frame(accent_pos, accent); frame.push_frame(base_pos, base.into_frame()); diff --git a/crates/typst-library/src/math/attach.rs b/crates/typst-library/src/math/attach.rs index c33b58e4..5d1e477e 100644 --- a/crates/typst-library/src/math/attach.rs +++ b/crates/typst-library/src/math/attach.rs @@ -106,7 +106,7 @@ impl LayoutMath for PrimesElem { // Custom amount of primes let prime = ctx.layout_fragment(&TextElem::packed('′'))?.into_frame(); let width = prime.width() * (count + 1) as f64 / 2.0; - let mut frame = Frame::new(Size::new(width, prime.height())); + let mut frame = Frame::soft(Size::new(width, prime.height())); frame.set_baseline(prime.ascent()); for i in 0..count { @@ -260,7 +260,7 @@ fn layout_attachments( return Ok(()); } - let mut frame = Frame::new(Size::new( + let mut frame = Frame::soft(Size::new( pre_width_max + base_width + post_max_width + scaled!(ctx, space_after_script), ascent + descent, )); @@ -331,7 +331,7 @@ fn attach_top_and_bottom( let base_pos = Point::new((width - base.width()) / 2.0, base_offset); let delta = base.italics_correction() / 2.0; - let mut frame = Frame::new(Size::new(width, height)); + let mut frame = Frame::soft(Size::new(width, height)); frame.set_baseline(base_pos.y + base.ascent()); frame.push_frame(base_pos, base.into_frame()); diff --git a/crates/typst-library/src/math/cancel.rs b/crates/typst-library/src/math/cancel.rs index d27031b9..4b87117c 100644 --- a/crates/typst-library/src/math/cancel.rs +++ b/crates/typst-library/src/math/cancel.rs @@ -171,7 +171,7 @@ fn draw_cancel_line( let start = Axes::new(-mid.x, mid.y).zip_map(scales, |l, s| l * s); let delta = Axes::new(width, -height).zip_map(scales, |l, s| l * s); - let mut frame = Frame::new(body_size); + let mut frame = Frame::soft(body_size); frame.push( start.to_point(), FrameItem::Shape(Geometry::Line(delta.to_point()).stroked(stroke), span), diff --git a/crates/typst-library/src/math/frac.rs b/crates/typst-library/src/math/frac.rs index 6a296203..93819184 100644 --- a/crates/typst-library/src/math/frac.rs +++ b/crates/typst-library/src/math/frac.rs @@ -110,7 +110,7 @@ fn layout( let denom_pos = Point::new((width - denom.width()) / 2.0, height - denom.height()); let baseline = line_pos.y + axis; - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); frame.set_baseline(baseline); frame.push_frame(num_pos, num); frame.push_frame(denom_pos, denom); diff --git a/crates/typst-library/src/math/fragment.rs b/crates/typst-library/src/math/fragment.rs index 5ac1f2dd..71d8d237 100644 --- a/crates/typst-library/src/math/fragment.rs +++ b/crates/typst-library/src/math/fragment.rs @@ -148,7 +148,7 @@ impl MathFragment { Self::Glyph(glyph) => glyph.into_frame(), Self::Variant(variant) => variant.frame, Self::Frame(fragment) => fragment.frame, - _ => Frame::new(self.size()), + _ => Frame::soft(self.size()), } } @@ -309,7 +309,7 @@ impl GlyphFragment { }], }; let size = Size::new(self.width, self.ascent + self.descent); - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); frame.set_baseline(self.ascent); frame.push(Point::with_y(self.ascent + self.shift), FrameItem::Text(item)); frame.meta_iter(self.meta); diff --git a/crates/typst-library/src/math/matrix.rs b/crates/typst-library/src/math/matrix.rs index 68f7f438..1dee5434 100644 --- a/crates/typst-library/src/math/matrix.rs +++ b/crates/typst-library/src/math/matrix.rs @@ -396,7 +396,7 @@ fn layout_mat_body( let ncols = rows.first().map_or(0, |row| row.len()); let nrows = rows.len(); if ncols == 0 || nrows == 0 { - return Ok(Frame::new(Size::zero())); + return Ok(Frame::soft(Size::zero())); } // Before the full matrix body can be laid out, the @@ -431,7 +431,7 @@ fn layout_mat_body( heights.iter().map(|&(a, b)| a + b).sum::<Abs>() + gap.y * (nrows - 1) as f64; // Width starts at zero because it can't be calculated until later - let mut frame = Frame::new(Size::new(Abs::zero(), total_height)); + let mut frame = Frame::soft(Size::new(Abs::zero(), total_height)); let mut x = Abs::zero(); diff --git a/crates/typst-library/src/math/root.rs b/crates/typst-library/src/math/root.rs index 03d0a212..49ceb75f 100644 --- a/crates/typst-library/src/math/root.rs +++ b/crates/typst-library/src/math/root.rs @@ -109,7 +109,7 @@ fn layout( let line_pos = Point::new(radicand_x, radicand_y - gap - (thickness / 2.0)); let radicand_pos = Point::new(radicand_x, radicand_y); - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); frame.set_baseline(ascent); if let Some(index) = index { diff --git a/crates/typst-library/src/math/row.rs b/crates/typst-library/src/math/row.rs index cf3a8af2..70813598 100644 --- a/crates/typst-library/src/math/row.rs +++ b/crates/typst-library/src/math/row.rs @@ -156,7 +156,7 @@ impl MathRow { } let AlignmentResult { points, width } = alignments(&rows); - let mut frame = Frame::new(Size::zero()); + let mut frame = Frame::soft(Size::zero()); for (i, row) in rows.into_iter().enumerate() { let sub = row.into_line_frame(&points, align); @@ -179,7 +179,7 @@ impl MathRow { fn into_line_frame(self, points: &[Abs], align: FixedAlign) -> Frame { let ascent = self.ascent(); - let mut frame = Frame::new(Size::new(Abs::zero(), ascent + self.descent())); + let mut frame = Frame::soft(Size::new(Abs::zero(), ascent + self.descent())); frame.set_baseline(ascent); let mut next_x = { diff --git a/crates/typst-library/src/math/stretch.rs b/crates/typst-library/src/math/stretch.rs index 910f7a81..e9bf6890 100644 --- a/crates/typst-library/src/math/stretch.rs +++ b/crates/typst-library/src/math/stretch.rs @@ -161,7 +161,7 @@ fn assemble( baseline = full / 2.0 + axis; } - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); let mut offset = Abs::zero(); frame.set_baseline(baseline); frame.meta_iter(base.meta); diff --git a/crates/typst-library/src/math/underover.rs b/crates/typst-library/src/math/underover.rs index 3e8dba1a..5d010c28 100644 --- a/crates/typst-library/src/math/underover.rs +++ b/crates/typst-library/src/math/underover.rs @@ -89,7 +89,7 @@ fn layout_underoverline( let size = Size::new(width, height); let content_class = content.class().unwrap_or(MathClass::Normal); - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); frame.set_baseline(baseline); frame.push_frame(content_pos, content.into_frame()); frame.push( @@ -295,7 +295,7 @@ pub(super) fn stack( .collect(); let mut y = Abs::zero(); - let mut frame = Frame::new(Size::new( + let mut frame = Frame::soft(Size::new( width, rows.iter().map(|row| row.height()).sum::<Abs>() + rows.len().saturating_sub(1) as f64 * gap, diff --git a/crates/typst-library/src/text/mod.rs b/crates/typst-library/src/text/mod.rs index 8bce5e8a..94ef426f 100644 --- a/crates/typst-library/src/text/mod.rs +++ b/crates/typst-library/src/text/mod.rs @@ -16,6 +16,7 @@ pub use self::shift::*; use rustybuzz::Tag; use ttf_parser::Rect; +use typst::diag::{bail, error, SourceResult}; use typst::font::{Font, FontStretch, FontStyle, FontWeight, VerticalFontMetric}; use crate::layout::ParElem; @@ -169,13 +170,23 @@ pub struct TextElem { #[default(Abs::pt(11.0))] pub size: TextSize, - /// The glyph fill color. + /// The glyph fill paint. /// /// ```example /// #set text(fill: red) /// This text is red. /// ``` - #[parse(args.named_or_find("fill")?)] + #[parse({ + let paint: Option<Spanned<Paint>> = args.named_or_find("fill")?; + if let Some(paint) = &paint { + // TODO: Implement gradients on text. + if matches!(paint.v, Paint::Gradient(_)) { + bail!(error!(paint.span, "text fill must be a solid color") + .with_hint("gradients on text will be supported soon")); + } + } + paint.map(|paint| paint.v) + })] #[default(Color::BLACK.into())] pub fill: Paint, diff --git a/crates/typst-library/src/text/shaping.rs b/crates/typst-library/src/text/shaping.rs index 4fe6b49b..df30a9c8 100644 --- a/crates/typst-library/src/text/shaping.rs +++ b/crates/typst-library/src/text/shaping.rs @@ -228,7 +228,7 @@ impl<'a> ShapedText<'a> { let size = Size::new(self.width, top + bottom); let mut offset = Abs::zero(); - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); frame.set_baseline(top); let shift = TextElem::baseline_in(self.styles); diff --git a/crates/typst-library/src/visualize/image.rs b/crates/typst-library/src/visualize/image.rs index b4a9015f..b0c9d8ea 100644 --- a/crates/typst-library/src/visualize/image.rs +++ b/crates/typst-library/src/visualize/image.rs @@ -206,7 +206,7 @@ impl Layout for ImageElem { // First, place the image in a frame of exactly its size and then resize // the frame to the target size, center aligning the image in the // process. - let mut frame = Frame::new(fitted); + let mut frame = Frame::soft(fitted); frame.push(Point::zero(), FrameItem::Image(image, fitted, self.span())); frame.resize(target, Axes::splat(FixedAlign::Center)); diff --git a/crates/typst-library/src/visualize/line.rs b/crates/typst-library/src/visualize/line.rs index 9960a2d3..6837caf1 100644 --- a/crates/typst-library/src/visualize/line.rs +++ b/crates/typst-library/src/visualize/line.rs @@ -75,7 +75,7 @@ impl Layout for LineElem { let size = start.max(start + delta).max(Size::zero()); let target = regions.expand.select(regions.size, size); - let mut frame = Frame::new(target); + let mut frame = Frame::soft(target); let shape = Geometry::Line(delta.to_point()).stroked(stroke); frame.push(start.to_point(), FrameItem::Shape(shape, self.span())); Ok(Fragment::frame(frame)) diff --git a/crates/typst-library/src/visualize/mod.rs b/crates/typst-library/src/visualize/mod.rs index a013853f..e39d50bc 100644 --- a/crates/typst-library/src/visualize/mod.rs +++ b/crates/typst-library/src/visualize/mod.rs @@ -18,6 +18,7 @@ use crate::prelude::*; pub(super) fn define(global: &mut Scope) { global.category("visualize"); global.define_type::<Color>(); + global.define_type::<Gradient>(); global.define_type::<Stroke>(); global.define_elem::<ImageElem>(); global.define_elem::<LineElem>(); diff --git a/crates/typst-library/src/visualize/path.rs b/crates/typst-library/src/visualize/path.rs index c252e95f..79364b07 100644 --- a/crates/typst-library/src/visualize/path.rs +++ b/crates/typst-library/src/visualize/path.rs @@ -82,7 +82,7 @@ impl Layout for PathElem { let mut size = Size::zero(); if points.is_empty() { - return Ok(Fragment::frame(Frame::new(size))); + return Ok(Fragment::frame(Frame::soft(size))); } // Only create a path if there are more than zero points. @@ -138,7 +138,7 @@ impl Layout for PathElem { Smart::Custom(stroke) => stroke.map(Stroke::unwrap_or_default), }; - let mut frame = Frame::new(size); + let mut frame = Frame::soft(size); let shape = Shape { geometry: Geometry::Path(path), stroke, fill }; frame.push(Point::zero(), FrameItem::Shape(shape, self.span())); diff --git a/crates/typst-library/src/visualize/polygon.rs b/crates/typst-library/src/visualize/polygon.rs index 9f573467..1d19a94d 100644 --- a/crates/typst-library/src/visualize/polygon.rs +++ b/crates/typst-library/src/visualize/polygon.rs @@ -130,7 +130,7 @@ impl Layout for PolygonElem { .collect(); let size = points.iter().fold(Point::zero(), |max, c| c.max(max)).to_size(); - let mut frame = Frame::new(size); + let mut frame = Frame::hard(size); // Only create a path if there are more than zero points. if points.is_empty() { diff --git a/crates/typst-library/src/visualize/shape.rs b/crates/typst-library/src/visualize/shape.rs index 64d1ece6..3d4368f5 100644 --- a/crates/typst-library/src/visualize/shape.rs +++ b/crates/typst-library/src/visualize/shape.rs @@ -492,7 +492,7 @@ fn layout( if kind.is_quadratic() { size = Size::splat(size.min_by_side()); } - frame = Frame::new(size); + frame = Frame::soft(size); } // Prepare stroke. |
