CAM-PDFTaxforms
view release on metacpan or search on metacpan
lib/CAM/PDFTaxforms.pm view on Meta::CPAN
# Try to pull out the font size, if any. If more than
# one, pick the last one. Font commands look like:
# "/<fontname> <size> Tf"
#JWT: CHGD. TO NEXT (BUG#58144 PATCH): if ($da =~ m{ \s*/(\w+)\s+(\d+)\s+Tf.*? \z }xms)
if ($da =~ m{ \s*/([\w-]+)\s+([.\d]+)\s+Tf.*? \z }xmso)
{
$fontname = $1;
$fontsize = $2;
if ($fontname)
{
if ($propdict->{DR})
{
my $dr = $self->getValue($propdict->{DR});
$fontmetrics = $self->getFontMetrics($dr, $fontname);
}
#print STDERR "Didn't get font\n" if (!$fontmetrics);
}
}
}
my %flags = (
Justify => 'left',
);
if ($propdict->{Ff})
{
# Just decode the ones we actually care about
# PDF ref, 3rd ed pp 532,543
my $ff = $self->getValue($propdict->{Ff});
my @flags = split m//xms, unpack 'b*', pack 'V', $ff;
$flags{ReadOnly} = $flags[0];
$flags{Required} = $flags[1];
$flags{NoExport} = $flags[2];
$flags{Multiline} = $flags[12];
$flags{Password} = $flags[13];
$flags{FileSelect} = $flags[20];
$flags{DoNotSpellCheck} = $flags[22];
$flags{DoNotScroll} = $flags[23];
}
if ($propdict->{Q})
{
my $q = $self->getValue($propdict->{Q}) || 0;
$flags{Justify} = $q==2 ? 'right' : ($q==1 ? 'center' : 'left');
}
# The order of the following sections is important!
$text =~ s/ [^\n] /*/gxms if ($flags{Password}); # Asterisks for password characters
if ($fontmetrics && ! $fontsize)
{
# Fix autoscale fonts
$stringwidth = 0;
my $lines = 0;
for my $line (split /\n/xmso, $text) # trailing null strings omitted
{
$lines++;
my $w = $self->getStringWidth($fontmetrics, $line);
$stringwidth = $w if ($w && $w > $stringwidth);
}
$lines ||= 1;
# Initial guess
$fontsize = ($dy - 2 * $border) / ($lines * 1.5);
my $fontwidth = $fontsize * $stringwidth;
my $maxwidth = $dx - 2 * $border;
$fontsize *= $maxwidth / $fontwidth if ($fontwidth > $maxwidth);
$da =~ s/ \/$fontname\s+0\s+Tf\b /\/$fontname $fontsize Tf/gxms;
}
if ($fontsize)
{
# This formula is TOTALLY empirical. It's probably wrong.
# #JWT:CHGD. TO NEXT: $ty = $border + 2 + (9 - $fontsize) * 0.4;
$ty = $border + 2 + (5 - $fontsize) * 0.4;
}
# escape characters
$text = $self->writeString($text);
if ($flags{Multiline})
{
# TODO: wrap the field with wrapString()??
# Shawn Dawson of Silent Solutions pointed out that this does not auto-wrap the input text
my $linebreaks = $text =~ s/ \\n /\) Tj T* \(/gxms;
# Total guess work:
# line height is either 150% of fontsize or thrice
# the corner offset
$tl = $fontsize ? $fontsize * 1.5 : $ty * 3;
# Bottom aligned
#$ty += $linebreaks * $tl;
# Top aligned
$ty = $dy - $border - $tl;
warn 'Justified text not supported for multiline fields' if ($flags{Justify} ne 'left');
$tl .= ' TL';
}
else
{
#JWT: CHGD. TO NEXT (BUG#58144 PATCH): if ($flags{Justify} ne 'left' && $fontmetrics)
if ($flags{Justify} ne 'left')
{
#JWT: CHGD. TO NEXT 8: my $width = $stringwidth || $self->getStringWidth($fontmetrics, $text);
my $width;
if ($stringwidth || $fontmetrics) {
#JWT:CHGD TO NEXT PER BUG#122890: $width = $self->getStringWidth($fontmetrics, $text);
$width = $self->getStringWidth($fontmetrics, (substr $text, 1, (length $text)-2));
} else { #JWT: NO FONT METRICS, SO HAVE TO GUESS WIDTH:
$width = (length($text)-1) * 0.57; #JWT:FIXME (HACK) FOR RIGHT-JUSTIFYING STANDARD SIZE 8 NUMERIC FONT.
my $commas = $text;
$width -= 0.29 while ($commas =~ s/\,//o); #JWT:FIXME (HACK) FUDGE FOR WIDTH OF COMMAS (SMALLER THAN DIGITS)
}
my $diff = $dx - $width * $fontsize;
$diff = 0 if ($diff < 0); #JWT:ADDED.
if ($flags{Justify} eq 'center')
{
$text = ($diff/2)." 0 Td $text";
}
elsif ($flags{Justify} eq 'right')
{
$text = "$diff 0 Td $text";
}
}
}
# Move text from lower left corner of form field
my $tm = "1 0 0 1 $tx $ty Tm ";
# if not 'none', draw a background as a filled rectangle of solid color
my $background_color
= $opts{background_color} eq 'none' ? q{}
: ref $opts{background_color} ? "@{$opts{background_color}} rgb"
: "$opts{background_color} g";
my $background = $background_color ? "$background_color 0 0 $dx $dy re f" : q{};
$text = "$tl $da $tm $text Tj";
$text = "$background /Tx BMC q 1 1 ".($dx-$border).q{ }.($dy-$border)." re W n BT $text ET Q EMC";
unless ($fieldType eq 'Btn') #JWT:ADDED CONDITION:
{
$formdict->{Length} = CAM::PDF::Node->new('number', length($text), $formonum, $formgnum);
# JWT:NEXT 3 ADDED PER BUG#125299 PATCH:
$formdict->{StreamData} = CAM::PDF::Node->new('stream', $text, $formonum, $formgnum);
delete $formdict->{ Filter };
$self-> encodeObject( $formonum, 'FlateDecode' );
}
( run in 1.716 second using v1.01-cache-2.11-cpan-39bf76dae61 )