diff --git a/ppd/PPD.pm b/ppd/PPD.pm index 00dc9e509093e0d91cac3c52fc5c6cacebbb5c9a..14206f45364ece359c83ca0d5c18f3d5ef603f35 100644 --- a/ppd/PPD.pm +++ b/ppd/PPD.pm @@ -29,13 +29,24 @@ our @EXPORT = qw(define_group define_ui_group switch_group declare get set maybe # Priority => pri, # OrderDependency priority, default = 100 # Values => [ # possible values (mandatory) # { Key => key, # key (mandatory) -# Name => key, # descriptive name (default: same as Key) +# Name => name, # descriptive name (default: same as Key) # PS => string, # PS code invocation to emit # String => string, # Unquoted string to emit instead of PS code # Default => 1, # if this is the default value # }, # ], # Default => key, # default value if not marked inside Values +# Custom => [ # further values with custom parameters (mostly a CUPS extension) +# PS => string, # PS code invocation to emit (with parameters on the stack) +# Params => [ # list of parameters (mandatory) +# { Key => key, # key (mandatory) +# Name => name, # descriptive name (default: same as Key) +# Unit => unit, # unit: int / points / real / string / ... +# Min => min, +# Max => max, +# }, +# ] +# ], # } my %keywords = (); @@ -64,27 +75,27 @@ my $current_group_key; # ] my @constraints = (); -sub define_group($$) { - my ($key, $g) = @_; +sub define_group($) { + my ($g) = @_; + my $key = $g->{Key}; !defined $groups{$key} or die "Group $key already exists\n"; $groups{$key} = $g; - $g->{Key} = $key; if ($g->{UI}) { push @ui_groups, $key; } elsif ($g->{Head}) { push @head_groups, $key; } else { push @nonui_groups, $key; } $current_group_key = $key; } -sub define_head_group($$) { - my ($key, $g) = @_; +sub define_head_group($) { + my ($g) = @_; $g->{Head} = 1; - define_group($key, $g); + define_group($g); } -sub define_ui_group($$) { - my ($key, $g) = @_; +sub define_ui_group($) { + my ($g) = @_; $g->{UI} = 1; - define_group($key, $g); + define_group($g); } sub switch_group($) { @@ -210,17 +221,17 @@ sub fonts($) { ### Known main keywords ### # Group "f": file description -define_head_group('f', { Name => 'File version' }); +define_head_group({ Key => 'f', Name => 'File version' }); declare('f', [ 'FormatVersion', 'q!', '4.3' ], [ 'LanguageEncoding', 's!', 'ISOLatin1' ], [ 'LanguageVersion', 's!', 'English' ], - [ 'FileVersion', 's!', undef ], + [ 'FileVersion', 'q!', undef ], [ 'PCFileName', 's!', undef ], ); # Group "p": product description -define_head_group('p', { Name => 'Product description' }); +define_head_group({ Key => 'p', Name => 'Product description' }); declare('p', [ 'Manufacturer', 'q!', undef ], [ 'ModelName', 'q!', undef ], # default: copy Product @@ -231,7 +242,7 @@ declare('p', ); # Group "d": device capabilities -define_head_group('d', { Name => 'Device capabilities' }); +define_head_group({ Key => 'd', Name => 'Device capabilities' }); declare('d', [ 'ColorDevice', 'b', 0 ], [ 'DefaultColorSpace', 's', 'Gray' ], @@ -250,13 +261,13 @@ declare('d', ); # Group "c": CUPS options -define_head_group('c', { Name => 'CUPS options' }); +define_head_group({ Key => 'c', Name => 'CUPS options' }); declare('c', [ 'cupsProtocol', 's', undef ], ); # Group "j": JCL options -define_head_group('j', { Name => 'JCL options' }); +define_head_group({ Key => 'j', Name => 'JCL options' }); declare('j', [ 'JCLBegin', 'q', undef ], [ 'JCLToPSInterpreter', 'q', undef ], @@ -264,7 +275,7 @@ declare('j', ); # Group "fonts": Fonts -define_group('fonts', { Name => 'Fonts' }); +define_group({ Key => 'fonts', Name => 'Fonts' }); ### Formatting of PPD ### @@ -299,7 +310,7 @@ sub heading($) { sub get_default($) { my ($o) = @_; - $o->{Default} and return $o->{Default}; + exists $o->{Default} and return $o->{Default}; # may be undef for my $val (@{$o->{Values}}) { return $val->{Key} if $val->{Default}; } @@ -310,14 +321,21 @@ sub emit_option($) { my ($o) = @_; my $key = $o->{Key}; print "%* === $key ===\n"; + my $jcl = ($o->{JCL} // ($key =~ /^JCL/)) ? "JCL" : ""; if (defined $o->{Choice}) { print "*${jcl}OpenUI *$key/", ($o->{Name} // $o->{Key}), ": ", $o->{Choice}, "\n"; + } + + if (defined($o->{Choice}) || defined($o->{Priority}) || defined($o->{Section})) { my $pri = $o->{Priority} // 100; my $sec = $o->{Section} // ($jcl ? "JCLSetup" : "AnySetup"); print '*', ((defined $o->{Choice}) ? "" : 'NonUI'), "OrderDependency $pri $sec *$key\n"; } - print "*Default$key: ", get_default($o), "\n"; + + # Normal option + my $def = get_default($o); + print "*Default$key: $def\n" if defined $def; for my $v (@{$o->{Values}}) { my $ps = $v->{PS}; print "*$key ", $v->{Key}; @@ -332,7 +350,22 @@ sub emit_option($) { } print "\n"; } + if (defined $o->{Choice}) { print "*${jcl}CloseUI *$key\n"; } + + my $c = $o->{Custom}; + if ($c) { + print "\n"; + print "*Custom$key True: ", format_value('i', $c->{PS}), "\n"; + my $i = 0; + for my $p (@{$c->{Params}}) { + $i++; + print "*Param$key ", $p->{Key}; + print '/', $p->{Name} if defined($p->{Name}) && $p->{Name} ne $p->{Key}; + printf ": %d %s %d %d\n", $i, $p->{Unit}, $p->{Min}, $p->{Max}; + } + } + print "\n"; } @@ -402,7 +435,7 @@ sub generate() { fill_defaults(); check_missing(); - print "*PPD-Adobe: ", get('FormatVersion'), "\n"; + print "*PPD-Adobe: ", format_value('q', get('FormatVersion')), "\n"; print "*% PPD file generated by UCW PPD generator\n"; for my $g (@head_groups, @ui_groups, @nonui_groups) { diff --git a/ppd/PPD/Paper.pm b/ppd/PPD/Paper.pm index 921fe07882d913f78125af0150f80646c2cf98fb..7464b6a954b8ca0c828a43a1198a3dad6310bc23 100644 --- a/ppd/PPD/Paper.pm +++ b/ppd/PPD/Paper.pm @@ -68,7 +68,7 @@ sub add_papers($) { } $o->{DefPaper} //= 'A4'; - define_ui_group('Media', { Name => 'Media settings' }); + define_ui_group({ Key => 'Media', Name => 'Media settings' }); option({ Key => 'PageSize', @@ -85,6 +85,16 @@ sub add_papers($) { } } sort keys %real_media ], Default => $o->{DefPaper}, + Custom => { + PS => 'pop pop pop << /PageSize [5 -2 roll] >> setpagedevice', + Params => [ + { Key => 'Width', Unit => 'points', Min => $minw, Max => $maxw }, + { Key => 'Height', Unit => 'points', Min => $minh, Max => $maxh }, + { Key => 'WidthOffset', Unit => 'points', Min => 0, Max => 0 }, + { Key => 'HeightOffset', Unit => 'points', Min => 0, Max => 0 }, + { Key => 'Orientation', Unit => 'int', Min => 1, Max => 1 }, + ] + }, }); option({ @@ -131,6 +141,18 @@ sub add_papers($) { } sort keys %real_media ], Default => $o->{DefPaper}, }); + + declare('Media', + [ 'LandscapeOrientation', 's', 'Plus90' ], + [ 'MaxMediaWidth', 'q', $maxw ], + [ 'MaxMediaHeight', 'q', $maxh ], + [ 'HWMargins', 's', sprintf("%d %d %d %d", $margh, $margv, $margh, $margv) ], # left, bottom, right, top + ); + + option({ + Key => 'LeadingEdge', + Values => [{ Key => 'PreferLong', PS => "", Default => 1 }], + }); } 42; diff --git a/ppd/gen-hp b/ppd/gen-hp index 89a312400041d05a77bc0a22f70ea583d7fdc61c..e509a3ca6511afec29885c30f7a96631004c8c42 100755 --- a/ppd/gen-hp +++ b/ppd/gen-hp @@ -21,7 +21,7 @@ set('Protocols', 'PJL TBCP'); set('cupsProtocol', 'None'); -define_ui_group('Basic', { Name => 'Basic options' }); +define_ui_group({ Key => 'Basic', Name => 'Basic options' }); option({ Key => 'Duplex', @@ -86,6 +86,17 @@ PPD::Paper::add_papers({ MarginH => 16, MarginV => 16, PSPageSize => sub { my ($m) = @_; return sprintf("<< /PageSize [%d %d] >> setpagedevice", $m->{W}, $m->{H}); }, }); +switch_group('Media'); + +# Initialize media selection mechanism +option({ + Key => 'HPInit', + Priority => 0, + Section => 'DocumentSetup', + Values => [ + { Key => 'Init', PS => '<< /DeferredMediaSelection true /ImagingBbox null /MediaClass null >>' }, + ] +}); option({ Key => 'MediaType', @@ -120,6 +131,13 @@ option({ { Key => 'Tray2', Name => 'Tray 2', PS => '<< /ManualFeed false /MediaPosition 0 >> setpagedevice' }, { Key => 'Tray3', Name => 'Tray 3', PS => '<< /ManualFeed false /MediaPosition 1 >> setpagedevice' }, ], + Default => 'Tray2', +}); + +option({ + Key => 'RequiresPageRegion', + Values => [{ Key => 'All', String => 'True' }], + Default => undef, }); constrain(undef, 'InputSlot', 'MediaType', sub { @@ -133,6 +151,18 @@ constrain(undef, 'Duplex', 'MediaType', sub { return !($dp ne 'None' && $mt =~ /^(Labels|Transparency|Bond)$/); }); +option({ + Key => 'HPPaperPolicy', + Name => 'Fit to Page', + Choice => 'PickOne', + Priority => 10, + Values => [ + { Key => 'PromptUser', Name => 'PromptUser', PS => '', Default => 1 }, + { Key => 'NearestSizeAdjust', Name => 'Nearest Size and Scale', PS => '<< /Policies << /DeferredMediaSelection true /PageSize 3 >> >> setpagedevice' }, + { Key => 'NearestSizeNoAdjust', Name => 'Nearest Size and Crop', PS => '<< /Policies << /DeferredMediaSelection true /PageSize 5 >> >> setpagedevice' }, + ], +}); + # As reported by the printer # (versions set to "(1.0)", because the printer reports just "(.)") fonts( <<'AMEN' ); @@ -231,4 +261,6 @@ ZapfChancery-MediumItalic: Standard (1.0) Standard ROM ZapfDingbats: Special (1.0) Special ROM AMEN +# FIXME: Omitted configuration of halftoning + generate();