@@ -304,14 +304,14 @@ impl Pdf {
304304 trailer_data. write_into_dict ( & mut trailer, xref_len) ;
305305 trailer. finish ( ) ;
306306
307- finish_trailer ( buf, xref_offset)
307+ finish_trailer ( buf, xref_offset, & [ b'\n' ] )
308308 }
309309
310310 /// TODO
311311 pub fn finish_with_xref_stream (
312312 self ,
313313 xref_id : Ref ,
314- hook : Option < Box < dyn FnOnce ( & [ u8 ] ) -> ( Vec < u8 > , Filter ) > > ,
314+ hook : Option < Box < dyn FnOnce ( & [ u8 ] ) -> ( Vec < u8 > , XRefFilter ) > > ,
315315 ) -> Vec < u8 > {
316316 let Chunk { mut buf, mut offsets } = self . chunk ;
317317 let trailer_data = self . trailer_data ;
@@ -336,7 +336,18 @@ impl Pdf {
336336 stream. pair ( Name ( b"Type" ) , Name ( b"XRef" ) ) ;
337337
338338 if let Some ( filter) = filter {
339- stream. filter ( filter) ;
339+ match filter {
340+ XRefFilter :: Single ( filter) => {
341+ stream. filter ( filter) ;
342+ }
343+ XRefFilter :: Multiple ( filters) => {
344+ let mut arr = stream. insert ( Name ( b"Filter" ) ) . array ( ) ;
345+
346+ for filter in filters {
347+ arr. item ( filter. to_name ( ) ) ;
348+ }
349+ }
350+ }
340351 }
341352
342353 trailer_data. write_into_dict ( stream. deref_mut ( ) , xref_len) ;
@@ -350,13 +361,22 @@ impl Pdf {
350361
351362 stream. finish ( ) ;
352363
353- finish_trailer ( buf, xref_offset)
364+ finish_trailer ( buf, xref_offset, & [ ] )
354365 }
355366}
356367
357- fn finish_trailer ( mut buf : Buf , xref_offset : usize ) -> Vec < u8 > {
368+ /// The filters used for the xref stream.
369+ pub enum XRefFilter {
370+ /// A single filter.
371+ Single ( Filter ) ,
372+ /// An array of filters.
373+ Multiple ( Vec < Filter > ) ,
374+ }
375+
376+ fn finish_trailer ( mut buf : Buf , xref_offset : usize , pad : & [ u8 ] ) -> Vec < u8 > {
377+ buf. extend ( pad) ;
358378 // Write startxref pointing to the xref stream
359- buf. extend ( b"\n startxref \n " ) ;
379+ buf. extend ( b"startxref \n " ) ;
360380 write ! ( buf. inner, "{}" , xref_offset) . unwrap ( ) ;
361381
362382 // Write EOF marker
@@ -475,13 +495,15 @@ impl XRefStreamWriter {
475495 fn write ( & mut self , entry_type : u8 , offset : usize , gen_number : u16 ) {
476496 let offset_bytes = ( offset as u64 ) . to_be_bytes ( ) ;
477497
498+ let start = self . buf . len ( ) ;
478499 self . buf . push ( entry_type) ;
479500 self . buf . extend (
480501 offset_bytes
481502 . iter ( )
482503 . skip ( offset_bytes. len ( ) - self . field_width as usize ) ,
483504 ) ;
484505 self . buf . extend_from_slice ( & gen_number. to_be_bytes ( ) ) ;
506+ eprintln ! ( "{:?}" , & self . buf[ start..] ) ;
485507 }
486508}
487509
@@ -659,4 +681,24 @@ mod tests {
659681 assert_eq ! ( determine_field_width( u16 :: MAX as usize + 1 ) , 3 ) ;
660682 assert_eq ! ( determine_field_width( u32 :: MAX as usize ) , 4 ) ;
661683 }
684+
685+ #[ test]
686+ fn test_xref_stream ( ) {
687+ let mut w = Pdf :: new ( ) ;
688+ w. indirect ( Ref :: new ( 1 ) ) . primitive ( 1 ) ;
689+ w. indirect ( Ref :: new ( 2 ) ) . primitive ( 2 ) ;
690+ w. indirect ( Ref :: new ( 5 ) ) . primitive ( 5 ) ;
691+ test ! (
692+ w. finish_with_xref_stream( Ref :: new( 6 ) , None ) ,
693+ b"%PDF-1.7\n %\x80 \x80 \x80 \x80 \n " ,
694+ b"1 0 obj\n 1\n endobj\n " ,
695+ b"2 0 obj\n 2\n endobj\n " ,
696+ b"5 0 obj\n 5\n endobj\n " ,
697+ b"6 0 obj\n <<\n /Length 28\n /Type /XRef\n /Size 7\n /W [1 1 2]\n >>\n stream" ,
698+ // [0, 3, 255, 255], [1, 16, 0, 0], [1, 34, 0, 0], [0, 4, 0, 0], [0, 0, 0, 0], [1, 52, 0, 0], [1, 70, 0, 0]
699+ b"\x00 \x03 \xFF \xFF \x01 \x10 \x00 \x00 \x01 \x22 \x00 \x00 \x00 \x04 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \x34 \x00 \x00 \x01 \x46 \x00 \x00 " ,
700+ b"endstream\n endobj\n " ,
701+ b"startxref\n 70\n %%EOF" ,
702+ )
703+ }
662704}
0 commit comments