diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-01-24 16:48:24 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-01-24 17:39:49 +0100 |
| commit | 3739ab77207e0e54edb55a110a16a1eb925b84f4 (patch) | |
| tree | 06c8e5987d2fe070ad273ef94641161bbaef7095 /tests | |
| parent | db158719d67fdef1d2c76300fb232cf2d4bfb35d (diff) | |
Export into rendered images
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ref/code/array.png | bin | 1899 -> 2534 bytes | |||
| -rw-r--r-- | tests/ref/code/block.png | bin | 1374 -> 2005 bytes | |||
| -rw-r--r-- | tests/ref/code/call.png | bin | 2397 -> 3388 bytes | |||
| -rw-r--r-- | tests/ref/code/closure.png | bin | 591 -> 801 bytes | |||
| -rw-r--r-- | tests/ref/code/comment.png | bin | 1691 -> 2585 bytes | |||
| -rw-r--r-- | tests/ref/code/dict.png | bin | 894 -> 1126 bytes | |||
| -rw-r--r-- | tests/ref/code/for.png | bin | 2128 -> 3123 bytes | |||
| -rw-r--r-- | tests/ref/code/if.png | bin | 1825 -> 2336 bytes | |||
| -rw-r--r-- | tests/ref/code/import.png | bin | 1810 -> 4675 bytes | |||
| -rw-r--r-- | tests/ref/code/include.png | bin | 29204 -> 48470 bytes | |||
| -rw-r--r-- | tests/ref/code/let.png | bin | 1239 -> 3170 bytes | |||
| -rw-r--r-- | tests/ref/code/ops.png | bin | 689 -> 977 bytes | |||
| -rw-r--r-- | tests/ref/code/repr.png | bin | 9933 -> 29464 bytes | |||
| -rw-r--r-- | tests/ref/code/while.png | bin | 761 -> 1058 bytes | |||
| -rw-r--r-- | tests/ref/coma.png | bin | 55412 -> 88177 bytes | |||
| -rw-r--r-- | tests/ref/layout/align.png | bin | 1355 -> 2388 bytes | |||
| -rw-r--r-- | tests/ref/layout/box-block.png | bin | 5194 -> 7628 bytes | |||
| -rw-r--r-- | tests/ref/layout/columns.png | bin | 37999 -> 109097 bytes | |||
| -rw-r--r-- | tests/ref/layout/grid-1.png | bin | 3250 -> 8863 bytes | |||
| -rw-r--r-- | tests/ref/layout/grid-2.png | bin | 9721 -> 16566 bytes | |||
| -rw-r--r-- | tests/ref/layout/grid-3.png | bin | 37234 -> 65891 bytes | |||
| -rw-r--r-- | tests/ref/layout/grid-4.png | bin | 431 -> 430 bytes | |||
| -rw-r--r-- | tests/ref/layout/grid-5.png | bin | 2565 -> 3814 bytes | |||
| -rw-r--r-- | tests/ref/layout/image.png | bin | 186196 -> 184771 bytes | |||
| -rw-r--r-- | tests/ref/layout/pad.png | bin | 52011 -> 53964 bytes | |||
| -rw-r--r-- | tests/ref/layout/page.png | bin | 4157 -> 12418 bytes | |||
| -rw-r--r-- | tests/ref/layout/pagebreak.png | bin | 3788 -> 5140 bytes | |||
| -rw-r--r-- | tests/ref/layout/place-background.png | bin | 80166 -> 80409 bytes | |||
| -rw-r--r-- | tests/ref/layout/place.png | bin | 33917 -> 44132 bytes | |||
| -rw-r--r-- | tests/ref/layout/shape-aspect.png | bin | 3601 -> 4663 bytes | |||
| -rw-r--r-- | tests/ref/layout/shape-circle.png | bin | 18861 -> 40653 bytes | |||
| -rw-r--r-- | tests/ref/layout/shape-ellipse.png | bin | 9455 -> 22046 bytes | |||
| -rw-r--r-- | tests/ref/layout/shape-fill-stroke.png | bin | 1942 -> 2893 bytes | |||
| -rw-r--r-- | tests/ref/layout/shape-rect.png | bin | 2914 -> 7261 bytes | |||
| -rw-r--r-- | tests/ref/layout/shape-square.png | bin | 6585 -> 18777 bytes | |||
| -rw-r--r-- | tests/ref/layout/spacing.png | bin | 2927 -> 3912 bytes | |||
| -rw-r--r-- | tests/ref/layout/stack-1.png | bin | 709 -> 1076 bytes | |||
| -rw-r--r-- | tests/ref/layout/stack-2.png | bin | 3298 -> 8673 bytes | |||
| -rw-r--r-- | tests/ref/layout/table.png | bin | 1313 -> 1566 bytes | |||
| -rw-r--r-- | tests/ref/layout/transform.png | bin | 54712 -> 56525 bytes | |||
| -rw-r--r-- | tests/ref/markup/emph.png | bin | 2499 -> 3772 bytes | |||
| -rw-r--r-- | tests/ref/markup/enums.png | bin | 4123 -> 6209 bytes | |||
| -rw-r--r-- | tests/ref/markup/escape.png | bin | 5203 -> 12375 bytes | |||
| -rw-r--r-- | tests/ref/markup/heading.png | bin | 9141 -> 25715 bytes | |||
| -rw-r--r-- | tests/ref/markup/linebreak.png | bin | 515 -> 641 bytes | |||
| -rw-r--r-- | tests/ref/markup/lists.png | bin | 14701 -> 21645 bytes | |||
| -rw-r--r-- | tests/ref/markup/math.png | bin | 2448 -> 3465 bytes | |||
| -rw-r--r-- | tests/ref/markup/raw.png | bin | 6770 -> 10127 bytes | |||
| -rw-r--r-- | tests/ref/markup/shorthands.png | bin | 2555 -> 3856 bytes | |||
| -rw-r--r-- | tests/ref/markup/strong.png | bin | 2287 -> 3481 bytes | |||
| -rw-r--r-- | tests/ref/style/construct.png | bin | 710 -> 935 bytes | |||
| -rw-r--r-- | tests/ref/style/set-block.png | bin | 812 -> 1151 bytes | |||
| -rw-r--r-- | tests/ref/style/set-site.png | bin | 4252 -> 12421 bytes | |||
| -rw-r--r-- | tests/ref/style/set-toggle.png | bin | 968 -> 1188 bytes | |||
| -rw-r--r-- | tests/ref/text/baseline.png | bin | 886 -> 1325 bytes | |||
| -rw-r--r-- | tests/ref/text/basic.png | bin | 35194 -> 58937 bytes | |||
| -rw-r--r-- | tests/ref/text/bidi.png | bin | 13945 -> 24694 bytes | |||
| -rw-r--r-- | tests/ref/text/chinese.png | bin | 14390 -> 22527 bytes | |||
| -rw-r--r-- | tests/ref/text/decorations.png | bin | 9668 -> 29451 bytes | |||
| -rw-r--r-- | tests/ref/text/em.png | bin | 878 -> 1193 bytes | |||
| -rw-r--r-- | tests/ref/text/features.png | bin | 8140 -> 11892 bytes | |||
| -rw-r--r-- | tests/ref/text/font.png | bin | 22792 -> 39190 bytes | |||
| -rw-r--r-- | tests/ref/text/linebreaks.png | bin | 9450 -> 14308 bytes | |||
| -rw-r--r-- | tests/ref/text/links.png | bin | 23388 -> 35066 bytes | |||
| -rw-r--r-- | tests/ref/text/par.png | bin | 9364 -> 13798 bytes | |||
| -rw-r--r-- | tests/ref/text/shaping.png | bin | 12021 -> 17047 bytes | |||
| -rw-r--r-- | tests/ref/text/tracking.png | bin | 2609 -> 3854 bytes | |||
| -rw-r--r-- | tests/ref/text/whitespace.png | bin | 4674 -> 6273 bytes | |||
| -rw-r--r-- | tests/ref/utility/basics.png | bin | 805 -> 1170 bytes | |||
| -rw-r--r-- | tests/typeset.rs | 590 |
70 files changed, 131 insertions, 459 deletions
diff --git a/tests/ref/code/array.png b/tests/ref/code/array.png Binary files differindex 752b2318..613aab97 100644 --- a/tests/ref/code/array.png +++ b/tests/ref/code/array.png diff --git a/tests/ref/code/block.png b/tests/ref/code/block.png Binary files differindex 0a43919d..9cd0ba36 100644 --- a/tests/ref/code/block.png +++ b/tests/ref/code/block.png diff --git a/tests/ref/code/call.png b/tests/ref/code/call.png Binary files differindex bd6f22f3..eefc8cae 100644 --- a/tests/ref/code/call.png +++ b/tests/ref/code/call.png diff --git a/tests/ref/code/closure.png b/tests/ref/code/closure.png Binary files differindex 17b4ef63..7d933033 100644 --- a/tests/ref/code/closure.png +++ b/tests/ref/code/closure.png diff --git a/tests/ref/code/comment.png b/tests/ref/code/comment.png Binary files differindex c5dffd67..d7b59976 100644 --- a/tests/ref/code/comment.png +++ b/tests/ref/code/comment.png diff --git a/tests/ref/code/dict.png b/tests/ref/code/dict.png Binary files differindex 09751ae8..43cf1370 100644 --- a/tests/ref/code/dict.png +++ b/tests/ref/code/dict.png diff --git a/tests/ref/code/for.png b/tests/ref/code/for.png Binary files differindex 852fee49..1ef08f7a 100644 --- a/tests/ref/code/for.png +++ b/tests/ref/code/for.png diff --git a/tests/ref/code/if.png b/tests/ref/code/if.png Binary files differindex 65adcee2..177e61bd 100644 --- a/tests/ref/code/if.png +++ b/tests/ref/code/if.png diff --git a/tests/ref/code/import.png b/tests/ref/code/import.png Binary files differindex 07140364..00d3b2ee 100644 --- a/tests/ref/code/import.png +++ b/tests/ref/code/import.png diff --git a/tests/ref/code/include.png b/tests/ref/code/include.png Binary files differindex 62166c64..f5a392e4 100644 --- a/tests/ref/code/include.png +++ b/tests/ref/code/include.png diff --git a/tests/ref/code/let.png b/tests/ref/code/let.png Binary files differindex 0753ae05..07afcb96 100644 --- a/tests/ref/code/let.png +++ b/tests/ref/code/let.png diff --git a/tests/ref/code/ops.png b/tests/ref/code/ops.png Binary files differindex b16ed1de..abcab137 100644 --- a/tests/ref/code/ops.png +++ b/tests/ref/code/ops.png diff --git a/tests/ref/code/repr.png b/tests/ref/code/repr.png Binary files differindex e0749e12..47f21b03 100644 --- a/tests/ref/code/repr.png +++ b/tests/ref/code/repr.png diff --git a/tests/ref/code/while.png b/tests/ref/code/while.png Binary files differindex e96caf95..026f9943 100644 --- a/tests/ref/code/while.png +++ b/tests/ref/code/while.png diff --git a/tests/ref/coma.png b/tests/ref/coma.png Binary files differindex d4c6c3de..34a6b30a 100644 --- a/tests/ref/coma.png +++ b/tests/ref/coma.png diff --git a/tests/ref/layout/align.png b/tests/ref/layout/align.png Binary files differindex 57945d5c..77619b32 100644 --- a/tests/ref/layout/align.png +++ b/tests/ref/layout/align.png diff --git a/tests/ref/layout/box-block.png b/tests/ref/layout/box-block.png Binary files differindex f6981fe5..87484c25 100644 --- a/tests/ref/layout/box-block.png +++ b/tests/ref/layout/box-block.png diff --git a/tests/ref/layout/columns.png b/tests/ref/layout/columns.png Binary files differindex 34eb1907..8a65443d 100644 --- a/tests/ref/layout/columns.png +++ b/tests/ref/layout/columns.png diff --git a/tests/ref/layout/grid-1.png b/tests/ref/layout/grid-1.png Binary files differindex 1996e25a..2c57e28c 100644 --- a/tests/ref/layout/grid-1.png +++ b/tests/ref/layout/grid-1.png diff --git a/tests/ref/layout/grid-2.png b/tests/ref/layout/grid-2.png Binary files differindex e04fdadc..64986797 100644 --- a/tests/ref/layout/grid-2.png +++ b/tests/ref/layout/grid-2.png diff --git a/tests/ref/layout/grid-3.png b/tests/ref/layout/grid-3.png Binary files differindex 505ed0ed..740ccf0a 100644 --- a/tests/ref/layout/grid-3.png +++ b/tests/ref/layout/grid-3.png diff --git a/tests/ref/layout/grid-4.png b/tests/ref/layout/grid-4.png Binary files differindex a291658f..c78eb721 100644 --- a/tests/ref/layout/grid-4.png +++ b/tests/ref/layout/grid-4.png diff --git a/tests/ref/layout/grid-5.png b/tests/ref/layout/grid-5.png Binary files differindex 51703b11..8afe9446 100644 --- a/tests/ref/layout/grid-5.png +++ b/tests/ref/layout/grid-5.png diff --git a/tests/ref/layout/image.png b/tests/ref/layout/image.png Binary files differindex 60aa5ab2..3bf5e56f 100644 --- a/tests/ref/layout/image.png +++ b/tests/ref/layout/image.png diff --git a/tests/ref/layout/pad.png b/tests/ref/layout/pad.png Binary files differindex 4fd2ca47..260b4586 100644 --- a/tests/ref/layout/pad.png +++ b/tests/ref/layout/pad.png diff --git a/tests/ref/layout/page.png b/tests/ref/layout/page.png Binary files differindex 57e4b8f1..20ac630f 100644 --- a/tests/ref/layout/page.png +++ b/tests/ref/layout/page.png diff --git a/tests/ref/layout/pagebreak.png b/tests/ref/layout/pagebreak.png Binary files differindex a6c0725e..364d9294 100644 --- a/tests/ref/layout/pagebreak.png +++ b/tests/ref/layout/pagebreak.png diff --git a/tests/ref/layout/place-background.png b/tests/ref/layout/place-background.png Binary files differindex 2fd0f711..7ac3b57b 100644 --- a/tests/ref/layout/place-background.png +++ b/tests/ref/layout/place-background.png diff --git a/tests/ref/layout/place.png b/tests/ref/layout/place.png Binary files differindex 4fdb1f70..fc97100f 100644 --- a/tests/ref/layout/place.png +++ b/tests/ref/layout/place.png diff --git a/tests/ref/layout/shape-aspect.png b/tests/ref/layout/shape-aspect.png Binary files differindex f76b4980..719c1e6e 100644 --- a/tests/ref/layout/shape-aspect.png +++ b/tests/ref/layout/shape-aspect.png diff --git a/tests/ref/layout/shape-circle.png b/tests/ref/layout/shape-circle.png Binary files differindex 30734cb5..040c6f0b 100644 --- a/tests/ref/layout/shape-circle.png +++ b/tests/ref/layout/shape-circle.png diff --git a/tests/ref/layout/shape-ellipse.png b/tests/ref/layout/shape-ellipse.png Binary files differindex e3c63427..740f005f 100644 --- a/tests/ref/layout/shape-ellipse.png +++ b/tests/ref/layout/shape-ellipse.png diff --git a/tests/ref/layout/shape-fill-stroke.png b/tests/ref/layout/shape-fill-stroke.png Binary files differindex 2d04b3dd..12fcbd55 100644 --- a/tests/ref/layout/shape-fill-stroke.png +++ b/tests/ref/layout/shape-fill-stroke.png diff --git a/tests/ref/layout/shape-rect.png b/tests/ref/layout/shape-rect.png Binary files differindex b6ab89aa..1fdb0dac 100644 --- a/tests/ref/layout/shape-rect.png +++ b/tests/ref/layout/shape-rect.png diff --git a/tests/ref/layout/shape-square.png b/tests/ref/layout/shape-square.png Binary files differindex 86bc1ff5..00a0c848 100644 --- a/tests/ref/layout/shape-square.png +++ b/tests/ref/layout/shape-square.png diff --git a/tests/ref/layout/spacing.png b/tests/ref/layout/spacing.png Binary files differindex 09f7d6d9..193be6f5 100644 --- a/tests/ref/layout/spacing.png +++ b/tests/ref/layout/spacing.png diff --git a/tests/ref/layout/stack-1.png b/tests/ref/layout/stack-1.png Binary files differindex 162ffc48..106cc791 100644 --- a/tests/ref/layout/stack-1.png +++ b/tests/ref/layout/stack-1.png diff --git a/tests/ref/layout/stack-2.png b/tests/ref/layout/stack-2.png Binary files differindex 470b57ec..52b75bbd 100644 --- a/tests/ref/layout/stack-2.png +++ b/tests/ref/layout/stack-2.png diff --git a/tests/ref/layout/table.png b/tests/ref/layout/table.png Binary files differindex 1a576c35..bc70d548 100644 --- a/tests/ref/layout/table.png +++ b/tests/ref/layout/table.png diff --git a/tests/ref/layout/transform.png b/tests/ref/layout/transform.png Binary files differindex 2593a3f2..65d94758 100644 --- a/tests/ref/layout/transform.png +++ b/tests/ref/layout/transform.png diff --git a/tests/ref/markup/emph.png b/tests/ref/markup/emph.png Binary files differindex d0598406..6b3bfb2d 100644 --- a/tests/ref/markup/emph.png +++ b/tests/ref/markup/emph.png diff --git a/tests/ref/markup/enums.png b/tests/ref/markup/enums.png Binary files differindex a201131f..a257b0dd 100644 --- a/tests/ref/markup/enums.png +++ b/tests/ref/markup/enums.png diff --git a/tests/ref/markup/escape.png b/tests/ref/markup/escape.png Binary files differindex 41b8c4d6..4d2b570e 100644 --- a/tests/ref/markup/escape.png +++ b/tests/ref/markup/escape.png diff --git a/tests/ref/markup/heading.png b/tests/ref/markup/heading.png Binary files differindex 52911d66..ac229180 100644 --- a/tests/ref/markup/heading.png +++ b/tests/ref/markup/heading.png diff --git a/tests/ref/markup/linebreak.png b/tests/ref/markup/linebreak.png Binary files differindex 4f3678f8..2304ab96 100644 --- a/tests/ref/markup/linebreak.png +++ b/tests/ref/markup/linebreak.png diff --git a/tests/ref/markup/lists.png b/tests/ref/markup/lists.png Binary files differindex 1405b95e..d39f3164 100644 --- a/tests/ref/markup/lists.png +++ b/tests/ref/markup/lists.png diff --git a/tests/ref/markup/math.png b/tests/ref/markup/math.png Binary files differindex 426f3dbf..448b2d12 100644 --- a/tests/ref/markup/math.png +++ b/tests/ref/markup/math.png diff --git a/tests/ref/markup/raw.png b/tests/ref/markup/raw.png Binary files differindex bd8b811a..4effb303 100644 --- a/tests/ref/markup/raw.png +++ b/tests/ref/markup/raw.png diff --git a/tests/ref/markup/shorthands.png b/tests/ref/markup/shorthands.png Binary files differindex aa6436dd..db27ef36 100644 --- a/tests/ref/markup/shorthands.png +++ b/tests/ref/markup/shorthands.png diff --git a/tests/ref/markup/strong.png b/tests/ref/markup/strong.png Binary files differindex 6e2a84e1..53062e9a 100644 --- a/tests/ref/markup/strong.png +++ b/tests/ref/markup/strong.png diff --git a/tests/ref/style/construct.png b/tests/ref/style/construct.png Binary files differindex e0dcf409..b5b3a152 100644 --- a/tests/ref/style/construct.png +++ b/tests/ref/style/construct.png diff --git a/tests/ref/style/set-block.png b/tests/ref/style/set-block.png Binary files differindex 8ee5cfb6..898c9c65 100644 --- a/tests/ref/style/set-block.png +++ b/tests/ref/style/set-block.png diff --git a/tests/ref/style/set-site.png b/tests/ref/style/set-site.png Binary files differindex affe2e1c..3188f7a7 100644 --- a/tests/ref/style/set-site.png +++ b/tests/ref/style/set-site.png diff --git a/tests/ref/style/set-toggle.png b/tests/ref/style/set-toggle.png Binary files differindex ae8101ca..daaa3d6c 100644 --- a/tests/ref/style/set-toggle.png +++ b/tests/ref/style/set-toggle.png diff --git a/tests/ref/text/baseline.png b/tests/ref/text/baseline.png Binary files differindex 6890236f..71f75d9b 100644 --- a/tests/ref/text/baseline.png +++ b/tests/ref/text/baseline.png diff --git a/tests/ref/text/basic.png b/tests/ref/text/basic.png Binary files differindex 88d3059c..e7887f07 100644 --- a/tests/ref/text/basic.png +++ b/tests/ref/text/basic.png diff --git a/tests/ref/text/bidi.png b/tests/ref/text/bidi.png Binary files differindex db8f77ac..7e0aab8f 100644 --- a/tests/ref/text/bidi.png +++ b/tests/ref/text/bidi.png diff --git a/tests/ref/text/chinese.png b/tests/ref/text/chinese.png Binary files differindex c47a8a2f..aa8801c0 100644 --- a/tests/ref/text/chinese.png +++ b/tests/ref/text/chinese.png diff --git a/tests/ref/text/decorations.png b/tests/ref/text/decorations.png Binary files differindex 183dacf9..3464beb2 100644 --- a/tests/ref/text/decorations.png +++ b/tests/ref/text/decorations.png diff --git a/tests/ref/text/em.png b/tests/ref/text/em.png Binary files differindex 4c168db6..e989eade 100644 --- a/tests/ref/text/em.png +++ b/tests/ref/text/em.png diff --git a/tests/ref/text/features.png b/tests/ref/text/features.png Binary files differindex 90521427..3da67e2b 100644 --- a/tests/ref/text/features.png +++ b/tests/ref/text/features.png diff --git a/tests/ref/text/font.png b/tests/ref/text/font.png Binary files differindex e194b00a..cb86f929 100644 --- a/tests/ref/text/font.png +++ b/tests/ref/text/font.png diff --git a/tests/ref/text/linebreaks.png b/tests/ref/text/linebreaks.png Binary files differindex 66697a89..1498a845 100644 --- a/tests/ref/text/linebreaks.png +++ b/tests/ref/text/linebreaks.png diff --git a/tests/ref/text/links.png b/tests/ref/text/links.png Binary files differindex 510c7e98..a334a435 100644 --- a/tests/ref/text/links.png +++ b/tests/ref/text/links.png diff --git a/tests/ref/text/par.png b/tests/ref/text/par.png Binary files differindex bb705a19..9ea42713 100644 --- a/tests/ref/text/par.png +++ b/tests/ref/text/par.png diff --git a/tests/ref/text/shaping.png b/tests/ref/text/shaping.png Binary files differindex 565dcb7c..1e57afca 100644 --- a/tests/ref/text/shaping.png +++ b/tests/ref/text/shaping.png diff --git a/tests/ref/text/tracking.png b/tests/ref/text/tracking.png Binary files differindex 43eb5e8a..5c35d94c 100644 --- a/tests/ref/text/tracking.png +++ b/tests/ref/text/tracking.png diff --git a/tests/ref/text/whitespace.png b/tests/ref/text/whitespace.png Binary files differindex 36fb2475..9a1ed3cd 100644 --- a/tests/ref/text/whitespace.png +++ b/tests/ref/text/whitespace.png diff --git a/tests/ref/utility/basics.png b/tests/ref/utility/basics.png Binary files differindex 0ac0447b..a80afe5f 100644 --- a/tests/ref/utility/basics.png +++ b/tests/ref/utility/basics.png diff --git a/tests/typeset.rs b/tests/typeset.rs index a4e20774..ac911401 100644 --- a/tests/typeset.rs +++ b/tests/typeset.rs @@ -5,18 +5,13 @@ use std::ops::Range; use std::path::Path; use std::rc::Rc; -use image::{GenericImageView, Rgba}; use tiny_skia as sk; -use ttf_parser::{GlyphId, OutlineBuilder}; -use usvg::FitTo; use walkdir::WalkDir; use typst::diag::Error; use typst::eval::{Smart, StyleMap, Value}; -use typst::font::Face; -use typst::frame::{Element, Frame, Geometry, Shape, Stroke, Text}; -use typst::geom::{self, Color, Length, Paint, PathElement, RgbaColor, Size, Transform}; -use typst::image::{Image, RasterImage, Svg}; +use typst::frame::{Element, Frame}; +use typst::geom::Length; use typst::library::{PageNode, TextNode}; use typst::loading::FsLoader; use typst::parse::Scanner; @@ -229,7 +224,7 @@ fn test( fs::write(pdf_path, pdf_data).unwrap(); } - let canvas = draw(ctx, &frames, 2.0); + let canvas = render(ctx, &frames); fs::create_dir_all(&png_path.parent().unwrap()).unwrap(); canvas.save_png(png_path).unwrap(); @@ -325,52 +320,61 @@ fn test_part( (ok, compare_ref, frames) } -#[cfg(feature = "layout-cache")] -fn test_incremental( - ctx: &mut Context, - i: usize, - tree: &RootNode, - frames: &[Rc<Frame>], -) -> bool { - let mut ok = true; +fn parse_metadata(source: &SourceFile) -> (Option<bool>, Vec<Error>) { + let mut compare_ref = None; + let mut errors = vec![]; - let reference = ctx.layouts.clone(); - for level in 0 .. reference.levels() { - ctx.layouts = reference.clone(); - ctx.layouts.retain(|x| x == level); - if ctx.layouts.is_empty() { - continue; + let lines: Vec<_> = source.src().lines().map(str::trim).collect(); + for (i, line) in lines.iter().enumerate() { + if line.starts_with("// Ref: false") { + compare_ref = Some(false); } - ctx.layouts.turnaround(); + if line.starts_with("// Ref: true") { + compare_ref = Some(true); + } - let cached = silenced(|| tree.layout(ctx)); - let total = reference.levels() - 1; - let misses = ctx - .layouts - .entries() - .filter(|e| e.level() == level && !e.hit() && e.age() == 2) - .count(); + let rest = if let Some(rest) = line.strip_prefix("// Error: ") { + rest + } else { + continue; + }; - if misses > 0 { - println!( - " Subtest {i} relayout had {misses} cache misses on level {level} of {total} ❌", - ); - ok = false; + fn num(s: &mut Scanner) -> usize { + s.eat_while(|c| c.is_numeric()).parse().unwrap() } - if cached != frames { - println!( - " Subtest {i} relayout differs from clean pass on level {level} ❌", - ); - ok = false; - } + let comments = + lines[i ..].iter().take_while(|line| line.starts_with("//")).count(); + + let pos = |s: &mut Scanner| -> usize { + let first = num(s) - 1; + let (delta, column) = + if s.eat_if(':') { (first, num(s) - 1) } else { (0, first) }; + let line = (i + comments) + delta; + source.line_column_to_byte(line, column).unwrap() + }; + + let mut s = Scanner::new(rest); + let start = pos(&mut s); + let end = if s.eat_if('-') { pos(&mut s) } else { start }; + let span = Span::new(source.id(), start, end); + + errors.push(Error::new(span, s.rest().trim())); } - ctx.layouts = reference; - ctx.layouts.turnaround(); + (compare_ref, errors) +} - ok +fn print_error(source: &SourceFile, line: usize, error: &Error) { + let start_line = 1 + line + source.byte_to_line(error.span.start).unwrap(); + let start_col = 1 + source.byte_to_column(error.span.start).unwrap(); + let end_line = 1 + line + source.byte_to_line(error.span.end).unwrap(); + let end_col = 1 + source.byte_to_column(error.span.end).unwrap(); + println!( + "Error: {start_line}:{start_col}-{end_line}:{end_col}: {}", + error.message, + ); } /// Pseudorandomly edit the source file and test whether a reparse produces the @@ -418,12 +422,13 @@ fn test_reparse(src: &str, i: usize, rng: &mut LinearShift) -> bool { } incr_source.edit(replace.clone(), with); - let edited_src = incr_source.src(); + let edited_src = incr_source.src(); let ref_source = SourceFile::detached(edited_src); let incr_root = incr_source.root(); let ref_root = ref_source.root(); - if incr_root != ref_root { + let same = incr_root == ref_root; + if !same { println!( " Subtest {i} reparse differs from clean parse when inserting '{with}' at {}-{} ❌\n", replace.start, replace.end, @@ -431,10 +436,9 @@ fn test_reparse(src: &str, i: usize, rng: &mut LinearShift) -> bool { println!(" Expected reference tree:\n{ref_root:#?}\n"); println!(" Found incremental tree:\n{incr_root:#?}"); println!("Full source ({}):\n\"{edited_src:?}\"", edited_src.len()); - false - } else { - true } + + same }; let mut pick = |range: Range<usize>| { @@ -443,7 +447,6 @@ fn test_reparse(src: &str, i: usize, rng: &mut LinearShift) -> bool { }; let insertions = (src.len() as f64 / 400.0).ceil() as usize; - for _ in 0 .. insertions { let supplement = supplements[pick(0 .. supplements.len())]; let start = pick(0 .. src.len()); @@ -457,459 +460,128 @@ fn test_reparse(src: &str, i: usize, rng: &mut LinearShift) -> bool { } let red = SourceFile::detached(src).red(); - let leafs = red.as_ref().leafs(); - let leaf_start = leafs[pick(0 .. leafs.len())].span().start; let supplement = supplements[pick(0 .. supplements.len())]; - ok &= apply(leaf_start .. leaf_start, supplement); ok } -fn parse_metadata(source: &SourceFile) -> (Option<bool>, Vec<Error>) { - let mut compare_ref = None; - let mut errors = vec![]; - - let lines: Vec<_> = source.src().lines().map(str::trim).collect(); - for (i, line) in lines.iter().enumerate() { - if line.starts_with("// Ref: false") { - compare_ref = Some(false); - } - - if line.starts_with("// Ref: true") { - compare_ref = Some(true); - } +#[cfg(feature = "layout-cache")] +fn test_incremental( + ctx: &mut Context, + i: usize, + tree: &RootNode, + frames: &[Rc<Frame>], +) -> bool { + let mut ok = true; - let rest = if let Some(rest) = line.strip_prefix("// Error: ") { - rest - } else { + let reference = ctx.layout_cache.clone(); + for level in 0 .. reference.levels() { + ctx.layout_cache = reference.clone(); + ctx.layout_cache.retain(|x| x == level); + if ctx.layout_cache.is_empty() { continue; - }; - - fn num(s: &mut Scanner) -> usize { - s.eat_while(|c| c.is_numeric()).parse().unwrap() } - let comments = - lines[i ..].iter().take_while(|line| line.starts_with("//")).count(); + ctx.layout_cache.turnaround(); - let pos = |s: &mut Scanner| -> usize { - let first = num(s) - 1; - let (delta, column) = - if s.eat_if(':') { (first, num(s) - 1) } else { (0, first) }; - let line = (i + comments) + delta; - source.line_column_to_byte(line, column).unwrap() - }; + let cached = silenced(|| tree.layout(ctx)); + let total = reference.levels() - 1; + let misses = ctx + .layout_cache + .entries() + .filter(|e| e.level() == level && !e.hit() && e.age() == 2) + .count(); - let mut s = Scanner::new(rest); - let start = pos(&mut s); - let end = if s.eat_if('-') { pos(&mut s) } else { start }; - let span = Span::new(source.id(), start, end); + if misses > 0 { + println!( + " Subtest {i} relayout had {misses} cache misses on level {level} of {total} ❌", + ); + ok = false; + } - errors.push(Error::new(span, s.rest().trim())); + if cached != frames { + println!( + " Subtest {i} relayout differs from clean pass on level {level} ❌", + ); + ok = false; + } } - (compare_ref, errors) -} + ctx.layout_cache = reference; + ctx.layout_cache.turnaround(); -fn print_error(source: &SourceFile, line: usize, error: &Error) { - let start_line = 1 + line + source.byte_to_line(error.span.start).unwrap(); - let start_col = 1 + source.byte_to_column(error.span.start).unwrap(); - let end_line = 1 + line + source.byte_to_line(error.span.end).unwrap(); - let end_col = 1 + source.byte_to_column(error.span.end).unwrap(); - println!( - "Error: {start_line}:{start_col}-{end_line}:{end_col}: {}", - error.message, - ); + ok } -fn draw(ctx: &Context, frames: &[Rc<Frame>], dpp: f32) -> sk::Pixmap { - let pad = Length::pt(5.0); - let width = 2.0 * pad + frames.iter().map(|l| l.size.x).max().unwrap_or_default(); - let height = pad + frames.iter().map(|l| l.size.y + pad).sum::<Length>(); +/// Draw all frames into one image with padding in between. +fn render(ctx: &mut Context, frames: &[Rc<Frame>]) -> sk::Pixmap { + let pixel_per_pt = 2.0; + let pixmaps: Vec<_> = frames + .iter() + .map(|frame| { + let limit = Length::cm(100.0); + if frame.size.x > limit || frame.size.y > limit { + panic!("overlarge frame: {:?}", frame.size); + } + typst::export::render(ctx, frame, pixel_per_pt) + }) + .collect(); - let pxw = (dpp * width.to_f32()) as u32; - let pxh = (dpp * height.to_f32()) as u32; - if pxw > 4000 || pxh > 4000 { - panic!("overlarge image: {pxw} by {pxh} ({width:?} x {height:?})",); - } + let pad = (5.0 * pixel_per_pt).round() as u32; + let pxw = 2 * pad + pixmaps.iter().map(sk::Pixmap::width).max().unwrap_or_default(); + let pxh = pad + pixmaps.iter().map(|pixmap| pixmap.height() + pad).sum::<u32>(); let mut canvas = sk::Pixmap::new(pxw, pxh).unwrap(); canvas.fill(sk::Color::BLACK); - let mut mask = sk::ClipMask::new(); - let rect = sk::Rect::from_xywh(0.0, 0.0, pxw as f32, pxh as f32).unwrap(); - let path = sk::PathBuilder::from_rect(rect); - mask.set_path(pxw, pxh, &path, sk::FillRule::default(), false); - - let mut ts = - sk::Transform::from_scale(dpp, dpp).pre_translate(pad.to_f32(), pad.to_f32()); - - for frame in frames { - let mut background = sk::Paint::default(); - background.set_color(sk::Color::WHITE); + let [x, mut y] = [pad; 2]; + for (frame, mut pixmap) in frames.iter().zip(pixmaps) { + let ts = sk::Transform::from_scale(pixel_per_pt, pixel_per_pt); + render_links(&mut pixmap, ts, ctx, frame); - let w = frame.size.x.to_f32(); - let h = frame.size.y.to_f32(); - let rect = sk::Rect::from_xywh(0.0, 0.0, w, h).unwrap(); - canvas.fill_rect(rect, &background, ts, None); + canvas.draw_pixmap( + x as i32, + y as i32, + pixmap.as_ref(), + &sk::PixmapPaint::default(), + sk::Transform::identity(), + None, + ); - draw_frame(&mut canvas, ts, &mask, ctx, frame, true); - ts = ts.pre_translate(0.0, (frame.size.y + pad).to_f32()); + y += pixmap.height() + pad; } canvas } -fn draw_frame( +/// Draw extra boxes for links so we can see whether they are there. +fn render_links( canvas: &mut sk::Pixmap, ts: sk::Transform, - mask: &sk::ClipMask, ctx: &Context, frame: &Frame, - clip: bool, ) { - let mut storage; - let mut mask = mask; - if clip { - let w = frame.size.x.to_f32(); - let h = frame.size.y.to_f32(); - let rect = sk::Rect::from_xywh(0.0, 0.0, w, h).unwrap(); - let path = sk::PathBuilder::from_rect(rect).transform(ts).unwrap(); - let rule = sk::FillRule::default(); - storage = mask.clone(); - if storage.intersect_path(&path, rule, false).is_none() { - // Fails if clipping rect is empty. In that case we just clip - // everything by returning. - return; - } - mask = &storage; - } - for (pos, element) in &frame.elements { - let x = pos.x.to_f32(); - let y = pos.y.to_f32(); - let ts = ts.pre_translate(x, y); - + let ts = ts.pre_translate(pos.x.to_pt() as f32, pos.y.to_pt() as f32); match *element { Element::Group(ref group) => { - let ts = ts.pre_concat(convert_typst_transform(group.transform)); - draw_frame(canvas, ts, &mask, ctx, &group.frame, group.clips); - } - Element::Text(ref text) => { - draw_text(canvas, ts, mask, ctx.fonts.get(text.face_id), text); - } - Element::Shape(ref shape) => { - draw_shape(canvas, ts, mask, shape); - } - Element::Image(id, size) => { - draw_image(canvas, ts, mask, ctx.images.get(id), size); - } - Element::Link(_, s) => { - let fill = RgbaColor::new(40, 54, 99, 40).into(); - let shape = Shape::filled(Geometry::Rect(s), fill); - draw_shape(canvas, ts, mask, &shape); - } - } - } -} - -fn draw_text( - canvas: &mut sk::Pixmap, - ts: sk::Transform, - mask: &sk::ClipMask, - face: &Face, - text: &Text, -) { - let ttf = face.ttf(); - let size = text.size.to_f32(); - let units_per_em = face.units_per_em as f32; - let pixels_per_em = text.size.to_f32() * ts.sy; - let scale = size / units_per_em; - - let mut x = 0.0; - for glyph in &text.glyphs { - let glyph_id = GlyphId(glyph.id); - let offset = x + glyph.x_offset.resolve(text.size).to_f32(); - let ts = ts.pre_translate(offset, 0.0); - - if let Some(tree) = ttf - .glyph_svg_image(glyph_id) - .and_then(|data| std::str::from_utf8(data).ok()) - .map(|svg| { - let viewbox = format!("viewBox=\"0 0 {0} {0}\" xmlns", units_per_em); - svg.replace("xmlns", &viewbox) - }) - .and_then(|s| { - usvg::Tree::from_str(&s, &usvg::Options::default().to_ref()).ok() - }) - { - for child in tree.root().children() { - if let usvg::NodeKind::Path(node) = &*child.borrow() { - // SVG is already Y-down, no flipping required. - let ts = convert_usvg_transform(node.transform) - .post_scale(scale, scale) - .post_concat(ts); - - if let Some(fill) = &node.fill { - let path = convert_usvg_path(&node.data); - let (paint, fill_rule) = convert_usvg_fill(fill); - canvas.fill_path(&path, &paint, fill_rule, ts, Some(mask)); - } - } - } - } else if let Some(raster) = - ttf.glyph_raster_image(glyph_id, pixels_per_em as u16) - { - // TODO: Vertical alignment isn't quite right for Apple Color Emoji, - // and maybe also for Noto Color Emoji. And: Is the size calculation - // correct? - let img = RasterImage::parse(&raster.data).unwrap(); - let h = text.size; - let w = (img.width() as f64 / img.height() as f64) * h; - let dx = (raster.x as f32) / (img.width() as f32) * size; - let dy = (raster.y as f32) / (img.height() as f32) * size; - let ts = ts.pre_translate(dx, -size - dy); - draw_image(canvas, ts, mask, &Image::Raster(img), Size::new(w, h)); - } else { - // Otherwise, draw normal outline. - let mut builder = WrappedPathBuilder(sk::PathBuilder::new()); - if ttf.outline_glyph(glyph_id, &mut builder).is_some() { - // Flip vertically because font design coordinate system is Y-up. - let ts = ts.pre_scale(scale, -scale); - let path = builder.0.finish().unwrap(); - let paint = convert_typst_paint(text.fill); - canvas.fill_path(&path, &paint, sk::FillRule::default(), ts, Some(mask)); - } - } - - x += glyph.x_advance.resolve(text.size).to_f32(); - } -} - -fn draw_shape( - canvas: &mut sk::Pixmap, - ts: sk::Transform, - mask: &sk::ClipMask, - shape: &Shape, -) { - let path = match shape.geometry { - Geometry::Rect(size) => { - let w = size.x.to_f32(); - let h = size.y.to_f32(); - let rect = sk::Rect::from_xywh(0.0, 0.0, w, h).unwrap(); - sk::PathBuilder::from_rect(rect) - } - Geometry::Ellipse(size) => { - let approx = geom::Path::ellipse(size); - convert_typst_path(&approx) - } - Geometry::Line(target) => { - let mut builder = sk::PathBuilder::new(); - builder.line_to(target.x.to_f32(), target.y.to_f32()); - builder.finish().unwrap() - } - Geometry::Path(ref path) => convert_typst_path(path), - }; - - if let Some(fill) = shape.fill { - let mut paint = convert_typst_paint(fill); - if matches!(shape.geometry, Geometry::Rect(_)) { - paint.anti_alias = false; - } - - let rule = sk::FillRule::default(); - canvas.fill_path(&path, &paint, rule, ts, Some(mask)); - } - - if let Some(Stroke { paint, thickness }) = shape.stroke { - let paint = convert_typst_paint(paint); - let mut stroke = sk::Stroke::default(); - stroke.width = thickness.to_f32(); - canvas.stroke_path(&path, &paint, &stroke, ts, Some(mask)); - } -} - -fn draw_image( - canvas: &mut sk::Pixmap, - ts: sk::Transform, - mask: &sk::ClipMask, - img: &Image, - size: Size, -) { - let view_width = size.x.to_f32(); - let view_height = size.y.to_f32(); - - let pixmap = match img { - Image::Raster(img) => { - let w = img.buf.width(); - let h = img.buf.height(); - let mut pixmap = sk::Pixmap::new(w, h).unwrap(); - for ((_, _, src), dest) in img.buf.pixels().zip(pixmap.pixels_mut()) { - let Rgba([r, g, b, a]) = src; - *dest = sk::ColorU8::from_rgba(r, g, b, a).premultiply(); - } - pixmap - } - Image::Svg(Svg(tree)) => { - let size = tree.svg_node().size; - let aspect = (size.width() / size.height()) as f32; - let scale = ts.sx.max(ts.sy); - let w = (scale * view_width.max(aspect * view_height)).ceil() as u32; - let h = ((w as f32) / aspect).ceil() as u32; - let mut pixmap = sk::Pixmap::new(w, h).unwrap(); - resvg::render( - &tree, - FitTo::Size(w, h), - sk::Transform::identity(), - pixmap.as_mut(), - ); - pixmap - } - }; - - let scale_x = view_width / pixmap.width() as f32; - let scale_y = view_height / pixmap.height() as f32; - - let mut paint = sk::Paint::default(); - paint.shader = sk::Pattern::new( - pixmap.as_ref(), - sk::SpreadMode::Pad, - sk::FilterQuality::Bilinear, - 1.0, - sk::Transform::from_scale(scale_x, scale_y), - ); - - let rect = sk::Rect::from_xywh(0.0, 0.0, view_width, view_height).unwrap(); - canvas.fill_rect(rect, &paint, ts, Some(mask)); -} - -fn convert_typst_transform(transform: Transform) -> sk::Transform { - let Transform { sx, ky, kx, sy, tx, ty } = transform; - sk::Transform::from_row( - sx.get() as _, - ky.get() as _, - kx.get() as _, - sy.get() as _, - tx.to_f32(), - ty.to_f32(), - ) -} - -fn convert_typst_paint(paint: Paint) -> sk::Paint<'static> { - let Paint::Solid(Color::Rgba(c)) = paint; - let mut paint = sk::Paint::default(); - paint.set_color_rgba8(c.r, c.g, c.b, c.a); - paint.anti_alias = true; - paint -} - -fn convert_typst_path(path: &geom::Path) -> sk::Path { - let mut builder = sk::PathBuilder::new(); - for elem in &path.0 { - match elem { - PathElement::MoveTo(p) => { - builder.move_to(p.x.to_f32(), p.y.to_f32()); - } - PathElement::LineTo(p) => { - builder.line_to(p.x.to_f32(), p.y.to_f32()); + let ts = ts.pre_concat(group.transform.into()); + render_links(canvas, ts, ctx, &group.frame); } - PathElement::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(), - ); - } - PathElement::ClosePath => { - builder.close(); - } - }; - } - builder.finish().unwrap() -} - -fn convert_usvg_transform(transform: usvg::Transform) -> sk::Transform { - let usvg::Transform { a, b, c, d, e, f } = transform; - sk::Transform::from_row(a as _, b as _, c as _, d as _, e as _, f as _) -} - -fn convert_usvg_fill(fill: &usvg::Fill) -> (sk::Paint<'static>, sk::FillRule) { - let mut paint = sk::Paint::default(); - paint.anti_alias = true; - - if let usvg::Paint::Color(usvg::Color { red, green, blue }) = fill.paint { - paint.set_color_rgba8(red, green, blue, fill.opacity.to_u8()) - } - - let rule = match fill.rule { - usvg::FillRule::NonZero => sk::FillRule::Winding, - usvg::FillRule::EvenOdd => sk::FillRule::EvenOdd, - }; - - (paint, rule) -} - -fn convert_usvg_path(path: &usvg::PathData) -> sk::Path { - let mut builder = sk::PathBuilder::new(); - for seg in path.iter() { - match *seg { - usvg::PathSegment::MoveTo { x, y } => { - builder.move_to(x as _, y as _); - } - usvg::PathSegment::LineTo { x, y } => { - builder.line_to(x as _, y as _); - } - usvg::PathSegment::CurveTo { x1, y1, x2, y2, x, y } => { - builder.cubic_to(x1 as _, y1 as _, x2 as _, y2 as _, x as _, y as _); - } - usvg::PathSegment::ClosePath => { - builder.close(); + Element::Link(_, size) => { + let w = size.x.to_pt() as f32; + let h = size.y.to_pt() as f32; + let rect = sk::Rect::from_xywh(0.0, 0.0, w, h).unwrap(); + let mut paint = sk::Paint::default(); + paint.set_color_rgba8(40, 54, 99, 40); + canvas.fill_rect(rect, &paint, ts, None); } + _ => {} } } - builder.finish().unwrap() -} - -struct WrappedPathBuilder(sk::PathBuilder); - -impl OutlineBuilder for WrappedPathBuilder { - fn move_to(&mut self, x: f32, y: f32) { - self.0.move_to(x, y); - } - - fn line_to(&mut self, x: f32, y: f32) { - self.0.line_to(x, y); - } - - fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) { - self.0.quad_to(x1, y1, x, y); - } - - fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) { - self.0.cubic_to(x1, y1, x2, y2, x, y); - } - - fn close(&mut self) { - self.0.close(); - } -} - -/// Additional methods for [`Length`]. -trait LengthExt { - /// Convert an em length to a number of points. - fn to_f32(self) -> f32; -} - -impl LengthExt for Length { - fn to_f32(self) -> f32 { - self.to_pt() as f32 - } } /// Disable stdout and stderr during execution of `f`. |
