Skip to content

Commit 53fc27c

Browse files
committed
Consider AFM fonts and practicality
1 parent 72a27f7 commit 53fc27c

File tree

1 file changed

+50
-17
lines changed

1 file changed

+50
-17
lines changed

doc/users/fonts.rst

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ contributions of tech giants such as the likes of Adobe, Apple and Microsoft.
66

77
Types
88
-----
9-
In practice, there are 3 types Matplotlib supports:
9+
In practice, there are 3 types Matplotlib supports (in addition to
10+
'core fonts', more about which is explained later in the guide):
1011

1112
.. list-table:: Type of Fonts
1213
:header-rows: 1
@@ -16,19 +17,14 @@ In practice, there are 3 types Matplotlib supports:
1617
- TrueType (PDF)
1718
* - One of the oldest types, introduced by Adobe
1819
- Similar to Type 1 in terms of introduction
19-
- Newer than previous types, most commonly used today, introduced by Apple
20-
* - They use simplified PostScript
21-
(subset of full PostScript language)
22-
- However, they use full PostScript language, which allows embedding
23-
arbitrary code!
20+
- Newer than previous types, used commonly today, introduced by Apple
21+
* - Restricted subset of PostScript, charstrings are in bytecode
22+
- Full PostScript language, allows embedding arbitrary code
2423
(in theory, even render fractals when rasterizing!)
25-
- They include a virtual machine that can execute code!
24+
- Include a virtual machine that can execute code!
2625
* - These fonts support font hinting
2726
- Do not support font hinting
2827
- Hinting supported (virtual machine processes the "hints")
29-
* - Expressed in pretty compact bytecode
30-
- Expressed in simple ASCII form
31-
- Expressed in binary code points
3228
* - Difficult to subset!
3329
- Easy to subset!
3430
- Very hard to subset!
@@ -65,15 +61,52 @@ most of the size bandwidth is captured by that font file data.
6561

6662
Font Subsetting is a way to embed only the *required* glyphs within the
6763
documents. Fonts can be considered as a collection of glyphs, so ultimately the
68-
goal is to find out *which* glyphs are required for a certain piece of text,
69-
and embed only those within the output.
64+
goal is to find out *which* glyphs are required for a certain array of
65+
characters, and embed only those within the output.
7066

71-
Since there is almost no consistency within multiple different backends and the
72-
types of subsetting, this is generally difficult! Luckily, Matplotlib uses a
73-
fork of an external dependency called
67+
.. note::
68+
The role of subsetter really shines when we encounter characters like `ä`
69+
(composed by calling subprograms for ``a`` and ``¨``); since the subsetter
70+
has to find out *all* such subprograms being called by every glyph included
71+
in the subset, and since there is almost no consistency within multiple
72+
different backends and the types of subsetting, this is a generally difficult
73+
problem!
74+
75+
Luckily, Matplotlib uses a fork of an external dependency called
7476
`ttconv <https://github.com/sandflow/ttconv>`_, which helps in embedding and
7577
subsetting stuff. (however, recent versions have moved away from ttconv to pure
76-
Python)
78+
Python for certain types)
7779

78-
| *Type 1 fonts are still non-subsetted* through Matplotlib.
80+
| *Type 1 fonts are still non-subsetted* through Matplotlib. (though one will only encounter these via `usetex`/`dviread` in PDF backend)
7981
| **Type 3 and Type 42 fonts are subsetted**, with a fair amount of exceptions and bugs for the latter.
82+
83+
What to use?
84+
------------
85+
Practically, most fonts that are readily available on most operating systems or
86+
are readily available on the internet to download include *TrueType fonts* and
87+
its "extensions" such as MacOS-resource fork fonts and the newer OpenType
88+
fonts.
89+
90+
PS and PDF backends provide support for yet another type of fonts, which remove
91+
the need of subsetting altogether! These are called **Core Fonts**, and
92+
Matplotlib calls them via the keyword **AFM**; all that is supplied from
93+
Matplotlib to such documents are font metrics (specified in AFM format), and it
94+
is the job of the viewer applications to supply the glyph definitions.
95+
96+
This is especially helpful to generate *really lightweight* documents.::
97+
98+
# trigger core fonts for PDF backend
99+
plt.rcParams["pdf.use14corefonts"] = True
100+
# trigger core fonts for PS backend
101+
plt.rcParams["ps.useafm"] = True
102+
103+
chars = "AFM ftw!"
104+
fig, ax = plt.subplots()
105+
ax.text(0.5, 0.5, chars)
106+
107+
fig.savefig("AFM_PDF.pdf", format="pdf")
108+
fig.savefig("AFM_PS.ps", format="ps)
109+
110+
.. note::
111+
These core fonts are limited to PDF and PS backends only; they can not be
112+
rendered in other backends.

0 commit comments

Comments
 (0)