--- PDF\API2\Basic\PDF\File.old Fri Jul 7 04:53:59 2017 +++ PDF\API2\Basic\PDF\File.pm Wed Apr 3 04:01:26 2019 @@ -522,6 +522,7 @@ if (defined $result->{'Type'} and defined $types{$result->{'Type'}->val}) { bless $result, $types{$result->{'Type'}->val}; + $result-> {' outto'} = [ $self ]; } # gdj: FIXME: if any of the ws chars were crs, then the whole # string might not have been read. @@ -540,7 +541,7 @@ } $result->{' parent'} = $self; weaken $result->{' parent'}; - $result->{' realised'} = 0; +#?? $result->{' realised'} = 0; # gdj: FIXME: if any of the ws chars were crs, then the whole # string might not have been read. } @@ -1282,7 +1283,7 @@ $tdict->{'Size'} = PDFNum($self->{' maxobj'}); my $tloc = $fh->tell(); - $fh->print("xref\n"); + my @out; my @xreflist = sort { $self->{' objects'}{$a->uid}[0] <=> $self->{' objects'}{$b->uid}[0] } (@{$self->{' printed'} || []}, @{$self->{' free'} || []}); @@ -1314,25 +1315,25 @@ # $fh->printf("0 1\n%010d 65535 f \n", $ff); # } if ($i > $#xreflist || $self->{' objects'}{$xreflist[$i]->uid}[0] != $j + 1) { - $fh->print(($first == -1 ? "0 " : "$self->{' objects'}{$xreflist[$first]->uid}[0] ") . ($i - $first) . "\n"); + push @out, ($first == -1 ? "0 " : "$self->{' objects'}{$xreflist[$first]->uid}[0] ") . ($i - $first) . "\n"; if ($first == -1) { - $fh->printf("%010d 65535 f \n", defined $freelist[$k] ? $self->{' objects'}{$freelist[$k]->uid}[0] : 0); + push @out, sprintf("%010d 65535 f \n", defined $freelist[$k] ? $self->{' objects'}{$freelist[$k]->uid}[0] : 0); $first = 0; } for ($j = $first; $j < $i; $j++) { my $xref = $xreflist[$j]; if (defined $freelist[$k] && defined $xref && "$freelist[$k]" eq "$xref") { $k++; - $fh->print(pack("A10AA5A4", + push @out, pack("A10AA5A4", sprintf("%010d", (defined $freelist[$k] ? $self->{' objects'}{$freelist[$k]->uid}[0] : 0)), " ", sprintf("%05d", $self->{' objects'}{$xref->uid}[1] + 1), - " f \n")); + " f \n"); } else { - $fh->print(pack("A10AA5A4", sprintf("%010d", $self->{' locs'}{$xref->uid}), " ", + push @out, pack("A10AA5A4", sprintf("%010d", $self->{' locs'}{$xref->uid}), " ", sprintf("%05d", $self->{' objects'}{$xref->uid}[1]), - " n \n")); + " n \n"); } } $first = $i; @@ -1342,9 +1343,48 @@ $j++; } } - $fh->print("trailer\n"); - $tdict->outobjdeep($fh, $self); - $fh->print("\nstartxref\n$tloc\n%%EOF\n"); + if ( exists $tdict-> { Type } and $tdict-> { Type }-> val eq 'XRef' ) { + + my ( @index, @stream ); + my $len = 2; # 2 or 4 will do + for ( @out ) { + $_ = [ split ]; + die if $_-> [ 0 ] >= 0xFFFFFFFF; # extremely unlikely, but better (any?) message would help + $len = 4 if $_-> [ 0 ] >= 0xFFFF; + @$_ == 2 ? push @index, @$_ : push @stream, $_ + } + my $c = $len == 2 ? 'n' : 'N'; + my $stream = join '', map { + pack "C${c}C", $_-> [ 2 ] eq 'n' ? 1 : 0, @{ $_ }[ 0 .. 1 ] + } @stream; + + $i = $self->{ ' maxobj' } ++; + $self-> add_obj( $tdict, $i, 0 ); + $self-> out_obj( $tdict ); + + push @index, $i, 1; + $stream .= pack "C${c}C", 1, $tloc, 0; + + $tdict-> { Size } = PDFNum( ++ $i ); + $tdict-> { Index } = PDFArray( map PDFNum( $_ ), @index ); + $tdict-> { W } = PDFArray( map PDFNum( $_ ), 1, $len, 1 ); + $tdict-> { Filter } = PDFName( 'FlateDecode' ); + + delete $tdict-> { DecodeParms }; # For such streams, prediction improves compression hugely, + # but "outfilt" just can't do it, alas. + + $stream = PDF::API2::Basic::PDF::Filter::FlateDecode-> new-> outfilt( $stream, 1 ); + $tdict-> { ' stream' } = $stream; + $tdict-> { ' nofilt' } = 1; + delete $tdict-> { Length }; + $self-> ship_out; + } + else { + $fh->print("xref\n", @out, "trailer\n"); + $tdict->outobjdeep($fh, $self); + $fh->print("\n"); + } + $fh->print("startxref\n$tloc\n%%EOF\n"); }