#=======================================================================
# ____ ____ _____ _ ____ ___ ____
# | _ \| _ \| ___| _ _ / \ | _ \_ _| |___ \
# | |_) | | | | |_ (_) (_) / _ \ | |_) | | __) |
# | __/| |_| | _| _ _ / ___ \| __/| | / __/
# |_| |____/|_| (_) (_) /_/ \_\_| |___| |_____|
#
# A Perl Module Chain to faciliate the Creation and Modification
# of High-Quality "Portable Document Format (PDF)" Files.
#
# Copyright 1999-2005 Alfred Reibenschuh <areibens@cpan.org>.
#
#=======================================================================
#
# THIS LIBRARY IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR
# MODIFY IT UNDER THE TERMS OF THE GNU LESSER GENERAL PUBLIC
# LICENSE AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION; EITHER
# VERSION 2 OF THE LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION.
#
# THIS FILE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
# AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
# SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS FILE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# SEE THE GNU LESSER GENERAL PUBLIC LICENSE FOR MORE DETAILS.
#
# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU LESSER GENERAL PUBLIC
# LICENSE ALONG WITH THIS LIBRARY; IF NOT, WRITE TO THE
# FREE SOFTWARE FOUNDATION, INC., 59 TEMPLE PLACE - SUITE 330,
# BOSTON, MA 02111-1307, USA.
#
# $Id: CoreFont.pm,v 2.0 2005/11/16 02:18:14 areibens Exp $
#
#=======================================================================
=head1 NAME
PDF::API2::Resource::Font::CoreFont - Module for using the 14 PDF built-in Fonts.
=head1 SYNOPSIS
#
use PDF::API2;
#
$pdf = PDF::API2->new;
$cft = $pdf->corefont('Times-Roman');
#
=head1 METHODS
=over 4
=cut
BEGIN {
use utf8;
use Encode qw(:all);
use vars qw( @ISA $fonts $alias $subs $encodings $VERSION );
@ISA=qw(PDF::API2::Resource::Font);
( $VERSION ) = sprintf '%i.%03i', split(/\./,('$Revision: 2.0 $' =~ /Revision: (\S+)\s/)[0]); # $Date: 2005/11/16 02:18:14 $
}
no warnings qw[ deprecated recursion uninitialized ];
=item $font = PDF::API2::Resource::Font::CoreFont->new $pdf, $fontname, %options
Returns a corefont object.
=cut
=pod
Valid %options are:
I<-encode>
... changes the encoding of the font from its default.
See I<perl's Encode> for the supported values.
I<-pdfname> ... changes the reference-name of the font from its default.
The reference-name is normally generated automatically and can be
retrived via $pdfname=$font->name.
=cut
sub _look_for_font ($)
{
my $fname=shift;
## return(%{$fonts->{$fname}}) if(defined $fonts->{$fname});
eval "require PDF::API2::Resource::Font::CoreFont::$fname; ";
unless($@)
{
no strict 'refs';
my $obj = "PDF::API2::Resource::Font::CoreFont::".$fname;
$fonts->{$fname} = deep_copy(${$obj."::FONTDATA"});
$fonts->{$fname}->{uni}||=[];
foreach my $n (0..255)
{
$fonts->{$fname}->{uni}->[$n]=uniByName($fonts->{$fname}->{char}->[$n]) unless(defined $fonts->{$fname}->{uni}->[$n]);
}
return(%{$fonts->{$fname}});
}
else
{
die "requested font '$fname' not installed ";
}
}
#
# Deep copy something, thanks to Randal L. Schwartz
# Changed to deal w/ CODE refs, in which case it doesn't try to deep copy
#
sub deep_copy
{
my $this = shift;
if (not ref $this)
{
$this;
}
elsif (ref $this eq "ARRAY")
{
[map &deep_copy($_), @$this];
}
elsif (ref $this eq "HASH")
{
+{map { $_ => &deep_copy($this->{$_}) } keys %$this};
}
elsif (ref $this eq "CODE")
{
# Can't deep copy code refs
return $this;
}
else
{
die "what type is $_?";
}
}
sub _look_for_fontfile ($)
{
my $fname=shift;
my $fpath=undef;
foreach my $dir (@INC)
{
$fpath="$dir/PDF/API2/Resource/Font/CoreFont/$fname";
last if(-f $fpath);
$fpath=undef;
}
return($fpath);
}
sub _look_for_fontmetricfile ($)
{
my $fname=shift;
my $fpath=undef;
foreach my $dir (@INC)
{
$fpath="$dir/PDF/API2/Resource/Font/CoreFont/$fname.fm";
last if(-f $fpath);
$fpath=undef;
}
return($fpath);
}
sub new
{
my ($class,$pdf,$name,@opts) = @_;
my ($self,$data);
my %opts=();
if(-f $name)
{
eval "require '$name'; ";
$name=basename($name,'.pm');
}
my $lookname=lc($name);
$lookname=~s/[^a-z0-9]+//gi;
%opts=@opts if((scalar @opts)%2 == 0);
$opts{-encode}||='asis';
$lookname = defined($alias->{$lookname}) ? $alias->{$lookname} : $lookname ;
if(defined $subs->{$lookname})
{
$data={_look_for_font($subs->{$lookname}->{-alias})};
foreach my $k (keys %{$subs->{$lookname}})
{
next if($k=~/^\-/);
$data->{$k}=$subs->{$lookname}->{$k};
}
}
else
{
unless(defined $opts{-metrics})
{
$data={_look_for_font($lookname)};
}
else
{
$data={%{$opts{-metrics}}};
}
}
die "Undefined Font '$name($lookname)'" unless($data->{fontname});
# we have data now here so we need to check if
# there is a -ttfile or -afmfile/-pfmfile/-pfbfile
# and proxy the call to the relevant modules
#
#if(defined $data->{-ttfile} && $data->{-ttfile}=_look_for_fontfile($data->{-ttfile}))
#{
# return(PDF::API2::Resource::CIDFont::TrueType->new($pdf,$data->{-ttfile},@opts));
#}
#elsif(defined $data->{-pfbfile} && $data->{-pfbfile}=_look_for_fontfile($data->{-pfbfile}))
#{
# $data->{-afmfile}=_look_for_fontfile($data->{-afmfile});
# return(PDF::API2::Resource::Font::Postscript->new($pdf,$data->{-pfbfile},$data->{-afmfile},@opts));
#}
#elsif(defined $data->{-gfx})
#{ # to be written and tested in 'Maki' first!
# return(PDF::API2::Resource::Font::gFont->new($pdf,$data,@opts);
#}
$class = ref $class if ref $class;
$self = $class->SUPER::new($pdf, $data->{apiname}.pdfkey().'~'.time());
$pdf->new_obj($self) unless($self->is_obj($pdf));
$self->{' data'}=$data;
$self->{-dokern}=1 if($opts{-dokern});
$self->{'Subtype'} = PDFName($self->data->{type});
$self->{'BaseFont'} = PDFName($self->fontname);
if($opts{-pdfname})
{
$self->name($opts{-pdfname});
}
unless($self->data->{iscore})
{
$self->{'FontDescriptor'}=$self->descrByData();
}
$self->encodeByData($opts{-encode});
return($self);
}
=item $font = PDF::API2::Resource::Font::CoreFont->new_api $api, $fontname, %options
Returns a corefont object. This method is different from 'new' that
it needs an PDF::API2-object rather than a PDF::API2::PDF::File-object.
=cut
sub new_api
{
my ($class,$api,@opts)=@_;
my $obj=$class->new($api->{pdf},@opts);
$api->{pdf}->new_obj($obj) unless($obj->is_obj($api->{pdf}));
## $api->resource('Font',$obj->name,$obj);
$api->{pdf}->out_obj($api->{pages});
return($obj);
}
=item PDF::API2::Resource::Font::CoreFont->loadallfonts()
"Requires in" all fonts available as corefonts.
=cut
sub loadallfonts
{
foreach my $f (qw[
courier courierbold courierboldoblique courieroblique
georgia georgiabold georgiabolditalic georgiaitalic
helveticaboldoblique helveticaoblique helveticabold helvetica
symbol
timesbolditalic timesitalic timesroman timesbold
verdana verdanabold verdanabolditalic verdanaitalic
webdings
wingdings
zapfdingbats
])
{
_look_for_font($f);
}
}
# andalemono
# arialrounded
# bankgothic
# impact
# ozhandicraft
# trebuchet
# trebuchetbold
# trebuchetbolditalic
# trebuchetitalic
BEGIN
{
$alias = {
## Windows Fonts with Type1 equivalence
'arial' => 'helvetica',
'arialitalic' => 'helveticaoblique',
'arialbold' => 'helveticabold',
'arialbolditalic' => 'helveticaboldoblique',
'times' => 'timesroman',
'timesnewromanbolditalic' => 'timesbolditalic',
'timesnewromanbold' => 'timesbold',
'timesnewromanitalic' => 'timesitalic',
'timesnewroman' => 'timesroman',
'couriernewbolditalic' => 'courierboldoblique',
'couriernewbold' => 'courierbold',
'couriernewitalic' => 'courieroblique',
'couriernew' => 'courier',
};
$subs = {
#'bankgothicbold' => {
# 'apiname' => 'Bg2',
# '-alias' => 'bankgothic',
# 'fontname' => 'BankGothicMediumBT,Bold',
# 'flags' => 32+262144,
#},
#'bankgothicbolditalic' => {
# 'apiname' => 'Bg3',
# '-alias' => 'bankgothic',
# 'fontname' => 'BankGothicMediumBT,BoldItalic',
# 'italicangle' => -15,
# 'flags' => 96+262144,
#},
#'bankgothicitalic' => {
# 'apiname' => 'Bg4',
# '-alias' => 'bankgothic',
# 'fontname' => 'BankGothicMediumBT,Italic',
# 'italicangle' => -15,
# 'flags' => 96,
#},
# 'impactitalic' => {
# 'apiname' => 'Imp2',
# '-alias' => 'impact',
# 'fontname' => 'Impact,Italic',
# 'italicangle' => -12,
# },
# 'ozhandicraftbold' => {
# 'apiname' => 'Oz2',
# '-alias' => 'ozhandicraft',
# 'fontname' => 'OzHandicraftBT,Bold',
# 'italicangle' => 0,
# 'flags' => 32+262144,
# },
# 'ozhandicraftitalic' => {
# 'apiname' => 'Oz3',
# '-alias' => 'ozhandicraft',
# 'fontname' => 'OzHandicraftBT,Italic',
# 'italicangle' => -15,
# 'flags' => 96,
# },
# 'ozhandicraftbolditalic' => {
# 'apiname' => 'Oz4',
# '-alias' => 'ozhandicraft',
# 'fontname' => 'OzHandicraftBT,BoldItalic',
# 'italicangle' => -15,
# 'flags' => 96+262144,
# },
# 'arialroundeditalic' => {
# 'apiname' => 'ArRo2',
# '-alias' => 'arialrounded',
# 'fontname' => 'ArialRoundedMTBold,Italic',
# 'italicangle' => -15,
# 'flags' => 96+262144,
# },
# 'arialitalic' => {
# 'apiname' => 'Ar2',
# '-alias' => 'arial',
# 'fontname' => 'Arial,Italic',
# 'italicangle' => -15,
# 'flags' => 96,
# },
# 'arialbolditalic' => {
# 'apiname' => 'Ar3',
# '-alias' => 'arial',
# 'fontname' => 'Arial,BoldItalic',
# 'italicangle' => -15,
# 'flags' => 96+262144,
# },
# 'arialbold' => {
# 'apiname' => 'Ar4',
# '-alias' => 'arial',
# 'fontname' => 'Arial,Bold',
# 'flags' => 32+262144,
# },
};
$fonts = { };
}
1;
__END__
=back
=head1 SUPPORTED FONTS
=item PDF::API::CoreFont supports the following 'Adobe Core Fonts':
Courier
Courier-Bold
Courier-BoldOblique
Courier-Oblique
Helvetica
Helvetica-Bold
Helvetica-BoldOblique
Helvetica-Oblique
Symbol
Times-Bold
Times-BoldItalic
Times-Italic
Times-Roman
ZapfDingbats
=item PDF::API::CoreFont supports the following 'Windows Fonts':
Georgia
Georgia,Bold
Georgia,BoldItalic
Georgia,Italic
Verdana
Verdana,Bold
Verdana,BoldItalic
Verdana,Italic
Webdings
Wingdings
=head1 AUTHOR
alfred reibenschuh
=head1 HISTORY
$Log: CoreFont.pm,v $
Revision 2.0 2005/11/16 02:18:14 areibens
revision workaround for SF cvs import not to screw up CPAN
Revision 1.2 2005/11/16 01:27:50 areibens
genesis2
Revision 1.1 2005/11/16 01:19:27 areibens
genesis
Revision 1.17 2005/10/19 19:15:12 fredo
added handling of optional kerning
Revision 1.16 2005/10/01 22:41:07 fredo
fixed font-naming race condition for multiple document updates
Revision 1.15 2005/09/26 20:07:19 fredo
added fontmetric stub
Revision 1.14 2005/09/12 16:56:20 fredo
applied mod_perl patch by Paul Schilling <pfschill@sbcglobal.net>
Revision 1.13 2005/06/17 19:44:03 fredo
fixed CPAN modulefile versioning (again)
Revision 1.12 2005/06/17 18:53:34 fredo
fixed CPAN modulefile versioning (dislikes cvs)
Revision 1.11 2005/05/29 09:47:38 fredo
cosmetic changes
Revision 1.10 2005/03/14 22:01:27 fredo
upd 2005
Revision 1.9 2005/01/21 10:04:15 fredo
rewrite fontproxy comment
Revision 1.8 2004/12/16 00:30:54 fredo
added no warn for recursion
Revision 1.7 2004/11/22 02:08:42 fredo
aaa
Revision 1.6 2004/06/21 22:25:44 fredo
added custom corefont handling
Revision 1.5 2004/06/15 09:14:53 fredo
removed cr+lf
Revision 1.4 2004/06/07 19:44:43 fredo
cleaned out cr+lf for lf
Revision 1.3 2003/12/08 13:06:01 Administrator
corrected to proper licencing statement
Revision 1.2 2003/11/30 17:32:48 Administrator
merged into default
Revision 1.1.1.1.2.2 2003/11/30 16:57:05 Administrator
merged into default
Revision 1.1.1.1.2.1 2003/11/30 14:45:22 Administrator
added CVS id/log
=cut