|
Packit |
5d935b |
=head1 NAME
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Font::TTF::Manual - Information regarding the whole module set
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 INTRODUCTION
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This document looks at the whole issue of how the various modules in the
|
|
Packit |
5d935b |
TrueType Font work together. As such it is partly information on this font
|
|
Packit |
5d935b |
system and partly information on TrueType fonts in general.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Due to the inter-relation between so many tables in a TrueType font, different
|
|
Packit |
5d935b |
tables will make expectations as to which other tables exist. At the very least
|
|
Packit |
5d935b |
a font should consist of a C<head> table and a C<maxp> table. The system has
|
|
Packit |
5d935b |
been designed around the expectation that the necessary tables for font
|
|
Packit |
5d935b |
rendering in the Windows environment exist. But inter table dependencies have
|
|
Packit |
5d935b |
been kept to what are considered necessary.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This module set is not meant as a simple to use, mindless, font editing suite,
|
|
Packit |
5d935b |
but as a low-level, get your hands dirty, know what you are doing, set of
|
|
Packit |
5d935b |
classes for those who understand the intricacies (and there are many) of
|
|
Packit |
5d935b |
TrueType fonts. To this end, if you get something wrong in the data structures,
|
|
Packit |
5d935b |
etc. then this module set won't tell you and will happily create fonts which
|
|
Packit |
5d935b |
don't work.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
At the time of writing, not every TrueType table in existence has been
|
|
Packit |
5d935b |
implemented! Only the core basic tables of TrueType 1.0 (i.e. no embedded bitmap
|
|
Packit |
5d935b |
tables, no postscript type tables, no OpenType tables and no GX tables) have
|
|
Packit |
5d935b |
been implemented. If you want to help by implementing another table or two, then
|
|
Packit |
5d935b |
please go ahead and send me your code. For a full list of tables, see
|
|
Packit |
5d935b |
L<Font::TTF::Font>.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 Design Principles
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
PERL is not C++. C++ encourages methods to be written for changing and reading
|
|
Packit |
5d935b |
each instance variable in a class. If we did this in this PERL program the
|
|
Packit |
5d935b |
results would be rather large and slow. Instead, since most access will be read
|
|
Packit |
5d935b |
access, we expose as much of the inner storage of an object to user access
|
|
Packit |
5d935b |
directly via hash lookup. The advantage this gives are great. For example, by
|
|
Packit |
5d935b |
following an instance variable chain, looking up the C<yMax> parameter for a
|
|
Packit |
5d935b |
particular glyph becomes:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f->{'loca'}{'glyphs'}[$glyph]{'yMax'}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Or, if we are feeling very lazy and don't mind waiting:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f->{'loca'}{'glyphs'}[$f->{'cmap'}->ms_lookup(0x41)]{'yMax'}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
The disadvantage of this method is that it behoves module users to behave
|
|
Packit |
5d935b |
themselves. Thus it does not hold your hand and ensure that if you make a change
|
|
Packit |
5d935b |
to a table, that the table is marked as I<dirty>, or that other tables are
|
|
Packit |
5d935b |
updated accordingly.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
It is up to the application developer to understand the implications of the
|
|
Packit |
5d935b |
changes they make to a font, and to take the necessary action to ensure that the
|
|
Packit |
5d935b |
data they get out is what they want. Thus, you could go and change the C<yMax>
|
|
Packit |
5d935b |
value on a glyph and output a new font with this change, but it is up to you to
|
|
Packit |
5d935b |
ensure that the font's bounding box details in the C<head> table are correct,
|
|
Packit |
5d935b |
and even that your changing C<yMax> is well motivated.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
To help with using the system, each module (or table) will not only describe the
|
|
Packit |
5d935b |
methods it supports, which are relatively few, but also the instance variables
|
|
Packit |
5d935b |
it supports, which are many. Most of the variables directly reflect table
|
|
Packit |
5d935b |
attributes as specified in the OpenType specification, available from Microsoft
|
|
Packit |
5d935b |
(L<http://www.microsoft.com/typography>), Adobe and Apple. A list of the names
|
|
Packit |
5d935b |
used is also given in each module, but not necessarily with any further
|
|
Packit |
5d935b |
description. After all, this code is not a TrueType manual as well!
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 Conventions
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
There are various conventions used in this system.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Firstly we consider the documentation conventions regarding instance variables.
|
|
Packit |
5d935b |
Each instance variable is marked indicating whether it is a B<(P)>rivate
|
|
Packit |
5d935b |
variable which users of the module are not expected to read and certainly not
|
|
Packit |
5d935b |
write to or a B<(R)>ead only variable which users may well want to read but not
|
|
Packit |
5d935b |
write to.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 METHODS
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This section examines various methods and how the various modules work with
|
|
Packit |
5d935b |
these methods.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 read and read_dat
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Before the data structures for a table can be accessed, they need to be filled
|
|
Packit |
5d935b |
in from somewhere. The usual way to do this is to read an existing TrueType
|
|
Packit |
5d935b |
font. This may be achieved by:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f = Font::TTF::Font->open($filename) || die "Unable to read $filename";
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This will open an existing font and read its directory header. Notice that at
|
|
Packit |
5d935b |
this point, none of the tables in the font have been read. (Actually, the
|
|
Packit |
5d935b |
C<head> and C<maxp> tables are read at this point too since they contain the
|
|
Packit |
5d935b |
commonly required parameters of):
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f->{'head'}{'unitsPerEm'}
|
|
Packit |
5d935b |
$f->{'maxp'}{'numGlyphs'}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
In order to be able to access information from a table, it is first necessary to
|
|
Packit |
5d935b |
C<read> it. Consider trying to find the advance width of a space character
|
|
Packit |
5d935b |
(U+0020). The following code should do it:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f = Font::TTF::Font->open($ARGV[0]);
|
|
Packit |
5d935b |
$snum = $f->{'cmap'}->ms_lookup(0x0020);
|
|
Packit |
5d935b |
$sadv = $f->{'hmtx'}{'advance'}[$snum];
|
|
Packit |
5d935b |
print $sadv;
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This would result in the value zero being printed, which is far from correct.
|
|
Packit |
5d935b |
But why? The first line would correctly read the font directory. The second line
|
|
Packit |
5d935b |
would, incidently, correctly locate the space character in the Windows cmap
|
|
Packit |
5d935b |
(assuming a non symbol encoded font). The third line would not succeed in its
|
|
Packit |
5d935b |
task since the C<hmtx> table has not been filled in from the font file. To
|
|
Packit |
5d935b |
achieve what we want we would first need to cause it to be read:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f->{'hmtx'}->read;
|
|
Packit |
5d935b |
$sadv = $f->{'hmtx'}{'advance'}[$snum];
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Or for those who are too lazy to write multiple lines, C<read> returns the
|
|
Packit |
5d935b |
object it reads. Thus we could write:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$sadv = $f->{'hmtx'}->read->{'advance'}[$snum];
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Why, if we always have to read tables before accessing information from them,
|
|
Packit |
5d935b |
did we not have to do this for the C<cmap> table? The answer lies in the method
|
|
Packit |
5d935b |
call. It senses that the table hasn't been read and reads it for us. This will
|
|
Packit |
5d935b |
generally happen with all method calls, it is only when we do direct data access
|
|
Packit |
5d935b |
that we have to take the responsibility to read the table first.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Reading a table does not necessarily result in all the data being placed into
|
|
Packit |
5d935b |
internal data structures. In the case of a simple table C<read> is sufficient.
|
|
Packit |
5d935b |
In fact, the normal case is that C<read_dat> reads the data from the file into
|
|
Packit |
5d935b |
an instance variable called C<' dat'> (including the space) and not into the
|
|
Packit |
5d935b |
data structures.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This is true except for the C<glyph> class which represents a single glyph. Here
|
|
Packit |
5d935b |
the process is reversed. Reading a C<glyph> reads the data for the glyph into
|
|
Packit |
5d935b |
the C<' dat'> instance variable and sets various header attributes for the glyph
|
|
Packit |
5d935b |
(C<xMin>, C<numContours>, etc.). The data is converted out of the variable into
|
|
Packit |
5d935b |
data structures via the C<read_dat> method.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
The aim, therefore, is that C<read> should do the natural thing (read into data
|
|
Packit |
5d935b |
structures for those tables and elements for which it is helpful -- all except
|
|
Packit |
5d935b |
C<glyph> at present) and C<read_dat> should do the unnatural thing: read just
|
|
Packit |
5d935b |
the binary data for normal tables and convert binary data to data structures for
|
|
Packit |
5d935b |
C<glyph>s.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
In summary, therefore, use C<read> unless you want to hack around with the
|
|
Packit |
5d935b |
internals of glyphs in which case see L<Font::TTF::Glyph> for more details.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 update
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
The aim of this method is to allow the various data elements in a C<read> font
|
|
Packit |
5d935b |
to update themselves. All tables know how to update themselves. All tables also
|
|
Packit |
5d935b |
contain information which cannot be I<updated> but is new knowledge in the font.
|
|
Packit |
5d935b |
As a result, certain tables do nothing when they are updated. We can, therefore,
|
|
Packit |
5d935b |
build an update hierarchy of tables, with the independent tables at the bottom
|
|
Packit |
5d935b |
and C<Font> at the top:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
+--loca
|
|
Packit |
5d935b |
|
|
|
Packit |
5d935b |
glyf--+--maxp
|
|
Packit |
5d935b |
|
|
|
Packit |
5d935b |
+---+--head
|
|
Packit |
5d935b |
|
|
|
Packit |
5d935b |
hmtx------+--hhea
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
cmap-----OS/2
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
name--
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
post--
|
|
Packit |
5d935b |
There is an important universal dependency which it is up to the user to
|
|
Packit |
5d935b |
keep up to date. This is C<maxp/numOfGlyphs> which is used to iterate over all
|
|
Packit |
5d935b |
the glyphs. Note that the glyphs themselves are not held in the C<glyph> table
|
|
Packit |
5d935b |
but in the C<loca> table, so adding glyphs, etc. automatically involves keeping
|
|
Packit |
5d935b |
the C<loca> table up to date.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 Creating fonts
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Suppose we were creating a font from scratch. How much information do we need
|
|
Packit |
5d935b |
to supply and how much will C<update> do for us?
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
The following information is required:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f->{'loca'}{'glyphs'}
|
|
Packit |
5d935b |
$f->{'head'}{'upem'}
|
|
Packit |
5d935b |
$f->{'maxp'}{'numGlyphs'} (doesn't come from $f->{'loca'}{'glyphs'})
|
|
Packit |
5d935b |
$f->{'hmtx'}{'advance'}
|
|
Packit |
5d935b |
$f->{'post'}['format'}
|
|
Packit |
5d935b |
$f->{'post'}{'VAL'}
|
|
Packit |
5d935b |
$f->{'cmap'}
|
|
Packit |
5d935b |
$f->{'name'}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Pretty much everything else is calculated for you. Details of what is needed
|
|
Packit |
5d935b |
for a glyph may be found in L<Font::TTF::Glyph>. Once we have all the
|
|
Packit |
5d935b |
information we need (and there is lots more that you could add) then we simply
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$f->dirty; # mark all tables dirty
|
|
Packit |
5d935b |
$f->update; # update the font
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 AUTHOR
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Martin Hosken L<http://scripts.sil.org/FontUtils>.
|
|
Packit |
5d935b |
(see CONTRIBUTORS for other authors).
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 LICENSING
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Copyright (c) 1998-2016, SIL International (http://www.sil.org)
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This module is released under the terms of the Artistic License 2.0.
|
|
Packit |
5d935b |
For details, see the full text of the license in the file LICENSE.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=cut
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
1;
|