Merge branch 'main' into table-subheaders

This commit is contained in:
PgBiel 2025-05-16 02:32:14 -03:00 committed by GitHub
commit 78c87c811d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
98 changed files with 168 additions and 15 deletions

7
Cargo.lock generated
View File

@ -1259,6 +1259,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "infer"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7"
[[package]] [[package]]
name = "inotify" name = "inotify"
version = "0.11.0" version = "0.11.0"
@ -3127,6 +3133,7 @@ dependencies = [
"comemo", "comemo",
"ecow", "ecow",
"image", "image",
"infer",
"krilla", "krilla",
"krilla-svg", "krilla-svg",
"serde", "serde",

View File

@ -71,6 +71,7 @@ icu_segmenter = { version = "1.4", features = ["serde"] }
if_chain = "1" if_chain = "1"
image = { version = "0.25.5", default-features = false, features = ["png", "jpeg", "gif"] } image = { version = "0.25.5", default-features = false, features = ["png", "jpeg", "gif"] }
indexmap = { version = "2", features = ["serde"] } indexmap = { version = "2", features = ["serde"] }
infer = { version = "0.19.0", default-features = false }
kamadak-exif = "0.6" kamadak-exif = "0.6"
krilla = { version = "0.4.0", default-features = false, features = ["raster-images", "comemo", "rayon"] } krilla = { version = "0.4.0", default-features = false, features = ["raster-images", "comemo", "rayon"] }
krilla-svg = "0.1.0" krilla-svg = "0.1.0"

View File

@ -690,13 +690,34 @@ fn breakpoints(p: &Preparation, mut f: impl FnMut(usize, Breakpoint)) {
let breakpoint = if point == text.len() { let breakpoint = if point == text.len() {
Breakpoint::Mandatory Breakpoint::Mandatory
} else { } else {
const OBJ_REPLACE: char = '\u{FFFC}';
match lb.get(c) { match lb.get(c) {
// Fix for: https://github.com/unicode-org/icu4x/issues/4146
LineBreak::Glue | LineBreak::WordJoiner | LineBreak::ZWJ => continue,
LineBreak::MandatoryBreak LineBreak::MandatoryBreak
| LineBreak::CarriageReturn | LineBreak::CarriageReturn
| LineBreak::LineFeed | LineBreak::LineFeed
| LineBreak::NextLine => Breakpoint::Mandatory, | LineBreak::NextLine => Breakpoint::Mandatory,
// https://github.com/typst/typst/issues/5489
//
// OBJECT-REPLACEMENT-CHARACTERs provide Contingent Break
// opportunities before and after by default. This behaviour
// is however tailorable, see:
// https://www.unicode.org/reports/tr14/#CB
// https://www.unicode.org/reports/tr14/#TailorableBreakingRules
// https://www.unicode.org/reports/tr14/#LB20
//
// Don't provide a line breaking opportunity between a LTR-
// ISOLATE (or any other Combining Mark) and an OBJECT-
// REPLACEMENT-CHARACTER representing an inline item, if the
// LTR-ISOLATE could end up as the only character on the
// previous line.
LineBreak::CombiningMark
if text[point..].starts_with(OBJ_REPLACE)
&& last + c.len_utf8() == point =>
{
continue;
}
_ => Breakpoint::Normal, _ => Breakpoint::Normal,
} }
}; };

View File

@ -20,7 +20,7 @@ use unicode_bidi::{BidiInfo, Level as BidiLevel};
use unicode_script::{Script, UnicodeScript}; use unicode_script::{Script, UnicodeScript};
use super::{decorate, Item, Range, SpanMapper}; use super::{decorate, Item, Range, SpanMapper};
use crate::modifiers::{FrameModifiers, FrameModify}; use crate::modifiers::FrameModifyText;
/// The result of shaping text. /// The result of shaping text.
/// ///
@ -327,7 +327,7 @@ impl<'a> ShapedText<'a> {
offset += width; offset += width;
} }
frame.modify(&FrameModifiers::get_in(self.styles)); frame.modify_text(self.styles);
frame frame
} }

View File

@ -1,6 +1,6 @@
use typst_library::foundations::StyleChain; use typst_library::foundations::StyleChain;
use typst_library::layout::{Fragment, Frame, FrameItem, HideElem, Point}; use typst_library::layout::{Abs, Fragment, Frame, FrameItem, HideElem, Point, Sides};
use typst_library::model::{Destination, LinkElem}; use typst_library::model::{Destination, LinkElem, ParElem};
/// Frame-level modifications resulting from styles that do not impose any /// Frame-level modifications resulting from styles that do not impose any
/// layout structure. /// layout structure.
@ -52,14 +52,7 @@ pub trait FrameModify {
impl FrameModify for Frame { impl FrameModify for Frame {
fn modify(&mut self, modifiers: &FrameModifiers) { fn modify(&mut self, modifiers: &FrameModifiers) {
if let Some(dest) = &modifiers.dest { modify_frame(self, modifiers, None);
let size = self.size();
self.push(Point::zero(), FrameItem::Link(dest.clone(), size));
}
if modifiers.hidden {
self.hide();
}
} }
} }
@ -82,6 +75,41 @@ where
} }
} }
pub trait FrameModifyText {
/// Resolve and apply [`FrameModifiers`] for this text frame.
fn modify_text(&mut self, styles: StyleChain);
}
impl FrameModifyText for Frame {
fn modify_text(&mut self, styles: StyleChain) {
let modifiers = FrameModifiers::get_in(styles);
let expand_y = 0.5 * ParElem::leading_in(styles);
let outset = Sides::new(Abs::zero(), expand_y, Abs::zero(), expand_y);
modify_frame(self, &modifiers, Some(outset));
}
}
fn modify_frame(
frame: &mut Frame,
modifiers: &FrameModifiers,
link_box_outset: Option<Sides<Abs>>,
) {
if let Some(dest) = &modifiers.dest {
let mut pos = Point::zero();
let mut size = frame.size();
if let Some(outset) = link_box_outset {
pos.y -= outset.top;
pos.x -= outset.left;
size += outset.sum_by_axis();
}
frame.push(pos, FrameItem::Link(dest.clone(), size));
}
if modifiers.hidden {
frame.hide();
}
}
/// Performs layout and modification in one step. /// Performs layout and modification in one step.
/// ///
/// This just runs `layout(styles).modified(&FrameModifiers::get_in(styles))`, /// This just runs `layout(styles).modified(&FrameModifiers::get_in(styles))`,

View File

@ -23,6 +23,7 @@ bytemuck = { workspace = true }
comemo = { workspace = true } comemo = { workspace = true }
ecow = { workspace = true } ecow = { workspace = true }
image = { workspace = true } image = { workspace = true }
infer = { workspace = true }
krilla = { workspace = true } krilla = { workspace = true }
krilla-svg = { workspace = true } krilla-svg = { workspace = true }
serde = { workspace = true } serde = { workspace = true }

View File

@ -34,6 +34,8 @@ pub(crate) fn embed_files(
}, },
}; };
let data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(embed.data.clone()); let data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(embed.data.clone());
// TODO: update when new krilla version lands (https://github.com/LaurenzV/krilla/pull/203)
let compress = should_compress(&embed.data).unwrap_or(true);
let file = EmbeddedFile { let file = EmbeddedFile {
path, path,
@ -41,7 +43,7 @@ pub(crate) fn embed_files(
description, description,
association_kind, association_kind,
data: data.into(), data: data.into(),
compress: true, compress,
location: Some(span.into_raw().get()), location: Some(span.into_raw().get()),
}; };
@ -52,3 +54,69 @@ pub(crate) fn embed_files(
Ok(()) Ok(())
} }
fn should_compress(data: &[u8]) -> Option<bool> {
let ty = infer::get(data)?;
match ty.matcher_type() {
infer::MatcherType::App => None,
infer::MatcherType::Archive => match ty.mime_type() {
#[rustfmt::skip]
"application/zip"
| "application/vnd.rar"
| "application/gzip"
| "application/x-bzip2"
| "application/vnd.bzip3"
| "application/x-7z-compressed"
| "application/x-xz"
| "application/vnd.ms-cab-compressed"
| "application/vnd.debian.binary-package"
| "application/x-compress"
| "application/x-lzip"
| "application/x-rpm"
| "application/zstd"
| "application/x-lz4"
| "application/x-ole-storage" => Some(false),
_ => None,
},
infer::MatcherType::Audio => match ty.mime_type() {
#[rustfmt::skip]
"audio/mpeg"
| "audio/m4a"
| "audio/opus"
| "audio/ogg"
| "audio/x-flac"
| "audio/amr"
| "audio/aac"
| "audio/x-ape" => Some(false),
_ => None,
},
infer::MatcherType::Book => None,
infer::MatcherType::Doc => None,
infer::MatcherType::Font => None,
infer::MatcherType::Image => match ty.mime_type() {
#[rustfmt::skip]
"image/jpeg"
| "image/jp2"
| "image/png"
| "image/webp"
| "image/vnd.ms-photo"
| "image/heif"
| "image/avif"
| "image/jxl"
| "image/vnd.djvu" => None,
_ => None,
},
infer::MatcherType::Text => None,
infer::MatcherType::Video => match ty.mime_type() {
#[rustfmt::skip]
"video/mp4"
| "video/x-m4v"
| "video/x-matroska"
| "video/webm"
| "video/quicktime"
| "video/x-flv" => Some(false),
_ => None,
},
infer::MatcherType::Custom => None,
}
}

View File

@ -655,6 +655,7 @@ fn visit_grouping_rules<'a>(
let matching = s.rules.iter().find(|&rule| (rule.trigger)(content, &s.kind)); let matching = s.rules.iter().find(|&rule| (rule.trigger)(content, &s.kind));
// Try to continue or finish an existing grouping. // Try to continue or finish an existing grouping.
let mut i = 0;
while let Some(active) = s.groupings.last() { while let Some(active) = s.groupings.last() {
// Start a nested group if a rule with higher priority matches. // Start a nested group if a rule with higher priority matches.
if matching.is_some_and(|rule| rule.priority > active.rule.priority) { if matching.is_some_and(|rule| rule.priority > active.rule.priority) {
@ -670,6 +671,16 @@ fn visit_grouping_rules<'a>(
} }
finish_innermost_grouping(s)?; finish_innermost_grouping(s)?;
i += 1;
if i > 512 {
// It seems like this case is only hit when there is a cycle between
// a show rule and a grouping rule. The show rule produces content
// that is matched by a grouping rule, which is then again processed
// by the show rule, and so on. The two must be at an equilibrium,
// otherwise either the "maximum show rule depth" or "maximum
// grouping depth" errors are triggered.
bail!(content.span(), "maximum grouping depth exceeded");
}
} }
// Start a new grouping. // Start a new grouping.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 B

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 617 B

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 833 B

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 699 B

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 B

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 749 B

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 828 B

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 508 B

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 981 B

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 B

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

After

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 B

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 1013 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 981 B

After

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 711 B

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 B

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 795 B

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 626 B

After

Width:  |  Height:  |  Size: 632 B

View File

@ -139,3 +139,11 @@ Some texts feature many longer
words. Those are often exceedingly words. Those are often exceedingly
challenging to break in a visually challenging to break in a visually
pleasing way. pleasing way.
--- issue-5489-matrix-stray-linebreak ---
#table(
columns: (70pt,) * 1,
align: horizon + center,
stroke: 0.6pt,
[$mat(2241/2210,-71/1105;-71/1105,147/1105)$],
)

View File

@ -258,3 +258,11 @@ I am *strong*, I am _emphasized_, and I am #[special<special>].
= Hello = Hello
*strong* *strong*
--- issue-5690-oom-par-box ---
// Error: 3:6-5:1 maximum grouping depth exceeded
#show par: box
Hello
World