CAM::PDF::GS::NoText - PDF graphic state


CAM-PDF documentation Contained in the CAM-PDF distribution.

Index


Code Index:

NAME

Top

CAM::PDF::GS::NoText - PDF graphic state

LICENSE

Top

See CAM::PDF.

SYNOPSIS

Top

    use CAM::PDF;
    my $pdf = CAM::PDF->new($filename);
    my $contentTree = $pdf->getPageContentTree(4);
    my $gs = $contentTree->computeGS(1);

DESCRIPTION

Top

This class is used to represent the graphic state at a point in the rendering flow of a PDF page. This does not include the graphics state for text blocks. That functionality is in the subclass, CAM::PDF::GS.

FUNCTIONS

Top

$pkg->new($hashref)

Create a new instance, setting all state values to their defaults. Stores a reference to $hashref and sets the property $hashref-{fm}> to undef.

$self->clone()

Duplicate the instance.

CONVERSION FUNCTIONS

Top

$self->applyMatrix($m1, $m2)

Apply $m1 to $m2, save in $m2.

$self->dot($matrix, $x, $y)

Compute the dot product of a position against the coordinate matrix.

$self->userToDevice($x, $y)

Convert user coordinates to device coordinates.

$self->getCoords($node)

Computes device coordinates for the specified node. This implementation handles line-drawing nodes.

$self->nodeType($node)

Returns one of block, path, paint, text or (the fallback case) op for the type of the specified node.

DATA FUNCTIONS

Top

$self->i($flatness)
$self->j($linejoin)
$self->J($linecap)
$self->ri($rendering_intent)
$self->Tc($charspace)
$self->TL($leading)
$self->Tr($rendering_mode)
$self->Ts($rise)
$self->Tw($wordspace)
$self->w($linewidth)
$self->g($gray)
$self->G($gray)
$self->rg($red, $green, $blue)
$self->RG($red, $green, $blue)
$self->k($cyan, $magenta, $yellow, $black)
$self->K($cyan, $magenta, $yellow, $black)
$self->gs()

(Not implemented...)

$self->cm M1, M2, M3, M4, M5, M6
$self->d($arrayref, $scalar)
$self->m($x, $y)

Move path.

$self->l($x, $y)

Line path.

$self->h()
$self->c($x1, $y1, $x2, $y2, $x3, $y3)
$self->v($x1, $y1, $x2, $y2)
$self->y($x1, $y1, $x2, $y2)
$self->re($x, $y, $width, $height)

Rectangle path.

AUTHOR

Top

See CAM::PDF


CAM-PDF documentation Contained in the CAM-PDF distribution.
package CAM::PDF::GS::NoText;

use 5.006;
use warnings;
use strict;
use Carp;
use English qw(-no_match_vars);

our $VERSION = '1.55';

##no critic (Bangs::ProhibitNumberedNames)

sub new
{
   my $pkg = shift;
   my $refs = shift;

   my $self = bless {

      mode => 'n',            # 'c'har, 's'tring, 'n'oop

      refs => $refs || {},

      c => undef,                # color
      cm => [1, 0, 0, 1, 0, 0],  # current transformation matrix
      w => 1.0,                  # line width
      J => 0,                    # line cap
      j => 0,                    # line join
      M => 0,                    # miter limit
      da => [],                  # dash pattern array
      dp => 0,                   # dash phase
      ri => undef,               # rendering intent
      i => 0,                    # flatness

      # Others, see PDF Ref page 149

      Tm => [1, 0, 0, 1, 0, 0],  # text matrix
      Tlm => [1, 0, 0, 1, 0, 0], # text matrix
      Tc => 0,                   # character spacing
      Tw => 0,                   # word spacing
      Tz => 1,                   # horizontal scaling
      TL => 0,                   # leading
      Tf => undef,               # font
      Tfs => undef,              # font size
      Tr => 0,                   # render mode
      Ts => 0,                   # rise
      wm => 0,                   # writing mode (0=horiz, 1=vert)

      Device => undef,
      device => undef,
      G => undef,
      g => undef,
      RG => undef,
      rg => undef,
      K => undef,
      k => undef,

      moved => [0,0],

      start => [0,0],
      last => [0,0],
      current => [0,0],

   }, $pkg;

   $self->{refs}->{fm} = undef;

   return $self;
}

sub clone
{
   my $self = shift;

   require Data::Dumper;
   my $newself;

   # don't clone references, just point to them
   my $refs = delete $self->{refs};

   if (!eval Data::Dumper->Dump([$self], ['newself']))  ## no critic (StringyEval)
   {
      die 'Error in '.__PACKAGE__."::clone() - $EVAL_ERROR";
   }
   $self->{refs} = $newself->{refs} = $refs;  # restore references
   @{$newself->{moved}} = (0,0);
   return $newself;
}

sub applyMatrix
{
   my $self = shift;
   my $m1 = shift;
   my $m2 = shift;

   if (ref $m1 ne 'ARRAY' || ref $m2 ne 'ARRAY')
   {
      require Data::Dumper;
      croak "Bad arrays:\n".Dumper($m1,$m2);
   }

   my @m3;

   $m3[0] = $m2->[0]*$m1->[0] + $m2->[2]*$m1->[1];
   $m3[1] = $m2->[1]*$m1->[0] + $m2->[3]*$m1->[1];
   $m3[2] = $m2->[0]*$m1->[2] + $m2->[2]*$m1->[3];
   $m3[3] = $m2->[1]*$m1->[2] + $m2->[3]*$m1->[3];
   $m3[4] = $m2->[0]*$m1->[4] + $m2->[2]*$m1->[5] + $m2->[4];
   $m3[5] = $m2->[1]*$m1->[4] + $m2->[3]*$m1->[5] + $m2->[5];

   @{$m2} = @m3;
   return;
}

sub dot
{
   my $self = shift;
   my $cm = shift;
   my $x = shift;
   my $y = shift;

   return ($cm->[0]*$x + $cm->[2]*$y + $cm->[4],
           $cm->[1]*$x + $cm->[3]*$y + $cm->[5]);
}

sub userToDevice
{
   my $self = shift;
   my $x = shift;
   my $y = shift;

   ($x,$y) = $self->dot($self->{cm}, $x, $y);
   $x -= $self->{refs}->{mediabox}->[0];
   $y -= $self->{refs}->{mediabox}->[1];
   return ($x, $y);
}

my %path_cmds  = map {$_ => 1} qw(m l h c v y re);
my %paint_cmds = map {$_ => 1} qw(S s F f f* B B* b b* n);

sub getCoords
{
   my $self = shift;
   my $node = shift;

   my ($x1,$y1,$x2,$y2);
   if ($path_cmds{$node->{name}})
   {
      ($x1,$y1) = $self->userToDevice(@{$self->{last}});
      ($x2,$y2) = $self->userToDevice(@{$self->{current}});
   }
   return ($x1,$y1,$x2,$y2);
}

sub nodeType
{
   my $self = shift;
   my $node = shift;

   return $node->{type} eq 'block'     ? 'block'
        : $path_cmds{$node->{name}}    ? 'path'
        : $paint_cmds{$node->{name}}   ? 'paint'
        : $node->{name} =~ / \A T /xms ? 'text'
        :                                'op';
}

# default setters
{
   no strict 'refs'; ## no critic(ProhibitNoStrict)
   foreach my $name (qw(i j J ri Tc TL Tr Ts Tw w))
   {
      *{$name} = sub { $_[0]->{$name} = $_[1]; return; };
   }
}

sub g
{
   my $self = shift;
   my $g = shift;

   $self->{g} = [$g];
   $self->{device} = 'DeviceGray';
   return;
}

sub G
{
   my $self = shift;
   my $g = shift;

   $self->{G} = [$g];
   $self->{Device} = 'DeviceGray';
   return;
}

sub rg
{
   my $self = shift;
   my $rd = shift;
   my $gr = shift;
   my $bl = shift;

   $self->{rg} = [$rd, $gr, $bl];
   $self->{device} = 'DeviceRGB';
   return;
}

sub RG
{
   my $self = shift;
   my $rd = shift;
   my $gr = shift;
   my $bl = shift;

   $self->{RG} = [$rd, $gr, $bl];
   $self->{Device} = 'DeviceRGB';
   return;
}

sub k
{
   my $self = shift;
   my $c = shift;
   my $m = shift;
   my $y = shift;
   my $k = shift;

   $self->{k} = [$c, $m, $y, $k];
   $self->{device} = 'DeviceCMYK';
   return;
}

sub K
{
   my $self = shift;
   my $c = shift;
   my $m = shift;
   my $y = shift;
   my $k = shift;

   $self->{K} = [$c, $m, $y, $k];
   $self->{Device} = 'DeviceCMYK';
   return;
}

sub gs
{
   my $self = shift;

   # See PDF Ref page 157
   #warn 'gs operator not yet implemented';
   return;
}

sub cm
{
   my ($self, @mtx) = @_;

   $self->applyMatrix([@mtx], $self->{cm});
   return;
}

sub d
{
   my $self = shift;
   my $da = shift;
   my $dp = shift;

   @{$self->{da}} = @{$da};
   $self->{dp} = $dp;
   return;
}

sub m    ##no critic (Homonym)
{
   my $self = shift;
   my $x = shift;
   my $y = shift;

   @{$self->{start}} = @{$self->{last}} = @{$self->{current}} = ($x,$y);
   return;
}

sub l
{
   my $self = shift;
   my $x = shift;
   my $y = shift;

   @{$self->{last}} = @{$self->{current}};
   @{$self->{current}} = ($x,$y);
   return;
}

sub h
{
   my $self = shift;

   @{$self->{last}} = @{$self->{current}};
   @{$self->{current}} = @{$self->{start}};
   return;
}

sub c  ## no critic (ProhibitManyArgs)
{
   my $self = shift;
   my $x1 = shift;
   my $y1 = shift;
   my $x2 = shift;
   my $y2 = shift;
   my $x3 = shift;
   my $y3 = shift;

   @{$self->{last}} = @{$self->{current}};
   @{$self->{current}} = ($x3,$y3);
   return;
}

sub v
{
   my $self = shift;
   my $x1 = shift;
   my $y1 = shift;
   my $x2 = shift;
   my $y2 = shift;

   @{$self->{last}} = @{$self->{current}};
   @{$self->{current}} = ($x2,$y2);
   return;
}

sub y    ##no critic (Homonym)
{
   my $self = shift;
   my $x1 = shift;
   my $y1 = shift;
   my $x2 = shift;
   my $y2 = shift;

   @{$self->{last}} = @{$self->{current}};
   @{$self->{current}} = ($x2,$y2);
   return;
}

sub re
{
   my $self = shift;
   my $x = shift;
   my $y = shift;
   my $w = shift;
   my $h = shift;

   @{$self->{start}} = @{$self->{last}} = @{$self->{current}} = ($x,$y);
   return;
}

1;
__END__