1#======================================================================= 2# ____ ____ _____ _ ____ ___ ____ 3# | _ \| _ \| ___| _ _ / \ | _ \_ _| |___ \ 4# | |_) | | | | |_ (_) (_) / _ \ | |_) | | __) | 5# | __/| |_| | _| _ _ / ___ \| __/| | / __/ 6# |_| |____/|_| (_) (_) /_/ \_\_| |___| |_____| 7# 8# A Perl Module Chain to faciliate the Creation and Modification 9# of High-Quality "Portable Document Format (PDF)" Files. 10# 11#======================================================================= 12# 13# THIS IS A REUSED PERL MODULE, FOR PROPER LICENCING TERMS SEE BELOW: 14# 15# 16# Copyright Martin Hosken <Martin_Hosken@sil.org> 17# 18# No warranty or expression of effectiveness, least of all regarding 19# anyone's safety, is implied in this software or documentation. 20# 21# This specific module is licensed under the Perl Artistic License. 22# 23# 24# $Id: Anchor.pm,v 2.0 2005/11/16 02:16:00 areibens Exp $ 25# 26#======================================================================= 27package PDF::API3::Compat::API2::Basic::TTF::Anchor; 28 29=head1 TITLE 30 31PDF::API3::Compat::API2::Basic::TTF::Anchor - Anchor points for GPOS tables 32 33=head1 DESCRIPTION 34 35The Anchor defines an anchor point on a glyph providing various information 36depending on how much is available, including such information as the co-ordinates, 37a curve point and even device specific modifiers. 38 39=head1 INSTANCE VARIABLES 40 41=over 4 42 43=item x 44 45XCoordinate of the anchor point 46 47=item y 48 49YCoordinate of the anchor point 50 51=item p 52 53Curve point on the glyph to use as the anchor point 54 55=item xdev 56 57Device table (delta) for the xcoordinate 58 59=item ydev 60 61Device table (delta) for the ycoordinate 62 63=item xid 64 65XIdAnchor for multiple master horizontal metric id 66 67=item yid 68 69YIdAnchor for multiple master vertical metric id 70 71=back 72 73=head1 METHODS 74 75=cut 76 77use strict; 78 79 80=head2 new 81 82Creates a new Anchor 83 84=cut 85 86sub new 87{ 88 my ($class) = shift; 89 my ($self) = {@_}; 90 91 bless $self, $class; 92} 93 94 95=head2 read($fh) 96 97Reads the anchor from the given file handle at that point. The file handle is left 98at an arbitrary read point, usually the end of something! 99 100=cut 101 102sub read 103{ 104 my ($self, $fh) = @_; 105 my ($dat, $loc, $fmt, $x, $y, $p, $xoff, $yoff); 106 107 $fh->read($dat, 6); 108 ($fmt, $x, $y) = unpack('n*', $dat); 109 if ($fmt == 4) 110 { ($self->{'xid'}, $self->{'yid'}) = ($x, $y); } 111 else 112 { ($self->{'x'}, $self->{'y'}) = ($x, $y); } 113 114 if ($fmt == 2) 115 { 116 $fh->read($dat, 2); 117 $self->{'p'} = unpack('n', $dat); 118 } elsif ($fmt == 3) 119 { 120 $fh->read($dat, 4); 121 ($xoff, $yoff) = unpack('n2', $dat); 122 $loc = $fh->tell() - 10; 123 if ($xoff) 124 { 125 $fh->seek($loc + $xoff, 0); 126 $self->{'xdev'} = PDF::API3::Compat::API2::Basic::TTF::Delta->new->read($fh); 127 } 128 if ($yoff) 129 { 130 $fh->seek($loc + $yoff, 0); 131 $self->{'ydev'} = PDF::API3::Compat::API2::Basic::TTF::Delta->new->read($fh); 132 } 133 } 134 $self; 135} 136 137 138=head2 out($fh, $style) 139 140Outputs the Anchor to the given file handle at this point also addressing issues 141of deltas. If $style is set, then no output is set to the file handle. The return 142value is the output string. 143 144=cut 145 146sub out 147{ 148 my ($self, $fh, $style) = @_; 149 my ($xoff, $yoff, $fmt, $out); 150 151 if (defined $self->{'xid'} || defined $self->{'yid'}) 152 { $out = pack('n*', 4, $self->{'xid'}, $self->{'yid'}); } 153 elsif (defined $self->{'p'}) 154 { $out = pack('n*', 2, @{$self}{'x', 'y', 'p'}); } 155 elsif (defined $self->{'xdev'} || defined $self->{'ydev'}) 156 { 157 $out = pack('n*', 3, @{$self}{'x', 'y'}); 158 if (defined $self->{'xdev'}) 159 { 160 $out .= pack('n2', 10, 0); 161 $out .= $self->{'xdev'}->out($fh, 1); 162 $yoff = length($out) - 10; 163 } 164 else 165 { $out .= pack('n2', 0, 0); } 166 if (defined $self->{'ydev'}) 167 { 168 $yoff = 10 unless $yoff; 169 substr($out, 8, 2) = pack('n', $yoff); 170 $out .= $self->{'ydev'}->out($fh, 1); 171 } 172 } else 173 { $out = pack('n3', 1, @{$self}{'x', 'y'}); } 174 $fh->print($out) unless $style; 175 $out; 176} 177 178 179=head2 $a->out_xml($context) 180 181Outputs the anchor in XML 182 183=cut 184 185sub out_xml 186{ 187 my ($self, $context, $depth) = @_; 188 my ($fh) = $context->{'fh'}; 189 my ($end); 190 191 $fh->print("$depth<anchor x='$self->{'x'}' y='$self->{'y'}'"); 192 $fh->print(" p='$self->{'p'}'") if defined ($self->{'p'}); 193 $end = (defined $self->{'xdev'} || defined $self->{'ydev'} || defined $self->{'xid'} || defined $self->{'yid'}); 194 unless ($end) 195 { 196 $fh->print("/>\n"); 197 return $self; 198 } 199 200 if (defined $self->{'xdev'}) 201 { 202 $fh->print("$depth$context->{'indent'}<xdev>\n"); 203 $self->{'xdev'}->out_xml($context, $depth . ($context->{'indent'} x 2)); 204 $fh->print("$depth$context->{'indent'}</xdev>\n"); 205 } 206 207 if (defined $self->{'ydev'}) 208 { 209 $fh->print("$depth$context->{'indent'}<ydev>\n"); 210 $self->{'ydev'}->out_xml($context, $depth . ($context->{'indent'} x 2)); 211 $fh->print("$depth$context->{'indent'}</ydev>\n"); 212 } 213 214 if (defined $self->{'xid'} || defined $self->{'yid'}) 215 { 216 $fh->print("$depth$context->{'indent'}<mmaster"); 217 $fh->print(" xid='$self->{'xid'}'") if defined ($self->{'xid'}); 218 $fh->print(" yid='$self->{'yid'}'") if defined ($self->{'yid'}); 219 $fh->print("/>\n"); 220 } 221 $fh->print("$depth</anchor>\n"); 222 $self; 223} 224 225 226=head1 AUTHOR 227 228Martin Hosken Martin_Hosken@sil.org. See L<PDF::API3::Compat::API2::Basic::TTF::Font> for copyright and 229licensing. 230 231=cut 232 2331; 234 235