<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Font::TTF::Anchor;

=head1 NAME

Font::TTF::Anchor - Anchor points for GPOS tables

=head1 DESCRIPTION

The Anchor defines an anchor point on a glyph providing various information
depending on how much is available, including such information as the co-ordinates,
a curve point and even device specific modifiers.

=head1 INSTANCE VARIABLES

=over 4

=item x

XCoordinate of the anchor point

=item y

YCoordinate of the anchor point

=item p

Curve point on the glyph to use as the anchor point

=item xdev

Device table (delta) for the xcoordinate

=item ydev

Device table (delta) for the ycoordinate

=item xid

XIdAnchor for multiple master horizontal metric id

=item yid

YIdAnchor for multiple master vertical metric id

=back

=head1 METHODS

=cut

use strict;
use Font::TTF::Utils;


=head2 new

Creates a new Anchor

=cut

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

    bless $self, $class;
}


=head2 read($fh)

Reads the anchor from the given file handle at that point. The file handle is left
at an arbitrary read point, usually the end of something!

=cut

sub read
{
    my ($self, $fh) = @_;
    my ($dat, $loc, $fmt, $p, $xoff, $yoff);

    $fh-&gt;read($dat, 6);
    $fmt = unpack('n', $dat);
    if ($fmt == 4)
    { ($self-&gt;{'xid'}, $self-&gt;{'yid'}) = TTF_Unpack('S2', substr($dat,2)); }
    else
    { ($self-&gt;{'x'}, $self-&gt;{'y'}) = TTF_Unpack('s2', substr($dat,2)); }

    if ($fmt == 2)
    {
        $fh-&gt;read($dat, 2);
        $self-&gt;{'p'} = unpack('n', $dat);
    } elsif ($fmt == 3)
    {
        $fh-&gt;read($dat, 4);
        ($xoff, $yoff) = unpack('n2', $dat);
        $loc = $fh-&gt;tell() - 10;
        if ($xoff)
        {
            $fh-&gt;seek($loc + $xoff, 0);
            $self-&gt;{'xdev'} = Font::TTF::Delta-&gt;new-&gt;read($fh);
        }
        if ($yoff)
        {
            $fh-&gt;seek($loc + $yoff, 0);
            $self-&gt;{'ydev'} = Font::TTF::Delta-&gt;new-&gt;read($fh);
        }
    }
    $self;
}


=head2 out($fh, $style)

Outputs the Anchor to the given file handle at this point also addressing issues
of deltas. If $style is set, then no output is sent to the file handle. The return
value is the output string.

=cut

sub out
{
    my ($self, $fh, $style) = @_;
    my ($xoff, $yoff, $fmt, $out);

    if (defined $self-&gt;{'xid'} || defined $self-&gt;{'yid'})
    { $out = TTF_Pack('SSS', 4, $self-&gt;{'xid'}, $self-&gt;{'yid'}); }
    elsif (defined $self-&gt;{'p'})
    { $out = TTF_Pack('Ssss', 2, @{$self}{'x', 'y', 'p'}); }
    elsif (defined $self-&gt;{'xdev'} || defined $self-&gt;{'ydev'})
    {
        $out = TTF_Pack('Sss', 3, @{$self}{'x', 'y'});
        if (defined $self-&gt;{'xdev'})
        {
            $out .= pack('n2', 10, 0);
            $out .= $self-&gt;{'xdev'}-&gt;out($fh, 1);
            $yoff = length($out) - 10;
        }
        else
        { $out .= pack('n2', 0, 0); }
        if (defined $self-&gt;{'ydev'})
        {
            $yoff = 10 unless $yoff;
            substr($out, 8, 2) = pack('n', $yoff);
            $out .= $self-&gt;{'ydev'}-&gt;out($fh, 1);
        }
    } else
    { $out = TTF_Pack('Sss', 1, @{$self}{'x', 'y'}); }
    $fh-&gt;print($out) unless $style;
    $out;
}


sub signature
{
    my ($self) = @_;
    return join (",", map {"${_}=$self-&gt;{$_}"} qw(x y p xdev ydev xid yid));
}


=head2 $a-&gt;out_xml($context)

Outputs the anchor in XML

=cut

sub out_xml
{
    my ($self, $context, $depth) = @_;
    my ($fh) = $context-&gt;{'fh'};
    my ($end);
    
    $fh-&gt;print("$depth&lt;anchor x='$self-&gt;{'x'}' y='$self-&gt;{'y'}'");
    $fh-&gt;print(" p='$self-&gt;{'p'}'") if defined ($self-&gt;{'p'});
    $end = (defined $self-&gt;{'xdev'} || defined $self-&gt;{'ydev'} || defined $self-&gt;{'xid'} || defined $self-&gt;{'yid'});
    unless ($end)
    {
        $fh-&gt;print("/&gt;\n");
        return $self;
    }

    if (defined $self-&gt;{'xdev'})
    {
        $fh-&gt;print("$depth$context-&gt;{'indent'}&lt;xdev&gt;\n");
        $self-&gt;{'xdev'}-&gt;out_xml($context, $depth . ($context-&gt;{'indent'} x 2));
        $fh-&gt;print("$depth$context-&gt;{'indent'}&lt;/xdev&gt;\n");
    }
    
    if (defined $self-&gt;{'ydev'})
    {
        $fh-&gt;print("$depth$context-&gt;{'indent'}&lt;ydev&gt;\n");
        $self-&gt;{'ydev'}-&gt;out_xml($context, $depth . ($context-&gt;{'indent'} x 2));
        $fh-&gt;print("$depth$context-&gt;{'indent'}&lt;/ydev&gt;\n");
    }
    
    if (defined $self-&gt;{'xid'} || defined $self-&gt;{'yid'})
    {
        $fh-&gt;print("$depth$context-&gt;{'indent'}&lt;mmaster");
        $fh-&gt;print(" xid='$self-&gt;{'xid'}'") if defined ($self-&gt;{'xid'});
        $fh-&gt;print(" yid='$self-&gt;{'yid'}'") if defined ($self-&gt;{'yid'});
        $fh-&gt;print("/&gt;\n");
    }
    $fh-&gt;print("$depth&lt;/anchor&gt;\n");
    $self;
}
        

=head1 AUTHOR

Martin Hosken Martin_Hosken@sil.org. See L&lt;Font::TTF::Font&gt; for copyright and
licensing.

=cut

1;

</pre></body></html>