Kite::PScript::Defs - useful PostScript definitions for kite layout et al
use Kite::PScript::Defs; # access package variables directly print $Kite::PScript::Defs::mm; # or as package subs print Kite::PScript::Defs::mm(); # or as class methods print Kite::PScript::Defs->mm(); # here's a convenient shorthand my $ps = 'Kite::PScript::Defs'; print $ps->mm; # import various definitions use Kite::PScript::Defs qw( mm clip ); print mm, clip; # or specify :all tag to import all definitions as subs use Kite::PScsript::Defs qw( :all ); print mm, reg, clip, pathtext;
Module defining a number of useful PostScript definitions for kite part layout and other similar tasks.
The definitions are provided as package variables which can be accessed directly:
use Kite::PScript::Defs; print $Kite::PScript::Defs::mm;
An AUTOLOAD method is provided which translates any subroutine or method calls into accesses to the appropriate variable. Thus, the PostScript definition specified in the $mm package variable can be accessed by calling either of:
Kite::PScript::mm(); Kite::PScript->mm();
The latter use allows a 'factory' variable to be defined to make this less tedious.
my $ps = 'Kite::PScript::Defs'; print $ps->mm, $ps->clip, $ps->pathtext;
You can specify import parameters when loading the module. Any definitions specified will be imported as subroutines into the caller's namespace.
use Kite::PScript::Defs qw( mm clip ); print mm, clip;
The ':all' import tag can be specified to import all the PoscScript definitions.
use Kite::PScript::Defs qw( :all ); print mm, clip, pathtext;
The module is defined to be intimately useful when used in conjunction with the Template Toolkit. To use the PostScript definitions within a template, simply ensure that the module is loaded and bless an empty hash into the Kite::PScript::Defs package. This will allow the Template Toolkit to resolve to the correct class methods.
use Template; use Kite::PScript::Defs; my $tt2 = Template->new(); my $vars = { psdefs => bless({ }, 'Kite::PScript::Defs'), }; $tt2->process(\*DATA, $vars) || die $tt2->error(); __END__ %!PS-Adobe-3.0 %%EndComments [% psdefs.mm %] [% psdefs.lines %] [% psdefs.cross %] [% psdefs.dot %] [% psdefs.circle %] [% psdefs.crop %] [% psdefs.reg %] 0 mm 0 mm moveto % /mm defined in psdefs.mm crop % /crop defined in psdefs.crop regmarks % /regmarks defined in psdefs.reg ...etc...
Defines millimetres /mm.
[% psdefs.mm %] 10 mm 10 mm moveto 50 mm 10 mm lineto
Defines the following line styles:
linelight % 0.25 setlinewidth linenormal % 0.5 setlinewidth lineheavy % 0.75 setlinewidth linedotted % 0.5 setlinewidth + dotted linedashed % 0.5 setlinewidth + dashed
Example:
[% psdefs.mm %] [% psdefs.lines %] linenormal newpath 0 mm 0 mm moveto 100 mm 0 mm lineto stroke
Defines a procedure to generate a cross from vertical and horizontal lines 10mm in length, crossing at the current point. Requires 'mm' and 'lines'.
[% psdefs.mm %] [% psdefs.lines %] [% psdefs.cross %] 50 mm 50 mm % move to a point cross % draw cross
Defines a procedure to generate a small filled dot at the current point. Requires 'mm' and 'lines'.
[% psdefs.mm %] [% psdefs.lines %] [% psdefs.dot %] 50 mm 50 mm % move to a point dot % draw dot
Defines a procedure to generate a small circle at the current point. Requires 'mm' and 'lines'.
[% psdefs.mm %] [% psdefs.lines %] [% psdefs.circle %] 50 mm 50 mm % move to a point circle % draw circle
Defines a procedure to generate a crop mark at the current point, built from a combination of /cross and /circle. Requires 'mm', 'lines', 'cross' and 'circle'.
[% psdefs.mm %] [% psdefs.lines %] [% psdefs.cross %] [% psdefs.circle %] 0 mm 0 mm % move to a point circle % draw crop mark
Defines /cliprect as a procedure to return a clipping rectangle set to the imageable size. Defines a number of other variables containing information about the clipping rectangle.
cliprect % clipping rectangle cliptrx % top right x cliptry % top right y clipblx % bottom left x clipbly % bottom left y clipxsize % width clipysize % height
Defines /regmarks to generate registration marks (crop) at the corners of the clipping rectangle, /cliprect. Requires 'mm', 'lines', 'cross', 'circle', 'crop' and 'clip'.
[% psdefs.mm %] [% psdefs.lines %] [% psdefs.cross %] [% psdefs.circle %] [% psdefs.crop %] [% psdefs.clip %] regmarks % draw registration marks
Defines /regmarks as a no-op procedure to prevent registration marks from being produced.
regmarks % null registration marks
Defines /pathtext to draw text along an arbitrary path.
path text pathtext % draw text along path ** TODO - see Blue Book for examples **
Defines /tiles as a procedure which calculates the number of pages required to display the current path on the output device. Also calculates the X/Y origin required for the path to be centered within the tile set. Defines the following items.
tilesnx % no. of tiles in x tilesny % no. of tiles in y tilesxorg % suggested x origin tilesyorg % suggested y origin
See next item for example of use.
Generates PostScript to tile an image into multiple pages. It requires that a number of items be pre-defined. The first, /tileimage, should be a procedure defined to generate the image itself.
/tileimage { ...PostScript to generate your image... } def
The next item, /tilepath, should be a procedure defined to generate a path which encloses the image. This is used to calculate the bounding box for the image.
/tilepath { ...PostScript path to bound your image... } def
Finally, the /tilepage item should be a procedure defined to generate any output required on each tiled page (i.e. independant of the main image which ends up split across many pages).
[% psdefs.mm %] [% psdefs.reg %] [% psdefs.clip %] /tilepage { regmarks % generate registration marks /Times-Roman findfont 24 scalefont setfont % set font clipblx 3 mm add clipbly 3 mm add moveto % move to lower left corner ([% title %]) show % print title tilemap % generate tiling map } def
To tile the image onto multiple pages, the /tiles procedure should be called to determine the tiling requirements. The /tilepath item should be on the stack (i.e. precede the call).
[% psdefs.tiles %] tilepath tiles
Then, the 'dotiles' method can be called to generate the appropriate PostScript code to tile the image onto multiple pages.
[% defs.dotiles %]
This item generates a PostScript definition for a Box object which can be used for all kinds of things boxlike. The following documentation items describe the available Box "methods" in more detail, but for now, here's a complete example.
%!PS-Adobe-3.0 %%Title: Box Example %%EndComments [% defs.mm %] [% defs.lines %] [% defs.cross %] [% defs.dot %] [% defs.circle %] [% defs.crop %] [% defs.box %] # define a general border value /border [% border %] mm def % convert the clipping path into a Box clippath pathbbox Box % inset this Box by /border border Box_border % and define /page to be this slightly smaller Box /page exch def % split /page into 3 vertical boxes page 3 border 0 Box_vsplit /upper exch def /middle exch def /lower exch def % inset upper box by border and define /inner upper border Box_border /inner exch def % split it horizontally into /left and /right inner 2 border 0 Box_hsplit /right exch def /left exch def % stroke /upper, /middle and /lower boxes. linenormal upper Box_rect rectstroke middle Box_rect rectstroke lower Box_rect rectstroke % focus the drawing context on the /middle box middle Box_focus newpath 0 0 moveto 100 mm 100 mm lineto ...more complicated stuff here... stroke middle Box_defocus showpage
Unpacks a Box structure to define various Box_* variables.
Box_try % top right y Box_trx % top right x Box_bly % bottom left y Box_blx % bottom left x Box_width % width of Box Box_height % height of Box
mybox Box_select
Unpacks a Box structure to a rect suitable for rectstroke, etc.
mybox Box_rect rectstroke
Unpacks a Box structure to a path suitable for stroke, clip, etc.
mybox Box_path stroke
Creates a new Box within a specified border of an existing Box.
mybox 10 mm Box_bqorder /smallbox exch def
Splits a box vertically into a number of equal sized boxes. Spacing and padding variables should also be specified to control the sizes and relative positions of the new boxes.
% split /mybox into 3 new Box objects, /upper, /middle and % /lower, padded 10 mm within existing /mybox and spaced % 5 mm apart from each other mybox 3 10 mm 5 mm Box_vsplit /upper exch def /middle exch def /lower exch def
As per Box_Vsplit but splitting a Box horizontally.
middle 2 10 mm 5 mm Box_hsplit /right exch def /left exch def
Creates a new drawing context which is focussed on a particular Box. That is, all drawing will happen relative to the origin of the Box and be clipped within its bounds.
middle Box_focus
Restores the previous drawing context saved by a prior Box_focus.
Simon Stapleton <simon@tufty.co.uk> wrote the original xml2ps.pl utility which inspired much of the original PostScript contained herein. Most of that, he freely admits, was gleaned from the Blue Book (PostScript Language Tutorial and Cookbook, Adobe).
Andy Wardley <abw@kfs.org> re-packaged it into a module for integration into the Kite bundle. Various features and more advanced defintions have been added along the way.
$Revision: 1.3 $
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
It would be nice to have some way of automatically managing all dependencies between different procedures. For example, if you call the 'circle' method then it should ensure that 'mm' and 'lines' are first called if they haven't been called previously.
It may make more sense to package this module as a general purpose PostScript library and/or plugin for the Template Toolkit.
For further information on the Kite::* modules, see Kite. For further information on the Template Toolkit, see Template or http://www.template-toolkit.org/ .
To install Kite, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Kite
CPAN shell
perl -MCPAN -e shell install Kite
For more information on module installation, please visit the detailed CPAN module installation guide.