in reply to PDF::API2 - issues with "delete()" and "title()" methods in Outline.pm
Update. PDF::API2 supports incremental PDF modification only, raw file size can only grow, comparing "snapshots" is useless. Modified objects must be marked as such, so they'll be "slapped" after original %%EOF on save. That, mostly, is what patch does (plus a few more things), all "setter" methods should include $self->{' api'}->{'pdf'}->out_obj($self);, and/or similar line if parent/siblings are modified. I stopped patching half way, now I see your particular intent was to change bookmark titles, then patch title setter too, it'll work then. Note PDF::API2::Outline::outline always adds a new descendant to invocant; PDF::API2::outline is different.
Line added to "main" module API2.pm is lazy way to ensure objects are re-blessed, so that e.g. $pdf->outline->first->delete won't boom. Two lines commented-out in patch look harmless but useless to me: parent method never called as setter, deleting ' children' array achieves nothing. + See modified PDF content in OP, object number is skipped, it's just not tidy, I wonder if it always was this way. These latter comments are for maintainer (Steve?) if they are interested.
__________
(PDF::API2... patch and fix and patch again). Below there are patches for 2 files in distribution, and your modified test program which produces four PDF files with expected content I think. I'll add later to this node as to why your tests as designed make no sense and why it's only "demo" patch, I gave up patching further because out of time, only your immediate test files are fixed.
--- C:\berrybrew\strawberry-perl-5.32.1.1-64bit-PDL\perl\site\lib\PDF\ +API2.pm.backup Wed Dec 8 07:53:45 2021 +++ C:\berrybrew\strawberry-perl-5.32.1.1-64bit-PDL\perl\site\lib\PDF\ +API2.pm Sat Sep 3 13:36:58 2022 @@ -824,6 +824,7 @@ bless $obj, 'PDF::API2::Outlines'; $obj->{' api'} = $self; weaken $obj->{' api'}; + $obj->count(); } else { $obj = PDF::API2::Outlines->new($self); --- C:\berrybrew\strawberry-perl-5.32.1.1-64bit-PDL\perl\site\lib\PDF\ +API2\Outline.pm.backup Wed Dec 8 07:53:45 2021 +++ C:\berrybrew\strawberry-perl-5.32.1.1-64bit-PDL\perl\site\lib\PDF\ +API2\Outline.pm Sat Sep 3 16:23:35 2022 @@ -90,25 +90,25 @@ if ($count) { $self->{'Count'} = PDFNum($self->is_open() ? $count : -$count +); } + else { + delete $self->{'Count'} + } return $count; } sub _load_children { my $self = shift(); + $self->{' children'} = []; my $item = $self->{'First'}; - return unless $item; - $item->realise(); - bless $item, __PACKAGE__; - - push @{$self->{' children'}}, $item; - while ($item->next()) { - $item = $item->next(); + + while ($item) { $item->realise(); bless $item, __PACKAGE__; + $item->{' api'} = $self->{' api'}; push @{$self->{' children'}}, $item; + $item = $item->next() } - return $self; } =head3 first @@ -121,8 +121,10 @@ sub first { my $self = shift(); - if (defined $self->{' children'} and defined $self->{' children'} +->[0]) { - $self->{'First'} = $self->{' children'}->[0]; + if (exists $self->{' children'}) { + $self->{'First'} = @{$self->{' children'}} + ? $self->{' children'}[0] + : undef } return $self->{'First'}; } @@ -137,8 +139,10 @@ sub last { my $self = shift(); - if (defined $self->{' children'} and defined $self->{' children'} +->[-1]) { - $self->{'Last'} = $self->{' children'}->[-1]; + if (exists $self->{' children'}) { + $self->{'Last'} = @{$self->{' children'}} + ? $self->{' children'}[-1] + : undef } return $self->{'Last'}; } @@ -154,7 +158,7 @@ sub parent { my $self = shift(); - $self->{'Parent'} = shift() if defined $_[0]; +# $self->{'Parent'} = shift() if defined $_[0]; return $self->{'Parent'}; } @@ -167,8 +171,11 @@ =cut sub prev { - my $self = shift(); - $self->{'Prev'} = shift() if defined $_[0]; + my ($self, $other) = @_; + if ($other) { + $self->{'Prev'} = $other; + $self->{' api'}{'pdf'}->out_obj($self); + } return $self->{'Prev'}; } @@ -181,8 +188,11 @@ =cut sub next { - my $self = shift(); - $self->{'Next'} = shift() if defined $_[0]; + my ($self, $other) = @_; + if ($other) { + $self->{'Next'} = $other; + $self->{' api'}{'pdf'}->out_obj($self); + } return $self->{'Next'}; } @@ -200,7 +210,9 @@ my $self = shift(); my $child = PDF::API2::Outline->new($self->{' api'}, $self); - $self->{' children'} //= []; + + $self->_load_children() unless exists $self->{' children'}; + $child->prev($self->{' children'}->[-1]) if @{$self->{' children' +}}; $self->{' children'}->[-1]->next($child) if @{$self->{' children' +}}; push @{$self->{' children'}}, $child; @@ -208,6 +220,7 @@ $self->{' api'}->{'pdf'}->new_obj($child); } + $self->{' api'}->{'pdf'}->out_obj($self); return $child; } @@ -268,6 +281,7 @@ $item = $item->next(); push @{$self->{' children'}}, $item; } + $self->{' api'}->{'pdf'}->out_obj($self); return $self; } @@ -291,7 +305,8 @@ my $siblings = $self->parent->{' children'}; @$siblings = grep { $_ ne $self } @$siblings; - delete $self->parent->{' children'} unless $self->parent->has_chi +ldren(); +# delete $self->parent->{' children'} unless $self->parent->has_ch +ildren(); + $self->{' api'}->{'pdf'}->out_obj($self->parent); return; }
############
#!/usr/bin/perl use 5.032; use warnings; use strict; use PDF::API2; my ($stringy_bare_pdf, $stringy_outline_pdf); BARE_PDF: { my $pdf = PDF::API2->new(-compress => 0); my $page1 = $pdf->page(); $pdf->save('bare.pdf'); } OUTLINE: { my $pdf = PDF::API2->new(-compress => 0); my $page1 = $pdf->page(); my $outlines = $pdf->outlines(); my $outline = $outlines->outline(); $outline->title('Test Outline 1'); $outline->dest(1); $stringy_outline_pdf = $pdf->to_string(); open my $fh, '>', 'outline.pdf' or die; binmode $fh; print $fh $stringy_outline_pdf; close $fh; } DELETE_OUTLINE: { my $pdf = PDF::API2->from_string($stringy_outline_pdf, -compress = +> 0) or die $!; my $root = $pdf->outlines(); my $outline = $root->first(); $outline->delete(); $pdf->save('outline_deleted.pdf'); } MODIFY_OUTLINE: { my $pdf = PDF::API2->from_string($stringy_outline_pdf, -compress = +> 0) or die $!; my $root = $pdf->outlines(); my $outline = $root->outline(); $outline->title('Test Outline 2'); $outline->dest(1); $pdf->save('outline_modified.pdf'); }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: PDF::API2 - issues with "delete()" and "title()" methods in Outline.pm
by ateague (Monk) on Sep 06, 2022 at 17:05 UTC | |
by vr (Curate) on Sep 06, 2022 at 20:50 UTC |