mirror of
https://github.com/typst/typst
synced 2025-06-08 13:16:24 +08:00
Initial commit
This commit is contained in:
parent
7add9b459a
commit
81e848140f
200
Cargo.lock
generated
200
Cargo.lock
generated
@ -222,6 +222,20 @@ name = "bytemuck"
|
|||||||
version = "1.18.0"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae"
|
checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck_derive"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
@ -742,12 +756,30 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
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]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "font-types"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fontconfig-parser"
|
name = "fontconfig-parser"
|
||||||
version = "0.5.7"
|
version = "0.5.7"
|
||||||
@ -771,6 +803,20 @@ dependencies = [
|
|||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@ -1255,6 +1301,34 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "krilla"
|
||||||
|
version = "0.3.0"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"bumpalo",
|
||||||
|
"flate2",
|
||||||
|
"float-cmp 0.10.0",
|
||||||
|
"fontdb 0.22.0",
|
||||||
|
"gif",
|
||||||
|
"image-webp",
|
||||||
|
"miniz_oxide",
|
||||||
|
"once_cell",
|
||||||
|
"pdf-writer 0.12.0 (git+https://github.com/LaurenzV/pdf-writer?rev=f95a19c)",
|
||||||
|
"resvg 0.44.0",
|
||||||
|
"rustybuzz",
|
||||||
|
"siphasher 1.0.1",
|
||||||
|
"skrifa",
|
||||||
|
"subsetter",
|
||||||
|
"tiny-skia",
|
||||||
|
"tiny-skia-path",
|
||||||
|
"usvg 0.44.0",
|
||||||
|
"xmp-writer 0.3.0 (git+https://github.com/LaurenzV/xmp-writer?rev=1c2b8ae9)",
|
||||||
|
"yoke",
|
||||||
|
"zune-jpeg",
|
||||||
|
"zune-png",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kurbo"
|
name = "kurbo"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@ -1694,6 +1768,17 @@ dependencies = [
|
|||||||
"ryu",
|
"ryu",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pdf-writer"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "git+https://github.com/LaurenzV/pdf-writer?rev=f95a19c#f95a19c07a1b3e3ee021c1199e91f19badb57d46"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
@ -1943,6 +2028,16 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "read-fonts"
|
||||||
|
version = "0.22.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a04b892cb6f91951f144c33321843790c8574c825aafdb16d815fd7183b5229"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"font-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.7"
|
version = "0.5.7"
|
||||||
@ -2005,7 +2100,24 @@ dependencies = [
|
|||||||
"rgb",
|
"rgb",
|
||||||
"svgtypes",
|
"svgtypes",
|
||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
"usvg",
|
"usvg 0.43.0",
|
||||||
|
"zune-jpeg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "resvg"
|
||||||
|
version = "0.44.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a325d5e8d1cebddd070b13f44cec8071594ab67d1012797c121f27a669b7958"
|
||||||
|
dependencies = [
|
||||||
|
"gif",
|
||||||
|
"image-webp",
|
||||||
|
"log",
|
||||||
|
"pico-args",
|
||||||
|
"rgb",
|
||||||
|
"svgtypes",
|
||||||
|
"tiny-skia",
|
||||||
|
"usvg 0.44.0",
|
||||||
"zune-jpeg",
|
"zune-jpeg",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2267,6 +2379,16 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
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]]
|
[[package]]
|
||||||
name = "slotmap"
|
name = "slotmap"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -2313,7 +2435,7 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"float-cmp",
|
"float-cmp 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2367,18 +2489,18 @@ version = "0.12.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5014c9dadcf318fb7ef8c16438e95abcc9de1ae24d60d5bccc64c55100c50364"
|
checksum = "5014c9dadcf318fb7ef8c16438e95abcc9de1ae24d60d5bccc64c55100c50364"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fontdb",
|
"fontdb 0.21.0",
|
||||||
"image",
|
"image",
|
||||||
"log",
|
"log",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pdf-writer",
|
"pdf-writer 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"resvg",
|
"resvg 0.43.0",
|
||||||
"siphasher 1.0.1",
|
"siphasher 1.0.1",
|
||||||
"subsetter",
|
"subsetter",
|
||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
"usvg",
|
"usvg 0.43.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2797,7 +2919,7 @@ dependencies = [
|
|||||||
"ecow",
|
"ecow",
|
||||||
"env_proxy",
|
"env_proxy",
|
||||||
"flate2",
|
"flate2",
|
||||||
"fontdb",
|
"fontdb 0.22.0",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"openssl",
|
"openssl",
|
||||||
@ -2853,7 +2975,7 @@ dependencies = [
|
|||||||
"csv",
|
"csv",
|
||||||
"ecow",
|
"ecow",
|
||||||
"flate2",
|
"flate2",
|
||||||
"fontdb",
|
"fontdb 0.22.0",
|
||||||
"hayagriva",
|
"hayagriva",
|
||||||
"icu_properties",
|
"icu_properties",
|
||||||
"icu_provider",
|
"icu_provider",
|
||||||
@ -2892,7 +3014,7 @@ dependencies = [
|
|||||||
"unicode-math-class",
|
"unicode-math-class",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unscanny",
|
"unscanny",
|
||||||
"usvg",
|
"usvg 0.44.0",
|
||||||
"wasmi",
|
"wasmi",
|
||||||
"xmlwriter",
|
"xmlwriter",
|
||||||
]
|
]
|
||||||
@ -2918,8 +3040,9 @@ dependencies = [
|
|||||||
"ecow",
|
"ecow",
|
||||||
"image",
|
"image",
|
||||||
"indexmap 2.6.0",
|
"indexmap 2.6.0",
|
||||||
|
"krilla",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"pdf-writer",
|
"pdf-writer 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde",
|
"serde",
|
||||||
"subsetter",
|
"subsetter",
|
||||||
"svg2pdf",
|
"svg2pdf",
|
||||||
@ -2930,7 +3053,7 @@ dependencies = [
|
|||||||
"typst-syntax",
|
"typst-syntax",
|
||||||
"typst-timing",
|
"typst-timing",
|
||||||
"typst-utils",
|
"typst-utils",
|
||||||
"xmp-writer",
|
"xmp-writer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2957,7 +3080,7 @@ dependencies = [
|
|||||||
"comemo",
|
"comemo",
|
||||||
"image",
|
"image",
|
||||||
"pixglyph",
|
"pixglyph",
|
||||||
"resvg",
|
"resvg 0.44.0",
|
||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
"typst-library",
|
"typst-library",
|
||||||
@ -3188,7 +3311,34 @@ dependencies = [
|
|||||||
"base64",
|
"base64",
|
||||||
"data-url",
|
"data-url",
|
||||||
"flate2",
|
"flate2",
|
||||||
"fontdb",
|
"fontdb 0.21.0",
|
||||||
|
"imagesize",
|
||||||
|
"kurbo",
|
||||||
|
"log",
|
||||||
|
"pico-args",
|
||||||
|
"roxmltree",
|
||||||
|
"rustybuzz",
|
||||||
|
"simplecss",
|
||||||
|
"siphasher 1.0.1",
|
||||||
|
"strict-num",
|
||||||
|
"svgtypes",
|
||||||
|
"tiny-skia-path",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-script",
|
||||||
|
"unicode-vo",
|
||||||
|
"xmlwriter",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "usvg"
|
||||||
|
version = "0.44.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7447e703d7223b067607655e625e0dbca80822880248937da65966194c4864e6"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"data-url",
|
||||||
|
"flate2",
|
||||||
|
"fontdb 0.22.0",
|
||||||
"imagesize",
|
"imagesize",
|
||||||
"kurbo",
|
"kurbo",
|
||||||
"log",
|
"log",
|
||||||
@ -3579,6 +3729,11 @@ version = "0.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8254499146a4fd0c86e3e99cf4a9f468f595808fb49ff8f3e495f2b117bf4ebc"
|
checksum = "8254499146a4fd0c86e3e99cf4a9f468f595808fb49ff8f3e495f2b117bf4ebc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xmp-writer"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "git+https://github.com/LaurenzV/xmp-writer?rev=1c2b8ae9#1c2b8ae9c217ceeec39b86cf5e215b67fe8870db"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xz2"
|
name = "xz2"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@ -3745,6 +3900,15 @@ version = "0.4.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
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]]
|
[[package]]
|
||||||
name = "zune-jpeg"
|
name = "zune-jpeg"
|
||||||
version = "0.4.13"
|
version = "0.4.13"
|
||||||
@ -3753,3 +3917,13 @@ checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"zune-core",
|
"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",
|
||||||
|
]
|
||||||
|
@ -54,7 +54,7 @@ dirs = "5"
|
|||||||
ecow = { version = "0.2", features = ["serde"] }
|
ecow = { version = "0.2", features = ["serde"] }
|
||||||
env_proxy = "0.4"
|
env_proxy = "0.4"
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
fontdb = { version = "0.21", default-features = false }
|
fontdb = { version = "0.22", default-features = false }
|
||||||
fs_extra = "1.3"
|
fs_extra = "1.3"
|
||||||
hayagriva = "0.8"
|
hayagriva = "0.8"
|
||||||
heck = "0.5"
|
heck = "0.5"
|
||||||
@ -68,6 +68,7 @@ if_chain = "1"
|
|||||||
image = { version = "0.25.2", default-features = false, features = ["png", "jpeg", "gif"] }
|
image = { version = "0.25.2", default-features = false, features = ["png", "jpeg", "gif"] }
|
||||||
indexmap = { version = "2", features = ["serde"] }
|
indexmap = { version = "2", features = ["serde"] }
|
||||||
kamadak-exif = "0.5"
|
kamadak-exif = "0.5"
|
||||||
|
krilla = { path = "../krilla/crates/krilla" }
|
||||||
kurbo = "0.11"
|
kurbo = "0.11"
|
||||||
libfuzzer-sys = "0.4"
|
libfuzzer-sys = "0.4"
|
||||||
lipsum = "0.9"
|
lipsum = "0.9"
|
||||||
@ -92,7 +93,7 @@ qcms = "0.3.0"
|
|||||||
quote = "1"
|
quote = "1"
|
||||||
rayon = "1.7.0"
|
rayon = "1.7.0"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
resvg = { version = "0.43", default-features = false, features = ["raster-images"] }
|
resvg = { version = "0.44", default-features = false, features = ["raster-images"] }
|
||||||
roxmltree = "0.20"
|
roxmltree = "0.20"
|
||||||
rust_decimal = { version = "1.36.0", default-features = false, features = ["maths"] }
|
rust_decimal = { version = "1.36.0", default-features = false, features = ["maths"] }
|
||||||
rustybuzz = "0.18"
|
rustybuzz = "0.18"
|
||||||
@ -126,7 +127,7 @@ unicode-script = "0.5"
|
|||||||
unicode-segmentation = "1"
|
unicode-segmentation = "1"
|
||||||
unscanny = "0.1"
|
unscanny = "0.1"
|
||||||
ureq = { version = "2", default-features = false, features = ["native-tls", "gzip", "json"] }
|
ureq = { version = "2", default-features = false, features = ["native-tls", "gzip", "json"] }
|
||||||
usvg = { version = "0.43", default-features = false, features = ["text"] }
|
usvg = { version = "0.44", default-features = false, features = ["text"] }
|
||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
wasmi = "0.39.0"
|
wasmi = "0.39.0"
|
||||||
xmlparser = "0.13.5"
|
xmlparser = "0.13.5"
|
||||||
|
@ -26,6 +26,7 @@ comemo = { workspace = true }
|
|||||||
ecow = { workspace = true }
|
ecow = { workspace = true }
|
||||||
image = { workspace = true }
|
image = { workspace = true }
|
||||||
indexmap = { workspace = true }
|
indexmap = { workspace = true }
|
||||||
|
krilla = { workspace = true }
|
||||||
miniz_oxide = { workspace = true }
|
miniz_oxide = { workspace = true }
|
||||||
pdf-writer = { workspace = true }
|
pdf-writer = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
@ -206,10 +206,11 @@ fn encode_svg(
|
|||||||
svg: &SvgImage,
|
svg: &SvgImage,
|
||||||
pdfa: bool,
|
pdfa: bool,
|
||||||
) -> Result<(Chunk, Ref), svg2pdf::ConversionError> {
|
) -> Result<(Chunk, Ref), svg2pdf::ConversionError> {
|
||||||
svg2pdf::to_chunk(
|
unimplemented!();
|
||||||
svg.tree(),
|
// svg2pdf::to_chunk(
|
||||||
svg2pdf::ConversionOptions { pdfa, ..Default::default() },
|
// svg.tree(),
|
||||||
)
|
// svg2pdf::ConversionOptions { pdfa, ..Default::default() },
|
||||||
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A pre-encoded image.
|
/// A pre-encoded image.
|
||||||
|
324
crates/typst-pdf/src/krilla.rs
Normal file
324
crates/typst-pdf/src/krilla.rs
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
|
||||||
|
use crate::{AbsExt};
|
||||||
|
use krilla::color::rgb;
|
||||||
|
use krilla::font::{GlyphUnits};
|
||||||
|
use krilla::geom::{Point, Transform};
|
||||||
|
use krilla::path::{Fill, PathBuilder, Stroke};
|
||||||
|
use krilla::surface::Surface;
|
||||||
|
use krilla::{PageSettings, SerializeSettings, SvgSettings};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::ops::Range;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use image::{GenericImageView, Rgba};
|
||||||
|
use krilla::validation::Validator;
|
||||||
|
use krilla::version::PdfVersion;
|
||||||
|
use svg2pdf::usvg::{NormalizedF32, Rect};
|
||||||
|
use typst_library::layout::{Frame, FrameItem, GroupItem, Size};
|
||||||
|
use typst_library::model::Document;
|
||||||
|
use typst_library::text::{Font, Glyph, TextItem};
|
||||||
|
use typst_library::visualize::{ColorSpace, FillRule, FixedStroke, Geometry, Image, ImageKind, LineCap, LineJoin, Paint, Path, PathItem, Shape};
|
||||||
|
|
||||||
|
pub struct ExportContext {
|
||||||
|
fonts: HashMap<Font, krilla::font::Font>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExportContext {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
fonts: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Change rustybuzz cluster behavior so it works with ActualText
|
||||||
|
|
||||||
|
#[typst_macros::time(name = "write pdf")]
|
||||||
|
pub fn pdf(typst_document: &Document) -> Vec<u8> {
|
||||||
|
let settings = SerializeSettings {
|
||||||
|
compress_content_streams: true,
|
||||||
|
no_device_cs: false,
|
||||||
|
ascii_compatible: false,
|
||||||
|
xmp_metadata: true,
|
||||||
|
force_type3_fonts: false,
|
||||||
|
cmyk_profile: None,
|
||||||
|
validator: Validator::None,
|
||||||
|
enable_tagging: false,
|
||||||
|
pdf_version: PdfVersion::Pdf17,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut document = krilla::Document::new_with(settings);
|
||||||
|
let mut context = ExportContext::new();
|
||||||
|
|
||||||
|
for typst_page in &typst_document.pages {
|
||||||
|
let settings = PageSettings::new(
|
||||||
|
typst_page.frame.width().to_f32(),
|
||||||
|
typst_page.frame.height().to_f32(),
|
||||||
|
);
|
||||||
|
let mut page = document.start_page_with(settings);
|
||||||
|
let mut surface = page.surface();
|
||||||
|
process_frame(&typst_page.frame, &mut surface, &mut context);
|
||||||
|
}
|
||||||
|
|
||||||
|
finish(document)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typst_macros::time(name = "finish document")]
|
||||||
|
pub fn finish(document: krilla::Document) -> Vec<u8> {
|
||||||
|
// TODO: Don't unwrap
|
||||||
|
document.finish().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_group(
|
||||||
|
group: &GroupItem,
|
||||||
|
surface: &mut Surface,
|
||||||
|
context: &mut ExportContext,
|
||||||
|
) {
|
||||||
|
surface.push_transform(&convert_transform(group.transform));
|
||||||
|
process_frame(&group.frame, surface, context);
|
||||||
|
surface.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_text(t: &TextItem, surface: &mut Surface, context: &mut ExportContext) {
|
||||||
|
let font = context
|
||||||
|
.fonts
|
||||||
|
.entry(t.font.clone())
|
||||||
|
.or_insert_with(|| {
|
||||||
|
krilla::font::Font::new(
|
||||||
|
// TODO: Don't do to_vec here!
|
||||||
|
Arc::new(t.font.data().to_vec()),
|
||||||
|
t.font.index(),
|
||||||
|
vec![],
|
||||||
|
)
|
||||||
|
// TODO: DOn't unwrap
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.clone();
|
||||||
|
let (paint, opacity) = convert_paint(&t.fill);
|
||||||
|
let fill = Fill {
|
||||||
|
paint,
|
||||||
|
opacity: NormalizedF32::new(opacity as f32 / 255.0).unwrap(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let text = t.text.as_str();
|
||||||
|
let size = t.size;
|
||||||
|
|
||||||
|
// TODO: Avoid creating vector?
|
||||||
|
let glyphs = t.glyphs.iter().map(|g| WrapperGlyph(g.clone())).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
surface.fill_glyphs(
|
||||||
|
Point::from_xy(0.0, 0.0),
|
||||||
|
fill,
|
||||||
|
&glyphs,
|
||||||
|
font.clone(),
|
||||||
|
text,
|
||||||
|
size.to_f32(),
|
||||||
|
GlyphUnits::Normalized,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(stroke) = t.stroke.as_ref().map(convert_fixed_stroke) {
|
||||||
|
surface.stroke_glyphs(
|
||||||
|
Point::from_xy(0.0, 0.0),
|
||||||
|
stroke,
|
||||||
|
&glyphs,
|
||||||
|
font.clone(),
|
||||||
|
text,
|
||||||
|
size.to_f32(),
|
||||||
|
GlyphUnits::Normalized,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typst_macros::time(name = "handle image")]
|
||||||
|
pub fn handle_image(
|
||||||
|
image: &Image,
|
||||||
|
size: &Size,
|
||||||
|
surface: &mut Surface,
|
||||||
|
_: &mut ExportContext,
|
||||||
|
) {
|
||||||
|
match image.kind() {
|
||||||
|
ImageKind::Raster(raster) => {
|
||||||
|
let image = krilla::image::Image::from_png(raster.data())
|
||||||
|
.unwrap();
|
||||||
|
surface.draw_image(
|
||||||
|
image,
|
||||||
|
krilla::geom::Size::from_wh(size.x.to_f32(), size.y.to_f32()).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ImageKind::Svg(svg) => {
|
||||||
|
surface.draw_svg(
|
||||||
|
svg.tree(),
|
||||||
|
krilla::geom::Size::from_wh(size.x.to_f32(), size.y.to_f32()).unwrap(),
|
||||||
|
SvgSettings::default(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_shape(shape: &Shape, surface: &mut Surface) {
|
||||||
|
let mut path_builder = PathBuilder::new();
|
||||||
|
|
||||||
|
match &shape.geometry {
|
||||||
|
Geometry::Line(l) => {
|
||||||
|
path_builder.move_to(0.0, 0.0);
|
||||||
|
path_builder.line_to(l.x.to_f32(), l.y.to_f32());
|
||||||
|
}
|
||||||
|
Geometry::Rect(r) => {
|
||||||
|
path_builder.push_rect(
|
||||||
|
Rect::from_xywh(0.0, 0.0, r.x.to_f32(), r.y.to_f32()).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Geometry::Path(p) => {
|
||||||
|
convert_path(p, &mut path_builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(path) = path_builder.finish() {
|
||||||
|
if let Some(paint) = &shape.fill {
|
||||||
|
let (paint, opacity) = convert_paint(paint);
|
||||||
|
|
||||||
|
let fill = Fill {
|
||||||
|
paint,
|
||||||
|
rule: convert_fill_rule(shape.fill_rule),
|
||||||
|
opacity: NormalizedF32::new(opacity as f32 / 255.0).unwrap(),
|
||||||
|
};
|
||||||
|
surface.fill_path(&path, fill);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(stroke) = &shape.stroke {
|
||||||
|
let stroke = convert_fixed_stroke(stroke);
|
||||||
|
|
||||||
|
surface.stroke_path(&path, stroke);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_path(path: &Path, 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(
|
||||||
|
p1.x.to_f32(),
|
||||||
|
p1.y.to_f32(),
|
||||||
|
p2.x.to_f32(),
|
||||||
|
p2.y.to_f32(),
|
||||||
|
p3.x.to_f32(),
|
||||||
|
p3.y.to_f32(),
|
||||||
|
),
|
||||||
|
PathItem::ClosePath => builder.close(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_frame(frame: &Frame, surface: &mut Surface, context: &mut ExportContext) {
|
||||||
|
for (point, item) in frame.items() {
|
||||||
|
surface.push_transform(&Transform::from_translate(
|
||||||
|
point.x.to_f32(),
|
||||||
|
point.y.to_f32(),
|
||||||
|
));
|
||||||
|
|
||||||
|
match item {
|
||||||
|
FrameItem::Group(g) => handle_group(g, surface, context),
|
||||||
|
FrameItem::Text(t) => handle_text(t, surface, context),
|
||||||
|
FrameItem::Shape(s, _) => handle_shape(s, surface),
|
||||||
|
FrameItem::Image(image, size, _) => {
|
||||||
|
handle_image(image, size, surface, context)
|
||||||
|
}
|
||||||
|
FrameItem::Link(_, _) => {}
|
||||||
|
FrameItem::Tag(_) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
surface.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WrapperGlyph(Glyph);
|
||||||
|
|
||||||
|
impl krilla::font::Glyph for WrapperGlyph {
|
||||||
|
fn glyph_id(&self) -> krilla::font::GlyphId {
|
||||||
|
krilla::font::GlyphId::new(self.0.id as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn text_range(&self) -> Range<usize> {
|
||||||
|
self.0.range.start as usize..self.0.range.end as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn x_advance(&self) -> f32 {
|
||||||
|
self.0.x_advance.get() as f32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn x_offset(&self) -> f32 {
|
||||||
|
self.0.x_offset.get() as f32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn y_offset(&self) -> f32 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn y_advance(&self) -> f32 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_fill_rule(fill_rule: FillRule) -> krilla::path::FillRule {
|
||||||
|
match fill_rule {
|
||||||
|
FillRule::NonZero => krilla::path::FillRule::NonZero,
|
||||||
|
FillRule::EvenOdd => krilla::path::FillRule::EvenOdd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_fixed_stroke(stroke: &FixedStroke) -> Stroke {
|
||||||
|
let (paint, opacity) = convert_paint(&stroke.paint);
|
||||||
|
Stroke {
|
||||||
|
paint,
|
||||||
|
width: stroke.thickness.to_f32(),
|
||||||
|
miter_limit: stroke.miter_limit.get() as f32,
|
||||||
|
line_join: convert_linejoin(stroke.join),
|
||||||
|
line_cap: convert_linecap(stroke.cap),
|
||||||
|
opacity: NormalizedF32::new(opacity as f32 / 255.0).unwrap(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_linecap(l: LineCap) -> krilla::path::LineCap {
|
||||||
|
match l {
|
||||||
|
LineCap::Butt => krilla::path::LineCap::Butt,
|
||||||
|
LineCap::Round => krilla::path::LineCap::Round,
|
||||||
|
LineCap::Square => krilla::path::LineCap::Square,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_linejoin(l: LineJoin) -> krilla::path::LineJoin {
|
||||||
|
match l {
|
||||||
|
LineJoin::Miter => krilla::path::LineJoin::Miter,
|
||||||
|
LineJoin::Round => krilla::path::LineJoin::Round,
|
||||||
|
LineJoin::Bevel => krilla::path::LineJoin::Bevel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_transform(t: crate::Transform) -> krilla::geom::Transform {
|
||||||
|
Transform::from_row(
|
||||||
|
t.sx.get() as f32,
|
||||||
|
t.ky.get() as f32,
|
||||||
|
t.kx.get() as f32,
|
||||||
|
t.sy.get() as f32,
|
||||||
|
t.tx.to_f32(),
|
||||||
|
t.ty.to_f32(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_paint(paint: &Paint) -> (krilla::paint::Paint, u8) {
|
||||||
|
match paint {
|
||||||
|
Paint::Solid(c) => {
|
||||||
|
let components = c.to_space(ColorSpace::Srgb).to_vec4_u8();
|
||||||
|
(
|
||||||
|
rgb::Color::new(components[0], components[1], components[2]).into(),
|
||||||
|
components[3],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Paint::Gradient(_) => (rgb::Color::black().into(), 255),
|
||||||
|
Paint::Pattern(_) => (rgb::Color::black().into(), 255),
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ mod extg;
|
|||||||
mod font;
|
mod font;
|
||||||
mod gradient;
|
mod gradient;
|
||||||
mod image;
|
mod image;
|
||||||
|
mod krilla;
|
||||||
mod named_destination;
|
mod named_destination;
|
||||||
mod outline;
|
mod outline;
|
||||||
mod page;
|
mod page;
|
||||||
@ -50,6 +51,7 @@ use crate::resources::{
|
|||||||
/// Returns the raw bytes making up the PDF file.
|
/// Returns the raw bytes making up the PDF file.
|
||||||
#[typst_macros::time(name = "pdf")]
|
#[typst_macros::time(name = "pdf")]
|
||||||
pub fn pdf(document: &Document, options: &PdfOptions) -> SourceResult<Vec<u8>> {
|
pub fn pdf(document: &Document, options: &PdfOptions) -> SourceResult<Vec<u8>> {
|
||||||
|
return Ok(krilla::pdf(document));
|
||||||
PdfBuilder::new(document, options)
|
PdfBuilder::new(document, options)
|
||||||
.phase(|builder| builder.run(traverse_pages))?
|
.phase(|builder| builder.run(traverse_pages))?
|
||||||
.phase(|builder| {
|
.phase(|builder| {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user