diff options
author | Didier Raboud <didier@raboud.com> | 2010-05-23 00:04:56 +0200 |
---|---|---|
committer | Didier Raboud <didier@raboud.com> | 2010-05-23 00:04:56 +0200 |
commit | 6fefeecb6abbb1f7dfe07ade1a0abef06dac5d32 (patch) | |
tree | f18a60b86ca3975a15dac03ad607f09cf6a9f566 /foomatic-rip.in | |
parent | 0743a0a49409ef8ee98d0052154f638aace291d7 (diff) |
Imported Upstream version 3.0.2-20080211upstream/3.0.2-20080211
Diffstat (limited to 'foomatic-rip.in')
-rw-r--r-- | foomatic-rip.in | 1156 |
1 files changed, 619 insertions, 537 deletions
diff --git a/foomatic-rip.in b/foomatic-rip.in index a681753..18b06a0 100644 --- a/foomatic-rip.in +++ b/foomatic-rip.in @@ -26,12 +26,12 @@ my $ripversion='$Revision$'; # spoolers run the print filters as a special user, as "lp", not as # "root" or as the user who sent the job). -# See http://www.linuxprinting.org/cups-doc.html -# http://www.linuxprinting.org/lpd-doc.html -# http://www.linuxprinting.org/ppr-doc.html -# http://www.linuxprinting.org/pdq-doc.html -# http://www.linuxprinting.org/direct-doc.html -# http://www.linuxprinting.org/ppd-doc.html +# See http://www.openprinting.org/cups-doc.html +# http://www.openprinting.org/lpd-doc.html +# http://www.openprinting.org/ppr-doc.html +# http://www.openprinting.org/pdq-doc.html +# http://www.openprinting.org/direct-doc.html +# http://www.openprinting.org/ppd-doc.html # ========================================================================== # @@ -114,8 +114,8 @@ my $logfile = "/tmp/foomatic-rip"; # # foomatic-rip spooler-independent PS->Printer filter (RIP) of Foomatic # -# Copyright 2002 - 2004 Grant Taylor <gtaylor@picante.com> -# & Till Kamppeter <till.kamppeter@gmx.net> +# Copyright 2002 - 2007 Grant Taylor <gtaylor@picante.com> +# & Till Kamppeter <till.kamppeter@gmail.com> # & Helge Blischke <h.blischke@srz.de> # # This program is free software; you can redistribute it and/or modify it @@ -1132,7 +1132,7 @@ while(<PPD>) { $line =~ m!^([^\"]*)\"!; $cmd .= $1; $model = unhtmlify($cmd); - } elsif (m!^\*FoomaticIDs:\s*(\S+)\s+(\S+)\s*$!) { + } elsif (m!^\*FoomaticIDs:\s*\"?\s*(\S+?)\s+(\S+?)\s*\"?\s*$!) { # "*FoomaticIDs: <printer ID> <driver ID>" my $id = $1; my $driver = $2; @@ -1181,6 +1181,17 @@ while(<PPD>) { $line =~ m!^([^\"]*)\"!; $cmd .= $1; $dat->{'cmd'} = unhtmlify($cmd); + } elsif (m!^\*FoomaticNoPageAccounting:\s*\"?\s*(\S+?)\s*\"?\s*$!) { + # "*FoomaticRIPNoPageAccounting: <boolean value>" + my $value = $1; + # Apply the value + if ($value =~ /^True$/i) { + # Driver is not compatible with page accounting according to the + # Foomatic database, so turn it off for this driver + $ps_accounting = 0; + $accounting_prolog = ''; + print $logh "CUPS page accounting disabled by driver.\n"; + } } elsif (m!^\*cupsFilter:\s*\"(.*)$!) { # "*cupsFilter: <code>" my $line = $1; @@ -1277,8 +1288,8 @@ while(<PPD>) { # Unmark the current argument to do not mis-interpret any keywords # as choices $currentargument = ""; - } elsif ((m!^\*FoomaticRIPOption ([^/:\s]+):\s*(\S+)\s+(\S+)\s+(\S)\s*$!) || - (m!^\*FoomaticRIPOption ([^/:\s]+):\s*(\S+)\s+(\S+)\s+(\S)\s+(\S+)\s*$!)){ + } elsif ((m!^\*FoomaticRIPOption ([^/:\s]+):\s*\"?\s*(\S+?)\s+(\S+)\s+(\S)\s*\"?\s*$!) || + (m!^\*FoomaticRIPOption ([^/:\s]+):\s*\"?\s*(\S+?)\s+(\S+)\s+(\S)\s+(\S+?)\s*\"?\s*$!)){ # "*FoomaticRIPOption <option>: <type> <style> <spot> [<order>]" # <order> only used for 1-choice enum options my $argname = $1; @@ -1330,7 +1341,7 @@ while(<PPD>) { $line =~ m!^([^\"]*)\"!; $proto .= $1; $dat->{'args_byname'}{$argname}{'proto'} = unhtmlify($proto); - } elsif (m!^\*FoomaticRIPOptionRange\s+([^/:\s]+):\s*(\S+)\s+(\S+)\s*$!) { + } elsif (m!^\*FoomaticRIPOptionRange\s+([^/:\s]+):\s*\"?\s*(\S+?)\s+(\S+?)\s*\"?\s*$!) { # "*FoomaticRIPOptionRange <option>: <min> <max>" # Used for numerical options only my $argname = $1; @@ -1341,7 +1352,7 @@ while(<PPD>) { # Store the values $dat->{'args_byname'}{$argname}{'min'} = $min; $dat->{'args_byname'}{$argname}{'max'} = $max; - } elsif (m!^\*FoomaticRIPOptionMaxLength\s+([^/:\s]+):\s*(\S+)\s*$!) { + } elsif (m!^\*FoomaticRIPOptionMaxLength\s+([^/:\s]+):\s*\"?\s*(\S+?)\s*\"?\s*$!) { # "*FoomaticRIPOptionMaxLength <option>: <length>" # Used for string options only my $argname = $1; @@ -1421,7 +1432,7 @@ while(<PPD>) { checkarg ($dat, $argname); # Store the value $dat->{'args_byname'}{$argname}{'default'} = $default; - } elsif (m!^\*FoomaticRIPDefault([^/:\s]+):\s*([^/:\s]+)\s*$!) { + } elsif (m!^\*FoomaticRIPDefault([^/:\s]+):\s*\"?\s*([^/:\s]+?)\s*\"?\s*$!) { # "*FoomaticRIPDefault<option>: <value>" # Used for numerical options only my $argname = $1; @@ -1463,7 +1474,7 @@ while(<PPD>) { checksetting ($dat, $currentargument, $setting); # Make sure that this argument has a default setting, even if # none is defined in this PPD file - if (!$dat->{'args_byname'}{$currentargument}{'default'}) { + if (!defined ($dat->{'args_byname'}{$currentargument}{'default'})) { $dat->{'args_byname'}{$currentargument}{'default'} = $setting; } $dat->{'args_byname'}{$currentargument}{'vals_byname'}{$setting}{'comment'} = $translation; @@ -1515,7 +1526,7 @@ while(<PPD>) { checksetting ($dat, $argname, $setting); # Make sure that this argument has a default setting, even if # none is defined in this PPD file - if (!$dat->{'args_byname'}{$argname}{'default'}) { + if (!defined ($dat->{'args_byname'}{$argname}{'default'})) { $dat->{'args_byname'}{$argname}{'default'} = $setting; } } @@ -1652,6 +1663,9 @@ if ((!defined(@{$dat->{'args'}})) || if ($arg->{'fdefault'} > $arg->{'max'}) { $arg->{'fdefault'} = $arg->{'max'}; } + if ($arg->{'type'} eq 'int') { + $arg->{'fdefault'} = POSIX::floor($arg->{'fdefault'}); + } my $mindiff = abs($arg->{'max'} - $arg->{'min'}); my $closestvalue; for my $val (@{$arg->{'vals'}}) { @@ -1936,9 +1950,10 @@ for (@opts) { # Handle the standard duplex option, mostly if ($avalue =~ m!^two-sided!i) { if (defined($dat->{'args_byname'}{'Duplex'})) { - # We set "Duplex" to '1' here, the real argument setting - # will be done later - $dat->{'args_byname'}{'Duplex'}{$optionset} = '1'; + # Default to long-edge binding here, for the case that + # there is no binding setting + $dat->{'args_byname'}{'Duplex'}{$optionset} = + 'DuplexNoTumble'; # Check the binding: "long edge" or "short edge" if ($avalue =~ m!long-edge!i) { if (defined($dat->{'args_byname'}{'Binding'})) { @@ -1946,7 +1961,7 @@ for (@opts) { $dat->{'args_byname'}{'Binding'}{'vals_byname'}{'LongEdge'}{'value'}; } else { $dat->{'args_byname'}{'Duplex'}{$optionset} = - 'LongEdge'; + 'DuplexNoTumble'; } } elsif ($avalue =~ m!short-edge!i) { if (defined($dat->{'args_byname'}{'Binding'})) { @@ -1954,15 +1969,13 @@ for (@opts) { $dat->{'args_byname'}{'Binding'}{'vals_byname'}{'ShortEdge'}{'value'}; } else { $dat->{'args_byname'}{'Duplex'}{$optionset} = - 'ShortEdge'; + 'DuplexTumble'; } } } } elsif ($avalue =~ m!^one-sided!i) { if (defined($dat->{'args_byname'}{'Duplex'})) { - # We set "Duplex" to '0' here, the real argument setting - # will be done later - $dat->{'args_byname'}{'Duplex'}{$optionset} = '0'; + $dat->{'args_byname'}{'Duplex'}{$optionset} = 'None'; } } @@ -2332,6 +2345,9 @@ for $file (@filelist) { my $twolinesbefore = ""; # The line two lines before the current # line (Non-DSC comments are ignored) + my $linesafterlastbeginfeature = ""; # All code lines after the last + # "%%BeginFeature:" + my @psheader = (); # The header of the PostScript file, # to be sent after each start of the # renderer @@ -2452,6 +2468,8 @@ for $file (@filelist) { my $ooo110 = 0; # Flag to work around an application # bug. + my $saved = 0; # DSC line not processed yet + if ($dontparse) { # We do not parse the PostScript to find Foomatic options, we check # only whether we have PostScript. @@ -2466,7 +2484,8 @@ for $file (@filelist) { # determining the last active line # and the one before the last - if (($printprevpage) || ($line=<STDIN>)) { + if (($printprevpage) || ($saved) || ($line=<STDIN>)) { + $saved = 0; if ($linect == $nonpslines) { # In the beginning should be the postscript leader, @@ -2554,537 +2573,571 @@ for $file (@filelist) { } } } else { - if ($line =~ m/^\s*\%\%BeginDocument[: ]/) { - # Beginning of an embedded document - # Note that Adobe Acrobat has a bug and so uses - # "%%BeginDocument " instead of "%%BeginDocument:" - $nestinglevel ++; - print $logh "Embedded document, " . - "nesting level now: $nestinglevel\n"; - } elsif (($line =~ m/^\s*\%\%EndDocument/) && - ($nestinglevel > 0)) { - # End of an embedded document - $nestinglevel --; - print $logh "End of Embedded document, " . - "nesting level now: $nestinglevel\n"; - } elsif (($line =~ m/^\s*\%\%Creator[: ](.*)$/) && - ($nestinglevel == 0)) { - # Here we set flags to treat particular bugs of the - # PostScript produced by certain applications - my $creator = $1; - if ($creator =~ /^\s*OpenOffice.org\s+1.1.\d+\s*$/) { - # OpenOffice.org 1.1.x - # The option settings supposed to affect the - # whole document are put into the "%%PageSetup" - # section of the first page - print $logh "Document created with " . - "OpenOffice.org 1.1.x\n"; - $ooo110 = 1; - } - } elsif (($line =~ m/^\%\%BeginProlog/) && - ($nestinglevel == 0)) { - # Note: Below is another place where a "Prolog" - # section start will be considered. There we assume - # start of the "Prolog" if the job is DSC-Conformimg, - # but an arbitrary comment starting with "%%Begin", but - # not a comment explicitly treated here, is found. This - # is done because many "dvips" (TeX/LaTeX) files miss - # the "%%BeginProlog" comment. - # Beginning of Prolog - print $logh "${added_lf}-----------\nFound: \%\%BeginProlog\n"; - $inprolog = 1; - $postscriptsection = 'prolog' if $inheader; - $nondsclines = 0; - # Insert options for "Prolog" - if (!$prologfound) { - $line .= makeprologsection($dat, $optionset, 0); - } - $prologfound = 1; - } elsif (($line =~ m/^\%\%EndProlog/) && - ($nestinglevel == 0)) { - # End of Prolog - print $logh "Found: \%\%EndProlog\n"; - $inprolog = 0; - $insertoptions = $linect + 1; - } elsif (($line =~ m/^\%\%BeginSetup/) && - ($nestinglevel == 0)) { - # Beginning of Setup - print $logh "${added_lf}-----------\nFound: \%\%BeginSetup\n"; - $insetup = 1; - # We need to distinguish with the $inheader variable - # here whether we are in the header or on a page, as - # OpenOffice.org inserts a "%%BeginSetup...%%EndSetup" - # section after the first "%%Page:..." line and assumes - # this section to be valid for all pages. - $postscriptsection = 'setup' if $inheader; - $nondsclines = 0; - if ($inheader) { - # If there was no "Prolog" but there are - # options for the "Prolog", push a "Prolog" - # with these options onto the @psfifo here - if (!$prologfound) { - # "Prolog" missing, insert it here - $line = makeprologsection($dat, $optionset, 1) . - $line; - # Now we have a "Prolog" - $prologfound = 1; + if ($line =~ /^\%\%/) { + if ($line =~ m/^\s*\%\%BeginDocument[: ]/) { + # Beginning of an embedded document + # Note that Adobe Acrobat has a bug and so uses + # "%%BeginDocument " instead of "%%BeginDocument:" + $nestinglevel ++; + print $logh "Embedded document, " . + "nesting level now: $nestinglevel\n"; + } elsif (($line =~ m/^\s*\%\%EndDocument/) && + ($nestinglevel > 0)) { + # End of an embedded document + $nestinglevel --; + print $logh "End of Embedded document, " . + "nesting level now: $nestinglevel\n"; + } elsif (($line =~ m/^\s*\%\%Creator[: ](.*)$/) && + ($nestinglevel == 0)) { + # Here we set flags to treat particular bugs of the + # PostScript produced by certain applications + my $creator = $1; + if ($creator =~ /^\s*OpenOffice.org\s+1.1.\d+\s*$/) { + # OpenOffice.org 1.1.x + # The option settings supposed to affect the + # whole document are put into the "%%PageSetup" + # section of the first page + print $logh "Document created with " . + "OpenOffice.org 1.1.x\n"; + $ooo110 = 1; } - # Insert options for "DocumentSetup" or "AnySetup" - if ($spooler ne 'cups') { - # For non-CUPS spoolers or no spooler at all, we leave - # everything as it is. - if (!$setupfound) { - $line .= makesetupsection($dat, $optionset, 0); - } - $setupfound = 1; + } elsif (($line =~ m/^\%\%BeginProlog/) && + ($nestinglevel == 0)) { + # Note: Below is another place where a "Prolog" + # section start will be considered. There we assume + # start of the "Prolog" if the job is DSC-Conformimg, + # but an arbitrary comment starting with "%%Begin", but + # not a comment explicitly treated here, is found. This + # is done because many "dvips" (TeX/LaTeX) files miss + # the "%%BeginProlog" comment. + # Beginning of Prolog + print $logh "${added_lf}-----------\nFound: \%\%BeginProlog\n"; + $inprolog = 1; + $postscriptsection = 'prolog' if $inheader; + $nondsclines = 0; + # Insert options for "Prolog" + if (!$prologfound) { + $line .= makeprologsection($dat, $optionset, 0); } - } else { - # Found option settings must be stuffed into both - # the header and the currrent page now. They will - # be written into both the "header" and the - # "currentpage" optionsets and the PostScript code - # lines of this section will not only go into the - # output stream, but also added to the end of the - # @psheader, so that they get repeated (to preserve - # the embedded PostScript option settings) on a - # restart of the renderer due to command line - # option changes - $optionsalsointoheader = 1; - print $logh "\"%%BeginSetup\" in page header\n"; - } - } elsif (($line =~ m/^\%\%EndSetup/) && - ($nestinglevel == 0)) { - # End of Setup - print $logh "Found: \%\%EndSetup\n"; - $insetup = 0; - if ($inheader) { - if ($spooler eq 'cups') { - # In case of CUPS, we must insert the - # accounting stuff just before the - # %%EndSetup comment in order to leave any - # EndPage procedures that have been - # defined by either the pstops filter or - # the PostScript job itself fully - # functional. - if (!$setupfound) { - $line = makesetupsection($dat, - $optionset, 0) . - $line; - } - $setupfound = 1; - } + $prologfound = 1; + } elsif (($line =~ m/^\%\%EndProlog/) && + ($nestinglevel == 0)) { + # End of Prolog + print $logh "Found: \%\%EndProlog\n"; + $inprolog = 0; $insertoptions = $linect + 1; - } else { - # The "%%BeginSetup...%%EndSetup" which - # OpenOffice.org has inserted after the first - # "%%Page:..." line ends here, so the following - # options go only onto the current page again - $optionsalsointoheader = 0; - } - } elsif (($line =~ m/^\%\%Page:(.*)$/) && - ($nestinglevel == 0)) { - if ((!$lastpassthru) && (!$inheader)) { - # In the last line we were not in passthru mode, - # so the last page is not printed. Prepare to do - # it now. - $printprevpage = 1; - # Print the previous page - $passthru = 1; - print $logh "New page found but previous not " . - "printed, print it now.\n"; - } else { - # The previous page is printed, so we can prepare - # the current one - $printprevpage = 0; - print $logh "${added_lf}-----------\nNew page: $1\n"; - # Count pages - $currentpage ++; - # We consider the beginning of the page already as - # page setup section, as some apps do not use - # "%%PageSetup" tags. - $postscriptsection = 'pagesetup'; - # Save PostScript state before beginning the page - #$line .= "/foomatic-saved-state save def\n"; - # Here begins a new page + } elsif (($line =~ m/^\%\%BeginSetup/) && + ($nestinglevel == 0)) { + # Beginning of Setup + print $logh "${added_lf}-----------\nFound: \%\%BeginSetup\n"; + $insetup = 1; + # We need to distinguish with the $inheader variable + # here whether we are in the header or on a page, as + # OpenOffice.org inserts a "%%BeginSetup...%%EndSetup" + # section after the first "%%Page:..." line and assumes + # this section to be valid for all pages. + $postscriptsection = 'setup' if $inheader; + $nondsclines = 0; if ($inheader) { - # Here we add some stuff which still belongs - # into the header - my $stillforheader; - # If there was no "Setup" but there are - # options for the "Setup", push a "Setup" - # with these options onto the @psfifo here - if (!$setupfound) { - # "Setup" missing, insert it here - $stillforheader = - makesetupsection($dat, $optionset, 1) . - $stillforheader; - # Now we have a "Setup" - $setupfound = 1; - } # If there was no "Prolog" but there are # options for the "Prolog", push a "Prolog" # with these options onto the @psfifo here if (!$prologfound) { # "Prolog" missing, insert it here - $stillforheader = + $line = makeprologsection($dat, $optionset, 1) . - $stillforheader; + $line; # Now we have a "Prolog" $prologfound = 1; } - # Now we push this onto the header - push (@psheader, $stillforheader); - # The first page starts, so the header ends - $inheader = 0; - $nondsclines = 0; - # Option setting should go into the - # page-specific option set now - $optionset = 'currentpage'; + # Insert options for "DocumentSetup" or "AnySetup" + if ($spooler ne 'cups') { + # For non-CUPS spoolers or no spooler at all, + # we leave everything as it is. + if (!$setupfound) { + $line .= + makesetupsection($dat, $optionset, 0); + } + $setupfound = 1; + } } else { - # Restore PostScript state after completing the - # previous page: - # - # foomatic-saved-state restore - # %%Page: ... - # /foomatic-saved-state save def - # - # Print this directly, so that if we need to - # restart the renderer for this page due to - # a command line change this is done under the - # old instance of the renderer - #print $rendererhandle - # "foomatic-saved-state restore\n"; - - # Save the option settings of the previous page - copyoptions($dat, 'currentpage', - 'previouspage'); - deleteoptions($dat, 'currentpage'); + # Found option settings must be stuffed into both + # the header and the currrent page now. They will + # be written into both the "header" and the + # "currentpage" optionsets and the PostScript code + # lines of this section will not only go into the + # output stream, but also added to the end of the + # @psheader, so that they get repeated (to preserve + # the embedded PostScript option settings) on a + # restart of the renderer due to command line + # option changes + $optionsalsointoheader = 1; + print $logh "\"%%BeginSetup\" in page header\n"; } - # Initialize the option set - copyoptions($dat, 'header', 'currentpage'); - # Set command line options which apply only - # given pages - setoptionsforpage($dat, 'currentpage', $currentpage); - $pagesetupfound = 0; - if ($spooler eq 'cups') { - # Remove the "notfirst" flag from all options - # forseen for the "PageSetup" section, because - # when these are numerical options for CUPS. - # they have to be set to the correct value - # for every page - for my $arg (@{$dat->{'args'}}) { - if (($arg->{'section'} eq 'PageSetup') && - (defined($arg->{'notfirst'}))) { - delete($arg->{'notfirst'}); + } elsif (($line =~ m/^\%\%EndSetup/) && + ($nestinglevel == 0)) { + # End of Setup + print $logh "Found: \%\%EndSetup\n"; + $insetup = 0; + if ($inheader) { + if ($spooler eq 'cups') { + # In case of CUPS, we must insert the + # accounting stuff just before the + # %%EndSetup comment in order to leave any + # EndPage procedures that have been + # defined by either the pstops filter or + # the PostScript job itself fully + # functional. + if (!$setupfound) { + $line = makesetupsection($dat, + $optionset, 0) . + $line; } + $setupfound = 1; } + $insertoptions = $linect + 1; + } else { + # The "%%BeginSetup...%%EndSetup" which + # OpenOffice.org has inserted after the first + # "%%Page:..." line ends here, so the following + # options go only onto the current page again + $optionsalsointoheader = 0; } - # Insert PostScript option settings - # (options for section "PageSetup". - if ($isdscjob) { - $line .= - makepagesetupsection($dat, $optionset, - 0); - $pagesetupfound = 1; + } elsif (($line =~ m/^\%\%Page:(.*)$/) && + ($nestinglevel == 0)) { + if ((!$lastpassthru) && (!$inheader)) { + # In the last line we were not in passthru mode, + # so the last page is not printed. Prepare to do + # it now. + $printprevpage = 1; + # Print the previous page + $passthru = 1; + print $logh "New page found but previous not " . + "printed, print it now.\n"; + } else { + # The previous page is printed, so we can prepare + # the current one + $printprevpage = 0; + print $logh "${added_lf}-----------\nNew page: $1\n"; + # Count pages + $currentpage ++; + # We consider the beginning of the page already as + # page setup section, as some apps do not use + # "%%PageSetup" tags. + $postscriptsection = 'pagesetup'; + # Save PostScript state before beginning the page + #$line .= "/foomatic-saved-state save def\n"; + # Here begins a new page + if ($inheader) { + # Here we add some stuff which still belongs + # into the header + my $stillforheader; + # If there was no "Setup" but there are + # options for the "Setup", push a "Setup" + # with these options onto the @psfifo here + if (!$setupfound) { + # "Setup" missing, insert it here + $stillforheader = + makesetupsection($dat, $optionset, 1) . + $stillforheader; + # Now we have a "Setup" + $setupfound = 1; + } + # If there was no "Prolog" but there are + # options for the "Prolog", push a "Prolog" + # with these options onto the @psfifo here + if (!$prologfound) { + # "Prolog" missing, insert it here + $stillforheader = + makeprologsection($dat, $optionset, + 1) . + $stillforheader; + # Now we have a "Prolog" + $prologfound = 1; + } + # Now we push this onto the header + push (@psheader, $stillforheader); + # The first page starts, so the header ends + $inheader = 0; + $nondsclines = 0; + # Option setting should go into the + # page-specific option set now + $optionset = 'currentpage'; + } else { + # Restore PostScript state after completing the + # previous page: + # + # foomatic-saved-state restore + # %%Page: ... + # /foomatic-saved-state save def + # + # Print this directly, so that if we need to + # restart the renderer for this page due to + # a command line change this is done under the + # old instance of the renderer + #print $rendererhandle + # "foomatic-saved-state restore\n"; + + # Save the option settings of the previous page + copyoptions($dat, 'currentpage', + 'previouspage'); + deleteoptions($dat, 'currentpage'); + } + # Initialize the option set + copyoptions($dat, 'header', 'currentpage'); + # Set command line options which apply only + # given pages + setoptionsforpage($dat, 'currentpage', $currentpage); + $pagesetupfound = 0; + if ($spooler eq 'cups') { + # Remove the "notfirst" flag from all options + # forseen for the "PageSetup" section, because + # when these are numerical options for CUPS. + # they have to be set to the correct value + # for every page + for my $arg (@{$dat->{'args'}}) { + if (($arg->{'section'} eq 'PageSetup') && + (defined($arg->{'notfirst'}))) { + delete($arg->{'notfirst'}); + } + } + } + # Insert PostScript option settings + # (options for section "PageSetup". + if ($isdscjob) { + $line .= + makepagesetupsection($dat, $optionset, + 0); + $pagesetupfound = 1; + } + # Now the page header comes, so buffer the data, + # because we must perhaps shut down and restart + # the renderer + $passthru = 0; + $ignorepageheader = 0; + $optionsalsointoheader = 0; } - # Now the page header comes, so buffer the data, - # because we must perhaps shut down and restart - # the renderer + } elsif (($line =~ m/^\%\%BeginPageSetup/) && + ($nestinglevel == 0) && + (!$ignorepageheader)) { + # Start of the page header, up to %%EndPageSetup + # nothing of the page will be drawn, page-specific + # option settngs (as letter-head paper for page 1) + # go here + print $logh "${added_lf}Found: \%\%BeginPageSetup\n"; $passthru = 0; - $ignorepageheader = 0; - $optionsalsointoheader = 0; - } - } elsif (($line =~ m/^\%\%BeginPageSetup/) && - ($nestinglevel == 0) && - (!$ignorepageheader)) { - # Start of the page header, up to %%EndPageSetup - # nothing of the page will be drawn, page-specific - # option settngs (as letter-head paper for page 1) - # go here - print $logh "${added_lf}Found: \%\%BeginPageSetup\n"; - $passthru = 0; - $inpageheader = 1; - $postscriptsection = 'pagesetup'; - if (($ooo110) && ($currentpage == 1)) { - $optionsalsointoheader = 1; - } else { + $inpageheader = 1; + $postscriptsection = 'pagesetup'; + if (($ooo110) && ($currentpage == 1)) { + $optionsalsointoheader = 1; + } else { + $optionsalsointoheader = 0; + } + } elsif (($line =~ m/^\%\%EndPageSetup/) && + ($nestinglevel == 0) && + (!$ignorepageheader)) { + # End of the page header, the page is ready to be + # printed + print $logh "Found: \%\%EndPageSetup\n"; + print $logh "End of page header\n"; + # We cannot for sure say that the page header ends here + # OpenOffice.org puts (due to a bug) a "%%BeginSetup... + # %%EndSetup" section after the first "%%Page:...". It + # is possible that CUPS inserts a "%%BeginPageSetup... + # %%EndPageSetup" before this section, which means that + # the options in the "%%BeginSetup...%%EndSetup" + # section are after the "%%EndPageSetup", so we + # continue for searching options up to the buffer size + # limit $maxlinesforpageoptions. + $passthru = 0; + $inpageheader = 0; $optionsalsointoheader = 0; - } - } elsif (($line =~ m/^\%\%EndPageSetup/) && - ($nestinglevel == 0) && - (!$ignorepageheader)) { - # End of the page header, the page is ready to be - # printed - print $logh "Found: \%\%EndPageSetup\n"; - print $logh "End of page header\n"; - # We cannot for sure say that the page header ends here - # OpenOffice.org puts (due to a bug) a "%%BeginSetup... - # %%EndSetup" section after the first "%%Page:...". It - # is possible that CUPS inserts a "%%BeginPageSetup... - # %%EndPageSetup" before this section, which means that - # the options in the "%%BeginSetup...%%EndSetup" section - # are after the "%%EndPageSetup", so we continue for - # searching options up to the buffer size limit - # $maxlinesforpageoptions. - $passthru = 0; - $inpageheader = 0; - $optionsalsointoheader = 0; - } elsif ((($line =~ m/^\%\%(BeginFeature):\s*\*?([^\*\s=]+)\s+()(\S[^\r\n]*)\r?\n?$/) || - ($line =~ m/^\s*\%\%\s*(FoomaticRIPOptionSetting):\s*([^\*\s=]+)\s*=\s*(\@?)([^\@\s][^\r\n]*)\r?\n?$/)) && - ($nestinglevel == 0) && - (!$optionreplaced) && - ((!$passthru) || (!$isdscjob))) { - my ($linetype, $option, $fromcomposite, $value) = - ($1, $2, $3, $4); - - # Mark that we are in a "Feature" section - if ($linetype eq 'BeginFeature') { - $infeature = 1; - } - - # OK, we have an option. If it's not a - # *ostscript-style option (ie, it's command-line or - # JCL) then we should note that fact, since the - # attribute-to-filter option passing in CUPS is kind of - # funky, especially wrt boolean options. - - print $logh "Found: $line"; - if (my $arg=argbyname($option)) { - print $logh " Option: $option=" . - ($fromcomposite ? "From" : "") . $value; - if (($spooler eq 'cups') && - ($linetype eq 'BeginFeature') && - (!defined($arg->{'notfirst'})) && - ($arg->{$optionset} ne $value) && - (($inheader) || - ($arg->{section} eq 'PageSetup'))) { - # We have the first occurence of an - # option setting and the spooler is CUPS, - # so this setting is inserted by "pstops". - # The value from the command line was not - # inserted by "pstops" so it seems to be - # not under the choices in the PPD. - # Possible reasons: - # - # - "pstops" ignores settings of numerical - # or string options which are not one of - # the choices in the PPD file, and inserts - # the default value instead. - # - # - On the command line an option was applied - # only to selected pages: - # "-o <page ranges>:<option>=<values> - # This is not supported by CUPS, so not - # taken care of by "pstops". - # - # We must fix this here by replacing the setting - # inserted by "pstops" with the exact setting - # given on the command line. - - # $arg->{$optionset} is already - # range-checked, so do not check again here - # Insert DSC comment - my $dest = ((($inheader) && ($isdscjob)) ? - \@psheader : \@psfifo); - push(@{$dest}, - "%%BeginFeature: " . - "*$option $arg->{$optionset}\n"); - my $val; - if ($arg->{'style'} eq 'G') { - # PostScript option, insert the code - if ($arg->{'type'} eq 'bool') { - # Boolean option - if (defined($arg->{$optionset}) && - $arg->{$optionset} == 1) { - push(@{$dest}, $arg->{'proto'} . "\n"); - } elsif ($arg->{'protof'}) { - push(@{$dest}, $arg->{'protof'}. "\n"); + } elsif ((($line =~ m/^\%\%(BeginFeature):\s*\*?([^\*\s=]+)\s+()(\S[^\r\n]*)\r?\n?$/) || + ($line =~ m/^\s*\%\%\s*(FoomaticRIPOptionSetting):\s*([^\*\s=]+)\s*=\s*(\@?)([^\@\s][^\r\n]*)\r?\n?$/)) && + ($nestinglevel == 0) && + (!$optionreplaced) && + ((!$passthru) || (!$isdscjob))) { + my ($linetype, $option, $fromcomposite, $value) = + ($1, $2, $3, $4); + + # Mark that we are in a "Feature" section + if ($linetype eq 'BeginFeature') { + $infeature = 1; + $linesafterlastbeginfeature = ""; + } + + # OK, we have an option. If it's not a + # *ostscript-style option (ie, it's command-line or + # JCL) then we should note that fact, since the + # attribute-to-filter option passing in CUPS is kind of + # funky, especially wrt boolean options. + + print $logh "Found: $line"; + if (my $arg=argbyname($option)) { + print $logh " Option: $option=" . + ($fromcomposite ? "From" : "") . $value; + if (($spooler eq 'cups') && + ($linetype eq 'BeginFeature') && + (!defined($arg->{'notfirst'})) && + ($arg->{$optionset} ne $value) && + (($inheader) || + ($arg->{section} eq 'PageSetup'))) { + + # We have the first occurence of an option + # setting and the spooler is CUPS, so this + # setting is inserted by "pstops" or + # "imagetops". The value from the command + # line was not inserted by "pstops" or + # "imagetops" so it seems to be not under + # the choices in the PPD. Possible + # reasons: + # + # - "pstops" and "imagetops" ignore settings + # of numerical or string options which are + # not one of the choices in the PPD file, + # and inserts the default value instead. + # + # - On the command line an option was applied + # only to selected pages: + # "-o <page ranges>:<option>=<values> + # This is not supported by CUPS, so not + # taken care of by "pstops". + # + # We must fix this here by replacing the + # setting inserted by "pstops" or "imagetops" + # with the exact setting given on the command + # line. + + # $arg->{$optionset} is already + # range-checked, so do not check again here + # Insert DSC comment + my $dest = ((($inheader) && ($isdscjob)) ? + \@psheader : \@psfifo); + my $val; + if ($arg->{'style'} eq 'G') { + # PostScript option, insert the code + if ($arg->{'type'} eq 'bool') { + # Boolean option + push(@{$dest}, + "%%BeginFeature: *$option " . + ($arg->{$optionset} == 1 ? + "True" : "False") . "\n"); + if (defined($arg->{$optionset}) && + $arg->{$optionset} == 1) { + push(@{$dest}, $arg->{'proto'} . + "\n"); + } elsif ($arg->{'protof'}) { + push(@{$dest}, $arg->{'protof'} . + "\n"); + } + } elsif ((($arg->{'type'} eq 'enum') || + ($arg->{'type'} eq 'string') || + ($arg->{'type'} eq + 'password')) && + (defined($val = + $arg->{'vals_byname'}{$arg->{$optionset}}))) { + # Enumerated choice of string or enum + # option + push(@{$dest}, + "%%BeginFeature: " . + "*$option $arg->{$optionset}\n"); + push(@{$dest}, $val->{'driverval'} . "\n"); + } elsif ((($arg->{'type'} eq 'string') || + ($arg->{'type'} eq + 'password')) && + ($arg->{$optionset} eq 'None')) { + # 'None' is mapped to the empty string + # in string options + push(@{$dest}, + "%%BeginFeature: " . + "*$option $arg->{$optionset}\n"); + my $driverval = $arg->{'proto'}; + $driverval =~ s/\%s//g; + push(@{$dest}, $driverval . "\n"); + } else { + # Setting for numerical or string + # option which is not under the + # enumerated choices + push(@{$dest}, + "%%BeginFeature: " . + "*$option $arg->{$optionset}\n"); + my $sprintfproto = $arg->{'proto'}; + $sprintfproto =~ s/\%(?!s)/\%\%/g; + push(@{$dest}, + sprintf($sprintfproto, + $arg->{$optionset}) . + "\n"); } - } elsif ((($arg->{'type'} eq 'enum') || - ($arg->{'type'} eq 'string') || - ($arg->{'type'} eq 'password')) && - (defined($val = - $arg->{'vals_byname'}{$arg->{$optionset}}))) { - # Enumerated choice of string or enum - # option - push(@{$dest}, $val->{'driverval'} . "\n"); - } elsif ((($arg->{'type'} eq 'string') || - ($arg->{'type'} eq 'password')) && - ($arg->{$optionset} eq 'None')) { - # 'None' is mapped to the empty string in - # string options - my $driverval = $arg->{'proto'}; - $driverval =~ s/\%s//g; - push(@{$dest}, $driverval . "\n"); } else { - # Setting for numerical or string option - # which is not under the enumerated choices - my $sprintfproto = $arg->{'proto'}; - $sprintfproto =~ s/\%(?!s)/\%\%/g; + # Command line or JCL option push(@{$dest}, - sprintf($sprintfproto, - $arg->{$optionset}) . - "\n"); + "%% FoomaticRIPOptionSetting: " . + "$option=$arg->{$optionset}\n"); } - } else { - # Command line or JCL option - push(@{$dest}, - "%% FoomaticRIPOptionSetting: " . - "$option=$arg->{$optionset}\n"); + print $logh " --> Correcting numerical/string " . + "option to $option=$arg->{$optionset}" . + " (Command line argument)\n"; + # We have replaced this option on the + # FIFO + $optionreplaced = 1; } - print $logh " --> Correcting numerical/string " . - "option to $option=$arg->{$optionset}" . - " (Command line argument)\n"; - # We have replaced this option on the - # FIFO - $optionreplaced = 1; - } - # Mark that we have already found this option - $arg->{'notfirst'} = 1; - if (!$optionreplaced) { - if ($arg->{'style'} ne 'G') { - # "Controlled by '<Composite>'" setting of - # a member option of a composite option - if ($fromcomposite) { - $value = "From$value"; - } - # Non-PostScript option - # Check whether it is valid - if (defined(my $newvalue = - checkoptionvalue($dat, $option, - $value, 0))) { - print $logh " --> Setting option\n"; - # Valid choice, set it. - $arg->{$optionset} = $newvalue; - if ($optionsalsointoheader) { - $arg->{'header'} = $newvalue; + # Mark that we have already found this option + $arg->{'notfirst'} = 1; + if (!$optionreplaced) { + if ($arg->{'style'} ne 'G') { + # "Controlled by '<Composite>'" setting of + # a member option of a composite option + if ($fromcomposite) { + $value = "From$value"; } - if (($arg->{'type'} eq 'enum') && - (($option eq 'PageSize') || - ($option eq 'PageRegion')) && - ($newvalue =~ /^Custom/) && - ($linetype eq - 'FoomaticRIPOptionSetting')) { - # Custom page size - $twolinesbefore =~ - /^\s*([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s*$/; - my ($w, $h) = ($1, $2); - if (($w) && ($h) && - ($w != 0) && ($h != 0)) { - $newvalue = "$newvalue.${w}x$h"; - $arg->{$optionset} = $newvalue; - if ($optionsalsointoheader) { - $arg->{'header'} = - $newvalue; + # Non-PostScript option + # Check whether it is valid + if (defined(my $newvalue = + checkoptionvalue($dat, $option, + $value, 0))) { + print $logh " --> Setting option\n"; + # Valid choice, set it. + $arg->{$optionset} = $newvalue; + if ($optionsalsointoheader) { + $arg->{'header'} = $newvalue; + } + if (($arg->{'type'} eq 'enum') && + (($option eq 'PageSize') || + ($option eq 'PageRegion')) && + ($newvalue =~ /^Custom/) && + ($linetype eq + 'FoomaticRIPOptionSetting')) { + # Custom page size + $linesafterlastbeginfeature =~ + /^[\s\r\n]*([\d\.]+)[\s\r\n]+([\d\.]+)[\s\r\n]+/s; + my ($w, $h) = ($1, $2); + if (($w) && ($h) && + ($w != 0) && ($h != 0)) { + $newvalue = + "$newvalue.${w}x$h"; + $arg->{$optionset} = $newvalue; + if ($optionsalsointoheader) { + $arg->{'header'} = + $newvalue; + } } } + # For a composite option insert the + # code from the member options with + # current setting "From<composite>" + # The code from the member options + # is chosen according to the setting + # of the composite option. + if (($arg->{'style'} eq 'X') && + ($linetype eq + 'FoomaticRIPOptionSetting')) { + buildcommandline($dat, $optionset); + $line .= + $arg->{$postscriptsection}; + } + # If this argument is PageSize or + # PageRegion, also set the other + syncpagesize($dat, $option, $newvalue, + $optionset); + if ($optionsalsointoheader) { + syncpagesize($dat, $option, + $newvalue, 'header'); + } + } else { + # Invalid option, log it. + print $logh " --> Invalid option " . + "setting found in job\n"; } - # For a composite option insert the - # code from the member options with - # current setting "From<composite>" - # The code from the member options - # is chosen according to the setting - # of the composite option. - if (($arg->{'style'} eq 'X') && - ($linetype eq - 'FoomaticRIPOptionSetting')) { + } elsif ($fromcomposite) { + # PostScript option, but we have to look up + # the PostScript code to be inserted from + # the setting of a composite option, as + # this option is set to "Controlled by + # '<Composite>'". + # Set the option + if (defined(my $newvalue = + checkoptionvalue + ($dat, $option, + "From$value", 0))) { + print $logh " --> Looking up setting " . + "in composite option '$value'\n"; + # Valid choice, set it. + $arg->{$optionset} = $newvalue; + if ($optionsalsointoheader) { + $arg->{'header'} = $newvalue; + } + # Update composite options buildcommandline($dat, $optionset); - $line .= $arg->{$postscriptsection}; + # Substitute PostScript comment by + # the real code + $line = $arg->{'compositesubst'}; + } else { + # Invalid option, log it. + print $logh " --> Invalid option " . + "setting found in job\n"; } - # If this argument is PageSize or - # PageRegion, also set the other - syncpagesize($dat, $option, $newvalue, - $optionset); - if ($optionsalsointoheader) { - syncpagesize($dat, $option, - $newvalue, 'header'); - } - } else { - # Invalid option, log it. - print $logh " --> Invalid option " . - "setting found in job\n"; - } - } elsif ($fromcomposite) { - # PostScript option, but we have to look up - # the PostScript code to be inserted from - # the setting of a composite option, as this - # option is set to "Controlled by - # '<Composite>'". - # Set the option - if (defined(my $newvalue = - checkoptionvalue - ($dat, $option, - "From$value", 0))) { - print $logh " --> Looking up setting " . - "in composite option '$value'\n"; - # Valid choice, set it. - $arg->{$optionset} = $newvalue; - if ($optionsalsointoheader) { - $arg->{'header'} = $newvalue; - } - # Update composite options - buildcommandline($dat, $optionset); - # Substitute PostScript comment by - # the real code - $line = $arg->{'compositesubst'}; } else { - # Invalid option, log it. - print $logh " --> Invalid option " . - "setting found in job\n"; + # it is a PostScript style option with + # the code readily inserted, no option + # for the renderer command line/JCL to set, + # no lookup of a composite option needed, + # so nothing to do here... + print $logh + " --> Option will be set by " . + "PostScript interpreter\n"; } - } else { - # it is a PostScript style option with - # the code readily inserted, no option - # for the renderer command line/JCL to set, - # no lookup of a composite option needed, - # so nothing to do here... - print $logh - " --> Option will be set by " . - "PostScript interpreter\n"; } + } else { + # This option is unknown to us. WTF? + print $logh "Unknown option $option=$value found " . + "in the job\n"; } - } else { - # This option is unknown to us. WTF? - print $logh "Unknown option $option=$value found " . - "in the job\n"; - } - } elsif (($line =~ m/^\%\%EndFeature/) && - ($nestinglevel == 0)) { - # End of Feature - $infeature = 0; - # If the option setting was replaced, it ends here, too, - # end the next option is not necessarily also replaced. - $optionreplaced = 0; - } elsif (($line =~ m/^\%\%Begin/) && - ($isdscjob) && - (!$prologfound) && - ($nestinglevel == 0)) { - # In some PostScript files (especially when generated - # by "dvips" of TeX/LaTeX) the "%%BeginProlog" is - # missing, so assume that it was before the current - # line (the first line starting with "%%Begin". - print $logh "Job claims to be DSC-conforming, but " . - "\"%%BeginProlog\" was missing before first " . - "line with another \"%%Begin...\" comment " . - "(is this a TeX/LaTeX/dvips-generated PostScript " . - "file?). Assuming start of \"Prolog\" here.\n"; - # Beginning of Prolog - $inprolog = 1; - $nondsclines = 0; - # Insert options for "Prolog" before the current line - if (!$prologfound) { - $line = - "%%BeginProlog\n" . - makeprologsection($dat, $optionset, 0) . - $line; + } elsif (($line =~ m/^\%\%EndFeature/) && + ($nestinglevel == 0)) { + # End of Feature + $infeature = 0; + # If the option setting was replaced, it ends here, + # too, and the next option is not necessarily also + # replaced. + $optionreplaced = 0; + $linesafterlastbeginfeature = ""; + } elsif (($line =~ m/^\%\%Begin/) && + ($isdscjob) && + (!$prologfound) && + ($nestinglevel == 0)) { + # In some PostScript files (especially when generated + # by "dvips" of TeX/LaTeX) the "%%BeginProlog" is + # missing, so assume that it was before the current + # line (the first line starting with "%%Begin". + print $logh "Job claims to be DSC-conforming, but " . + "\"%%BeginProlog\" was missing before first " . + "line with another \"%%Begin...\" comment " . + "(is this a TeX/LaTeX/dvips-generated PostScript " . + "file?). Assuming start of \"Prolog\" here.\n"; + # Beginning of Prolog + $inprolog = 1; + $nondsclines = 0; + # Insert options for "Prolog" before the current line + if (!$prologfound) { + $line = + "%%BeginProlog\n" . + makeprologsection($dat, $optionset, 0) . + $line; + } + $prologfound = 1; + } elsif (($line =~ m/^\s*\%/) || ($line =~ m/^\s*$/)) { + # This is an unknown PostScript comment or a blank + # line, no active code + $ignoreline = 1; } - $prologfound = 1; - } elsif (($line =~ m/^\s*\%/) || ($line =~ m/^\s*$/)) { - # This is an unknown PostScript comment or a blank line, - # no active code - $ignoreline = 1; } else { # This line is active PostScript code + if ($infeature) { + # Collect coe in a "%%BeginFeature: ... %%EndFeature" + # section, to get the values for a custom option + # setting + $linesafterlastbeginfeature .= $line; + } if ($inheader) { if ((!$inprolog) && (!$insetup)) { # Outside the "Prolog" and "Setup" section @@ -3151,10 +3204,10 @@ for $file (@filelist) { # Debug info if ($lastpassthru != $passthru) { if ($passthru) { - print $logh "Found:\n $line" . + print $logh "Found: $line" . " --> Output goes directly to the renderer now.\n${added_lf}"; } else { - print $logh "Found:\n $line" . + print $logh "Found: $line" . " --> Output goes to the FIFO buffer now.${added_lf}\n"; } } @@ -3221,6 +3274,19 @@ for $file (@filelist) { # Send line to renderer if (!$printprevpage) { print $rendererhandle $line; + + while ($line=<STDIN>) + { + if ($line =~ /^\%\%[A-Za-z\s]{3,}/) { + print $logh "Found: $line" . + " --> Continue DSC parsing now.${added_lf}\n"; + $saved = 1; + last; + } else { + print $rendererhandle $line; + $linect++; + } + } } } else { # Push the line onto the stack for later spitting up... @@ -3773,6 +3839,7 @@ sub getrendererhandle { # value $line =~ /^([^=]+)/; my $cmd = $1; + $cmd =~ s/^\s*(.*?)\s*$/$1/; my $cmdfound = 0; for (@jclheader) { # If the command is there, replace it @@ -3824,8 +3891,9 @@ sub getrendererhandle { } # The rest of the job data - while (<KID4_IN>) { - print $fileh $_; + my $buf; + while (read(KID4_IN, $buf, 1024)) { + print $fileh $buf; } # A JCL trailer @@ -4005,7 +4073,7 @@ sub getfileconverterhandle { # CUPS can stuff the default settings into the PostScript output # of the file converter (so all CUPS settings get also applied when # one prints the documentation pages (all other files we get - # already converted to PostScript by CUPS. + # already converted to PostScript by CUPS). if ($spooler eq 'cups') { $fileconverter .= " | ${programdir}pstops '$rargs[0]' '$rargs[1]' '$rargs[2]' " . @@ -4195,8 +4263,9 @@ sub getfileconverterhandle { # filter print KID2 $alreadyread; # Then read the rest from standard input - while (<STDIN>) { - print KID2 $_; + my $buf; + while (read(STDIN, $buf, 1024)) { + print KID2 $buf; } if (!close STDIN && $! != $ESPIPE) { @@ -4847,6 +4916,12 @@ sub rip_die { } else { print STDERR $message . "\n"; } + if ($debug) { + use Data::Dumper; + local $Data::Dumper::Purity=1; + local $Data::Dumper::Indent=1; + print $logh Dumper($dat); + } exit $exitstat; } @@ -5116,7 +5191,11 @@ sub checkoptionvalue { ($arg->{'type'} eq 'float')) { if (($value <= $arg->{'max'}) && ($value >= $arg->{'min'})) { + if ($arg->{'type'} eq 'int') { + return POSIX::floor($value); + } else { return $value; + } } elsif ($forcevalue) { my $name = $arg->{'name'}; my $newvalue; @@ -5462,8 +5541,6 @@ sub parsepageranges { my $currentnumber = 0; my $rangestart = 0; -####### Question: is rangeend ever used? - my $rangeend = 0; my $currentkeyword = ''; my $invalidrange = 0; my $totalscore = 0; @@ -5537,8 +5614,7 @@ sub parsepageranges { } } elsif ($c =~ /[a-z_]/i) { # Letter or underscore - if (($rangestart > 0) || ($rangeend > 0) || - ($currentnumber > 0)) { + if (($rangestart > 0) || ($currentnumber > 0)) { # Keyword not allowed after a page number or a # page range $invalidrange = 1; @@ -5587,10 +5663,10 @@ sub setoptionsforpage { # number of the page my ($dat, $optionset, $page) = @_; - my $bestscore = 10000000; my $value; for my $arg (@{$dat->{'args'}}) { $value = ''; + my $bestscore = 10000000; for my $key (keys %{$arg}) { next if $key !~ /^pages:(.*)$/; my $pageranges = $1; @@ -5754,8 +5830,8 @@ sub buildcommandline { # Custom paper size $val = valbyname($arg,"Custom"); $found = 1; - } elsif ($userval eq '0') { - foreach (qw(No Off False None)) { + } elsif ($userval =~ /^(0|No|Off|False)$/i) { + foreach (qw(0 No Off False None)) { if ($val=valbyname($arg,$_)) { $userval = $_; $arg->{$optionset} = $userval; @@ -5763,8 +5839,8 @@ sub buildcommandline { last; } } - } elsif ($userval eq '1') { - foreach (qw(Yes On True)) { + } elsif ($userval =~ /^(1|Yes|On|True)$/i) { + foreach (qw(1 Yes On True)) { if ($val=valbyname($arg,$_)) { $userval = $_; $arg->{$optionset} = $userval; @@ -5772,7 +5848,7 @@ sub buildcommandline { last; } } - } elsif ($userval eq 'LongEdge') { + } elsif ($userval =~ /^(LongEdge|DuplexNoTumble)$/i) { # Handle different names for the choices of the # "Duplex" option foreach (qw(LongEdge DuplexNoTumble)) { @@ -5783,7 +5859,7 @@ sub buildcommandline { last; } } - } elsif ($userval eq 'ShortEdge') { + } elsif ($userval =~ /^(ShortEdge|DuplexTumble)$/i) { foreach (qw(ShortEdge DuplexTumble)) { if ($val=valbyname($arg,$_)) { $userval = $_; @@ -5826,7 +5902,8 @@ sub buildcommandline { # Custom page size for PostScript printers $cmdvar = "$width $height 0 0 0\n$cmdvar"; } else { - # Custom page size for Foomatic/Gimp-Print + # Custom page size for Foomatic/Gutenprint/ + # Gimp-Print $cmdvar =~ s/\%0/$width/ or $cmdvar =~ s/(\W)0(\W)/$1$width$2/ or $cmdvar =~ s/^0(\W)/$width$1/m or @@ -5876,7 +5953,12 @@ sub buildcommandline { # Place this Postscript command onto the prepend queue # for the appropriate section. if ($cmdvar) { - my $open = "[{\n%%BeginFeature: *$name $userval\n"; + my $open = "[{\n%%BeginFeature: *$name "; + if ($type eq 'bool') { + $open .= ($userval == 1 ? "True" : "False") . "\n"; + } else { + $open .= "$userval\n"; + } my $close = "\n%%EndFeature\n} stopped cleartomark\n"; if ($section eq "Prolog") { push (@prologprepend, "$open$cmdvar$close"); |