[docs] Document afmLib (#1933)

This commit is contained in:
Simon Cozens 2020-05-12 11:18:36 +01:00 committed by GitHub
parent 2cef07af80
commit 94cb1759f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 9 deletions

View File

@ -1,8 +1,8 @@
###### ###########################################
afmLib afmLib: Read/write Adobe Font Metrics files
###### ###########################################
.. automodule:: fontTools.afmLib .. automodule:: fontTools.afmLib
:inherited-members:
.. autoclass:: fontTools.afmLib.AFM
:members: :members:
:undoc-members:

View File

@ -1,8 +1,50 @@
"""Module for reading and writing AFM files.""" """Module for reading and writing AFM (Adobe Font Metrics) files.
Note that this has been designed to read in AFM files generated by Fontographer
and has not been tested on many other files. In particular, it does not
implement the whole Adobe AFM specification [#f1]_ but, it should read most
"common" AFM files.
Here is an example of using `afmLib` to read, modify and write an AFM file:
>>> from fontTools.afmLib import AFM
>>> f = AFM("Tests/afmLib/data/TestAFM.afm")
>>>
>>> # Accessing a pair gets you the kern value
>>> f[("V","A")]
-60
>>>
>>> # Accessing a glyph name gets you metrics
>>> f["A"]
(65, 668, (8, -25, 660, 666))
>>> # (charnum, width, bounding box)
>>>
>>> # Accessing an attribute gets you metadata
>>> f.FontName
'TestFont-Regular'
>>> f.FamilyName
'TestFont'
>>> f.Weight
'Regular'
>>> f.XHeight
500
>>> f.Ascender
750
>>>
>>> # Attributes and items can also be set
>>> f[("A","V")] = -150 # Tighten kerning
>>> f.FontName = "TestFont Squished"
>>>
>>> # And the font written out again
>>> f.write("testfont-squished.afm")
.. rubric:: Footnotes
.. [#f1] `Adobe Technote 5004 <https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5004.AFM_Spec.pdf>`_,
Adobe Font Metrics File Format Specification.
"""
# XXX reads AFM's generated by Fog, not tested with much else.
# It does not implement the full spec (Adobe Technote 5004, Adobe Font Metrics
# File Format Specification). Still, it should read most "common" AFM files.
from fontTools.misc.py23 import * from fontTools.misc.py23 import *
import re import re
@ -97,6 +139,11 @@ class AFM(object):
] ]
def __init__(self, path=None): def __init__(self, path=None):
"""AFM file reader.
Instantiating an object with a path name will cause the file to be opened,
read, and parsed. Alternatively the path can be left unspecified, and a
file can be parsed later with the :meth:`read` method."""
self._attrs = {} self._attrs = {}
self._chars = {} self._chars = {}
self._kerning = {} self._kerning = {}
@ -107,6 +154,7 @@ class AFM(object):
self.read(path) self.read(path)
def read(self, path): def read(self, path):
"""Opens, reads and parses a file."""
lines = readlines(path) lines = readlines(path)
for line in lines: for line in lines:
if not line.strip(): if not line.strip():
@ -189,6 +237,7 @@ class AFM(object):
self._composites[charname] = components self._composites[charname] = components
def write(self, path, sep='\r'): def write(self, path, sep='\r'):
"""Writes out an AFM font to the given path."""
import time import time
lines = [ "StartFontMetrics 2.0", lines = [ "StartFontMetrics 2.0",
"Comment Generated by afmLib; at %s" % ( "Comment Generated by afmLib; at %s" % (
@ -258,24 +307,40 @@ class AFM(object):
writelines(path, lines, sep) writelines(path, lines, sep)
def has_kernpair(self, pair): def has_kernpair(self, pair):
"""Returns `True` if the given glyph pair (specified as a tuple) exists
in the kerning dictionary."""
return pair in self._kerning return pair in self._kerning
def kernpairs(self): def kernpairs(self):
"""Returns a list of all kern pairs in the kerning dictionary."""
return list(self._kerning.keys()) return list(self._kerning.keys())
def has_char(self, char): def has_char(self, char):
"""Returns `True` if the given glyph exists in the font."""
return char in self._chars return char in self._chars
def chars(self): def chars(self):
"""Returns a list of all glyph names in the font."""
return list(self._chars.keys()) return list(self._chars.keys())
def comments(self): def comments(self):
"""Returns all comments from the file."""
return self._comments return self._comments
def addComment(self, comment): def addComment(self, comment):
"""Adds a new comment to the file."""
self._comments.append(comment) self._comments.append(comment)
def addComposite(self, glyphName, components): def addComposite(self, glyphName, components):
"""Specifies that the glyph `glyphName` is made up of the given components.
The components list should be of the following form::
[
(glyphname, xOffset, yOffset),
...
]
"""
self._composites[glyphName] = components self._composites[glyphName] = components
def __getattr__(self, attr): def __getattr__(self, attr):