This file is indexed.

/usr/share/perl5/PostScript/File/Functions.pm is in libpostscript-file-perl 2.20+dfsg-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
#---------------------------------------------------------------------
package PostScript::File::Functions;
#
# Copyright 2012 Christopher J. Madsen
#
# Author: Christopher J. Madsen <perl@cjmweb.net>
# Created:  2 Feb 2012
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either the
# GNU General Public License or the Artistic License for more details.
#
# ABSTRACT: Collection of useful PostScript functions
#---------------------------------------------------------------------

use 5.008;
use strict;
use warnings;

our $VERSION = '2.20';
# This file is part of PostScript-File 2.20 (February 11, 2012)

use Carp qw(croak);
use PostScript::File 2.20 (); # strip method

# Constant indexes of the arrayrefs in the _functions hash:
sub _id_       () { 0 } ## no critic
sub _code_     () { 1 } ## no critic
sub _requires_ () { 2 } ## no critic

#=====================================================================
# Initialization:
#
# Subclasses should call __PACKAGE__->_init_module(\*DATA);

sub _init_module
{
  my ($class, $fh) = @_;

  my $function = $class->_functions;
  my @keys;
  my $routine;

  while (<$fh>) {
    if (/^%-+$/) {
      PostScript::File::->strip(all_comments => $routine);
      next unless $routine;
      $routine =~ m!^/(\w+)! or die "Can't find name in $routine";
      push @keys, $1;
      $function->{$1} = [ undef, $routine ];
      $routine = '';
    }

    $routine .= $_;
  } # end while <DATA>

  my $id = 'A';
  $id   .= 'A' while @keys > 26 ** length $id;

  my $re = join('|', @keys);
  $re = qr/\b($re)\b/;

  for my $name (@keys) {
    my $f = $function->{$name};
    $$f[_id_] = $id++;

    my %req;

    $req{$_} = 1 for $$f[_code_] =~ m/$re/g;
    delete $req{$name};

    $$f[_requires_] = [ keys %req ] if %req;
  } # end for each $f in @keys

  close $fh;

  1;
} # end _init_module
#=====================================================================


sub new
{
  my ($class) = @_;

  # Create the object:
  bless {}, $class;
} # end new

#---------------------------------------------------------------------
# The hash of available functions (class attribute):
#
# This is automatically per-class, so subclasses normally don't need
# to override it.

{
my %functions;
sub _functions
{
  my $self = shift;

  $functions{ref($self) || $self} ||= {};
} # end _functions
} # end scope of %functions

#---------------------------------------------------------------------


sub add
{
  my ($self, @names) = @_;

  my $available = $self->_functions;

  while (@names) {
    my $name = shift @names;

    croak "$name is not an available function" unless $available->{$name};
    $self->{$name} = 1;

    next unless my $need = $available->{$name}[_requires_];
    push @names, grep { not $self->{$_} } @$need;
  } # end while @names to add

  return $self;
} # end add
#---------------------------------------------------------------------


sub generate_procset
{
  my ($self, $name) = @_;

  my @list = sort { $a->[_id_] cmp $b->[_id_] }
                  @{ $self->_functions }{ keys %$self };

  my $code = join('', map { $_->[_code_] } @list);

  my $blkid = join('', map { $_->[_id_] } @list);

  unless (defined $name) {
    $name = ref $self;
    $name =~ s/::/_/g;
  }

  return wantarray
      ? ("$name-$blkid", $code, $self->VERSION)
      : $code;
} # end generate_procset
#---------------------------------------------------------------------


sub add_to_file
{
  my $self = shift;
  my $ps   = shift;

  $ps->add_procset( $self->generate_procset(@_) );
} # end add_to_file

#=====================================================================
# Package Return Value:

__PACKAGE__->_init_module(\*DATA);

#use YAML::Tiny; print Dump(\%function);

=head1 NAME

PostScript::File::Functions - Collection of useful PostScript functions

=head1 VERSION

This document describes version 2.20 of
PostScript::File::Functions, released February 11, 2012
as part of PostScript-File version 2.20.

=head1 SYNOPSIS

  use PostScript::File;

  my $ps = PostScript::File->new;
  $ps->use_functions(qw( setColor showCenter ));
  $ps->add_to_page("1 setColor\n" .
                   "400 400 (Hello, World!) showCenter\n");

=head1 DESCRIPTION

PostScript::File::Functions provides a library of handy PostScript
functions that can be used in documents created with PostScript::File.
You don't normally use this module directly; PostScript::File's
C<use_functions> method loads it automatically.

=head1 POSTSCRIPT FUNCTIONS

=head2 boxPath

  LEFT TOP RIGHT BOTTOM boxPath

Given the coordinates of the sides of a box, this creates a new,
closed path starting at the bottom right corner, across to the
bottom left, up to the top left, over to the top right, and then
back to the bottom right.

=head2 clipBox

   LEFT TOP RIGHT BOTTOM clipBox

This clips to the box defined by the coordinates.

=head2 drawBox

   LEFT TOP RIGHT BOTTOM drawBox

This calls L<boxPath> to and then strokes the path using the current
pen.

=head2 fillBox

  LEFT TOP RIGHT BOTTOM COLOR fillBox

This fills the path created by L<boxPath> with C<COLOR>, which can
be anything accepted by L<setColor>.

=head2 hLine

  WIDTH X Y hline

Stroke a horizontal line with the current pen with the left endpoint
at position C<X, Y>, extending C<WIDTH> points rightwards.

=head2 setColor

  RGB-ARRAY|BW-NUMBER setColor

This combines C<setgray> and C<setrgbcolor> into a single function.
You can provide either an array of 3 numbers for C<setrgbcolor>, or
a single number for C<setgray>.  The L<PostScript::File/str>
function was designed to format the parameter to this function.

=head2 showCenter

  X Y STRING showCenter

This prints C<STRING> centered horizontally at position X using
baseline Y and the current font.

=head2 showLeft

  X Y STRING showLeft

This prints C<STRING> left justified at position X using baseline Y
and the current font.

=head2 showLines

  X Y LINES SPACING FUNC showLines

This calls C<FUNC> for each element of C<LINES>, which should be an
array of strings.  C<FUNC> is called with C<X Y STRING> on the
stack, and it must pop those off.  C<SPACING> is subtracted from
C<Y> after every line.  C<FUNC> will normally be C<showCenter>,
C<showLeft>, or C<showRight>.

=head2 showRight

  X Y STRING showRight

This prints C<STRING> right justified at position X using baseline Y
and the current font.

=head2 vLine

  HEIGHT X Y vline

Stroke a vertical line with the current pen with the bottom endpoint
at position C<X, Y>, extending C<HEIGHT> points upwards.

=head1 METHODS

While you don't normally deal with PostScript::File::Functions objects
directly, it is possible.  The following methods are available:



=head2 new

  $funcs = PostScript::File::Functions->new;

The constructor takes no parameters.


=head2 add

  $funcs->add('functionRequested', ...);

Add one or more functions to the procset to be generated.  All
dependencies of the requsted functions are added automatically.  See
L</"POSTSCRIPT FUNCTIONS"> for the list of available functions.


=head2 add_to_file

  $funcs->add_to_file($ps, $basename);

This is short for

  $ps->add_procset( $funcs->generate_procset($basename) );

C<$ps> should normally be a PostScript::File object.
See L<PostScript::File/add_procset>.


=head2 generate_procset

  ($name, $code, $version) = $funcs->generate_procset($basename);

This collects the requsted functions into a block of PostScript code.

C<$name> is a suitable name for the procset, created by appending the
ids of the requsted functions to C<$basename>.  If C<$basename> is
omitted, it defaults to the class name with C<::> replaced by C<_>.

C<$code> is a block of PostScript code that defines the functions.  It
contains no comments or excess whitespace.

C<$version> is the version number of the procset.

In scalar context, returns C<$code>.

=head1 DIAGNOSTICS

=over

=item C<< %s is not an available function >>

You requsted a function that this version of
PostScript::File::Functions doesn't provide.


=back

=head1 CONFIGURATION AND ENVIRONMENT

PostScript::File::Functions requires no configuration files or environment variables.

=head1 INCOMPATIBILITIES

None reported.

=head1 BUGS AND LIMITATIONS

No bugs have been reported.

=head1 AUTHOR

Christopher J. Madsen  S<C<< <perl AT cjmweb.net> >>>

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

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

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Christopher J. Madsen.

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

=head1 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.

=cut

__DATA__

%---------------------------------------------------------------------
% Set the color:  RGB-ARRAY|BW-NUMBER setColor
%
% This combines C<setgray> and C<setrgbcolor> into a single function.
% You can provide either an array of 3 numbers for C<setrgbcolor>, or
% a single number for C<setgray>.  The L<PostScript::File/str>
% function was designed to format the parameter to this function.

/setColor
{
  dup type (arraytype) eq {
    % We have an array, so it's RGB:
    aload pop
    setrgbcolor
  }{
    % Otherwise, it must be a gray level:
    setgray
  } ifelse
} bind def

%---------------------------------------------------------------------
% Create a rectangular path:  LEFT TOP RIGHT BOTTOM boxPath
%
% Given the coordinates of the sides of a box, this creates a new,
% closed path starting at the bottom right corner, across to the
% bottom left, up to the top left, over to the top right, and then
% back to the bottom right.

/boxPath
{
  % stack L T R B
  newpath
  2 copy moveto                 % move to BR
  3 index exch lineto	        % line to BL
  % stack L T R
  1 index
  % stack L T R T
  4 2 roll
  % stack R T L T
  lineto                        % line to TL
  lineto                        % line to TR
  closepath
} bind def

%---------------------------------------------------------------------
% Clip to a rectangle:   LEFT TOP RIGHT BOTTOM clipBox
%
% This clips to the box defined by the coordinates.

/clipBox { boxPath clip } bind def

%---------------------------------------------------------------------
% Draw a rectangle:   LEFT TOP RIGHT BOTTOM drawBox
%
% This calls L<boxPath> to and then strokes the path using the current
% pen.

/drawBox { boxPath stroke } bind def

%---------------------------------------------------------------------
% Fill a box with color:  LEFT TOP RIGHT BOTTOM COLOR fillBox
%
% This fills the path created by L<boxPath> with C<COLOR>, which can
% be anything accepted by L<setColor>.

/fillBox
{
  gsave
  setColor
  boxPath
  fill
  grestore
} bind def

%---------------------------------------------------------------------
% Print text centered at a point:  X Y STRING showCenter
%
% This prints C<STRING> centered horizontally at position X using
% baseline Y and the current font.

/showCenter
{
  newpath
  0 0 moveto
  % stack X Y STRING
  dup 4 1 roll                          % Put a copy of STRING on bottom
  % stack STRING X Y STRING
  false charpath flattenpath pathbbox   % Compute bounding box of STRING
  % stack STRING X Y Lx Ly Ux Uy
  pop exch pop                          % Discard Y values (... Lx Ux)
  add 2 div neg                         % Compute X offset
  % stack STRING X Y Ox
  0                                     % Use 0 for y offset
  newpath
  moveto
  rmoveto
  show
} bind def

%---------------------------------------------------------------------
% Print left justified text:  X Y STRING showLeft
%
% This prints C<STRING> left justified at position X using baseline Y
% and the current font.

/showLeft
{
  newpath
  3 1 roll  % STRING X Y
  moveto
  show
} bind def

%---------------------------------------------------------------------
% Print right justified text:  X Y STRING showRight
%
% This prints C<STRING> right justified at position X using baseline Y
% and the current font.

/showRight
{
  newpath
  0 0 moveto
  % stack X Y STRING
  dup 4 1 roll                          % Put a copy of STRING on bottom
  % stack STRING X Y STRING
  false charpath flattenpath pathbbox   % Compute bounding box of STRING
  % stack STRING X Y Lx Ly Ux Uy
  pop exch pop                          % Discard Y values (... Lx Ux)
  add neg                               % Compute X offset
  % stack STRING X Y Ox
  0                                     % Use 0 for y offset
  newpath
  moveto
  rmoveto
  show
} bind def

%---------------------------------------------------------------------
% Print text on multiple lines:  X Y LINES SPACING FUNC showLines
%
% This calls C<FUNC> for each element of C<LINES>, which should be an
% array of strings.  C<FUNC> is called with C<X Y STRING> on the
% stack, and it must pop those off.  C<SPACING> is subtracted from
% C<Y> after every line.  C<FUNC> will normally be C<showCenter>,
% C<showLeft>, or C<showRight>.

/showLines
{
  cvx                    % convert name of FUNC to executable function
  5 2 roll               % stack SPACING FUNC X Y LINES
  {                      % stack SPACING FUNC X Y STRING
    2 index              % stack SPACING FUNC X Y STRING X
    2 index              % stack SPACING FUNC X Y STRING X Y
    6 index  sub         % subtract SPACING from Y
    5 2 roll             % stack SPACING FUNC X Y' X Y STRING
    5 index exec         % execute FUNC; stack SPACING FUNC X Y'
  } forall
  pop pop pop pop
} bind def

%---------------------------------------------------------------------
% Stroke a horizontal line:  WIDTH X Y hline
%
% Stroke a horizontal line with the current pen with the left endpoint
% at position C<X, Y>, extending C<WIDTH> points rightwards.

/hLine
{
  newpath
  moveto
  0 rlineto stroke
} bind def

%---------------------------------------------------------------------
% Stroke a vertical line:  HEIGHT X Y vline
%
% Stroke a vertical line with the current pen with the bottom endpoint
% at position C<X, Y>, extending C<HEIGHT> points upwards.

/vLine
{
  newpath
  moveto
  0 exch rlineto stroke
} bind def

%---------------------------------------------------------------------
%EOF