Provided by: libpostscript-file-perl_2.22+dfsg-1_all bug

NAME

       PostScript::File - Class for creating Adobe PostScript files

VERSION

       This document describes version 2.22 of PostScript::File, released May 9, 2015 as part of
       PostScript-File version 2.22.

       Attributes and methods added since version 2.00 are marked with the version they were
       added in (e.g. "(v2.10)").  Because there were significant API changes in 2.00, I
       recommend that any code using PostScript::File specify a minimum version of at least 2.

SYNOPSIS

   Simplest
       A 'hello world' program:

           use PostScript::File 2;

           my $ps = PostScript::File->new(reencode => 'cp1252');

           $ps->add_to_page( <<END_PAGE );
               /Helvetica findfont
               12 scalefont
               setfont
               72 300 moveto
               (hello world) show
           END_PAGE

           $ps->output( "test" );

   All options
           my $ps = PostScript::File->new(
               paper => 'Letter',
               height => 500,
               width => 400,
               bottom => 30,
               top => 30,
               left => 30,
               right => 30,
               clip_command => 'stroke',
               clipping => 1,
               eps => 1,
               dir => '~/foo',
               file => "bar",
               landscape => 0,

               headings => 1,
               reencode => 'cp1252',
               font_suffix => '-iso',
               need_fonts  => [qw(Helvetica Helvetica-Bold)],

               errors => 1,
               errmsg => 'Failed:',
               errfont => 'Helvetica',
               errsize => 12,
               errx => 72,
               erry => 300,

               debug => 2,
               db_active => 1,
               db_xgap => 120,
               db_xtab => 8,
               db_base => 300,
               db_ytop => 500,
               db_color => '1 0 0 setrgbcolor',
               db_font => 'Times-Roman',
               db_fontsize => 11,
               db_bufsize => 256,
           );

DESCRIPTION

       PostScript::File is a class that writes PostScript files following Adobe's Document
       Structuring Conventions (DSC).  You should be familiar with the DSC if you're using this
       class directly; consult the PostScript Language Document Structuring Conventions
       Specification linked to in "SEE ALSO".

       There are also a number of modules that build upon PostScript::File to produce various
       kinds of documents without requiring knowledge of PostScript.  These are listed in "SEE
       ALSO".

       It is possible to construct and output files in either normal PostScript (*.ps files) or
       as Encapsulated PostScript (*.epsf or *.epsi files).  By default a minimal file is output,
       but support for font encoding, PostScript error reporting and debugging can be built in if
       required.

       Documents can typically be built using only these functions:

           new           The constructor, with many options
           add_procset   Add PostScript functions to the prolog
           add_to_page   Add PostScript to construct each page
           newpage       Begins a new page in the document
           output        Construct the file and saves it

       The rest of the module involves fine-tuning this.  Some settings only really make sense
       when given once, while others can control each page independently.  See "new" for the
       functions that duplicate option settings, they all have "get_" counterparts.  The
       following provide additional support.

           get/set_bounding_box
           get/set_page_bounding_box
           get/set_page_clipping
           get/set_page_landscape
           set_page_margins
           get_pagecount
           draw_bounding_box
           clip_bounding_box

       The functions which insert entries into each of the DSC sections all begin with 'add_'.
       They also have "get_" counterparts.

           add_comment
           add_preview
           add_default
           add_resource
           add_procset
           add_setup
           add_page_setup
           add_to_page
           add_page_trailer
           add_trailer

       Finally, there are a few stand-alone functions.  These are not methods and are available
       for export if requested.

           check_tilde
           check_file
           incpage_label
           incpage_roman

   Hyphens and Minus Signs
       In ASCII, the character "\x2D" ("\055") is used as both a hyphen and a minus sign.
       Unicode calls this character HYPHEN-MINUS (U+002D).  PostScript has two characters, which
       it calls "/hyphen" and "/minus".  The difference is that "/minus" is usually wider than
       "/hyphen" (except in Courier, of course).

       In PostScript's StandardEncoding (what you get if you don't use "reencode"), character
       "\x2D" is "/hyphen", and "/minus" is not available.  In the Latin1-based encodings created
       by "reencode", character "\x2D" is "/minus", and character "\xAD" is "/hyphen".  ("\xAD"
       is supposed to be a "soft hyphen" (U+00AD) that appears only if the line is broken at that
       point, but it doesn't work that way in PostScript.)

       Unicode has additional non-ambiguous characters: HYPHEN (U+2010), NON-BREAKING HYPHEN
       (U+2011), and MINUS SIGN (U+2212).  The first two always indicate "/hyphen", and the last
       is always "/minus".  When you set "reencode" to "cp1252" or "iso-8859-1", those characters
       will be handled automatically.

       To make it easier to handle strings containing HYPHEN-MINUS, PostScript::File provides the
       "auto_hyphen" attribute.  When this is true (the default when using "cp1252" or
       "iso-8859-1"), the "pstr" method will automatically translate HYPHEN-MINUS to either
       HYPHEN or MINUS SIGN.  (This happens only when "pstr" is called as an object method.)

       The rule is that if a HYPHEN-MINUS is surrounded by whitespace, or surrounded by digits,
       or it's preceded by whitespace or punctuation and followed by a digit, or it's followed by
       a currency symbol, it's translated to MINUS SIGN.  Otherwise, it's translated to HYPHEN.

ATTRIBUTES

       Unlike many classes that use the same method for reading and writing an attribute's value,
       PostScript::File has separate methods for reading and writing.  The read accessor is
       prefixed with "get_", and the write accessor is prefixed with "set_".  If no write
       accessor is mentioned, then the attribute is read-only.

       auto_hyphen

         $ps = PostScript::File->new( auto_hyphen => $translate )

         $translate = $ps->get_auto_hyphen

         $ps->set_auto_hyphen( $translate )

       If $translate is a true value, then "pstr" will do automatic hyphen-minus translation when
       called as an object method (but only if the document uses character set translation).
       (Default: true) See "Hyphens and Minus Signs".

       clipping

         $ps = PostScript::File->new( clipping => $clipping )

         $clipping = $ps->get_clipping

         $ps->set_clipping( $clipping )

       If $clipping is true, printing will be clipped to each page's bounding box.  This is the
       document's default value.  Each page has its own "page_clipping" attribute, which is
       initialized to this default value when the page is created.  (Default: false)

       eps

         $ps = PostScript::File->new( eps => $eps )

         $eps = $ps->get_eps

       $eps is true if this is an Encapsulated PostScript document.  False indicates an ordinary
       PostScript document.

       extensions

         $ps = PostScript::File->new( extensions => $extensions )

         $extensions = $ps->get_extensions

       The PostScript extensions required by this document, for use in the %%Extensions DSC
       comment.  (Default: "undef", meaning omit the %%Extensions comment)

       file_ext

         $ps = PostScript::File->new( file_ext => $file_ext )

         $file_ext = $ps->get_file_ext

         $ps->set_file_ext( $file_ext )

       If $file_ext is undef (the default), then the extension is set automatically based on the
       output type.  ".ps" will be added for ordinary PostScript files.  EPS files have an
       extension of ".epsf" without or ".epsi" with a preview image.

       If $file_ext is the empty string, then no extension will be added to the filename.
       Otherwise, it should be a string like '.ps' or '.eps'.  (But setting this has no effect on
       the actual type of the output file, only its name.)

       filename

         $ps = PostScript::File->new( file => $file, [dir => $dir] )

         $filename = $ps->get_filename

         $ps->set_filename( $file, [$dir] )

       $file
           An optional fully qualified path-and-file, a simple file name, the empty string (which
           stands for the special file "File::Spec->devnull"), or "undef" (which indicates the
           document has no associated filename).

       $dir
           An optional directory name.  If present (and $file is not already an absolute path),
           it is prepended to $file.  If no $file was specified, $dir is ignored.

       The base filename for the output file(s).  When the filename is set, if that filename
       includes a directory component, the directories are created immediately (if they don't
       already exist).

       See "file_ext" for details on how the filename extension is handled.

       If "eps" has been set, multiple pages will have the page label appended to the file name.

       Example:

           $ps = PostScript::File->new( eps => 1 );
           $ps->set_filename( "pics", "~/book" );
           $ps->newpage("vi");
               ... draw page
           $ps->newpage("7");
               ... draw page
           $ps->newpage();
               ... draw page
           $ps->output();

       The three pages for user 'chris' on a Unix system would be:

           /home/chris/book/pics-vi.epsf
           /home/chris/book/pics-7.epsf
           /home/chris/book/pics-8.epsf

       It would be wise to use "set_page_bounding_box" explicitly for each page if using multiple
       pages in EPS files.

       incpage_handler

         $ps = PostScript::File->new( incpage_handler => \&handler )

         $handler = $ps->get_incpage_handler

         $ps->set_incpage_handler( [\&handler] )

       The function used to increment the page label when creating a new page.  "\&handler" is a
       reference to a subroutine that takes the current page label as its only argument and
       returns the new label.

       This module provides the "incpage_label" (which uses Perl's autoincrement operator) and
       "incpage_roman" (which handles lowercase Roman numberals from i to xxxix, 1-39) functions
       for use as "incpage_handler".  (Default: "\&incpage_label")

       langlevel

         $ps = PostScript::File->new( langlevel => $langlevel )

         $langlevel = $ps->get_langlevel

         $ps->set_min_langlevel( $langlevel ) # added in v2.20

       The level of the PostScript language used in this document, for use in the %%LanguageLevel
       DSC comment.  The "set_min_langlevel" method can be used to raise the language level, but
       it cannot be decreased.  (Default: "undef", meaning omit the %%LanguageLevel comment)

       order

         $ps = PostScript::File->new( order => $order )

         $order = $ps->get_order

       The order the pages are defined in the document, for use in the %%PageOrder DSC comment.
       It must be one of "Ascend", "Descend" or "Special" (meaning a document manager must not
       reorder the pages).  The default is "undef", meaning omit the %%PageOrder comment.

       strip (attribute)

         $ps = PostScript::File->new( strip => $strip )

         $strip = $ps->get_strip

         $ps->set_strip( $strip )

       Determine whether the PostScript code is filtered.  $strip must be one of the following
       values: "space" strips leading spaces so the user can indent freely without increasing the
       file size.  "comments" removes lines beginning with '%' as well.  "all_comments" (v2.20)
       also removes comments that aren't at the beginning of a line.  See also the strip method,
       which actually does the filtering described here.

       Passing "undef" or omitting $strip sets it to the default value, "space".

       title

         $ps = PostScript::File->new( title => $title )

         $title = $ps->get_title

       The document's title for use in the %%Title DSC comment.  The default ("undef") means to
       use the document's filename as the title.  If no filename is available when the document
       is output, the %%Title comment wil be omitted.

       version

         $ps = PostScript::File->new( version => $version )

         $version = $ps->get_version

       The document's version for use in the %%Version DSC comment.  The $version should be a
       string in the form "VERNUM REV", where "VERNUM" is a floating point number and "REV" is an
       unsigned integer.  (Default: "undef", meaning omit the %%Version comment)

   Paper Size and Margins
       These attributes are interrelated, and changing one may change the others.

       bounding_box

         ( $llx, $lly, $urx, $ury ) = $ps->get_bounding_box

         $ps->set_bounding_box( $llx, $lly, $urx, $ury )

       The bounding box for the whole document.  The lower left corner is "($llx, $lly)", and the
       upper right corner is "($urx, $ury)".

       Setting the bounding box automatically enables clipping.  Call "$ps->set_clipping(0)"
       afterwards to undo that.

       The default "bounding_box" is calculated from the paper size (taken from the "paper",
       "height", and "width" attributes) and the "left", "right", "top", and "bottom" margins.

       Each page also has an individual "page_bounding_box", which is initialized from the
       document's "bounding_box" when the page is created.

       height

         $ps = PostScript::File->new( height => $height )

         $height = $ps->get_height

         $ps->set_height( $height )

       The page height in points.  This is normally the longer dimension of the paper.  Note that
       in landscape mode this is actually the width of the bounding box.

       Setting this sets "paper" to "Custom" and the "bounding_box" is expanded to the full
       height.

       landscape

         $ps = PostScript::File->new( landscape => $landscape )

         $landscape = $ps->get_landscape

         $ps->set_landscape( $landscape )

       If $landscape is true, the page is rotated 90 degrees counter-clockwise, swapping the
       meaning of height & width.  (Default: false)

       In landscape mode the coordinates are rotated 90 degrees and the origin moved to the
       bottom left corner.  Thus the coordinate system appears the same to the user, with the
       origin at the bottom left.

       paper

         $ps = PostScript::File->new( paper => $paper_size )

         $paper_size = $ps->get_paper

         $ps->set_paper( $paper_size )

       Set the paper size of each page.  A document can be created using a standard paper size
       without having to remember the size of paper using PostScript points. Valid choices are
       currently A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, B0, B1, B2, B3, B4, B5, B6, B7, B8, B9,
       B10, Executive, Folio, Half-Letter, Letter, US-Letter, Legal, US-Legal, Tabloid, SuperB,
       Ledger, 'Comm #10 Envelope', Envelope-Monarch, Envelope-DL, Envelope-C5, and EuroPostcard.
       (Default: "A4")

       You can also give a string in the form 'WIDTHxHEIGHT', where WIDTH and HEIGHT are numbers
       (in points).  This sets the paper size to "Custom".

       Setting this also sets "bounding_box", "height", and "width" to the full height and width
       of the paper.

       width

         $ps = PostScript::File->new( width => $width )

         $width = $ps->get_width

         $ps->set_width( $width )

       The page width in points.  This is normally the shorter dimension of the paper.  Note that
       in landscape mode this is actually the height of the bounding box.

       Setting this sets "paper" to "Custom" and the "bounding_box" is expanded to the full
       width.

   Page Attributes
       The following attributes can have a different value for every page.  You can't set them
       directly in the constructor, but they all have a document-wide default value that each
       page inherits when it is created.  When accessing or setting them, $page is the page
       label.  If $page is omitted, it defaults to the current page.

       page_bounding_box

         ( $llx, $lly, $urx, $ury ) = $ps->get_page_bounding_box( [$page] )

         $ps->set_page_bounding_box( [$page,] $llx, $lly, $urx, $ury )

       The bounding box for this page.  The lower left corner is "($llx, $lly)", and the upper
       right corner is "($urx, $ury)".

       Note that calling "set_page_bounding_box" automatically enables clipping for that page.
       If this isn't what you want, call "$ps->set_page_clipping(0)" afterwards.

       When a page is created, "page_bounding_box" is initialized from the document's
       "bounding_box" attribute.

       page_clipping

         $clipping = $ps->get_page_clipping( [$page] )

         $ps->set_page_clipping( [[$page,] $clipping] )

       If $clipping is true, printing will be clipped to this page's bounding box. (Default:
       false)

       When a page is created, "page_clipping" is initialized from the document's "clipping"
       attribute.

       page_label

         $ps = PostScript::File->new( page => $page )

         $page = $ps->get_page_label

         $ps->set_page_label( [$page] )

       The label for the current page (used in the %%Page comment).  (Default: "1")

       Unlike the other page attributes, you can only access the "page_label" of the current
       page.  (Since pages are specified by label, it makes no sense to ask for the label of a
       different page.)

       When a page is created, "page_label" is initialized by passing the previous page's label
       to the "incpage_handler".  For the first page, it's initialized from the "page" given to
       the constructor.

       page_landscape

         $landscape = $ps->get_page_landscape( [$page] )

         $ps->set_page_landscape( [[$page,] $landscape] )

       If $landscape is true, this page is using landscape mode. (Default: false)

       When a page is created, "page_landscape" is initialized from the document's "landscape"
       attribute.

METHODS

       Note: In the following descriptions, "[]" are used to denote optional parameters, not
       array references.

   Constructor
       new

         $ps = PostScript::File->new(options)

       Create a new PostScript::File object, either a set of pages or an Encapsulated PostScript
       (EPS) file. Options are hash keys and values.  All values should be in the native
       PostScript units of 1/72 inch.

       Example

           $ps = PostScript::File->new(
                   eps       => 1,
                   landscape => 1,
                   width     => 216,
                   height    => 288,
                   left      => 36,
                   right     => 44,
                   clipping  => 1,
                 );

       This creates an Encapsulated PostScript document, 4 by 3 inch pages printing landscape
       with left and right margins of around half an inch.  The width is always the shortest
       side, even in landscape mode.  3*72=216 and 4*72=288.  Being in landscape mode, these
       would be swapped.  The bounding box used for clipping would then be from (50,0) to
       (244,216).

       "options" may be a single hash reference instead of an options list, but the hash must
       have the same structure.  This is more convenient when used as a base class.

       The following keys are recognized options:

       Attributes

       The following attributes can be set through the constructor: "auto_hyphen", "clipping",
       "eps", "extensions", "file_ext", "filename", "height", "incpage_handler", "landscape",
       "langlevel", "order", "page_label", "paper", strip, "title", "version", and "width".

       File size keys

       There are four options which control how much gets put into the resulting file.

       debug

       "undef"
             No debug code is added to the file.  Of course there must be no calls to debug
             functions in the PostScript code.  This is the default.

       0     db_ functions are replaced by dummy functions which do nothing.

       1     A range of functions are added to the file to support debugging PostScript.  This
             switch is similar to the 'C' "NDEBUG" macro in that debugging statements may be left
             in the PostScript code but their effect is removed.

             Of course, being an interpreted language, it is not quite the same as the calls
             still takes up space - they just do nothing.  See "POSTSCRIPT DEBUGGING SUPPORT" for
             details of the functions.

       2     Loads the debug functions and gives some reassuring output at the start and a stack
             dump at the end of each page.

             A mark is placed on the stack at the beginning of each page and 'cleartomark' is
             given at the end, avoiding potential "invalidrestore" errors.  Note, however, that
             if the page does not end with a clean stack, it will fail when debugging is turned
             off.

       errors

       PostScript has a nasty habit of failing silently. If "errors" is true, code that prints
       fatal error messages on the bottom left of the paper is added to the file.  For user
       functions, a PostScript function report_error is defined.  This expects a message string
       on the stack, which it prints before stopping.  (Default: true)

       headings

       If true, add PostScript DSC comments recording the date of creation and user's name.
       (Default: false)

       The comments inserted when "headings" is true are:

         %%For: USER@HOSTNAME
         %%Creator: Perl module PostScript::File v2.22
         %%CreationDate: Sun Jan  1 00:00:00 2012
         %%DocumentMedia: US-Letter 612 792 80 ( ) ( )

       USER comes from "getlogin() || getpwuid($<)", and HOSTNAME comes from Sys::Hostname.  The
       DocumentMedia values come from the paper size attributes.  The DocumentMedia comment is
       omitted from EPS files.

       If you want different values, leave "headings" false and use "add_comment" to add whatever
       you want.

       reencode

       Requests that a font re-encode function be added and that the fonts used by this document
       get re-encoded in the specified encoding.  The only allowed values are "cp1252",
       "iso-8859-1", and "ISOLatin1Encoding".  You should almost always set this to "cp1252",
       even if you are not using Windows.

       The list of fonts to re-encode comes from the "need_fonts" parameter, the "need_resource"
       method, and all fonts added using "embed_font" or "add_resource".  The Symbol font is
       never re-encoded, because it uses a non-standard character set.

       Setting this to "cp1252" or "iso-8859-1" also causes the document to be encoded in that
       character set.  Any strings you add to the document that have the UTF-8 flag set will be
       re-encoded automatically.  Strings that do not have the UTF-8 flag are expected to be in
       the correct character set already.  This means that you should be able to set this to
       "cp1252", use Unicode characters in your code and the "-iso" versions of the fonts, and
       just have it do the right thing.

       Windows code page 1252 (a.k.a. WinLatin1) is a superset of the printable characters in
       ISO-8859-1 (a.k.a. Latin1).  It adds a number of characters that are not in Latin1,
       especially common punctuation marks like the curly quotation marks, en & em dashes, Euro
       sign, and ellipsis.  These characters exist in the standard PostScript fonts, but there's
       no easy way to access them when using the standard or ISOLatin1 encodings.
       <http://en.wikipedia.org/wiki/Windows-1252>

       For backwards compatibility with versions of PostScript::File older than 1.05, setting
       this to "ISOLatin1Encoding" re-encodes the fonts, but does not do any character set
       translation in the document.

       Initialization keys

       There are a few initialization settings that are only relevant when the file object is
       constructed.

       bottom

       The margin in from the paper's bottom edge, specifying the non-printable area.  Remember
       to specify "clipping" if that is what is wanted.  (Default: 28)

       clip_command

       The bounding box is used for clipping if this is set to "clip" or is drawn with "stroke".
       This also makes the whole page area available for debugging output.  (Default: "clip").

       font_suffix

       This string is appended to each font name as it is re-encoded.  (Default: "-iso")

       The string value is appended to these to make the new names.

       Example:

           $ps = PostScript::File->new(
                   font_suffix => "-iso",
                   reencode => "cp1252"
                 );

       "Courier" still has the standard mapping while "Courier-iso" includes the additional
       European characters.

       left

       The margin in from the paper's left edge, specifying the non-printable area.  Remember to
       specify "clipping" if that is what is wanted.  (Default: 28)

       need_fonts

       An arrayref of font names required by this document.  This is equivalent to calling
       "$ps->need_resource(font => @$arrayref)".  See "need_resource" for details.

       newpage

       (v2.10) Normally, an initial page is created automatically (using the label specified by
       "page").  But starting with PostScript::File 2.10, you can pass "newpage => 0" to override
       this.  This makes for more natural loops:

           use PostScript::File 2.10;
           my $ps = PostScript::File->new(newpage => 0);
           for (@pages) {
             $ps->newpage;  # don't need "unless first page"
             ...
           }

       It's important to require PostScript::File 2.10 if you do this, because older versions
       would produce an initial blank page.

       If you don't pass a page label to the first call to "newpage", it will be taken from the
       "page" option.  After the first page, the page label will increment as specified by
       "incpage_handler".

       right

       The margin in from the paper's right edge.  It is a positive offset, so "right=36" will
       leave a half inch no-go margin on the right hand side of the page.  Remember to specify
       "clipping" if that is what is wanted.  (Default: 28)

       top

       The margin in from the paper's top edge.  It is a positive offset, so "top=36" will leave
       a half inch no-go margin at the top of the page.  Remember to specify "clipping" if that
       is what is wanted.  (Default: 28)

       Debugging support keys

       This makes most sense in the PostScript code rather than Perl.  However, it is convenient
       to be able to set defaults for the output position and so on.  See "POSTSCRIPT DEBUGGING
       SUPPORT" for further details.

       db_active

       Set to 0 to temporarily suppress the debug output.  (Default: 1)

       db_base

       Debug printing will not occur below this point.  (Default: 6)

       db_bufsize

       The size of string buffers used.  Output must be no longer than this.  (Default: 256)

       db_color

       This is the whole PostScript command (with any parameters) to specify the colour of the
       text printed by the debug routines.  (Default: "0 setgray")

       db_font

       The name of the font to use.  (Default: "Courier")

           Courier
           Courier-Bold
           Courier-BoldOblique
           Courier-Oblique
           Helvetica
           Helvetica-Bold
           Helvetica-BoldOblique
           Helvetica-Oblique
           Times-Roman
           Times-Bold
           Times-BoldItalic
           Times-Italic
           Symbol

       db_fontsize

       The size of the font.  PostScript uses its own units, but they are almost points.
       (Default: 10)

       db_xgap

       Typically, the output comprises single values such as a column showing the stack contents.
       "db_xgap" specifies the width of each column.  By default, this is calculated to allow 4
       columns across the page.

       db_xpos

       The left edge, where debug output starts.  (Default: 6)

       db_xtab

       The amount indented by "db_indent".  (Default: 10)

       db_ytop

       The top line of debugging output.  Defaults to 6 below the top of the page.

       Error handling keys

       If "errors" is set, the position of any fatal error message can be controlled with the
       following options.  Each value is placed into a PostScript variable of the same name, so
       they can be overridden from within the code if necessary.

       errfont

       The name of the font used to show the error message.  (Default: "Courier-Bold")

       errmsg

       The error message comprises two lines.  The second is the name of the PostScript error.
       This sets the first line.  (Default: "ERROR:")

       errsize

       Size of the error message font.  (Default: 12)

       errx

       X position of the error message on the page.  (Default: (72))

       erry

       Y position of the error message on the page.  (Default: (72))

   Main Methods
       newpage

         $ps->newpage( [$page] )

       Generate a new PostScript page, unless in a EPS file when it is ignored.

       If $page is not specified the previous page's label is incremented using the
       "incpage_handler".

       output

         $ps->output( [$file, [$dir]] )

       If $file is an open filehandle, write the PostScript document to that filehandle and
       return nothing.

       If a filename has been given either here, to "new", or to "set_filename", write the
       PostScript document to that file and return its pathname.  ($file and $dir have the same
       meaning here as they do in set_filename.)

       If no filename has been given, or $file is undef, return the PostScript document as a
       string.

       In "eps" mode, each page of the document becomes a separate EPS file.  In list context,
       returns a list of these files (either the pathname or the PostScript code as explained
       above).  In scalar context, only the first page is returned (but all pages will still be
       processed).  If you pass a filehandle when you have multiple pages, all the documents are
       written to that filehandle, which is probably not what you want.

       Use this option whenever output is required to disk. The current PostScript document in
       memory is not cleared, and can still be extended or output again.

       as_string

         $postscript_code = $ps->as_string

       This returns the PostScript document as a string.  It is equivalent to
       "$ps->output(undef)".

       testable_output

         $postscript_code = $ps->testable_output( [$verbatim] )

       This returns the PostScript document as a string, but with the PostScript::File generated
       code removed (unless $verbatim is true).  This is intended for use in test scripts, so
       they won't see changes in the output caused by different versions of PostScript::File.
       The PostScript code returned by this method will probably not work in a PostScript
       interpreter.

       If $verbatim is true, this is equivalent to "$ps->output(undef)".

   Access Methods
       Use these "get_" and "set_" methods to access a PostScript::File object's data.

       get_metrics

         $metrics = $ps->get_metrics( $font, [$size, [$encoding]] )

       Construct a PostScript::File::Metrics object for $font.  The $encoding is normally
       determined automatically from the font name and the document's encoding.  The default
       $size is 1000.

       If this document uses "reencode", and the font ends with "font_suffix", then the Metrics
       object will use that encoding.  Otherwise, the encoding is "std" (except for the Symbol
       font, which always uses "sym").

       No matter what encoding the font uses, the Metrics object will always use the same Unicode
       translation setting as this document.  It also inherits the current value of the
       "auto_hyphen" attribute.

       set_min_langlevel

         $new_langlevel = $ps->set_min_langlevel( $langlevel )

       (v2.20) Set the "langlevel" attribute of this document to $langlevel, but only if the
       current level is less than $langlevel.  It returns the value of "langlevel", which will be
       greater than or equal to $langlevel.

       set_page_margins

         $ps->set_page_margins( [$page,] $left, $bottom, $right, $top )

       This sets the "page_bounding_box" based on the paper size and the specified margins.  It
       also automatically enables clipping for the page.  If this isn't what you want, call
       "$ps->set_page_clipping(0)" afterwards.

       get_page_printable_height

         $height = $ps->get_page_printable_height( [$page] )

       (v2.10) Returns the height of the page's bounding box ("ury - lly").

       get_page_printable_width

         $width = $ps->get_page_printable_width( [$page] )

       (v2.10) Returns the width of the page's bounding box ("urx - llx".

       get_page_variable

         $value = $ps->get_page_variable( $key )

       Retrieve a user defined value previously assigned by "set_page_variable".

       set_page_variable

         $ps->set_page_variable( $key, $value )

       Assign a user defined hash key and value only valid on the current page.  Provided to keep
       track of states within the PostScript code, such as which styles are currently active.
       PostScript::File does not use this (except to clear it at the start of each page).  It is
       recommended that $key is the module name to avoid clashes.  The $value could then be a
       hash holding any number of user variables.

       get_pagecount

         $pages = $ps->get_pagecount

       Returns the number of pages currently in the document.

       get_printable_height

         $height = $ps->get_printable_height

       (v2.10) Returns the height of the document's bounding box ("ury - lly").

       get_printable_width

         $width = $ps->get_printable_width

       (v2.10) Returns the width of the document's bounding box ("urx - llx").

       get_variable

         $value = $ps->get_variable( $key )

       Retrieve a user defined value previously assigned by "set_variable".

       set_variable

         $ps->set_variable( $key, $value )

       Assign a user defined hash key and value.  Provided to keep track of states within the
       PostScript code, such as which dictionaries are currently open.  PostScript::File does not
       use this - it is provided for client programs.  It is recommended that $key is the module
       name to avoid clashes.  The $value could then be a hash holding any number of user
       variables.

   Content Methods
       add_comment

         $ps->add_comment( $comment )

       Append a comment to the document's DSC comments section.  Most of the required and
       recommended comments are set directly from the document's attributes, so this method
       should rarely be needed.  It is provided for completeness so that comments not otherwise
       supported can be added.  $comment should contain the bare PostScript DSC name and value,
       with additional lines merely prefixed by "+".  It should NOT end with a newline.

       Programs written for older versions of PostScript::File might use this to add a
       "DocumentNeededResources" comment.  That is now deprecated; you should use "need_resource"
       instead.

       Examples:

           $ps->add_comment("ProofMode: NotifyMe");
           $ps->add_comment("Requirements: manualfeed");

       get_comments

         $comments = $ps->get_comments

       Retrieve any extra DSC comments added by "add_comment".

       add_default

         $ps->add_default( $default )

       Use this to append a PostScript DSC comment to the Defaults section.  These would be
       typically values like "PageCustomColors:" or "PageRequirements:".  The format is the same
       as for "add_comment".

       get_defaults

         $comments = $ps->get_defaults

       Returns the contents of the DSC Defaults section, if any.

       embed_document

         $code = $ps->embed_document( $filename )

       This reads the contents of $filename, which should be a PostScript file.  It returns a
       string with the contents of the file surrounded by %%BeginDocument and %%EndDocument
       comments, and adds $filename to the list of document supplied resources.

       You must pass the returned string to add_to_page or some other method that will actually
       include it in the document.

       embed_font

         $font_name = $ps->embed_font( $filename, [$type] )

       This reads the contents of $filename, which must contain a PostScript font.  It calls
       "add_resource" to add the font to the document, and returns the name of the font (without
       a leading slash).

       If $type is omitted, the $filename's extension is used as the type.  Type names are not
       case sensitive.  The currently supported types are:

       PFA A PostScript font in ASCII format

       PFB A PostScript font in binary format.  This requires the t1ascii program from
           <http://www.lcdf.org/type/#t1utils>.  (You can set $PostScript::File::t1ascii to the
           name of the program to use.  It defaults to t1ascii.)

       TTF A TrueType font.  This requires the ttftotype42 program from
           <http://www.lcdf.org/type/#typetools>.  (You can set $PostScript::File::ttftotype42 to
           the name of the program to use.  It defaults to ttftotype42.)

           Since TrueType (a.k.a. Type42) font support was introduced in PostScript level 2,
           embedding a TTF font automatically sets "langlevel" to 2 (unless it was already set to
           a higher level).  Be aware that not all printers can handle Type42 fonts.  (Even
           PostScript level 2 printers need not support them.)  Ghostscript does support Type42
           fonts (when compiled with the "ttfont" option).

       need_resource

         $ps->need_resource( $type, @resources )

       This adds resources to the DocumentNeededResources comment.  $type is one of "encoding",
       "file", "font", "form", "pattern", or "procset" (case sensitive).

       Any number of resources (of a single type) may be added in one call.  For most types,
       $resource[N] is just the resource name.  But for "procset", each element of @resources
       should be an arrayref of 3 elements: "[$name, $version, $revision]".  Names that contain
       special characters such as spaces will be quoted automatically.

       If "need_resource" is never called for the "font" type (and "need_fonts" is not used), it
       assumes the document requires all 13 of the standard PostScript fonts: Courier, Courier-
       Bold, Courier-BoldOblique, Courier-Oblique, Helvetica, Helvetica-Bold, Helvetica-
       BoldOblique, Helvetica-Oblique, Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
       and Symbol.  But this behaviour is deprecated; a document should explicitly list the fonts
       it requires.  If you don't use any of the standard fonts, pass "need_fonts => []" to the
       constructor (or call "$ps->need_resource('font')") to indicate that.

       add_to_page

         $ps->add_to_page( [$page,] $code )

       This appends $code to the specified $page, which can be any page label.  (Default: the
       current page)

       If the specified $page does not exist, a new page is added with that label.  Note that
       this is added on the end, not in the order you might expect.  So adding "vi" to page set
       "iii, iv, v, 6, 7, 8" would create a new page after "8" not after "v".

       Examples

           $ps->add_to_page( <<END_PAGE );
               ...PostScript building this page
           END_PAGE

           $ps->add_to_page( "3", <<END_PAGE );
               ...PostScript building page 3
           END_PAGE

       The first example adds code onto the end of the current page.  The second one either adds
       additional code to page 3 if it exists, or starts a new one.

       get_page

         $code = $ps->get_page( [$page] )

       Returns the PostScript code from the body of the page.

       add_page_setup

         $ps->add_page_setup( $code )

       Appends $code to the DSC PageSetup section.  Note that this is a document-global value,
       although the code will be repeated on each page.

       Also note that any settings defined here will be active for each page separately.  Use
       "add_setup" if you want to carry settings from one page to another.

       get_page_setup

         $setup = $ps->get_page_setup

       Returns the contents of the DSC PageSetup section, if any.  Note that this is a document-
       global value, although the code will be repeated on each page.

       add_page_trailer

         $ps->add_page_trailer( $code )

       Appends $code to the DSC PageTrailer section.  Note that this is a document-global value,
       although the code will be repeated on each page.

       Code added here is output after each page.  It may refer to settings made during
       "add_page_setup" or "add_to_page".

       get_page_trailer

         $code = $ps->get_page_trailer

       Returns the contents of the DSC PageTrailer section, if any.  Note that this is a
       document-global value, although the code will be repeated on each page.

       add_preview

         $ps->add_preview( $width, $height, $depth, $lines, $preview )

       Sets the EPSI format preview for this document - an ASCII representation of a bitmap.
       Only EPS files should have a preview, but that is not enforced.  If an EPS file has a
       preview it becomes an EPSI file rather than EPSF.

       get_preview

         $preview = $ps->get_preview

       Returns the EPSI preview of the document, if any, including the %%BeginPreview and
       %%EndPreview comments.

       add_procset

         $ps->add_procset( $name, $code, [$version, [$revision]] )

       (v2.20) Add a ProcSet containing user defined functions to the PostScript prolog.  $name
       is an arbitrary identifier of this resource.  $code is a block of PostScript code, usually
       from a 'here' document.  If the document already contains ProcSet $name (as reported by
       "has_procset", then "add_procset" does nothing.

       $version is a real number, and $revision is an unsigned integer.  They both default to 0.
       PostScript::File does not make any use of these, but a PostScript document manager may
       assume that a procset with a higher revision number may be substituted for a procset with
       the same name and version but a lower revision.

       Returns true if the ProcSet was added, or false if it already existed.

       Example

           $ps->add_procset( "My_Functions", <<END_FUNCTIONS );
               % PostScript code can be freely indented
               % as leading spaces and blank lines
               % (and comments, if desired) are stripped

               % foo does this...
               /foo {
                   ... definition of foo
               } bind def

               % bar does that...
               /bar {
                   ... definition of bar
               } bind def
           END_FUNCTIONS

       Note that "get_procsets" (in common with the others) will return all user defined
       functions possibly including those added by other classes.

       has_procset

         $exists = $ps->has_procset( $name )

       (v2.20) This returns true if $name has already been included in the file.  The name should
       be identical to that given to "add_procset".

       get_procsets

         $code = $ps->get_procsets

       (v2.20) Return all the procsets defined in this document.

       add_resource

         $ps->add_resource( $type, $name, $params, $resource )

       $type
           A string indicating the DSC type of the resource.  It should be one of "Document",
           "Feature", "encoding", "file", "font", "form", or "pattern" (case sensitive).

       $name
           An arbitrary identifier of this resource.  (For a Font, it must be the PostScript name
           of the font, without a leading slash.)

       $params
           Some resource types require parameters.  See the Adobe documentation for details.

       $resource
           A string containing the PostScript code. Probably best provided a 'here' document.

       Use this to add fonts or images (although you may prefer "embed_font" or
       "embed_document").  "add_procset" is provided for functions.

       Example

           $ps->add_resource( "File", "My_File1",
                              "", <<END_FILE1 );
               ...PostScript resource definition
           END_FILE1

       get_resources

         $resources = $ps->get_resources

       Returns all resources provided by this document.  This does not include procsets.

       add_setup

        $ps->add_setup( $code )

       This appends $code to the DSC Setup section.  Use this for "setpagedevice", "statusdict"
       or other settings that initialize the device or document.

       get_setup

         $setup = $ps->get_setup

       Returns the contents of the DSC Setup section, if any.

       add_trailer

         $ps->add_trailer( $code )

       Appends $code to the document's DSC Trailer section.  Use this for any tidying up after
       all the pages are output.

       get_trailer

         $code = $ps->get_trailer

       Returns the contents of the document's DSC Trailer section, if any.

       use_functions

         $ps->use_functions( @function_names )

       This requests that the PostScript functions listed in @function_names be included in this
       document.  See PostScript::File::Functions for a list of available functions.

   Text Processing Methods
       convert_hyphens

         $converted_text = $ps->convert_hyphens( $text )

       Converts any HYPHEN-MINUS (U+002D) characters in $text to either HYPHEN (U+2010) or MINUS
       SIGN (U+2212) according to the rules described in "Hyphens and Minus Signs".  This has the
       side-effect of setting the UTF-8 flag on $converted_text.

       If $text does not have the UTF-8 flag set, it is assumed to be in the document's character
       encoding.

       If $text does not contain any HYPHEN-MINUS characters, it is returned as-is.

       decode_text

         $text = $ps->decode_text( $encoded_text, [$preserve_minus] )

       This is the inverse of "encode_text".  It converts $encoded_text from the document's
       character encoding into Unicode.  If $encoded_text already has the UTF-8 flag set, or the
       document is not using character translation, then it returns $encoded_text as-is.

       If the optional argument $preserve_minus is true (and $encoded_text is not being returned
       as-is), then any HYPHEN-MINUS (U+002D) characters in $encoded_text are decoded as MINUS
       SIGN (U+2212).  This ensures that "encode_text" will treat them as minus signs instead of
       hyphens.

       encode_text

         $encoded_text = $ps->encode_text( $text )

       This returns $text converted to the document's character encoding.  If $text does not have
       the UTF-8 flag set, or the document is not using character translation, then it returns
       $text as-is.

       pstr

         $code = $ps->pstr( $string, [$nowrap] )

         $code = PostScript::File->pstr( $string, [$nowrap] )

         $code = pstr( $string )

       Converts the string to a PostScript string literal.  If the result is more than 240
       characters, it will be broken into multiple lines.  (A PostScript file should not contain
       lines with more than 255 characters.)

       When called as a class or object method, you can pass a second parameter $nowrap.  If this
       optional parameter is true, then the string will not be wrapped, no matter how long it is.

       When called as an object method, "pstr" will do automatic hyphen-minus translation if
       "auto_hyphen" is true.  This has the side-effect of setting the UTF-8 flag on the returned
       string.  (If the UTF-8 flag was not set on the input string, it will be decoded using the
       document's character set.)  See "Hyphens and Minus Signs".  For this reason, "pstr" should
       normally be called as an object method.

       strip (method)

         $ps->strip( $code )

         $ps->strip( $strip => @code )

       The "strip" method filters PostScript code according to the value of $strip, which can be
       any valid value for the strip attribute.  The code is modified in-place; there is no
       return value.  If $code is "undef", it is left unchanged.

       When called with a single argument, strips $code according to the current value of the
       "strip" attribute.

SUBROUTINES

   array_as_string
         $code = array_as_string( @array )

       Converts a Perl array to a PostScript array literal.  The array elements are used as-is.
       If you want an array of strings, you should do something like:

         $code = array_as_string( map { $ps->pstr($_) } @array )

   check_file
         $pathname = check_file( $file, [$dir, [$create]] )

       $file
           An optional fully qualified path-and-file or a simple file name. If omitted or the
           empty string, the special file "File::Spec->devnull" is returned.

       $dir
           An optional directory path.  If defined (and $file is not already an absolute path),
           it is prepended to $file.

       $create
           If true, create the file if it doesn't exist already.  (Default: false)

       This converts a filename and optional directory to an absolute path, and then creates any
       directories that don't already exist.  Any leading "~" is expanded to the user's home
       directory using "check_tilde".

       If $create is true, and $pathname does not exist, it is created as an empty file.

       File::Spec is used throughout so file access should be portable.

   check_tilde
         $expanded_path = check_tilde( $path )

       Expands a leading "~" or "~user" in $path to the home directory.

   incpage_label
         $next_label = incpage_label( $label )

       This function applies Perl's autoincrement operator to $label and returns the result.
       (This means that the magic string autoincrement applies to values that match
       "/^[a-zA-Z]*[0-9]*\z/".)

       This function is the default value of the "incpage_handler" attribute.

   incpage_roman
         $next_label = incpage_roman( $label )

       This function increments lower case Roman numerals.  $label must be a value between "i"
       and "xxxviii" (1 to 38), and $next_label will be "ii" to "xxxix" (2 to 39).  That should
       be quite enough for numbering the odd preface.

       This function is normally used as the value of the "incpage_handler" attribute:

         $ps->set_incpage_handler( \&PostScript::File::incpage_roman )

   quote_text
         $quoted = quote_text( $string )

         $quoted = PostScript::File->quote_text( $string )

         $quoted = $ps->quote_text( $string )

       Quotes the string if it contains special characters, making it suitable for a DSC comment.
       Strings without special characters are returned unchanged.

       This may also be called as a class or object method, but it does not do hyphen-minus
       translation, even if "auto_hyphen" is true.

   str
         $code = str( $value )

       If $value is an arrayref, returns "array_as_string(@$value)".  Otherwise, returns $value
       as-is.  This function was designed to simplify passing colors to the PostScript function
       "setColor" in PostScript::File::Functions, which expects either an RGB array or a
       greyscale decimal.

POSTSCRIPT DEBUGGING SUPPORT

       This section documents the PostScript functions which provide debugging output.  Please
       note that any clipping or bounding boxes will also hide the debugging output which by
       default starts at the top left of the page.  Typical "new" options required for debugging
       would include the following.

           $ps = PostScript::File->new (
                   errors => "page",
                   debug => 2,
                   clipcmd => "stroke" );

       The debugging output is printed on the page being drawn.  In practice this works fine,
       especially as it is possible to move the output around.  Where the text appears is
       controlled by a number of PostScript variables, most of which may also be given as options
       to "new".

       The main controller is "db_active" which needs to be non-zero for any output to be seen.
       It might be useful to set this to 0 in "new", then at some point in your code enable it.
       Remember that the "debugdict" dictionary needs to be selected in order for any of its
       variables to be changed.  This is better done with "db_on" but it illustrates the point.

           /debugdict begin
               /db_active 1 def
           end
           (this will now show) db_show

       At any time, the next output will appear at "db_xpos" and "db_ypos".  These can of course
       be set directly.  However, after most prints, the equivalent of a 'newline' is executed.
       It moves down "db_fontsize" and left to "db_xpos".  If, however, that would take it below
       "db_ybase", "db_ypos" is reset to "db_ytop" and the x coordinate will have "db_xgap" added
       to it, starting a new column.

       The positioning of the debug output is changed by setting "db_xpos" and "db_ytop" to the
       top left starting position, with "db_ybase" guarding the bottom.  Extending to the right
       is controlled by not printing too much!  Judicious use of "db_active" can help there.

   PostScript functions
       x0 y0 x1 y1 cliptobox

       This function is only available if 'clipping' is set.  By calling the Perl method
       "draw_bounding_box" (and resetting with "clip_bounding_box") it is possible to use this to
       identify areas on the page.

           $ps->draw_bounding_box();
           $ps->add_to_page( <<END_CODE );
               ...
               my_l my_b my_r my_t cliptobox
               ...
           END_CODE
           $ps->clip_bounding_box();

       msg report_error

       If 'errors' is enabled, this call allows you to report a fatal error from within your
       PostScript code.  It expects a string on the stack and it does not return.

       All the "db_" variables (including function names) are defined within their own dictionary
       ("debugdict").  But this can be ignored by all calls originating from within code passed
       to "add_to_page" (usually including "add_procset" code) as the dictionary is automatically
       put on the stack before each page and taken off as each finishes.

       any db_show

       The workhorse of the system.  This takes the item off the top of the stack and outputs a
       string representation of it.  So you can call it on numbers or strings and it will show
       them.  Arrays are printed using "db_array" and marks are shown as '--mark--'.

       n msg db_nshow

       This shows top "n" items on the stack.  It requires a number and a string on the stack,
       which it removes.  It prints out "msg" then the top "n" items on the stack, assuming there
       are that many.  It can be used to do a labelled stack dump.  Note that if "new" was given
       the option "debug =" 2>, There will always be a '--mark--' entry at the base of the stack.
       See "debug".

           count (at this point) db_nshow

       db_stack

       Prints out the contents of the stack.  No stack requirements.

       The stack contents is printed top first, the last item printed is the lowest one
       inspected.

       array db_print

       The closest this module has to a print statement.  It takes an array of strings and/or
       numbers off the top of the stack and prints them with a space in between each item.

           [ (myvar1=) myvar1 (str2=) str2 ] db_print

       will print something like the following.

           myvar= 23.4 str2= abc

       When printing something from the stack you need to take into account the array-building
       items, too.  In the next example, at the point '2 index' fetches 111, the stack holds '222
       111 [ (top=)' but 'index' requires 5 to get at 222 because the stack now holds '222 111 [
       (top=) 111 (next=)'.

           222 111
           [ (top=) 2 index (next=) 5 index ] db_print

       willl output this.

           top= 111 next= 222

       It is important that the output does not exceed the string buffer size.  The default is
       256, but it can be changed by giving "new" the option "bufsize".

       x y msg db_point

       It is common to have coordinates as the top two items on the stack.  This call inspects
       them.  It pops the message off the stack, leaving x and y in place, then prints all three.

           450 666
           (starting point=) db_print
           moveto

       would produce:

           starting point= ( 450 , 666 )

       array db_array

       Like "db_print" but the array is printed enclosed within square brackets.

       var db_where

       A 'where' search is made to find the dictionary containing "var".  The messages 'found' or
       'not found' are output accordingly.  Of course, "var" should be quoted with '/' to put the
       name on the stack, otherwise it will either be executed or force an error.

       db_newcol

       Starts the next debugging column.  No stack requirements.

       db_on

       Enable debug output

       db_off

       Disable debug output

       db_down

       Does a 'carriage-return, line-feed'.  No stack requirements.

       db_indent

       Moves output right by "db_xtab".  No stack requirements.  Useful for indenting output
       within loops.

       db_unindent

       Moves output left by "db_xtab".  No stack requirements.

EXPORTS

       No functions are exported by default.  All the functions listed in "SUBROUTINES" may be
       exported by request.

       In addition, the "pstr" method may be exported as a subroutine, but this usage is
       deprecated.

BUGS AND LIMITATIONS

       When making EPS files, the landscape transformation throws the coordinates off.  To work
       around this, avoid the landscape flag and set width and height differently.

       Most of these functions have only had a couple of tests, so please feel free to report all
       you find.

AUTHOR

       Chris Willmot   "<chris AT willmot.co.uk>"

       Thanks to Johan Vromans for the ISOLatin1Encoding.

       As of September 2009, PostScript::File is now being maintained by Christopher J. Madsen
       "<perl AT cjmweb.net>".

       Please report any bugs or feature requests to "<bug-PostScript-File AT rt.cpan.org>", or
       through the web interface at
       <http://rt.cpan.org/Public/Bug/Report.html?Queue=PostScript-File>

       You can follow or contribute to PostScript::File's development at
       <https://github.com/madsen/postscript-file>.

COPYRIGHT AND LICENSE

       Copyright 2002, 2003 Christopher P Willmot.  All rights reserved.

       Copyright 2015 Christopher J. Madsen. All rights reserved.

       This is free software; you can redistribute it and/or modify it under the same terms as
       the Perl 5 programming language system itself.

SEE ALSO

       PostScript Language Document Structuring Conventions Specification Version 3.0 and
       Encapsulated PostScript File Format Specification Version 3.0 published by Adobe, 1992.
       <http://partners.adobe.com/asn/developer/technotes/postscript.html>

       PostScript::Convert, for PDF or PNG output.

       PostScript::Calendar, for creating monthly calendars.

       PostScript::Report, for creating tabular reports.

       PostScript::ScheduleGrid, for printing schedules in a grid format.

       PostScript::ScheduleGrid::XMLTV, for printing TV listings in a grid format.

       PostScript::Graph::Paper, PostScript::Graph::Style, PostScript::Graph::Key,
       PostScript::Graph::XY, PostScript::Graph::Bar, PostScript::Graph::Stock.

DISCLAIMER OF WARRANTY

       BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE,
       TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
       COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF
       ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
       THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE
       DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

       IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT
       HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY
       THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
       INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
       SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
       LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY
       OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
       SUCH DAMAGES.