[docs] Document afmLib (#1933)
This commit is contained in:
parent
2cef07af80
commit
94cb1759f7
@ -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:
|
|
||||||
|
@ -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):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user