mirror of
https://github.com/typst/typst
synced 2025-08-15 15:38:33 +08:00
part 1
This commit is contained in:
parent
38fba0a02c
commit
b464c46a8a
310
Cargo.lock
generated
310
Cargo.lock
generated
@ -217,6 +217,20 @@ name = "bytemuck"
|
||||
version = "1.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@ -749,6 +763,15 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -761,6 +784,15 @@ version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
||||
|
||||
[[package]]
|
||||
name = "font-types"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontconfig-parser"
|
||||
version = "0.5.7"
|
||||
@ -781,7 +813,33 @@ dependencies = [
|
||||
"memmap2",
|
||||
"slotmap",
|
||||
"tinyvec",
|
||||
"ttf-parser",
|
||||
"ttf-parser 0.24.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdb"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3a6f9af55fb97ad673fb7a69533eb2f967648a06fa21f8c9bb2cd6d33975716"
|
||||
dependencies = [
|
||||
"fontconfig-parser",
|
||||
"log",
|
||||
"memmap2",
|
||||
"slotmap",
|
||||
"tinyvec",
|
||||
"ttf-parser 0.24.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdb"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905"
|
||||
dependencies = [
|
||||
"log",
|
||||
"slotmap",
|
||||
"tinyvec",
|
||||
"ttf-parser 0.25.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1183,6 +1241,16 @@ dependencies = [
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image-webp"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f"
|
||||
dependencies = [
|
||||
"byteorder-lite",
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imagesize"
|
||||
version = "0.13.0"
|
||||
@ -1310,6 +1378,36 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "krilla"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/LaurenzV/krilla#478e4639001bc96118a6f651f06d42d37d0be7a8"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bumpalo",
|
||||
"flate2",
|
||||
"float-cmp 0.10.0",
|
||||
"fontdb 0.22.0",
|
||||
"gif",
|
||||
"image-webp 0.1.3",
|
||||
"imagesize",
|
||||
"miniz_oxide",
|
||||
"once_cell",
|
||||
"pdf-writer",
|
||||
"resvg 0.44.0",
|
||||
"rustybuzz 0.18.0",
|
||||
"siphasher",
|
||||
"skrifa",
|
||||
"subsetter",
|
||||
"tiny-skia",
|
||||
"tiny-skia-path",
|
||||
"usvg 0.44.0",
|
||||
"xmp-writer",
|
||||
"yoke",
|
||||
"zune-jpeg",
|
||||
"zune-png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kurbo"
|
||||
version = "0.11.1"
|
||||
@ -1738,9 +1836,8 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||
|
||||
[[package]]
|
||||
name = "pdf-writer"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5df03c7d216de06f93f398ef06f1385a60f2c597bb96f8195c8d98e08a26b1d5"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/LaurenzV/pdf-writer?rev=f95a19c#f95a19c07a1b3e3ee021c1199e91f19badb57d46"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"itoa",
|
||||
@ -1808,7 +1905,7 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d15afa937836bf3d876f5a04ce28810c06045857bf46c3d0d31073b8aada5494"
|
||||
dependencies = [
|
||||
"ttf-parser",
|
||||
"ttf-parser 0.24.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1997,6 +2094,16 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "read-fonts"
|
||||
version = "0.22.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"font-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.8"
|
||||
@ -2048,18 +2155,35 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "resvg"
|
||||
version = "0.43.0"
|
||||
version = "0.44.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7314563c59c7ce31c18e23ad3dd092c37b928a0fa4e1c0a1a6504351ab411d1"
|
||||
checksum = "4a325d5e8d1cebddd070b13f44cec8071594ab67d1012797c121f27a669b7958"
|
||||
dependencies = [
|
||||
"gif",
|
||||
"image-webp",
|
||||
"image-webp 0.1.3",
|
||||
"log",
|
||||
"pico-args",
|
||||
"rgb",
|
||||
"svgtypes",
|
||||
"tiny-skia",
|
||||
"usvg",
|
||||
"usvg 0.44.0",
|
||||
"zune-jpeg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resvg"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd43d1c474e9dadf09a8fdf22d713ba668b499b5117b9b9079500224e26b5b29"
|
||||
dependencies = [
|
||||
"gif",
|
||||
"image-webp 0.2.1",
|
||||
"log",
|
||||
"pico-args",
|
||||
"rgb",
|
||||
"svgtypes",
|
||||
"tiny-skia",
|
||||
"usvg 0.45.0",
|
||||
"zune-jpeg",
|
||||
]
|
||||
|
||||
@ -2130,9 +2254,27 @@ dependencies = [
|
||||
"core_maths",
|
||||
"log",
|
||||
"smallvec",
|
||||
"ttf-parser",
|
||||
"unicode-bidi-mirroring",
|
||||
"unicode-ccc",
|
||||
"ttf-parser 0.24.1",
|
||||
"unicode-bidi-mirroring 0.3.0",
|
||||
"unicode-ccc 0.3.0",
|
||||
"unicode-properties",
|
||||
"unicode-script",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustybuzz"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"bytemuck",
|
||||
"core_maths",
|
||||
"log",
|
||||
"smallvec",
|
||||
"ttf-parser 0.25.1",
|
||||
"unicode-bidi-mirroring 0.4.0",
|
||||
"unicode-ccc 0.4.0",
|
||||
"unicode-properties",
|
||||
"unicode-script",
|
||||
]
|
||||
@ -2315,6 +2457,16 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||
|
||||
[[package]]
|
||||
name = "skrifa"
|
||||
version = "0.22.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"read-fonts",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.0.7"
|
||||
@ -2361,7 +2513,7 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||
dependencies = [
|
||||
"float-cmp",
|
||||
"float-cmp 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2405,28 +2557,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "subsetter"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74f98178f34057d4d4de93d68104007c6dea4dfac930204a69ab4622daefa648"
|
||||
|
||||
[[package]]
|
||||
name = "svg2pdf"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5014c9dadcf318fb7ef8c16438e95abcc9de1ae24d60d5bccc64c55100c50364"
|
||||
dependencies = [
|
||||
"fontdb",
|
||||
"image",
|
||||
"log",
|
||||
"miniz_oxide",
|
||||
"once_cell",
|
||||
"pdf-writer",
|
||||
"resvg",
|
||||
"siphasher",
|
||||
"subsetter",
|
||||
"tiny-skia",
|
||||
"ttf-parser",
|
||||
"usvg",
|
||||
]
|
||||
source = "git+https://github.com/typst/subsetter?rev=172416a#172416a806246e6e9010d400d5690ca7a026e53d"
|
||||
|
||||
[[package]]
|
||||
name = "svgtypes"
|
||||
@ -2716,6 +2847,15 @@ dependencies = [
|
||||
"core_maths",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
||||
dependencies = [
|
||||
"core_maths",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "two-face"
|
||||
version = "0.4.3"
|
||||
@ -2897,7 +3037,7 @@ dependencies = [
|
||||
"ecow",
|
||||
"env_proxy",
|
||||
"flate2",
|
||||
"fontdb",
|
||||
"fontdb 0.21.0",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"openssl",
|
||||
@ -2927,9 +3067,9 @@ dependencies = [
|
||||
"icu_provider_blob",
|
||||
"icu_segmenter",
|
||||
"kurbo",
|
||||
"rustybuzz",
|
||||
"rustybuzz 0.20.1",
|
||||
"smallvec",
|
||||
"ttf-parser",
|
||||
"ttf-parser 0.25.1",
|
||||
"typst-assets",
|
||||
"typst-library",
|
||||
"typst-macros",
|
||||
@ -2956,7 +3096,7 @@ dependencies = [
|
||||
"csv",
|
||||
"ecow",
|
||||
"flate2",
|
||||
"fontdb",
|
||||
"fontdb 0.21.0",
|
||||
"hayagriva",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
@ -2976,7 +3116,7 @@ dependencies = [
|
||||
"regex-syntax",
|
||||
"roxmltree",
|
||||
"rust_decimal",
|
||||
"rustybuzz",
|
||||
"rustybuzz 0.20.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml 0.9.34+deprecated",
|
||||
@ -2985,7 +3125,7 @@ dependencies = [
|
||||
"syntect",
|
||||
"time",
|
||||
"toml",
|
||||
"ttf-parser",
|
||||
"ttf-parser 0.25.1",
|
||||
"two-face",
|
||||
"typed-arena",
|
||||
"typst-assets",
|
||||
@ -2998,7 +3138,7 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
"unicode-segmentation",
|
||||
"unscanny",
|
||||
"usvg",
|
||||
"usvg 0.45.0",
|
||||
"wasmi",
|
||||
"xmlwriter",
|
||||
]
|
||||
@ -3017,26 +3157,17 @@ dependencies = [
|
||||
name = "typst-pdf"
|
||||
version = "0.13.1"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"base64",
|
||||
"bytemuck",
|
||||
"comemo",
|
||||
"ecow",
|
||||
"image",
|
||||
"indexmap 2.7.1",
|
||||
"miniz_oxide",
|
||||
"pdf-writer",
|
||||
"serde",
|
||||
"subsetter",
|
||||
"svg2pdf",
|
||||
"ttf-parser",
|
||||
"krilla",
|
||||
"typst-assets",
|
||||
"typst-library",
|
||||
"typst-macros",
|
||||
"typst-syntax",
|
||||
"typst-timing",
|
||||
"typst-utils",
|
||||
"xmp-writer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3063,9 +3194,9 @@ dependencies = [
|
||||
"comemo",
|
||||
"image",
|
||||
"pixglyph",
|
||||
"resvg",
|
||||
"resvg 0.45.0",
|
||||
"tiny-skia",
|
||||
"ttf-parser",
|
||||
"ttf-parser 0.25.1",
|
||||
"typst-library",
|
||||
"typst-macros",
|
||||
"typst-timing",
|
||||
@ -3080,7 +3211,7 @@ dependencies = [
|
||||
"ecow",
|
||||
"flate2",
|
||||
"image",
|
||||
"ttf-parser",
|
||||
"ttf-parser 0.25.1",
|
||||
"typst-library",
|
||||
"typst-macros",
|
||||
"typst-timing",
|
||||
@ -3189,12 +3320,24 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64af057ad7466495ca113126be61838d8af947f41d93a949980b2389a118082f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi-mirroring"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ccc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "260bc6647b3893a9a90668360803a15f96b85a5257b1c3a0c3daf6ae2496de42"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ccc"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
@ -3288,20 +3431,47 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "usvg"
|
||||
version = "0.43.0"
|
||||
version = "0.44.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6803057b5cbb426e9fb8ce2216f3a9b4ca1dd2c705ba3cbebc13006e437735fd"
|
||||
checksum = "7447e703d7223b067607655e625e0dbca80822880248937da65966194c4864e6"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"data-url",
|
||||
"flate2",
|
||||
"fontdb",
|
||||
"fontdb 0.22.0",
|
||||
"imagesize",
|
||||
"kurbo",
|
||||
"log",
|
||||
"pico-args",
|
||||
"roxmltree",
|
||||
"rustybuzz",
|
||||
"rustybuzz 0.18.0",
|
||||
"simplecss",
|
||||
"siphasher",
|
||||
"strict-num",
|
||||
"svgtypes",
|
||||
"tiny-skia-path",
|
||||
"unicode-bidi",
|
||||
"unicode-script",
|
||||
"unicode-vo",
|
||||
"xmlwriter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usvg"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ac8e0e3e4696253dc06167990b3fe9a2668ab66270adf949a464db4088cb354"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"data-url",
|
||||
"flate2",
|
||||
"fontdb 0.23.0",
|
||||
"imagesize",
|
||||
"kurbo",
|
||||
"log",
|
||||
"pico-args",
|
||||
"roxmltree",
|
||||
"rustybuzz 0.20.1",
|
||||
"simplecss",
|
||||
"siphasher",
|
||||
"strict-num",
|
||||
@ -3661,8 +3831,7 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
|
||||
[[package]]
|
||||
name = "xmp-writer"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb5954c9ca6dcc869e98d3e42760ed9dab08f3e70212b31d7ab8ae7f3b7a487"
|
||||
source = "git+https://github.com/LaurenzV/xmp-writer?rev=a1cbb887#a1cbb887a84376fea4d7590d41c194a332840549"
|
||||
|
||||
[[package]]
|
||||
name = "xz2"
|
||||
@ -3830,6 +3999,15 @@ version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
||||
|
||||
[[package]]
|
||||
name = "zune-inflate"
|
||||
version = "0.2.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-jpeg"
|
||||
version = "0.4.14"
|
||||
@ -3838,3 +4016,13 @@ checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
|
||||
dependencies = [
|
||||
"zune-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-png"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d29c085769c6f29effea890f093120ac019375fdc789d2a496ba8ba96c77509"
|
||||
dependencies = [
|
||||
"zune-core",
|
||||
"zune-inflate",
|
||||
]
|
||||
|
@ -70,6 +70,7 @@ if_chain = "1"
|
||||
image = { version = "0.25.5", default-features = false, features = ["png", "jpeg", "gif"] }
|
||||
indexmap = { version = "2", features = ["serde"] }
|
||||
kamadak-exif = "0.6"
|
||||
krilla = { git = "https://github.com/LaurenzV/krilla" }
|
||||
kurbo = "0.11"
|
||||
libfuzzer-sys = "0.4"
|
||||
lipsum = "0.9"
|
||||
@ -96,10 +97,10 @@ quote = "1"
|
||||
rayon = "1.7.0"
|
||||
regex = "1"
|
||||
regex-syntax = "0.8"
|
||||
resvg = { version = "0.43", default-features = false, features = ["raster-images"] }
|
||||
resvg = { version = "0.45.0", default-features = false, features = ["raster-images"] }
|
||||
roxmltree = "0.20"
|
||||
rust_decimal = { version = "1.36.0", default-features = false, features = ["maths"] }
|
||||
rustybuzz = "0.18"
|
||||
rustybuzz = "0.20.1"
|
||||
same-file = "1"
|
||||
self-replace = "1.3.7"
|
||||
semver = "1"
|
||||
@ -122,7 +123,7 @@ time = { version = "0.3.20", features = ["formatting", "macros", "parsing"] }
|
||||
tiny_http = "0.12"
|
||||
tiny-skia = "0.11"
|
||||
toml = { version = "0.8", default-features = false, features = ["parse", "display"] }
|
||||
ttf-parser = "0.24.1"
|
||||
ttf-parser = "0.25.1"
|
||||
two-face = { version = "0.4.3", default-features = false, features = ["syntect-fancy"] }
|
||||
typed-arena = "2"
|
||||
unicode-bidi = "0.3.18"
|
||||
@ -133,7 +134,7 @@ unicode-normalization = "0.1.24"
|
||||
unicode-segmentation = "1"
|
||||
unscanny = "0.1"
|
||||
ureq = { version = "2", default-features = false, features = ["native-tls", "gzip", "json"] }
|
||||
usvg = { version = "0.43", default-features = false, features = ["text"] }
|
||||
usvg = { version = "0.45.0", default-features = false, features = ["text"] }
|
||||
walkdir = "2"
|
||||
wasmi = "0.40.0"
|
||||
web-sys = "0.3"
|
||||
|
@ -22,7 +22,7 @@ pub struct RasterImage(Arc<Repr>);
|
||||
struct Repr {
|
||||
data: Bytes,
|
||||
format: RasterFormat,
|
||||
dynamic: image::DynamicImage,
|
||||
dynamic: Arc<DynamicImage>,
|
||||
icc: Option<Bytes>,
|
||||
dpi: Option<f64>,
|
||||
}
|
||||
@ -136,7 +136,7 @@ impl RasterImage {
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Self(Arc::new(Repr { data, format, dynamic, icc, dpi })))
|
||||
Ok(Self(Arc::new(Repr { data, format, dynamic: Arc::new(dynamic), icc, dpi })))
|
||||
}
|
||||
|
||||
/// The raw image data.
|
||||
@ -167,7 +167,7 @@ impl RasterImage {
|
||||
}
|
||||
|
||||
/// Access the underlying dynamic image.
|
||||
pub fn dynamic(&self) -> &image::DynamicImage {
|
||||
pub fn dynamic(&self) -> &Arc<DynamicImage> {
|
||||
&self.0.dynamic
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,8 @@ use krilla::error::KrillaError;
|
||||
use krilla::page::PageLabel;
|
||||
use krilla::path::PathBuilder;
|
||||
use krilla::surface::Surface;
|
||||
use krilla::validation::ValidationError;
|
||||
use krilla::version::PdfVersion;
|
||||
use krilla::{Document, PageSettings, SerializeSettings};
|
||||
use krilla::configure::{Configuration, PdfVersion, ValidationError};
|
||||
use typst_library::diag::{bail, SourceResult};
|
||||
use typst_library::foundations::NativeElement;
|
||||
use typst_library::introspection::Location;
|
||||
@ -34,7 +33,7 @@ pub fn convert(
|
||||
typst_document: &PagedDocument,
|
||||
options: &PdfOptions,
|
||||
) -> SourceResult<Vec<u8>> {
|
||||
let version = get_version(options)?;
|
||||
let configuration = get_configuration(options)?;
|
||||
|
||||
let settings = SerializeSettings {
|
||||
compress_content_streams: true,
|
||||
@ -42,9 +41,8 @@ pub fn convert(
|
||||
ascii_compatible: false,
|
||||
xmp_metadata: true,
|
||||
cmyk_profile: None,
|
||||
validator: options.validator,
|
||||
configuration,
|
||||
enable_tagging: false,
|
||||
pdf_version: version,
|
||||
};
|
||||
|
||||
let mut document = Document::new_with(settings);
|
||||
@ -295,7 +293,7 @@ pub(crate) fn handle_group(
|
||||
fc.state_mut().pre_concat(group.transform);
|
||||
|
||||
let clip_path = group
|
||||
.clip_path
|
||||
.clip
|
||||
.as_ref()
|
||||
.and_then(|p| {
|
||||
let mut builder = PathBuilder::new();
|
||||
@ -321,6 +319,8 @@ pub(crate) fn handle_group(
|
||||
|
||||
/// Finish a krilla document and handle export errors.
|
||||
fn finish(document: Document, gc: GlobalContext) -> SourceResult<Vec<u8>> {
|
||||
let validator: krilla::configure::Validator = gc.options.validator.into();
|
||||
|
||||
match document.finish() {
|
||||
Ok(r) => Ok(r),
|
||||
Err(e) => match e {
|
||||
@ -336,8 +336,9 @@ fn finish(document: Document, gc: GlobalContext) -> SourceResult<Vec<u8>> {
|
||||
// We can only produce 1 error, so just take the first one.
|
||||
let prefix = format!(
|
||||
"validated export for {} failed:",
|
||||
gc.options.validator.as_str()
|
||||
validator.as_str()
|
||||
);
|
||||
|
||||
match &ve[0] {
|
||||
ValidationError::TooLongString => {
|
||||
bail!(Span::detached(), "{prefix} a PDF string longer \
|
||||
@ -407,6 +408,16 @@ fn finish(document: Document, gc: GlobalContext) -> SourceResult<Vec<u8>> {
|
||||
hint: "export using a different standard that supports transparency"
|
||||
);
|
||||
}
|
||||
ValidationError::ImageInterpolation => {
|
||||
bail!(Span::detached(), "{prefix} document contains an image with smooth interpolation";
|
||||
hint: "such images are not supported in this export mode"
|
||||
);
|
||||
}
|
||||
ValidationError::EmbeddedFile(_) => {
|
||||
bail!(Span::detached(), "{prefix} document contains an embedded file";
|
||||
hint: "embedded files are not supported in this export mode"
|
||||
);
|
||||
}
|
||||
|
||||
// The below errors cannot occur yet, only once Typst supports full PDF/A
|
||||
// and PDF/UA.
|
||||
@ -423,16 +434,20 @@ fn finish(document: Document, gc: GlobalContext) -> SourceResult<Vec<u8>> {
|
||||
bail!(Span::detached(), "{prefix} missing document language";
|
||||
hint: "set the language of the document");
|
||||
}
|
||||
|
||||
// Needs to be set by typst-pdf.
|
||||
ValidationError::MissingHeadingTitle => {
|
||||
bail!(Span::detached(), "{prefix} missing heading title";
|
||||
hint: "please report this as a bug");
|
||||
}
|
||||
// Needs to be set by typst-pdf.
|
||||
ValidationError::MissingDocumentOutline => {
|
||||
bail!(Span::detached(), "{prefix} missing document outline";
|
||||
hint: "please report this as a bug");
|
||||
}
|
||||
ValidationError::MissingTagging => {
|
||||
bail!(Span::detached(), "{prefix} missing document tags";
|
||||
hint: "please report this as a bug");
|
||||
}
|
||||
ValidationError::NoDocumentTitle => {
|
||||
bail!(Span::detached(), "{prefix} missing document title";
|
||||
hint: "set the title of the document");
|
||||
@ -494,21 +509,31 @@ fn collect_named_destinations(
|
||||
locs_to_names
|
||||
}
|
||||
|
||||
fn get_version(options: &PdfOptions) -> SourceResult<PdfVersion> {
|
||||
match options.pdf_version {
|
||||
None => Ok(options.validator.recommended_version()),
|
||||
Some(v) => {
|
||||
if !options.validator.compatible_with_version(v) {
|
||||
let v_string = v.as_str();
|
||||
let s_string = options.validator.as_str();
|
||||
fn get_configuration(options: &PdfOptions) -> SourceResult<Configuration> {
|
||||
let config = match (options.pdf_version, options.validator) {
|
||||
(None, None) => Configuration::new_with_version(PdfVersion::Pdf17),
|
||||
(Some(pdf), None) => Configuration::new_with_version(pdf.into()),
|
||||
(None, Some(v)) => Configuration::new_with_validator(v.into()),
|
||||
(Some(pdf), Some(v)) => {
|
||||
let pdf = pdf.into();
|
||||
let v = v.into();
|
||||
|
||||
match Configuration::new_with(v, pdf) {
|
||||
Some(c) => c,
|
||||
None => {
|
||||
let pdf_string = pdf.as_str();
|
||||
let s_string = v.as_str();
|
||||
|
||||
let h_message = format!(
|
||||
"export using {} instead",
|
||||
options.validator.recommended_version().as_str()
|
||||
v.recommended_version().as_str()
|
||||
);
|
||||
bail!(Span::detached(), "{v_string} is not compatible with standard {s_string}"; hint: "{h_message}");
|
||||
} else {
|
||||
Ok(v)
|
||||
|
||||
bail!(Span::detached(), "{pdf_string} is not compatible with standard {s_string}"; hint: "{h_message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
@ -1,122 +0,0 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ecow::EcoString;
|
||||
use pdf_writer::types::AssociationKind;
|
||||
use pdf_writer::{Filter, Finish, Name, Ref, Str, TextStr};
|
||||
use typst_library::diag::{bail, SourceResult};
|
||||
use typst_library::foundations::{NativeElement, Packed, StyleChain};
|
||||
use typst_library::pdf::{EmbedElem, EmbeddedFileRelationship};
|
||||
|
||||
use crate::catalog::{document_date, pdf_date};
|
||||
use crate::{deflate, NameExt, PdfChunk, StrExt, WithGlobalRefs};
|
||||
|
||||
/// Query for all [`EmbedElem`] and write them and their file specifications.
|
||||
///
|
||||
/// This returns a map of embedding names and references so that we can later
|
||||
/// add them to the catalog's `/Names` dictionary.
|
||||
pub fn write_embedded_files(
|
||||
ctx: &WithGlobalRefs,
|
||||
) -> SourceResult<(PdfChunk, BTreeMap<EcoString, Ref>)> {
|
||||
let mut chunk = PdfChunk::new();
|
||||
let mut embedded_files = BTreeMap::default();
|
||||
|
||||
let elements = ctx.document.introspector.query(&EmbedElem::elem().select());
|
||||
for elem in &elements {
|
||||
if !ctx.options.standards.embedded_files {
|
||||
// PDF/A-2 requires embedded files to be PDF/A-1 or PDF/A-2,
|
||||
// which we don't currently check.
|
||||
bail!(
|
||||
elem.span(),
|
||||
"file embeddings are not currently supported for PDF/A-2";
|
||||
hint: "PDF/A-3 supports arbitrary embedded files"
|
||||
);
|
||||
}
|
||||
|
||||
let embed = elem.to_packed::<EmbedElem>().unwrap();
|
||||
if embed.path.derived.len() > Str::PDFA_LIMIT {
|
||||
bail!(embed.span(), "embedded file path is too long");
|
||||
}
|
||||
|
||||
let id = embed_file(ctx, &mut chunk, embed)?;
|
||||
if embedded_files.insert(embed.path.derived.clone(), id).is_some() {
|
||||
bail!(
|
||||
elem.span(),
|
||||
"duplicate embedded file for path `{}`", embed.path.derived;
|
||||
hint: "embedded file paths must be unique",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok((chunk, embedded_files))
|
||||
}
|
||||
|
||||
/// Write the embedded file stream and its file specification.
|
||||
fn embed_file(
|
||||
ctx: &WithGlobalRefs,
|
||||
chunk: &mut PdfChunk,
|
||||
embed: &Packed<EmbedElem>,
|
||||
) -> SourceResult<Ref> {
|
||||
let embedded_file_stream_ref = chunk.alloc.bump();
|
||||
let file_spec_dict_ref = chunk.alloc.bump();
|
||||
|
||||
let data = embed.data.as_slice();
|
||||
let compressed = deflate(data);
|
||||
|
||||
let mut embedded_file = chunk.embedded_file(embedded_file_stream_ref, &compressed);
|
||||
embedded_file.filter(Filter::FlateDecode);
|
||||
|
||||
if let Some(mime_type) = embed.mime_type(StyleChain::default()) {
|
||||
if mime_type.len() > Name::PDFA_LIMIT {
|
||||
bail!(embed.span(), "embedded file MIME type is too long");
|
||||
}
|
||||
embedded_file.subtype(Name(mime_type.as_bytes()));
|
||||
} else if ctx.options.standards.pdfa {
|
||||
bail!(embed.span(), "embedded files must have a MIME type in PDF/A-3");
|
||||
}
|
||||
|
||||
let mut params = embedded_file.params();
|
||||
params.size(data.len() as i32);
|
||||
|
||||
let (date, tz) = document_date(ctx.document.info.date, ctx.options.timestamp);
|
||||
if let Some(pdf_date) = date.and_then(|date| pdf_date(date, tz)) {
|
||||
params.modification_date(pdf_date);
|
||||
} else if ctx.options.standards.pdfa {
|
||||
bail!(
|
||||
embed.span(),
|
||||
"the document must have a date when embedding files in PDF/A-3";
|
||||
hint: "`set document(date: none)` must not be used in this case"
|
||||
);
|
||||
}
|
||||
|
||||
params.finish();
|
||||
embedded_file.finish();
|
||||
|
||||
let mut file_spec = chunk.file_spec(file_spec_dict_ref);
|
||||
file_spec.path(Str(embed.path.derived.as_bytes()));
|
||||
file_spec.unic_file(TextStr(&embed.path.derived));
|
||||
file_spec
|
||||
.insert(Name(b"EF"))
|
||||
.dict()
|
||||
.pair(Name(b"F"), embedded_file_stream_ref)
|
||||
.pair(Name(b"UF"), embedded_file_stream_ref);
|
||||
|
||||
if ctx.options.standards.pdfa {
|
||||
// PDF 2.0, but ISO 19005-3 (PDF/A-3) Annex E allows it for PDF/A-3.
|
||||
file_spec.association_kind(match embed.relationship(StyleChain::default()) {
|
||||
Some(EmbeddedFileRelationship::Source) => AssociationKind::Source,
|
||||
Some(EmbeddedFileRelationship::Data) => AssociationKind::Data,
|
||||
Some(EmbeddedFileRelationship::Alternative) => AssociationKind::Alternative,
|
||||
Some(EmbeddedFileRelationship::Supplement) => AssociationKind::Supplement,
|
||||
None => AssociationKind::Unspecified,
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(description) = embed.description(StyleChain::default()) {
|
||||
if description.len() > Str::PDFA_LIMIT {
|
||||
bail!(embed.span(), "embedded file description is too long");
|
||||
}
|
||||
file_spec.description(TextStr(description));
|
||||
}
|
||||
|
||||
Ok(file_spec_dict_ref)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::sync::{Arc, OnceLock};
|
||||
|
||||
use image::{DynamicImage, GenericImageView, Rgba};
|
||||
use image::{DynamicImage, EncodableLayout, GenericImageView, Rgba};
|
||||
use krilla::image::{BitsPerComponent, CustomImage, ImageColorspace};
|
||||
use krilla::surface::Surface;
|
||||
use krilla::SvgSettings;
|
||||
@ -137,7 +137,7 @@ impl CustomImage for PdfImage {
|
||||
| DynamicImage::ImageRgb8(_)
|
||||
| DynamicImage::ImageRgba8(_)
|
||||
) {
|
||||
self.raster.icc()
|
||||
self.raster.icc().map(|b| b.as_bytes())
|
||||
} else {
|
||||
// In all other cases, the dynamic will be converted into RGB8 or LUMA8, so the ICC
|
||||
// profile may become invalid, and thus we don't include it.
|
||||
|
@ -15,9 +15,6 @@ use typst_library::diag::SourceResult;
|
||||
use typst_library::foundations::{Datetime, Smart};
|
||||
use typst_library::layout::{PageRanges, PagedDocument};
|
||||
|
||||
pub use ::krilla::validation::Validator;
|
||||
pub use ::krilla::version::PdfVersion;
|
||||
|
||||
/// Export a document into a PDF file.
|
||||
///
|
||||
/// Returns the raw bytes making up the PDF file.
|
||||
@ -26,6 +23,72 @@ pub fn pdf(document: &PagedDocument, options: &PdfOptions) -> SourceResult<Vec<u
|
||||
convert::convert(document, options)
|
||||
}
|
||||
|
||||
/// The version of a PDF document.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum PdfVersion {
|
||||
/// PDF 1.4.
|
||||
Pdf14,
|
||||
/// PDF 1.5.
|
||||
Pdf15,
|
||||
/// PDF 1.6.
|
||||
Pdf16,
|
||||
/// PDF 1.7.
|
||||
Pdf17,
|
||||
/// PDF 2.0.
|
||||
Pdf20,
|
||||
}
|
||||
|
||||
impl From<PdfVersion> for krilla::configure::PdfVersion {
|
||||
fn from(value: PdfVersion) -> Self {
|
||||
match value {
|
||||
PdfVersion::Pdf14 => krilla::configure::PdfVersion::Pdf14,
|
||||
PdfVersion::Pdf15 => krilla::configure::PdfVersion::Pdf15,
|
||||
PdfVersion::Pdf16 => krilla::configure::PdfVersion::Pdf16,
|
||||
PdfVersion::Pdf17 => krilla::configure::PdfVersion::Pdf17,
|
||||
PdfVersion::Pdf20 => krilla::configure::PdfVersion::Pdf20,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A validator for exporting PDF documents to a specific subset of PDF.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Validator {
|
||||
/// The validator for the PDF/A1-A standard.
|
||||
A1_A,
|
||||
/// The validator for the PDF/A1-B standard.
|
||||
A1_B,
|
||||
/// The validator for the PDF/A2-B standard.
|
||||
A2_B,
|
||||
/// The validator for the PDF/A2-U standard.
|
||||
A2_U,
|
||||
/// The validator for the PDF/A3-B standard.
|
||||
A3_B,
|
||||
/// The validator for the PDF/A3-U standard.
|
||||
A3_U,
|
||||
/// The validator for the PDF/A4 standard.
|
||||
A4,
|
||||
/// The validator for the PDF/A4f standard.
|
||||
A4F,
|
||||
/// The validator for the PDF/A4e standard.
|
||||
A4E,
|
||||
}
|
||||
|
||||
impl From<Validator> for krilla::configure::Validator {
|
||||
fn from(value: Validator) -> Self {
|
||||
match value {
|
||||
Validator::A1_A => krilla::configure::Validator::A1_A,
|
||||
Validator::A1_B => krilla::configure::Validator::A1_B,
|
||||
Validator::A2_B => krilla::configure::Validator::A2_B,
|
||||
Validator::A2_U => krilla::configure::Validator::A2_U,
|
||||
Validator::A3_B => krilla::configure::Validator::A3_B,
|
||||
Validator::A3_U => krilla::configure::Validator::A3_U,
|
||||
Validator::A4 => krilla::configure::Validator::A4,
|
||||
Validator::A4F => krilla::configure::Validator::A4F,
|
||||
Validator::A4E => krilla::configure::Validator::A4E,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Settings for PDF export.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct PdfOptions<'a> {
|
||||
@ -50,7 +113,7 @@ pub struct PdfOptions<'a> {
|
||||
/// The version that should be used to export the PDF.
|
||||
pub pdf_version: Option<PdfVersion>,
|
||||
/// A standard the PDF should conform to.
|
||||
pub validator: Validator,
|
||||
pub validator: Option<Validator>,
|
||||
}
|
||||
|
||||
/// A timestamp with timezone information.
|
||||
|
@ -6,9 +6,7 @@ use krilla::path as kp;
|
||||
use krilla::path::PathBuilder;
|
||||
use typst_library::layout::{Abs, Point, Size, Transform};
|
||||
use typst_library::text::Font;
|
||||
use typst_library::visualize::{
|
||||
Color, ColorSpace, FillRule, LineCap, LineJoin, Path, PathItem,
|
||||
};
|
||||
use typst_library::visualize::{Color, ColorSpace, Curve, CurveItem, FillRule, LineCap, LineJoin};
|
||||
|
||||
pub(crate) trait SizeExt {
|
||||
fn to_krilla(&self) -> kg::Size;
|
||||
@ -118,12 +116,12 @@ pub(crate) fn display_font(font: &Font) -> String {
|
||||
}
|
||||
|
||||
/// Build a typst path using a path builder.
|
||||
pub(crate) fn convert_path(path: &Path, builder: &mut PathBuilder) {
|
||||
pub(crate) fn convert_path(path: &Curve, builder: &mut PathBuilder) {
|
||||
for item in &path.0 {
|
||||
match item {
|
||||
PathItem::MoveTo(p) => builder.move_to(p.x.to_f32(), p.y.to_f32()),
|
||||
PathItem::LineTo(p) => builder.line_to(p.x.to_f32(), p.y.to_f32()),
|
||||
PathItem::CubicTo(p1, p2, p3) => builder.cubic_to(
|
||||
CurveItem::Move(p) => builder.move_to(p.x.to_f32(), p.y.to_f32()),
|
||||
CurveItem::Line(p) => builder.line_to(p.x.to_f32(), p.y.to_f32()),
|
||||
CurveItem::Cubic(p1, p2, p3) => builder.cubic_to(
|
||||
p1.x.to_f32(),
|
||||
p1.y.to_f32(),
|
||||
p2.x.to_f32(),
|
||||
@ -131,7 +129,7 @@ pub(crate) fn convert_path(path: &Path, builder: &mut PathBuilder) {
|
||||
p3.x.to_f32(),
|
||||
p3.y.to_f32(),
|
||||
),
|
||||
PathItem::ClosePath => builder.close(),
|
||||
CurveItem::Close => builder.close(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user