1
1
use std:: io:: Cursor ;
2
- use std:: num:: NonZeroUsize ;
3
2
4
3
use protocol:: Rendered ;
5
4
use typst:: eval:: Tracer ;
@@ -50,6 +49,9 @@ fn to_string(v: impl ToString) -> String {
50
49
v. to_string ( )
51
50
}
52
51
52
+ const PAGE_LIMIT : usize = 5 ;
53
+ const BYTES_LIMIT : usize = 25 * 1024 * 1024 ;
54
+
53
55
pub fn render ( sandbox : & Sandbox , source : String ) -> Result < Rendered , String > {
54
56
let world = sandbox. with_source ( source) ;
55
57
@@ -58,34 +60,47 @@ pub fn render(sandbox: &Sandbox, source: String) -> Result<Rendered, String> {
58
60
typst:: compile ( & world, & mut tracer) . map_err ( |diags| format_diagnostics ( & world, & diags) ) ?;
59
61
let warnings = tracer. warnings ( ) ;
60
62
61
- let frame = & document
63
+ let transparent = Color :: from_u8 ( 0 , 0 , 0 , 0 ) ;
64
+ let mut total_attachment_size = 0 ;
65
+
66
+ let images = document
62
67
. pages
63
- . first ( )
64
- . ok_or ( "no pages in rendered output" ) ?
65
- . frame ;
66
- let more_pages = NonZeroUsize :: new ( document. pages . len ( ) . saturating_sub ( 1 ) ) ;
68
+ . iter ( )
69
+ . take ( PAGE_LIMIT )
70
+ . map ( |page| {
71
+ let frame = & page. frame ;
72
+ let pixels_per_point = determine_pixels_per_point ( frame. size ( ) ) . map_err ( to_string) ?;
73
+ let pixmap = typst_render:: render ( frame, pixels_per_point, transparent) ;
74
+
75
+ let mut writer = Cursor :: new ( Vec :: new ( ) ) ;
76
+
77
+ // The unwrap will never fail since `Vec`'s `Write` implementation is infallible.
78
+ image:: write_buffer_with_format (
79
+ & mut writer,
80
+ bytemuck:: cast_slice ( pixmap. pixels ( ) ) ,
81
+ pixmap. width ( ) ,
82
+ pixmap. height ( ) ,
83
+ image:: ColorType :: Rgba8 ,
84
+ image:: ImageFormat :: Png ,
85
+ )
86
+ . unwrap ( ) ;
87
+
88
+ Ok ( writer. into_inner ( ) )
89
+ } )
90
+ . take_while ( |image| {
91
+ if let Ok ( image) = image {
92
+ total_attachment_size += image. len ( ) ;
93
+ total_attachment_size <= BYTES_LIMIT
94
+ } else {
95
+ true
96
+ }
97
+ } )
98
+ . collect :: < Result < Vec < _ > , String > > ( ) ?;
67
99
68
- let pixels_per_point = determine_pixels_per_point ( frame . size ( ) ) . map_err ( to_string ) ? ;
100
+ let more_pages = document . pages . len ( ) - images . len ( ) ;
69
101
70
- let transparent = Color :: from_u8 ( 0 , 0 , 0 , 0 ) ;
71
- let pixmap = typst_render:: render ( frame, pixels_per_point, transparent) ;
72
-
73
- let mut writer = Cursor :: new ( Vec :: new ( ) ) ;
74
-
75
- // The unwrap will never fail since `Vec`'s `Write` implementation is infallible.
76
- image:: write_buffer_with_format (
77
- & mut writer,
78
- bytemuck:: cast_slice ( pixmap. pixels ( ) ) ,
79
- pixmap. width ( ) ,
80
- pixmap. height ( ) ,
81
- image:: ColorType :: Rgba8 ,
82
- image:: ImageFormat :: Png ,
83
- )
84
- . unwrap ( ) ;
85
-
86
- let image = writer. into_inner ( ) ;
87
102
Ok ( Rendered {
88
- image ,
103
+ images ,
89
104
more_pages,
90
105
warnings : format_diagnostics ( & world, & warnings) ,
91
106
} )
0 commit comments