[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[groff] 01/01: Add page transitions to pdfs created with gropdf.
From: |
Deri James |
Subject: |
[groff] 01/01: Add page transitions to pdfs created with gropdf. |
Date: |
Thu, 1 Mar 2018 10:21:09 -0500 (EST) |
deri pushed a commit to branch master
in repository groff.
commit f2a92911c552c3995c010f8beb9b89de3612e95a
Author: Deri James <address@hidden>
Date: Thu Mar 1 15:16:11 2018 +0000
Add page transitions to pdfs created with gropdf.
* src/devices/gropdf.pl: Handle new '\X' commands to support
page transitions in presentation mode pdfs. These commands are a
subset of the commands used in present.tmac allowing slideshows
to be directly produced from -Tpdf without using postscript ->
gpresent.pl -> ghostscript.
* tmac/pdf.tmac: New macros '.pdfpause' and '.pdftransition' to
support page transitions.
* src/devices/gropdf.1.man: Document the '\X' commands
supported.
---
ChangeLog | 15 +++
src/devices/gropdf/gropdf.1.man | 240 ++++++++++++++++++++++++++++++++++++++++
src/devices/gropdf/gropdf.pl | 211 ++++++++++++++++++++++++++++++-----
tmac/pdf.tmac | 8 +-
4 files changed, 447 insertions(+), 27 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 337bf08..1506e57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2018-03-01 Deri James <address@hidden>
+
+ Add page transitions to pdfs created with gropdf.
+
+ * src/devices/gropdf.pl: Handle new '\X' commands to support page
+ transitions in presentation mode pdfs. These commands are a subset
+ of the commands used in present.tmac allowing slideshows to be
+ directly produced from -Tpdf without using postscript -> gpresent.pl
+ -> ghostscript.
+
+ * tmac/pdf.tmac: New macros '.pdfpause' and '.pdftransition' to
+ support page transitions.
+
+ * src/devices/gropdf.1.man: Document the '\X' commands supported.
+
2018-03-01 Werner LEMBERG <address@hidden>
Use $(AM_V_GEN) and $(AM_V_P) to silence even more file generation.
diff --git a/src/devices/gropdf/gropdf.1.man b/src/devices/gropdf/gropdf.1.man
index 0ff132e..e07946d 100644
--- a/src/devices/gropdf/gropdf.1.man
+++ b/src/devices/gropdf/gropdf.1.man
@@ -695,8 +695,54 @@ A subset of these macros are installed automatically when
you use
so you should not need to use \[oq]\-m pdfmark\[cq] for using most of
the PDF functionality.
.
+.LP
+.B gropdf
+also supports a subset of the commands introduced in present.tmac.
+Specifically it supports:-
+.IP
+PAUSE
+.br
+BLOCKS
+.br
+BLOCKE
.
.LP
+Which allows you to create presentation type PDFs. Many of the other
+commands are already available in other macro packages.
+.LP
+These commands are implemented with
+.B groff
+X commands:-
+.LP
+.TP
+.BI "\[rs]X'ps: exec %%%%PAUSE"
+The section before this is treated as a block and is introduced using the
+current BLOCK transition setting (see \[oq]pdf: transition\[cq] below). This
command
+can be introduced using the macro
+.BR .pdfpause .
+.TP
+.B "\[rs]X'ps: exec %%%%BEGINONCE"
+Any text following this command (up to %%%%ENDONCE) is shown only once,
+the next %%%%PAUSE will remove it. If producing a non presentation pdf, i.e.
+ignoring the pauses, see GROPDF_NOSLIDE below, this text is ignored.
+.LP
+.TP
+.B "\[rs]X'ps: exec %%%%ENDONCE"
+This terminates the block defined by %%%%BEGINONCE. This pair of commands
+is what implements the .BLOCKS Once/.BLOCKE commands in present.tmac.
+.LP
+The
+.B mom
+macro set already has integration with these extensions so you can build
+slides with
+.BR mom .
+.LP
+If you use present.tmac with
+.B gropdf
+there is no need to run the program
+.BR presentps (@MAN1EXT@)
+since the output will already be a presentation pdf.
+.LP
All other
.B ps:
tags are silently ignored.
@@ -820,6 +866,193 @@ respectively.
.
These macros must only be used within page traps.)
.
+.TP
+.BR "\[rs]X'pdf: transition'" "feature mode duration dimension motion
direction scale bool"
+where
+.IP
+.I feature
+can be either SLIDE or BLOCK. When it is SLIDE the transition is used
+when a new slide is introduced to the screen, if BLOCK then this transition
+is used for the individual blocks which make up the slide.
+.br
+.I mode
+is the transition type between slides:-
+.RS
+.IP
+.B Split
+- Two lines sweep across the screen, revealing the new page. The lines
+may be either horizontal or vertical and may move inward from the
+edges of the page or outward from the center, as specified by the
+.I dimension
+and
+.I motion
+entries, respectively.
+.br
+.B Blinds
+- Multiple lines, evenly spaced across the screen, synchronously
+sweep in the same direction to reveal the new page. The lines may be
+either horizontal or vertical, as specified by the
+.I dimension
+ entry. Horizontal
+lines move downward; vertical lines move to the right.
+.br
+.B Box
+- A rectangular box sweeps inward from the edges of the page or
+outward from the center, as specified by the
+.I motion
+entry, revealing the new page.
+.br
+.B Wipe
+- A single line sweeps across the screen from one edge to the other in
+the direction specified by the
+.I direction
+entry, revealing the new page.
+.br
+.B Dissolve
+- The old page dissolves gradually to reveal the new one.
+.br
+.B Glitter
+- Similar to Dissolve, except that the effect sweeps across the page in a
+wide band moving from one side of the screen to the other in the
+direction specified by the
+.I direction
+entry.
+.br
+.B R
+- The new page simply replaces the old one with no special transition
+effect; the
+.I direction
+entry shall be ignored.
+.br
+.B Fly
+- (PDF 1.5) Changes are flown out or in (as specified by
+.IR motion ),
+in the
+direction specified by
+.IR direction ,
+to or from a location that is offscreen except
+when
+.I direction
+is
+.BR None .
+.br
+.B Push
+- (PDF 1.5) The old page slides off the screen while the new page
+slides in, pushing the old page out in the direction specified by
+.IR direction .
+.br
+.B Cover
+- (PDF 1.5) The new page slides on to the screen in the direction
+specified by
+.IR direction ,
+covering the old page.
+.br
+.B Uncover
+- (PDF 1.5) The old page slides off the screen in the direction
+specified by
+.IR direction ,
+uncovering the new page in the direction
+specified by
+.IR direction .
+.br
+.B Fade
+- (PDF 1.5) The new page gradually becomes visible through the
+old one.
+.LP
+.RE
+.IP
+.I duration
+is the length of the transition in seconds (default 1).
+.LP
+.IP
+.I dimension
+(Optional;
+.BR Split " and " Blinds
+transition styles only) The dimension in which the
+specified transition effect shall occur:
+.B H
+Horizontal, or
+.B V
+Vertical.
+.LP
+.IP
+.I motion
+(Optional;
+.BR Split ,
+.BR Box " and " Fly
+transition styles only) The direction of motion for
+the specified transition effect:
+.B I
+Inward from the edges of the page, or
+.B O
+Outward from the center of the page.
+.LP
+.IP
+.I direction
+(Optional;
+.BR Wipe ,
+.BR Glitter ,
+.BR Fly ,
+.BR Cover ,
+.BR Uncover " and " Push
+transition styles only)
+The direction in which the specified transition effect shall moves, expressed
in
+degrees counterclockwise starting from a left-to-right direction.
+If the value is a number, it shall be one of:
+.B 0
+= Left to right,
+.B 90
+= Bottom to top (Wipe only),
+.B 180
+= Right to left (Wipe only),
+.B 270
+= Top to bottom,
+.B 315
+= Top-left to bottom-right (Glitter only)
+The value can be
+.BR None ,
+which is relevant only for the
+.B Fly
+transition when the value of
+.I scale
+is not 1.0.
+.LP
+.IP
+.I scale
+(Optional; PDF 1.5;
+.B Fly
+transition style only) The starting or ending scale at
+which the changes shall be drawn. If
+.I motion
+specifies an inward transition, the scale
+of the changes drawn shall progress from
+.I scale
+to 1.0 over the course of the
+transition. If
+.I motion
+specifies an outward transition, the scale of the changes drawn
+shall progress from 1.0 to
+.I scale
+over the course of the transition
+.LP
+.IP
+.I bool
+(Optional; PDF 1.5;
+.B Fly
+transition style only) If
+.BR true ,
+the area that shall be flown
+in is rectangular and opaque.
+.LP
+.IP
+This command can be used by calling the macro
+.B .pdftransition
+using the parameters described above.
+.LP
+.IP
+.B Note:
+not all PDF Readers support any or all these transitions.
+.LP
.
.\" ====================================================================
.SS Importing graphics
@@ -1011,6 +1244,13 @@ for more details.
.
.TP
.SM
+.B GROPDF_NOSLIDE
+If this is set true,
+.B gropdf
+will ignore all commands which produce a presentation pdf,
+and produce a normal pdf instead.
+.TP
+.SM
.B SOURCE_DATE_EPOCH
A timestamp (expressed as seconds since the Unix epoch) to use as the
creation timestamp in place of the current time.
diff --git a/src/devices/gropdf/gropdf.pl b/src/devices/gropdf/gropdf.pl
index 5e61e2f..8a4b4b6 100644
--- a/src/devices/gropdf/gropdf.pl
+++ b/src/devices/gropdf/gropdf.pl
@@ -121,12 +121,23 @@ my $wt=-1;
my $thislev=1;
my $mark=undef;
my $suspendmark=undef;
+
+
+
my $n_flg=1;
my $pginsert=-1; # Growth point for kids array
my %pgnames; # 'names' of pages for switchtopage
my @outlines=(); # State of Bookmark Outlines at end of each page
my $custompaper=0; # Has there been an X papersize
my $textenccmap=''; # CMap for groff text.enc encoding
+my @XOstream=();
+my @PageAnnots={};
+my $noslide=0;
+my $transition={PAGE => {Type => '/Trans', S => '', D => 1, Dm => '/H', M =>
'/I', Di => 0, SS => 1.0, B => 0},
+ BLOCK => {Type => '/Trans', S => '', D => 1, Dm => '/H', M =>
'/I', Di => 0, SS => 1.0, B => 0}};
+my $firstpause=0;
+
+$noslide=1 if exists($ENV{GROPDF_NOSLIDE}) and $ENV{GROPDF_NOSLIDE};
my %ppsz=( 'ledger'=>[1224,792],
'legal'=>[612,1008],
@@ -328,10 +339,29 @@ while (<>)
}
+exit 0 if $lct==0;
if ($cpageno > 0)
{
+ my $trans='BLOCK';
+
+ $trans='PAGE' if $firstpause;
+
+ if (scalar(@XOstream))
+ {
+ MakeXO() if $stream;
+ $stream=join("\n",@XOstream)."\n";
+ }
+
+ my %t=%{$transition->{$trans}};
$cpage->address@hidden if $custompaper;
+ $cpage->{Trans}=FixTrans(\%t) if $t{S};
+
+ if ($#PageAnnots >= 0)
+ {
+ @{$cpage->address@hidden;
+ }
+
PutObj($cpageno);
OutStream($cpageno+1);
}
@@ -572,7 +602,7 @@ sub LoadDownload
OpenFile(\$f,$dir,"download");
next if !defined($f);
$found++;
-
+
while (<$f>)
{
chomp;
@@ -756,6 +786,53 @@ sub do_x
$linecap=$1;
$stream.="$linecap J\n";
}
+ elsif ($par=~m/exec %%%%PAUSE/i and !$noslide)
+ {
+ my $trans='BLOCK';
+
+ if ($firstpause)
+ {
+ $trans='PAGE';
+ $firstpause=0;
+ }
+ MakeXO();
+ NewPage($trans);
+ $cat->{PageMode}='/FullScreen';
+ }
+ elsif ($par=~m/exec %%%%BEGINONCE/)
+ {
+ if ($noslide)
+ {
+ $suppress=1;
+ }
+ else
+ {
+ my $trans='BLOCK';
+
+ if ($firstpause)
+ {
+ $trans='PAGE';
+ $firstpause=0;
+ }
+ MakeXO();
+ NewPage($trans);
+ $cat->{PageMode}='/FullScreen';
+ }
+ }
+ elsif ($par=~m/exec %%%%ENDONCE/)
+ {
+ if ($noslide)
+ {
+ $suppress=0;
+ }
+ else
+ {
+ MakeXO();
+ NewPage('BLOCK');
+ $cat->{PageMode}='/FullScreen';
+ pop(@XOstream);
+ }
+ }
elsif ($par=~m/\[(.+) pdfmark/)
{
my $pdfmark=$1;
@@ -814,7 +891,7 @@ sub do_x
$annot->{DATA}->{Type}='/Annot';
FixRect($annot->{DATA}->{Rect}); # Y origin to ll
FixPDFColour($annot->{DATA});
- push(@{$cpage->{Annots}},$annotno);
+ push(@PageAnnots,$annotno);
}
elsif ($pdfmark=~m/(.+) \/OUT/)
{
@@ -1118,6 +1195,31 @@ sub do_x
}
}
}
+ elsif (lc($xprm[1]) eq 'transition')
+ {
+ if (uc($xprm[2]) eq 'PAGE' or uc($xprm[2] eq 'SLIDE'))
+ {
+ $transition->{PAGE}->{S}='/'.ucfirst($xprm[3]) if $xprm[3]
and $xprm[3] ne '.';
+ $transition->{PAGE}->{D}=$xprm[4] if $xprm[4] and $xprm[4]
ne '.';
+ $transition->{PAGE}->{Dm}='/'.$xprm[5] if $xprm[5] and
$xprm[5] ne '.';
+ $transition->{PAGE}->{M}='/'.$xprm[6] if $xprm[6] and
$xprm[6] ne '.';
+ $xprm[7]='/None' if $xprm[7] and uc($xprm[7]) eq 'NONE';
+ $transition->{PAGE}->{Di}=$xprm[7] if $xprm[7] and $xprm[7]
ne '.';
+ $transition->{PAGE}->{SS}=$xprm[8] if $xprm[8] and $xprm[8]
ne '.';
+ $transition->{PAGE}->{B}=$xprm[9] if $xprm[9] and $xprm[9]
ne '.';
+ }
+ elsif (uc($xprm[2]) eq 'BLOCK')
+ {
+ $transition->{BLOCK}->{S}='/'.ucfirst($xprm[3]) if $xprm[3]
and $xprm[3] ne '.';
+ $transition->{BLOCK}->{D}=$xprm[4] if $xprm[4] and $xprm[4]
ne '.';
+ $transition->{BLOCK}->{Dm}='/'.$xprm[5] if $xprm[5] and
$xprm[5] ne '.';
+ $transition->{BLOCK}->{M}='/'.$xprm[6] if $xprm[6] and
$xprm[6] ne '.';
+ $xprm[7]='/None' if $xprm[7] and uc($xprm[7]) eq 'NONE';
+ $transition->{BLOCK}->{Di}=$xprm[7] if $xprm[7] and
$xprm[7] ne '.';
+ $transition->{BLOCK}->{SS}=$xprm[8] if $xprm[8] and
$xprm[8] ne '.';
+ $transition->{BLOCK}->{B}=$xprm[9] if $xprm[9] and $xprm[9]
ne '.';
+ }
+ }
}
elsif (lc(substr($xprm[0],0,9)) eq 'papersize')
{
@@ -1190,7 +1292,7 @@ sub PutHotSpot
$annot->{DATA}->{Rect}=[$mark->{xpos},$mark->{ypos}-$mark->{rsb},$endx+$mark->{lead},$mark->{ypos}-$mark->{rst}];
FixPDFColour($annot->{DATA});
FixRect($annot->{DATA}->{Rect}); # Y origin to ll
- push(@{$cpage->{Annots}},$annotno);
+ push(@PageAnnots,$annotno);
}
sub sgn
@@ -1358,14 +1460,14 @@ sub OpenInc
foreach my $dir (@idirs)
{
$fnm="$dir/$fn";
-
+
if (-r "$fnm" and open($F,"<$fnm"))
{
return($F,$fnm);
}
}
}
-
+
return(undef,$fn);
}
@@ -1384,7 +1486,7 @@ sub LoadPDF
my $cont;
my ($PD,$PDnm)=OpenInc($pdfnm);
-
+
if (!defined($PD))
{
Msg(0,"Failed to open PDF '$pdfnm'");
@@ -2284,59 +2386,59 @@ sub GetChunk
my ($type,$hdr,$chunk,@msg);
binmode($F);
my $enc="ascii";
-
+
while (1)
{
# There may be multiple chunks of the same type
-
+
my $ct=read($F,$hdr,2);
-
+
if ($ct==2)
{
if (substr($hdr,0,1) eq "\x80")
{
# binary chunk
-
+
my $chunktype=ord(substr($hdr,1,1));
$enc="binary";
-
+
if (defined($type) and $type != $chunktype)
{
seek($F,-2,1);
last;
}
-
+
$type=$chunktype;
return if $chunktype == 3;
-
+
$ct=read($F,$hdr,4);
-
+
Msg(1,"Failed to read binary segment length"), return if $ct !=
4;
-
+
my $sl=unpack('L',$hdr);
my $data;
my $chk=read($F,$data,$sl);
-
+
Msg(1 ,"Failed to read binary segment"), return if $chk != $sl;
-
+
$chunk.=$data;
}
else
{
# ascii chunk
-
+
my $hex=0;
seek($F,-2,1);
my $ct=0;
-
+
while (1)
{
my $lin=<$F>;
-
+
last if !$lin;
-
+
$hex=1,$enc.=" hex" if $segno == 2 and !$ct and
$lin=~m/^[A-F0-9a-f]{4,4}/;
-
+
if ($segno !=2 and $lin=~m/^(.*$ascterm\n?)(.*)/)
{
$chunk.=$1;
@@ -2349,11 +2451,11 @@ sub GetChunk
seek($F,-length($2)-1,1) if $2;
last;
}
-
+
chomp($lin), $lin=pack('H*',$lin) if $hex;
$chunk.=$lin; $ct++;
}
-
+
last;
}
}
@@ -2362,7 +2464,7 @@ sub GetChunk
push(@msg,"Failed to read 2 header bytes");
}
}
-
+
return $chunk;
}
@@ -2380,11 +2482,54 @@ sub OutStream
sub do_p
{
+ my $trans='BLOCK';
+
+ $trans='PAGE' if $firstpause;
+ NewPage($trans);
+ @XOstream=();
+ @PageAnnots=();
+ $firstpause=1;
+}
+
+sub FixTrans
+{
+ my $t=shift;
+ my $style=$t->{S};
+
+ if ($style)
+ {
+ delete($t->{Dm}) if $style ne '/Split' and $style ne '/Blinds';
+ delete($t->{M}) if !($style eq '/Split' or $style eq '/Box' or $style
eq '/Fly');
+ delete($t->{Di}) if !($style eq '/Wipe' or $style eq '/Glitter' or
$style eq '/Fly' or $style eq '/Cover' or $style eq '/Uncover' or $style eq
'/Push') or ($style eq '/Fly' and $t->{Di} eq '/None' and $t->{SS} != 1);
+ delete($t->{SS}) if !($style eq '/Fly');
+ delete($t->{B}) if !($style eq '/Fly');
+ }
+
+ return($t);
+}
+
+sub NewPage
+{
+ my $trans=shift;
# Start of pages
if ($cpageno > 0)
{
+ if ($#XOstream>=0)
+ {
+ MakeXO() if $stream;
+ $stream=join("\n",@XOstream,'');
+ }
+
+ my %t=%{$transition->{$trans}};
$cpage->address@hidden if $custompaper;
+ $cpage->{Trans}=FixTrans(\%t) if $t{S};
+
+ if ($#PageAnnots >= 0)
+ {
+ @{$cpage->address@hidden;
+ }
+
PutObj($cpageno);
OutStream($cpageno+1);
}
@@ -2414,6 +2559,20 @@ sub do_p
# @address@hidden;
}
+sub MakeXO
+{
+ $stream.="%mode=$mode\n";
+ IsGraphic();
+ $stream.="Q\n";
+ my $xobj=++$objct;
+ my $xonm="XO$xobj";
+ $pages->{'Resources'}->{'XObject'}->{$xonm}=BuildObj($xobj,{'Type' =>
'/XObject', 'BBox' => address@hidden, 'Name' => "/$xonm", 'FormType' => 1,
'Subtype' => '/Form', 'Length' => 0, 'Type' => "/XObject"});
+ $obj[$xobj]->{STREAM}=$stream;
+ $stream='';
+ push(@XOstream,"q") if $#XOstream==-1;
+ push(@XOstream,"/$xonm Do");
+}
+
sub do_f
{
my $par=shift;
@@ -2966,7 +3125,7 @@ sub PutLine
$wd->[0]=~s/!\|!\|/\\/g;
$wd->[1]=d3($wd->[1]);
}
-
+
if (0)
{
if (scalar(@lin) == 1 and (!defined($lin[0]->[1]) or $lin[0]->[1] == 0))
diff --git a/tmac/pdf.tmac b/tmac/pdf.tmac
index 4a002c3..350f783 100644
--- a/tmac/pdf.tmac
+++ b/tmac/pdf.tmac
@@ -18,7 +18,7 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License
for more details.
You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
+along with this program. If not, see <http://www.gnu.org/licenses/>.
Author's Note
=============
@@ -799,6 +799,12 @@ am solely responsible for any bugs I may have introduced
into this file.
.de pdfswitchtopage
.nop \!x X pdf: switchtopage \\$*
..
+.de pdfpause
+.nop \!x X ps: exec %%%%PAUSE
+..
+.de pdftransition
+.nop \!x X pdf: transition \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
+..
.\" Local Variables:
.\" mode: nroff
.\" End:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [groff] 01/01: Add page transitions to pdfs created with gropdf.,
Deri James <=