summaryrefslogtreecommitdiff
path: root/src/foomatic/foomatic-generator.in
diff options
context:
space:
mode:
Diffstat (limited to 'src/foomatic/foomatic-generator.in')
-rw-r--r--src/foomatic/foomatic-generator.in909
1 files changed, 810 insertions, 99 deletions
diff --git a/src/foomatic/foomatic-generator.in b/src/foomatic/foomatic-generator.in
index 57950aa..b5b3f7a 100644
--- a/src/foomatic/foomatic-generator.in
+++ b/src/foomatic/foomatic-generator.in
@@ -1,10 +1,48 @@
#!@PERL@
+# Get command line options
+use Getopt::Long;
+Getopt::Long::Configure("no_ignore_case", "pass_through");
+GetOptions("m=s" => \$opt_m, # Map file
+ "t=s" => \$opt_t, # Template directory
+ "f=s" => \$opt_f, # Foomatic version
+ "o" => \$opt_o, # Old Foomatic IDs
+ "d=s" => \@opt_d); # which Drivers?
+
# Wherever we put it...
my $mapfile;
# $mapfile = "../main/printers.xml";
-$mapfile = "foomatic-printermap";
+$mapfile = $opt_m;
+
+my $templatedir;
+$templatedir = $opt_t;
+
+my @drivertypes = ();
+for my $d (@opt_d) {
+ if (lc($d) eq "gs") {
+ push (@drivertypes, "gs");
+ }
+ if (lc($d) eq "ijs") {
+ push (@drivertypes, "ijs");
+ }
+ if (lc($d) eq "nogs") {
+ @drivertypes = ("ijs");
+ }
+ if (lc($d) eq "noijs") {
+ @drivertypes = ("gs");
+ }
+ if (lc($d) eq "all") {
+ @drivertypes = ("gs", "ijs");
+ }
+ if (lc($d) eq "both") {
+ @drivertypes = ("gs", "ijs");
+ }
+}
+
+exit 0 if ($#drivertypes < 0); # Nothing to be done, exit silently
+# Do we have Foomatic 2.9 or newer
+my $foomatic3 = ((defined($opt_f)) && ($opt_f >= 2.9));
# The following substitutions happen to the template XML files:
# @@STPVER@@ - the version number (ie '4.1.5')
@@ -39,6 +77,10 @@ my $funcs = { 'InputSlot' => { 'OPTCONSTRAINTS' => \&build_cons,
'ENUMVALS' => \&build_ev },
'Resolution' => { 'OPTCONSTRAINTS' => \&build_resolution_cons,
'ENUMVALS' => \&build_resolution_ev },
+ 'PrintoutMode' => { 'OPTCONSTRAINTS' =>
+ \&build_printoutmode_cons,
+ 'ENUMVALS' =>
+ \&build_printoutmode_ev },
};
my $drivervals = { 'PageSize' => \&optmap_pagesize,
@@ -50,9 +92,15 @@ my $debug = 0;
# Foomatic name => Gimp-print name
%argnamemap = ('Quality' => 'Resolution');
-%colormap = ('Grayscale' => 0,
- 'Color' => 1,
- 'BlackAndWhite' => 2);
+$colormap = { 'gs' => { 'Grayscale' => '0',
+ 'Color' => '1',
+ 'BlackAndWhite' => '2' },
+ 'ijs' => { 'Grayscale' => 'DeviceGray',
+ 'Color' => 'DeviceRGB',
+ 'BlackAndWhite' =>
+ 'DeviceGray -dBitsPerSample=1',
+ 'RawCMYK' => 'DeviceCMYK' }
+ };
use Data::Dumper;
@@ -65,6 +113,15 @@ while(<PIPE>) {
close PIPE or die "Cannot run printer_options: $!\n";
print STDERR "done.\n";
+if ($foomatic3) {
+ open PIPE, "./printer_margins|" or die "Cannot run printer_margins: $!\n";
+ print STDERR "Loading margins from ./printer_margins...";
+ $code = join('', <PIPE>);
+ close PIPE or die "Cannot run printer_margins: $!\n";
+ eval $code or die "Cannot run printer_margins: $!\n";
+ print STDERR "done.\n";
+}
+
open PIPE, "./stp_limits|" or die "Cannot run stp_limits: $!\n";
print STDERR "Loading options from ./stp_limits...";
while(<PIPE>) {
@@ -83,6 +140,24 @@ while(<PIPE>) {
close PIPE or die "Cannot run printers: $!\n";
print STDERR "done.\n";
+my %oldid;
+if ($opt_o) {
+ # Load table to translate the Foomatic IDs to the old (numerical) ones
+ print STDERR
+ "Loading printer ID translation table from @srcdir@/oldprinterids...";
+ my $translation_table = "@srcdir@/oldprinterids";
+ open TRTAB, "< $translation_table" or
+ die "Cannot read printer ID translation table: $!\n";
+ while (<TRTAB>) {
+ chomp;
+ if (/^\s*(\S+)\s+(\S+)\s*$/) {
+ $oldid{"printer/$2"} = "printer/$1";
+ }
+ }
+ close TRTAB;
+ print STDERR "done.\n";
+}
+
# OK, now %stpdata is a big honking thing, and %defaults is in there, too.
# Invert, to build %bar{$optionname} = [ choice1, choice2 ];
@@ -98,6 +173,31 @@ for $a (keys(%stpdata)) {
}
}
+if ($foomatic3) {
+ # Generate data for "PrintoutMode" option, only needed for
+ # Foomatic 2.9.x or newer
+ print STDERR "Generating data for \"PrintoutMode\" option...";
+ ($printoutmode, $printoutmodechoices) = getprintoutmode();
+ print STDERR "done.\n";
+ # Foomatic >= 2.9: Make a list of all choice entries needed in the
+ # "PrintoutMode" option XML file. Note: every choice ("Draft",
+ # "Normal", ...) will appear several times, but with different
+ # strings in "<ev_driverval>". Constraints will make only the
+ # right choices getting into the PPD file. Assign a unique ID to
+ # each entry.
+ for $a (keys(%{$printoutmode})) {
+ for $vtmp (keys %{$printoutmode->{$a}}) {
+ my $mode = $printoutmode->{$a}{$vtmp};
+ if (!$seen_modes{$vtmp}{$mode}++) {
+ if (!defined($nums{$vtmp})) {
+ $nums{$vtmp} = 0;
+ }
+ $nums{$vtmp} ++;
+ $modes{$vtmp}{$mode} = "$vtmp-$nums{$vtmp}";
+ }
+ }
+ }
+}
# Step 1: construct a map from Model= values to Foomatic model id's
# this map is %mapstp. The inverse from model to Model is %mapdb
@@ -106,9 +206,16 @@ for $a (keys(%stpdata)) {
open PRINTERS, $mapfile or die "Cannot open mapfile $mapfile: $!\n";
for (<PRINTERS>) {
- if (m!^#\s*gptofoo\s+([^\s]+)\s+([^\s]+)!) {
- push (@{$mapstp{$1}}, $2);
- $mapfoo{$2} = $1; # do we need?
+ if (m!^\#\s*gptofoo\s+([^\s]+)\s+([^\s]+)!) {
+ my $foomaticid = $2;
+ my $deviceclass = $1;
+ if ($opt_o) {
+ # Translate the Foomatic IDs to the old (numerical) ones
+ $foomaticid = $oldid{$foomaticid}
+ if defined($oldid{$foomaticid});
+ }
+ push (@{$mapstp{$deviceclass}}, $foomaticid);
+ $mapfoo{$foomaticid} = $deviceclass; # do we need?
}
}
@@ -122,6 +229,13 @@ for (keys(%stpdata)) {
}
}
+for (keys(%mapstp)) {
+ if (!defined($stpdata{$_})) {
+ $missing_drivers = 1;
+ warn "No gimp-print printer for foomatic ID $_.\n";
+ }
+}
+
if ($missing_drivers) {
die "Cannot continue\n";
}
@@ -131,7 +245,6 @@ open PIPE, "./gimp-print-version|" or die "Cannot run gimp-print-version: $!\n";
my $stpvers = <PIPE>;
close PIPE or die "Cannot run gimp-print-version: $!\n";
chomp $stpvers;
-print STDERR "Using drivername gimp-print\n";
# Build <printers> clause...
my @printerlist = ();
@@ -139,96 +252,215 @@ push (@printerlist, " <printers>\n");
my $p1;
for $p1 (keys(%mapstp)) {
push (@printerlist, " <!-- gimp-print driver: $p1 -->\n");
- for (@{$mapstp{$p1}}) {
- push(@printerlist, " <printer><id>$_</id></printer>\n");
+ for my $id (@{$mapstp{$p1}}) {
+ if ($foomatic3) {
+ # Add unprintable margins (only Foonmatic 2.9.x)
+ push(@printerlist, " <printer>\n");
+ push(@printerlist, " <id>$id</id>\n");
+ push(@printerlist, " <margins>\n");
+ my ($cleft, $cright, $ctop, $cbottom) =
+ (undef, undef, undef, undef);
+ if (defined($imageableareas{$p1}{'Custom'})) {
+ $cleft = $imageableareas{$p1}{'Custom'}{'left'};
+ $cright = $imageableareas{$p1}{'Custom'}{'right'};
+ $ctop = $imageableareas{$p1}{'Custom'}{'top'};
+ $cbottom = $imageableareas{$p1}{'Custom'}{'bottom'};
+ push(@printerlist, " <general>\n");
+ push(@printerlist, " <relative />\n");
+ push(@printerlist, " <left>$cleft</left>\n");
+ push(@printerlist, " <right>$cright</right>\n");
+ push(@printerlist, " <top>$ctop</top>\n");
+ push(@printerlist, " <bottom>$cbottom</bottom>\n");
+ push(@printerlist, " </general>\n");
+ }
+ for my $ps (keys %{$imageableareas{$p1}}) {
+ next if $ps eq 'Custom'; # We have done "Custom" already
+ my ($left, $right, $top, $bottom, $width, $height);
+ $left = $imageableareas{$p1}{$ps}{'left'};
+ $right = $imageableareas{$p1}{$ps}{'right'};
+ $top = $imageableareas{$p1}{$ps}{'top'};
+ $bottom = $imageableareas{$p1}{$ps}{'bottom'};
+ $width = $imageableareas{$p1}{$ps}{'width'};
+ $height = $imageableareas{$p1}{$ps}{'height'};
+ # If the <general> section serves for this paper size,
+ # do not define an <exception>
+ next if ((defined($cleft)) &&
+ ($left == $cleft) &&
+ ($right == $width - $cright) &&
+ ($top == $height - $ctop) &&
+ ($bottom == $cbottom));
+ push(@printerlist, " <exception PageSize=\"$ps\">\n");
+ push(@printerlist, " <absolute />\n");
+ if ($left != $cleft) {
+ push(@printerlist, " <left>$left</left>\n");
+ }
+ if ($right != $width - $cright) {
+ push(@printerlist, " <right>$right</right>\n");
+ }
+ if ($top != $height - $ctop) {
+ push(@printerlist, " <top>$top</top>\n");
+ }
+ if ($bottom != $cbottom) {
+ push(@printerlist, " <bottom>$bottom" .
+ "</bottom>\n");
+ }
+ push(@printerlist, " </exception>\n");
+ }
+ push(@printerlist, " </margins>\n");
+ push(@printerlist, " </printer>\n");
+ } else {
+ # Printer IDs only
+ push(@printerlist, " <printer><id>$id</id></printer>\n");
+ }
}
}
push (@printerlist, " </printers>\n");
+$drivernameprefix = "gimp-print";
+print STDERR "Using driver name prefix \"$drivernameprefix\"\n";
+
my $generalsubs = { 'STPVER' => $stpvers,
- 'DRVNAME' => "gimp-print",
+ 'DRVNAME' => $drivernameprefix,
'STPRINTERS' => join('', @printerlist) };
-my @numericsubs = ('MINVAL', 'MAXVAL', 'DEFVAL');
+my $optiongroups = { 'PageSize' => 'General',
+ 'InputSlot' => 'General',
+ 'MediaType' => 'General',
+ 'InkType' => 'General',
+ 'PrintoutMode' => 'General',
+ 'Resolution' => 'PrintoutMode',
+ 'Quality' => 'PrintoutMode',
+ 'Color' => 'PrintoutMode',
+ 'ImageType' => 'PrintoutMode',
+ 'Dither' => 'PrintoutMode',
+ 'Gamma' => 'Adjustment',
+ 'Density' => 'Adjustment',
+ 'Brightness' => 'Adjustment',
+ 'Contrast' => 'Adjustment',
+ 'Saturation' => 'Adjustment',
+ 'Cyan' => 'Adjustment',
+ 'Magenta' => 'Adjustment',
+ 'Yellow' => 'Adjustment' };
-opendir TDIR, "foomatic-templates" or die "Cannot open templates directory: $!\n";
+my @numericsubs = ('MINVAL', 'MAXVAL', 'DEFVAL');
-# OK, make the db heirarchy alongside the templates one...
-mkdir 'foomatic-db', 0755 or die "Cannot create directory foomatic-db: $!\n"
- unless -d 'foomatic-db';
-mkdir 'foomatic-db/opt', 0755 or die "Cannot create directory foomatic-db/opt: $!\n"
- unless -d 'foomatic-db/opt';
-mkdir 'foomatic-db/driver', 0755 or die "Cannot create directory foomatic-db/driver: $!\n"
- unless -d 'foomatic-db/driver';
+# OK, make the db directory...
+mkdir "foomatic-db", 0755 or
+ die "Cannot create directory foomatic-db: $!\n"
+ unless -d "foomatic-db";
# Now do stuff, already. Do the substitution into each file...
my $tmpl;
-while ($tmpl=readdir(TDIR)) {
- next if ($tmpl !~ m!.+\.xml$!);
-
- my $fooopt = $tmpl;
- $fooopt =~ s!\.xml$!!;
- my $stpopt = $argnamemap{$fooopt};
- $stpopt = $fooopt if ! defined ($stpopt);
-
-# print STDERR "Argnamemap '$fooopt' => '$stpopt'\n";
+for $drivertype (@drivertypes) {
+ $drivertypesuffix = "-$drivertype";
+ $drivertypesuffix =~ s/-gs//;
+ my $drvname = "$drivernameprefix$drivertypesuffix";
+ $generalsubs->{'DRVNAME'} = $drvname;
+ print "Generating Foomatic data for driver \"$drvname\"...\n";
+
+ # OK, make the db heirarchy alongside the templates one...
+ mkdir "foomatic-db/$drvname", 0755 or
+ die "Cannot create directory foomatic-db/$drvname: $!\n"
+ unless -d "foomatic-db/$drvname";
+ mkdir "foomatic-db/$drvname/opt", 0755 or
+ die "Cannot create directory foomatic-db/$drvname/opt: $!\n"
+ unless -d "foomatic-db/$drvname/opt";
+ mkdir "foomatic-db/$drvname/driver", 0755 or
+ die "Cannot create directory foomatic-db/$drvname/driver: $!\n"
+ unless -d 'foomatic-db/$drvname/driver';
+
+ opendir TDIR, "$templatedir-$drivertype" or
+ die "Cannot open templates directory: $!\n";
+
+ while ($tmpl=readdir(TDIR)) {
+
+ # Only XML files
+ next if ($tmpl !~ m!.+\.xml$!);
+ # The "PrintoutMode" option is only supported by Foomatic 2.9.x or
+ # newer
+ next if ((!$foomatic3) && ($tmpl eq "PrintoutMode.xml"));
+
+ my $fooopt = $tmpl;
+ $fooopt =~ s!\.xml$!!;
+ my $stpopt = $argnamemap{$fooopt};
+ $stpopt = $fooopt if ! defined ($stpopt);
+
+# print STDERR "Argnamemap '$fooopt' => '$stpopt'\n";
+
+ open TMPL, "$templatedir-$drivertype/$tmpl";
+ my @datafile = <TMPL>;
+ close TMPL;
+
+ print STDERR "Processing $tmpl...";
+
+ my $template = join('',@datafile);
+
+ # First, do the generic substitutions.
+
+ my ($substr);
+ for $substr (keys(%$generalsubs)) {
+ my $substitution = $generalsubs->{$substr};
+ $template =~ s!\@\@$substr\@\@!$substitution!g;
+ }
- open TMPL, "foomatic-templates/$tmpl";
- my @datafile = <TMPL>;
- close TMPL;
+ # Put the options into PPD groups (Foomatic >= 2.9)
- print STDERR "Processing $tmpl...";
+ if ($foomatic3) {
+ my $substitution = "\n <arg_group>" .
+ $optiongroups->{$fooopt} . "</arg_group>";
+ $template =~ s!\@\@GROUP\@\@!$substitution!g;
+ } else {
+ $template =~ s!\@\@GROUP\@\@!!g;
+ }
- my $template = join('',@datafile);
+ # Now do the numeric substitutions
- # First, do the generic substitutions.
+ for $substr (@numericsubs) {
+ my $substitution = $stp_values{$substr}{$stpopt};
+ $template =~ s!\@\@$substr\@\@!$substitution!g;
+ }
- my ($substr);
- for $substr (keys(%$generalsubs)) {
- my $substitution = $generalsubs->{$substr};
- $template =~ s!\@\@$substr\@\@!$substitution!g;
- }
+ # Now do special-purpose substitutions
- # Now do the numeric substitutions
+ for $substr (keys(%{$funcs->{$fooopt}})) {
+ my $substitution = &{$funcs->{$fooopt}{$substr}}($stpopt);
+ if (defined($substitution)) {
+ $template =~ s!\@\@$substr\@\@!$substitution!g;
+ }
+ }
- for $substr (@numericsubs) {
- my $substitution = $stp_values{$substr}{$stpopt};
- $template =~ s!\@\@$substr\@\@!$substitution!g;
- }
+ # Any more?
+ grep (m!\@\@([^\@]+)\@\@!g
+ && do { warn " Unknown substitution $1 in $tmpl!\n"; },
+ split("\n",$template));
- # Now do special-purpose substitutions
+ # Finally, write out the new file
- for $substr (keys(%{$funcs->{$fooopt}})) {
- my $substitution = &{$funcs->{$fooopt}{$substr}}($stpopt);
- if (defined($substitution)) {
- $template =~ s!\@\@$substr\@\@!$substitution!g;
- }
- }
+ # Options are under opt/
+ my $dbfilename = lc("foomatic-db/$drvname/opt/$drvname-$tmpl");
- # Any more?
- grep (m!\@\@([^\@]+)\@\@!g
- && do { warn " Unknown substitution $1 in $tmpl!\n"; },
- split("\n",$template));
+ # Special case the actual driver file under driver/
+ $dbfilename = "foomatic-db/$drvname/driver/$drvname.xml"
+ if ($tmpl eq 'gimp-print.xml');
- # Finally, write out the new file
+ open NEWF, "> $dbfilename" or die "Cannot create $dbfilename: $!";
+ print STDERR "writing $dbfilename...";
+ print NEWF $template;
+ print STDERR "done.\n";
+ close NEWF;
- # Options are under opt/
- my $dbfilename = lc("foomatic-db/opt/gimp-print-$tmpl");
+ }
- # Special case the actual driver file under driver/
- $dbfilename = "foomatic-db/driver/gimp-print.xml"
- if ($tmpl eq 'gimp-print.xml');
+ closedir TDIR;
- open NEWF, "> $dbfilename" or die "Cannot create $dbfilename: $!";
- print STDERR "writing $dbfilename...";
- print NEWF $template;
- print STDERR "done.\n";
- close NEWF;
+ # The paper size and resolution maps must be regenerated for the next
+ # driver, because the "driverval"s are different for the different
+ # drivers. So delete the caches.
+ undef $pagemap;
+ undef %rescache;
}
-
-
sub get_ev_shortname {
my ($val) = @_;
$val =~ s/ //g;
@@ -244,7 +476,7 @@ sub get_ev_key {
sub build_ev {
my ($stpopt) = @_;
- my $drvname = $generalsubs->{'DRVNAME'};
+ my $drvname = "$drivernameprefix$drivertypesuffix";
my @vals = ();
@@ -254,6 +486,11 @@ sub build_ev {
# Put in the basic choice info: ev names, etc
my $ev_longname = @$ev[1];
my $ev_shortname = @$ev[0];
+
+ # The GhostScript driver has no "RawCMYK" output type setting
+ next if (($drivertype eq "gs") && ($stpopt eq "Color") &&
+ ($ev_shortname eq "RawCMYK"));
+
my $ev_id = get_ev_key($ev_shortname, $drvname);
my $ev_driverval;
@@ -266,6 +503,8 @@ sub build_ev {
} else {
$ev_driverval = $ev_shortname;
}
+ # Remove "Roll" paper sizes, user has to use "Custom" instead.
+ next if (($stpopt eq "PageSize") && ($ev_driverval eq ""));
push (@vals,
" <enum_val id='$ev_id'>\n",
" <ev_longname><en>$ev_longname</en></ev_longname>\n",
@@ -277,13 +516,13 @@ sub build_ev {
" <driver>$drvname</driver>\n",
" </constraint>\n");
- # Build constraints for this particular ev
+ # Build constraints for this particular choice
my $stpprn;
for $stpprn (keys(%stpdata)) {
my $fooprn;
for $fooprn (@{$mapstp{$stpprn}}) {
if ($stpdata{$stpprn}{$stpopt}{$ev_shortname}) {
- # OK, this choice applies to this enum
+ # OK, this choice applies to this printer
push (@vals,
" <constraint sense='true'>\n",
" <!-- $fooprn == $stpprn -->\n",
@@ -309,7 +548,7 @@ sub build_cons {
my ($stpopt) = @_;
- my $drvname = $generalsubs->{'DRVNAME'};
+ my $drvname = "$drivernameprefix$drivertypesuffix";
my @PNCONS = ();
@@ -352,7 +591,7 @@ sub build_cons {
push (@PNCONS,
" <constraint sense='true'>\n",
- " <driver>gimp-print</driver>\n",
+ " <driver>$drvname</driver>\n",
" <printer>$fooname</printer><!-- gimp-print name: $stpname -->\n",
" <arg_defval>$foodefval</arg_defval>\n",
" </constraint>\n");
@@ -377,10 +616,15 @@ sub optmap_pagesize {
chomp;
$_ =~ m!^\s*(.+\S)\s+([0-9]+)\s+([0-9]+)\s*$!;
my ($name, $width, $height) = ($1, $2, $3);
- if ($width >= 0 and $height >= 0) {
- $pagemap->{$name} = "$width $height";
+ if (($width > 0 and $height > 0) or
+ ($name eq "Custom")) {
+ if ($drivertype eq "gs") {
+ $pagemap->{$name} = "$width $height";
+ } else {
+ $pagemap->{$name} = "-dDEVICEWIDTHPOINTS=$width -dDEVICEHEIGHTPOINTS=$height";
+ }
# print STDERR "PageSize '$name' driverval '$width $height'\n";
- }
+ }
}
close PUTIL;
}
@@ -390,8 +634,8 @@ sub optmap_pagesize {
sub optmap_color {
my ($value) = @_;
- if (defined $colormap{$value}) {
- return $colormap{$value};
+ if (defined $colormap->{$drivertype}{$value}) {
+ return $colormap->{$drivertype}{$value};
} else {
die "Cannot map output type '$value'\n";
}
@@ -399,15 +643,15 @@ sub optmap_color {
sub build_model_cons {
my ($stpopt) = @_;
- my $drvname = $generalsubs->{'DRVNAME'};
+ my $drvname = "$drivernameprefix$drivertypesuffix";
# OK, this is funky. For each stp model, we have a choice. That
# choice is valid for only the foo printers that correspond. For
# any given foo printer, there is *exactly one* available choice.
# The defval is the one available choice. Backends and
- # applications do not show choices with only one option; they just
- # select that option. So we don't bother to make pretty option
+ # applications do not show options with only one choice; they just
+ # select that choice. So we don't bother to make pretty option
# names or anything.
#
# See also build_model_ev()
@@ -445,7 +689,7 @@ sub build_model_cons {
# See build_model_cons, above.
sub build_model_ev {
my ($stpopt) = @_;
- my $drvname = $generalsubs->{'DRVNAME'};
+ my $drvname = "$drivernameprefix$drivertypesuffix";
my @vals = ();
@@ -457,8 +701,24 @@ sub build_model_ev {
my $ev_longname = $printer_name{$ev};
my $ev_shortname = get_ev_shortname($ev);
my $ev_id = get_ev_key($ev, $drvname);
- my $ev_driverval = $ev;
-
+ my $ev_driverval;
+ if ($drivertype eq "gs") {
+ $ev_driverval = $ev;
+ } else {
+ my $make;
+ if ($ev =~ /^escp2/) {
+ $make = "EPSON";
+ } elsif ($ev =~ /^bjc/) {
+ $make = "CANON";
+ } elsif ($ev =~ /^pcl/) {
+ $make = "HEWLETT-PACKARD";
+ } elsif ($ev =~ /^lexmark/) {
+ $make = "LEXMARK";
+ } else {
+ die "Could not determine printer manufacturer from \"$ev\"!\n";
+ }
+ $ev_driverval = "-sDeviceManufacturer=$make -sDeviceModel=$ev";
+ }
push (@vals,
" <enum_val id='$ev_id'>\n",
" <ev_longname><en>$ev_longname</en></ev_longname>\n",
@@ -507,11 +767,15 @@ sub build_model_ev {
# - What are the legal resolutions? Sort of parse and compute these
# from the Resolution values.
#
-# The driverval is "x y", and gets passedin a /HWResolution ps clause
+# In the case of the GhostScript driver The driverval is "X Y", and gets
+# passed in a /HWResolution ps clause, for the IJS driver it is "XxY" and
+# gets passed via the "-r" command line option of GhostScript.
sub compute_resolutions {
my ($stpname) = @_;
+ my $drvname = "$drivernameprefix$drivertypesuffix";
+
if (!defined($rescache{$stpname})) {
my @reslist = ();
@@ -524,15 +788,24 @@ sub compute_resolutions {
my ($x, $y) = ($1, $3);
$y = $x if !defined($y);
- my $r = {'x' => $x,
- 'y' => $y,
- 'driverval' => "$x $y",
- 'ev_key' => get_ev_key("res-$x-$y", "gimp-print")
- };
+ my $r;
+ if ($drivertype eq "gs") {
+ $r = {'x' => $x,
+ 'y' => $y,
+ 'driverval' => "$x $y",
+ 'ev_key' => get_ev_key("res-$x-$y", $drvname)
+ };
+ } else {
+ $r = {'x' => $x,
+ 'y' => $y,
+ 'driverval' => "${x}x${y}",
+ 'ev_key' => get_ev_key("res-$x-$y", $drvname)
+ };
+ }
push (@reslist, $r);
# Default?
- $defval = get_ev_key("res-$x-$y", "gimp-print")
+ $defval = get_ev_key("res-$x-$y", $drvname)
if ($qual eq $defaults{$stpname}{'Resolution'});
# Note that this resolution value exists
@@ -547,9 +820,6 @@ sub compute_resolutions {
$rescache{$stpname}{'list'} = \@reslist;
$rescache{$stpname}{'defval'} = $defval;
$rescache{$stpname}{'takesit'} = \%hash;
-
- die "No default gsResolution found for printer $stpname!?\n"
- if ! defined($defval);
}
return $rescache{$stpname};
@@ -564,7 +834,7 @@ sub do_all_res {
sub build_resolution_ev {
my ($stpopt) = @_;
- my $drvname = $generalsubs->{'DRVNAME'};
+ my $drvname = "$drivernameprefix$drivertypesuffix";
my @vals = ();
@@ -580,7 +850,12 @@ sub build_resolution_ev {
my $ev_longname = "$x x $y DPI";
my $ev_shortname = get_ev_shortname($ev_longname);
my $ev_id = get_ev_key("res-$x-$y", $drvname);
- my $ev_driverval = "$x $y";
+ my $ev_driverval;
+ if ($drivertype eq "gs") {
+ $ev_driverval = "$x $y";
+ } else {
+ $ev_driverval = "${x}x${y}";
+ }
push (@vals,
" <enum_val id='$ev_id'>\n",
@@ -633,7 +908,7 @@ sub build_resolution_ev {
sub build_resolution_cons {
my ($stpopt) = @_;
- my $drvname = $generalsubs->{'DRVNAME'};
+ my $drvname = "$drivernameprefix$drivertypesuffix";
my @PNCONS = ();
@@ -666,6 +941,442 @@ sub build_resolution_cons {
" </constraints>\n");
}
+sub build_printoutmode_ev {
+ my ($stpopt) = @_;
+ my $drvname = "$drivernameprefix$drivertypesuffix";
-exit(0);
+ my @vals = ();
+
+ # OK, now for each choice ("Draft", "Normal", ...) ...
+ my $choice;
+ for $choice (keys %modes) {
+ # ... and each possible "<ev_driverval>" for it
+ my $ev_driverval;
+ for $ev_driverval (keys %{$modes{$choice}}) {
+ # Put in the basic choice info: ev names, etc
+ my $ev_longname = $printoutmodechoices->{$choice};
+ my $ev_shortname = $choice;
+
+ my $ev_id =
+ get_ev_key($modes{$choice}{$ev_driverval}, $drvname);
+ push (@vals,
+ " <enum_val id='$ev_id'>\n",
+ " <ev_longname><en>$ev_longname</en></ev_longname>\n",
+ " <ev_shortname><en>$ev_shortname</en></ev_shortname>\n",
+ " <ev_driverval>$ev_driverval</ev_driverval>\n",
+ " <constraints>\n",
+ " <!-- Assume the option doesn't apply... -->\n",
+ " <constraint sense='false'>\n",
+ " <driver>$drvname</driver>\n",
+ " </constraint>\n");
+
+ # Build constraints for this particular ev_driverval
+ my $stpprn;
+ for $stpprn (keys(%stpdata)) {
+ my $fooprn;
+ for $fooprn (@{$mapstp{$stpprn}}) {
+ if ($printoutmode->{$stpprn}{$choice} eq
+ $ev_driverval) {
+ # OK, this choice applies to this printer
+ push (@vals,
+ " <constraint sense='true'>\n",
+ " <!-- $fooprn == $stpprn -->\n",
+ " <driver>$drvname</driver>\n",
+ " <printer>$fooprn</printer>\n",
+ " </constraint>\n");
+ }
+ }
+ }
+
+ push (@vals,
+ " </constraints>\n",
+ " </enum_val>\n");
+ }
+ }
+
+ return join('',
+ "<enum_vals>\n",
+ @vals,
+ " </enum_vals>\n");
+}
+
+sub build_printoutmode_cons {
+ my ($stpopt) = @_;
+ my $drvname = "$drivernameprefix$drivertypesuffix";
+
+ my @PNCONS = ();
+
+ # For each stp printer...
+ my $stpname;
+ for $stpname (keys(%mapstp)) {
+
+ # For each possible foo name
+ my $fooname;
+ for $fooname (@{$mapstp{$stpname}}) {
+
+ # What's the default value (always the "Normal" mode)?
+ my $normalmode = $printoutmode->{$stpname}{'Normal'};
+ my $foodefval = get_ev_key($modes{'Normal'}{$normalmode},
+ $drvname);
+
+ push (@PNCONS,
+ " <constraint sense='true'>\n",
+ " <driver>$drvname</driver>\n",
+ " <printer>$fooname</printer>\n",
+ " <arg_defval>$foodefval</arg_defval>\n",
+ " </constraint>\n");
+ }
+ }
+
+ return join('',
+ "<constraints>\n",
+ @PNCONS,
+ " </constraints>\n");
+}
+
+sub qualityorder {
+ # List of suffixes of the Quality choices
+ my @suffixes = (
+ # General
+ "",
+ "dpi",
+ # Epson/Lexmark
+ "mw",
+ "mw2",
+ "sw",
+ "fol",
+ "fol2",
+ "fourp",
+ "uni",
+ "mwuni",
+ "mw2uni",
+ "swuni",
+ "foluni",
+ "fol2uni",
+ "fourpuni",
+ "hq",
+ "hquni",
+ "hq2",
+ "hq2uni",
+ # Canon
+ "dmt",
+ # HP
+ "mono",
+ );
+ my ($a, $b) = @_;
+ # Bring the suffixes to lower case
+ my $first = lc($a);
+ my $second = lc($b);
+ # Check whether they are in the @suffixes list
+ my $i;
+ for ($i = 0; $i <= $#suffixes; $i++) {
+ my $firstinlist = ($first eq $suffixes[$i]);
+ my $secondinlist = ($second eq $suffixes[$i]);
+ if (($firstinlist) && (!$secondinlist)) {return -1};
+ if (($secondinlist) && (!$firstinlist)) {return 1};
+ if (($firstinlist) && ($secondinlist)) {return 0};
+ }
+
+ # Equal quality
+ die "The quality choice suffixes $a and $b are unknown!\n";
+ return 0;
+
+}
+
+sub getprintoutmode {
+ my $choicelongnames = {
+ 'Draft' => 'Draft (Economy)',
+ 'Draft.Gray' => 'Draft Grayscale (Economy)',
+ 'Normal' => 'Normal',
+ 'Normal.Gray' => 'Normal Grayscale',
+ 'High' => 'High Quality',
+ 'High.Gray' => 'High Quality Grayscale',
+ 'VeryHigh' => 'Very High Quality',
+ 'VeryHigh.Gray' => 'Very High Quality Grayscale',
+ 'Photo' => 'Photo',
+ 'Photo.Gray' => 'Photo Grayscale',
+ };
+
+ ### BASIC RULES
+
+ # See mode-specific rules below
+
+ # There must be always a "Normal" mode, this will be the default.
+
+ # On black-and-white printers there are no modes with ".Gray"
+ # specifier, the standard modes are already grayscale.
+
+ # No "Photo" mode on laser printers.
+
+ # If on a PCL printer "600mono" is the chose quality, it will be
+ # replaced by "300dpi" in color mode (This can lead to a mode being
+ # removed by the following two rules).
+
+ # If "VeryHigh" has exactly the same settings as "High", "VeryHigh"
+ # is left out.
+
+ # If "High" has exactly the same settings as "Normal", "High"
+ # is left out.
+
+ # If nothing is found for a certain mode, this mode is left out.
+
+ my $modes = {};
+ # Treat all printers
+ my $stpprn;
+ for $stpprn (keys(%stpdata)) {
+ my $modeinfo = {};
+ my ($draftminres, $draftbestsymmetry, $draftlowestqualstr) =
+ (99999999, 99999999, "xxx");
+ my $normaldefaultqual = $defaults{$stpprn}{'Resolution'};
+ my ($highmaxres, $highbestsymmetry, $highbestqualstr) =
+ (0, 99999999, "");
+ my ($veryhighmaxres, $veryhighbestsymmetry, $veryhighbestqualstr) =
+ (0, 99999999, "");
+ my ($photomaxres, $photobestsymmetry, $photobestqualstr) =
+ (0, 99999999, "");
+ # Go through all choices of the "Quality" option and find the
+ # best values for the "PrintoutMode" option
+ my $quality;
+ for $quality (keys(%{$stpdata{$stpprn}{'Resolution'}})) {
+ my ($xres, $yres, $qualstr);
+ if ($quality =~ /^(\d+)x(\d+)(\D.*)$/) {
+ $xres = $1;
+ $yres = $2;
+ $qualstr = $3;
+ } elsif ($quality =~ /^(\d+)(\D.*)$/) {
+ $xres = $1;
+ $yres = $1;
+ $qualstr = $2;
+ } else {
+ die "Invalid quality: $quality\n";
+ }
+ # Resolution in dots per square inch
+ my $respersquareinch = $xres * $yres;
+ # Symmetry: Shows how far from symmetric a resolution is,
+ # the smaller, the more symmetric, symmetric resolutions (as
+ # 300x300 dpi) give zero.
+ my $symmetry = abs(log($yres/$xres));
+
+ ### Mode: DRAFT
+
+ # Use always the lowest available resolution/quality,
+ # preferrably symmetric resolutions,
+
+ # Do not use resolutions with less than 150 dpi in both
+ # demensions.
+
+ # VeryFast dithering, ImageType LineArt
+
+ if (($respersquareinch < $draftminres) ||
+ (($respersquareinch == $draftminres) &&
+ ($symmetry < $draftbestsymmetry)) ||
+ (($respersquareinch == $draftminres) &&
+ ($symmetry == $draftbestsymmetry) &&
+ (qualityorder($qualstr, $draftlowestqualstr) < 0))) {
+ $draftbestsymmetry = $symmetry;
+ $draftminres = $respersquareinch;
+ $draftlowestqualstr = $qualstr;
+ next if (($xres < 150) && # Resolution not lower than
+ ($yres < 150)); # 150x150, 360x120 allowed
+ $modeinfo->{'Draft'} = {
+ 'quality' => $quality,
+ 'xres' => $xres,
+ 'yres' => $yres,
+ 'dither' => 'VeryFast',
+ 'image' => 'LineArt'
+ }
+ }
+
+ ### Mode: NORMAL
+
+ # Default resolution/quality of GIMP-Print, upgrade to
+ # unidirectional if possible, use 600x600 dpi for
+ # Lexmark Z..
+
+ # Adaptive Hybrid dithering, ImageType Photographs
+
+ if ((($stpprn =~ /^lexmark\-z/) &&
+ ($xres == 600) && ($yres == 600) && ($qualstr eq "uni")) ||
+ (($stpprn !~ /^lexmark\-z/) &&
+ (($quality eq "${normaldefaultqual}uni") ||
+ (($quality eq $normaldefaultqual) &&
+ (!defined($normal->{'quality'})))))) {
+ $modeinfo->{'Normal'} = {
+ 'quality' => $quality,
+ 'xres' => $xres,
+ 'yres' => $yres,
+ 'dither' => 'Adaptive',
+ 'image' => 'Photographs'
+ }
+ }
+
+ ### Mode: HIGH
+
+ # High: The highest resolution which is not higher than
+ # 720x720 dpi (Lexmark Z..: 1200x1200 dpi),
+ # unidirectional if possible,
+ # not "fol", "fourp", "hq", "hq2"
+
+ # Adaptive Hybrid dithering, ImageType Photographs
+
+ if (($respersquareinch > $highmaxres) ||
+ (($respersquareinch == $highmaxres) &&
+ ($symmetry < $highbestsymmetry)) ||
+ (($respersquareinch == $highmaxres) &&
+ ($symmetry == $highbestsymmetry) &&
+ (qualityorder($qualstr, $highbestqualstr) > 0))) {
+ unless ((($stpprn !~ /^lexmark\-z/) &&
+ (($xres > 720) || # Resolution not higher than
+ ($yres > 720))) || # 720x720 for non Lexmark
+ ($xres > 1200) || # not bigger than 1200x1200
+ ($yres > 1200) || # in general
+ ($qualstr =~ /^(hq.*|fo.*)$/)) { # Not "hq", "hq2",
+ # "fol", "fourp"
+ $highbestsymmetry = $symmetry;
+ $highmaxres = $respersquareinch;
+ $highbestqualstr = $qualstr;
+ $modeinfo->{'High'} = {
+ 'quality' => $quality,
+ 'xres' => $xres,
+ 'yres' => $yres,
+ 'dither' => 'Adaptive',
+ 'image' => 'Photographs'
+ }
+ }
+ }
+
+ ### Mode: VERY HIGH
+
+ # Use always the highest available resolution/quality,
+ # preferrably symmetric resolutions,
+
+ # On Epsons: Maximum 1440x720, not "hq2".
+
+ # Adaptive Hybrid dithering, ImageType Photographs
+
+ if (($respersquareinch > $veryhighmaxres) ||
+ (($respersquareinch == $veryhighmaxres) &&
+ ($symmetry < $veryhighbestsymmetry)) ||
+ (($respersquareinch == $veryhighmaxres) &&
+ ($symmetry == $veryhighbestsymmetry) &&
+ (qualityorder($qualstr, $veryhighbestqualstr) > 0))) {
+ unless (($stpprn =~ /^escp2/) && # Epson
+ (($xres > 1440) || # Resolution not higher than
+ ($yres > 720) || # 1440x720
+ ($qualstr eq "hq2"))) { # Not "hq2"
+ $veryhighbestsymmetry = $symmetry;
+ $veryhighmaxres = $respersquareinch;
+ $veryhighbestqualstr = $qualstr;
+ $modeinfo->{'VeryHigh'} = {
+ 'quality' => $quality,
+ 'xres' => $xres,
+ 'yres' => $yres,
+ 'dither' => 'Adaptive',
+ 'image' => 'Photographs'
+ }
+ }
+ }
+
+ ### Mode: PHOTO
+
+ # Use always the highest available resolution/quality,
+ # preferrably symmetric resolutions,
+
+ # On Epsons: Maximum 2880x720
+
+ # EvenTone dithering, ImageType Photographs
+
+ if (($respersquareinch > $photomaxres) ||
+ (($respersquareinch == $photomaxres) &&
+ ($symmetry < $photobestsymmetry)) ||
+ (($respersquareinch == $photomaxres) &&
+ ($symmetry == $photobestsymmetry) &&
+ (qualityorder($qualstr, $photobestqualstr) > 0))) {
+ unless (($stpprn =~ /^escp2/) && # Epson
+ (($xres > 2880) || # Resolution not higher than
+ ($yres > 720))) { # 2880x720
+ $photobestsymmetry = $symmetry;
+ $photomaxres = $respersquareinch;
+ $photobestqualstr = $qualstr;
+ $modeinfo->{'Photo'} = {
+ 'quality' => $quality,
+ 'xres' => $xres,
+ 'yres' => $yres,
+ 'dither' => 'EvenTone',
+ 'image' => 'Photographs'
+ }
+ }
+ }
+ }
+
+ # We must have a "Normal" mode for every printer.
+ if (!defined($modeinfo->{'Normal'}{'quality'})) {
+ die "No 'Normal' mode for $stpprn!\n";
+ }
+
+ # Build the strings with the settings for the "PrintoutMode"
+ # option
+ for my $m (keys(%{$modeinfo})) {
+ # If we didn't find anything for a certain mode, skip this
+ # mode
+ next if (!defined($modeinfo->{$m}{'quality'}));
+ my $modestr =
+ "GSResolution=$modeinfo->{$m}{'xres'}x" .
+ "$modeinfo->{$m}{'yres'}DPI " .
+ "Quality=$modeinfo->{$m}{'quality'} " .
+ "Dither=$modeinfo->{$m}{'dither'} " .
+ "ImageType=$modeinfo->{$m}{'image'}";
+ if (defined($stpdata{$stpprn}{'Color'}{'Color'})) {
+ # Color printer
+ $modes->{$stpprn}{$m} = $modestr . " OutputType=Color";
+ $modes->{$stpprn}{"$m.Gray"} =
+ $modestr . " OutputType=Grayscale";
+ # Some HP inkjets have a "600mono" quality mode which
+ # is only available in Grayscale, replace this mode by
+ # "300dpi" in the settings for color printing
+ if ($modes->{$stpprn}{$m} =~ /600mono/) {
+ if(!defined($stpdata{$stpprn}{'Resolution'}{'300dpi'})){
+ die "No '300dpi' mode for $stpprn!";
+ }
+ $modes->{$stpprn}{$m} =~ s/600x600DPI/300x300DPI/;
+ $modes->{$stpprn}{$m} =~ s/600mono/300dpi/;
+ }
+ } else {
+ # bw printer
+ if ($stpprn =~ /^pcl\-[2-6][vls]?i?$/) { # Laser printer
+ # No 'Photo' mode on laser printers
+ next if ($m eq 'Photo');
+ # Always "VeryFast" dithering on laser printers
+ $modestr =~ s/(Dither=)\S+/$1VeryFast/;
+ }
+ $modes->{$stpprn}{$m} = $modestr . " OutputType=Grayscale";
+ }
+ }
+ # Remove 'VeryHigh' and 'High' if they are identical to lower
+ # quality modes
+ if ($modes->{$stpprn}{'VeryHigh'} eq
+ $modes->{$stpprn}{'High'}) {
+ delete($modes->{$stpprn}{'VeryHigh'});
+ }
+ if ($modes->{$stpprn}{'High'} eq
+ $modes->{$stpprn}{'Normal'}) {
+ delete($modes->{$stpprn}{'High'});
+ }
+ if (defined($stpdata{$stpprn}{'Color'}{'Color'})) {
+ # Color printer
+ if ($modes->{$stpprn}{'VeryHigh.Gray'} eq
+ $modes->{$stpprn}{'High.Gray'}) {
+ delete($modes->{$stpprn}{'VeryHigh.Gray'});
+ }
+ if ($modes->{$stpprn}{'High.Gray'} eq
+ $modes->{$stpprn}{'Normal.Gray'}) {
+ delete($modes->{$stpprn}{'High.Gray'});
+ }
+ }
+ }
+
+ return ($modes, $choicelongnames)
+}
+
+exit(0);