8000 ft2font: Convert loading flags into an enum · matplotlib/matplotlib@36349aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 36349aa

Browse files
QuLogictacaswell
authored andcommitted
ft2font: Convert loading flags into an enum
Unfortunately, FreeType doesn't define this as an enum of any sort, just as a bunch of macro `#define`s. So we have to make our own for pybind11 to bind.
1 parent 9e02512 commit 36349aa

File tree

12 files changed

+277
-99
lines changed

12 files changed

+277
-99
lines changed

doc/api/next_api_changes/deprecations/28842-ES.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,27 @@ prefix):
1010
- ``KERNING_DEFAULT``
1111
- ``KERNING_UNFITTED``
1212
- ``KERNING_UNSCALED``
13+
14+
The following constants are now part of `.ft2font.LoadFlags` (without the ``LOAD_``
15+
prefix):
16+
17+
- ``LOAD_DEFAULT``
18+
- ``LOAD_NO_SCALE``
19+
- ``LOAD_NO_HINTING``
20+
- ``LOAD_RENDER``
21+
- ``LOAD_NO_BITMAP``
22+
- ``LOAD_VERTICAL_LAYOUT``
23+
- ``LOAD_FORCE_AUTOHINT``
24+
- ``LOAD_CROP_BITMAP``
25+
- ``LOAD_PEDANTIC``
26+
- ``LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH``
27+
- ``LOAD_NO_RECURSE``
28+
- ``LOAD_IGNORE_TRANSFORM``
29+
- ``LOAD_MONOCHROME``
30+
- ``LOAD_LINEAR_DESIGN``
31+
- ``LOAD_NO_AUTOHINT``
32+
- ``LOAD_TARGET_NORMAL``
33+
- ``LOAD_TARGET_LIGHT``
34+
- ``LOAD_TARGET_MONO``
35+
- ``LOAD_TARGET_LCD``
36+
- ``LOAD_TARGET_LCD_V``

lib/matplotlib/_mathtext.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from ._mathtext_data import (
3030
latex_to_bakoma, stix_glyph_fixes, stix_virtual_fonts, tex2uni)
3131
from .font_manager import FontProperties, findfont, get_font
32-
from .ft2font import FT2Font, FT2Image, Kerning
32+
from .ft2font import FT2Font, FT2Image, Kerning, LoadFlags
3333

3434
from packaging.version import parse as parse_version
3535
from pyparsing import __version__ as pyparsing_version
@@ -227,14 +227,14 @@ class Fonts(abc.ABC):
227227
to do the actual drawing.
228228
"""
229229

230-
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
230+
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlags):
231231
"""
232232
Parameters
233233
----------
234234
default_font_prop : `~.font_manager.FontProperties`
235235
The default non-math font, or the base font for Unicode (generic)
236236
font rendering.
237-
load_glyph_flags : int
237+
load_glyph_flags : `.ft2font.LoadFlags`
238238
Flags passed to the glyph loader (e.g. ``FT_Load_Glyph`` and
239239
``FT_Load_Char`` for FreeType-based fonts).
240240
"""
@@ -332,7 +332,7 @@ class TruetypeFonts(Fonts, metaclass=abc.ABCMeta):
332332
(through FT2Font).
333333
"""
334334

335-
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
335+
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlags):
336336
super().__init__(default_font_prop, load_glyph_flags)
337337
# Per-instance cache.
338338
self._get_info = functools.cache(self._get_info) # type: ignore[method-assign]
@@ -448,7 +448,7 @@ class BakomaFonts(TruetypeFonts):
448448
'ex': 'cmex10',
449449
}
450450

451-
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
451+
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlags):
452452
self._stix_fallback = StixFonts(default_font_prop, load_glyph_flags)
453453

454454
super().__init__(default_font_prop, load_glyph_flags)
@@ -557,7 +557,7 @@ class UnicodeFonts(TruetypeFonts):
557557
0x2212: 0x00A1, # Minus sign.
558558
}
559559

560-
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
560+
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlags):
561561
# This must come first so the backend's owner is set correctly
562562
fallback_rc = mpl.rcParams['mathtext.fallback']
563563
font_cls: type[TruetypeFonts] | None = {
@@ -672,7 +672,7 @@ def get_sized_alternatives_for_symbol(self, fontname: str,
672672
class DejaVuFonts(UnicodeFonts, metaclass=abc.ABCMeta):
673673
_fontmap: dict[str | int, str] = {}
674674

675-
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
675+
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlags):
676676
# This must come first so the backend's owner is set correctly
677677
if isinstance(self, DejaVuSerifFonts):
678678
self._fallback_font = StixFonts(default_font_prop, load_glyph_flags)
@@ -776,7 +776,7 @@ class StixFonts(UnicodeFonts):
776776
_fallback_font = None
777777
_sans = False
778778

779-
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
779+
def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlags):
780780
TruetypeFonts.__init__(self, default_font_prop, load_glyph_flags)
781781
for key, name in self._fontmap.items():
782782
fullpath = findfont(name)

lib/matplotlib/_text_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import dataclasses
88

99
from . import _api
10-
from .ft2font import LOAD_NO_HINTING, FT2Font, Kerning
10+
from .ft2font import FT2Font, Kerning, LoadFlags
1111

1212

1313
@dataclasses.dataclass(frozen=True)
@@ -76,7 +76,7 @@ def layout(string, font, *, kern_mode=Kerning.DEFAULT):
7676
if prev_glyph_idx is not None else 0.
7777
)
7878
x += kern
79-
glyph = font.load_glyph(glyph_idx, flags=LOAD_NO_HINTING)
79+
glyph = font.load_glyph(glyph_idx, flags=LoadFlags.NO_HINTING)
8080
yield LayoutItem(font, char, glyph_idx, x, kern)
8181
x += glyph.linearHoriAdvance / 65536
8282
prev_glyph_idx = glyph_idx

lib/matplotlib/backends/_backend_pdf_ps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def get_text_width_height_descent(self, s, prop, ismath):
161161
return w, h, d
162162
else:
163163
font = self._get_font_ttf(prop)
164-
font.set_text(s, 0.0, flags=ft2font.LOAD_NO_HINTING)
164+
font.set_text(s, 0.0, flags=ft2font.LoadFlags.NO_HINTING)
165165
w, h = font.get_width_height()
166166
d = font.get_descent()
167167
scale = 1 / 64

lib/matplotlib/backends/backend_agg.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
from matplotlib.backend_bases import (
3232
_Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
3333
from matplotlib.font_manager import fontManager as _fontManager, get_font
34-
from matplotlib.ft2font import (LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING,
35-
LOAD_DEFAULT, LOAD_NO_AUTOHINT)
34+
from matplotlib.ft2font import LoadFlags
3635
from matplotlib.mathtext import MathTextParser
3736
from matplotlib.path import Path
3837
from matplotlib.transforms import Bbox, BboxBase
@@ -41,16 +40,16 @@
4140

4241
def get_hinting_flag():
4342
mapping = {
44-
'default': LOAD_DEFAULT,
45-
'no_autohint': LOAD_NO_AUTOHINT,
46-
'force_autohint': LOAD_FORCE_AUTOHINT,
47-
'no_hinting': LOAD_NO_HINTING,
48-
True: LOAD_FORCE_AUTOHINT,
49-
False: LOAD_NO_HINTING,
50-
'either': LOAD_DEFAULT,
51-
'native': LOAD_NO_AUTOHINT,
52-
'auto': LOAD_FORCE_AUTOHINT,
53-
'none': LOAD_NO_HINTING,
43+
'default': LoadFlags.DEFAULT,
44+
'no_autohint': LoadFlags.NO_AUTOHINT,
45+
'force_autohint': LoadFlags.FORCE_AUTOHINT,
46+
'no_hinting': LoadFlags.NO_HINTING,
47+
True: LoadFlags.FORCE_AUTOHINT,
48+
False: LoadFlags.NO_HINTING,
49+
'either': LoadFlags.DEFAULT,
50+
'native': LoadFlags.NO_AUTOHINT,
51+
'auto': LoadFlags.FORCE_AUTOHINT,
52+
'none': LoadFlags.NO_HINTING,
5453
}
5554
return mapping[mpl.rcParams['text.hinting']]
5655

lib/matplotlib/backends/backend_pdf.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
from matplotlib.figure import Figure
3636
from matplotlib.font_manager import get_font, fontManager as _fontManager
3737
from matplotlib._afm import AFM
38-
from matplotlib.ft2font import (FIXED_WIDTH, ITALIC, LOAD_NO_SCALE,
39-
LOAD_NO_HINTING, FT2Font, Kerning)
38+
from matplotlib.ft2font import FIXED_WIDTH, ITALIC, FT2Font, Kerning, LoadFlags
4039
from matplotlib.transforms import Affine2D, BboxBase
4140
from matplotlib.path import Path
4241
from matplotlib.dates import UTC
@@ -617,7 +616,7 @@ def _get_pdf_charprocs(font_path, glyph_ids):
617616
conv = 1000 / font.units_per_EM # Conversion to PS units (1/1000's).
618617
procs = {}
619618
for glyph_id in glyph_ids:
620-
g = font.load_glyph(glyph_id, LOAD_NO_SCALE)
619+
g = font.load_glyph(glyph_id, LoadFlags.NO_SCALE)
621620
# NOTE: We should be using round(), but instead use
622621
# "(x+.5).astype(int)" to keep backcompat with the old ttconv code
623622
# (this is different for negative x's).
@@ -1185,7 +1184,7 @@ def embedTTFType3(font, characters, descriptor):
11851184
def get_char_width(charcode):
11861185
s = ord(cp1252.decoding_table[charcode])
11871186
width = font.load_char(
1188-
s, flags=LOAD_NO_SCALE | LOAD_NO_HINTING).horiAdvance
1187+
s, flags=LoadFlags.NO_SCALE | LoadFlags.NO_HINTING).horiAdvance
11891188
return cvt(width)
11901189
with warnings.catch_warnings():
11911190
# Ignore 'Required glyph missing from current font' warning
@@ -1322,7 +1321,7 @@ def embedTTFType42(font, characters, descriptor):
13221321
ccode = c
13231322
gind = font.get_char_index(ccode)
13241323
glyph = font.load_char(ccode,
1325-
flags=LOAD_NO_SCALE | LOAD_NO_HINTING)
1324+
flags=LoadFlags.NO_SCALE | LoadFlags.NO_HINTING)
13261325
widths.append((ccode, cvt(glyph.horiAdvance)))
13271326
if ccode < 65536:
13281327
cid_to_gid_map[ccode] = chr(gind)

lib/matplotlib/backends/backend_ps.py

Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
_Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
3030
from matplotlib.cbook import is_writable_file_like, file_requires_unicode
3131
from matplotlib.font_manager import get_font
32-
from matplotlib.ft2font import LOAD_NO_SCALE
32+
from matplotlib.ft2font import LoadFlags
3333
from matplotlib._mathtext_data import uni2type1
3434
from matplotlib.path import Path
3535
from matplotlib.texmanager import TexManager
@@ -148,7 +148,7 @@ def _font_to_ps_type3(font_path, chars):
148148

149149
entries = []
150150
for glyph_id in glyph_ids:
151-
g = font.load_glyph(glyph_id, LOAD_NO_SCALE)
151+
g = font.load_glyph(glyph_id, LoadFlags.NO_SCALE)
152152
v, c = font.get_path()
153153
entries.append(
154154
"/%(name)s{%(bbox)s sc\n" % {

lib/matplotlib/ft2font.pyi

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from enum import Enum
1+
from enum import Enum, Flag
22
import sys
33
from typing import BinaryIO, Literal, TypedDict, final, overload
44
from typing_extensions import Buffer # < Py 3.12
@@ -17,26 +17,6 @@ GLYPH_NAMES: int
1717
HORIZONTAL: int
1818
ITALIC: int
1919
KERNING: int
20-
LOAD_CROP_BITMAP: int
21-
LOAD_DEFAULT: int
22-
LOAD_FORCE_AUTOHINT: int
23-
LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH: int
24-
LOAD_IGNORE_TRANSFORM: int
25-
LOAD_LINEAR_DESIGN: int
26-
LOAD_MONOCHROME: int
27-
LOAD_NO_AUTOHINT: int
28-
LOAD_NO_BITMAP: int
29-
LOAD_NO_HINTING: int
30-
LOAD_NO_RECURSE: int
31-
LOAD_NO_SCALE: int
32-
LOAD_PEDANTIC: int
33-
LOAD_RENDER: int
34-
LOAD_TARGET_LCD: int
35-
LOAD_TARGET_LCD_V: int
36-
LOAD_TARGET_LIGHT: int
37-
LOAD_TARGET_MONO: int
38-
LOAD_TARGET_NORMAL: int
39-
LOAD_VERTICAL_LAYOUT: int
4020
MULTIPLE_MASTERS: int
4121
SCALABLE: int
4222
SFNT: int
@@ -47,6 +27,33 @@ class Kerning(Enum):
4727
UNFITTED: int
4828
UNSCALED: int
4929

30+
class LoadFlags(Flag):
31+
DEFAULT: int
32+
NO_SCALE: int
33+
NO_HINTING: int
34+
RENDER: int
35+
NO_BITMAP: int
36+
VERTICAL_LAYOUT: int
37+
FORCE_AUTOHINT: int
38+
CROP_BITMAP: int
39+
PEDANTIC: int
40+
IGNORE_GLOBAL_ADVANCE_WIDTH: int
41+
NO_RECURSE: int
42+
IGNORE_TRANSFORM: int
43+
MONOCHROME: int
44+
LINEAR_DESIGN: int
45+
NO_AUTOHINT: int
46+
COLOR: int
47+
COMPUTE_METRICS: int # FT 2.6.1
48+
# BITMAP_METRICS_ONLY: int # FT 2.7.1
49+
# NO_SVG: int # FT 2.13.1
50+
# The following should be unique, but the above can be OR'd together.
51+
TARGET_NORMAL: int
52+
TARGET_LIGHT: int
53+
TARGET_MONO: int
54+
TARGET_LCD: int
55+
TARGET_LCD_V: int
56+
5057
class _SfntHeadDict(TypedDict):
5158
version: tuple[int, int]
5259
fontRevision: tuple[int, int]
@@ -210,13 +217,13 @@ class FT2Font(Buffer):
210217
@overload
211218
def get_sfnt_table(self, name: Literal["pclt"]) -> _SfntPcltDict | None: ...
212219
def get_width_height(self) -> tuple[int, int]: ...
213-
def load_char(self, charcode: int, flags: int = ...) -> Glyph: ...
214-
def load_glyph(self, glyphindex: int, flags: int = ...) -> Glyph: ...
220+
def load_char(self, charcode: int, flags: LoadFlags = ...) -> Glyph: ...
221+
def load_glyph(self, glyphindex: int, flags: LoadFlags = ...) -> Glyph: ...
215222
def select_charmap(self, i: int) -> None: ...
216223
def set_charmap(self, i: int) -> None: ...
217224
def set_size(self, ptsize: float, dpi: float) -> None: ...
218225
def set_text(
219-
self, string: str, angle: float = ..., flags: int = ...
226+
self, string: str, angle: float = ..., flags: LoadFlags = ...
220227
) -> NDArray[np.float64]: ...
221228
@property
222229
def ascender(self) -> int: ...

lib/matplotlib/mathtext.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import matplotlib as mpl
2222
from matplotlib import _api, _mathtext
23-
from matplotlib.ft2font import LOAD_NO_HINTING
23+
from matplotlib.ft2font import LoadFlags
2424
from matplotlib.font_manager import FontProperties
2525
from ._mathtext import ( # noqa: F401, reexported API
2626
RasterParse, VectorParse, get_unicode_index)
@@ -80,7 +80,7 @@ def parse(self, s, dpi=72, prop=None, *, antialiased=None):
8080
antialiased = mpl._val_or_rc(antialiased, 'text.antialiased')
8181
from matplotlib.backends import backend_agg
8282
load_glyph_flags = {
83-
"vector": LOAD_NO_HINTING,
83+
"vector": LoadFlags.NO_HINTING,
8484
"raster": backend_agg.get_hinting_flag(),
8585
}[self._output_type]
8686
return self._parse_cached(s, dpi, prop, antialiased, load_glyph_flags)

lib/matplotlib/tests/test_font_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def test_missing_family(caplog):
251251

252252
def _test_threading():
253253
import threading
254-
from matplotlib.ft2font import LOAD_NO_HINTING
254+
from matplotlib.ft2font import LoadFlags
255255
import matplotlib.font_manager as fm
256256

257257
def loud_excepthook(args):
@@ -266,7 +266,7 @@ def bad_idea(n):
266266
b.wait(timeout=5)
267267
for j in range(100):
268268
font = fm.get_font(fm.findfont("DejaVu Sans"))
269-
font.set_text(str(n), 0.0, flags=LOAD_NO_HINTING)
269+
font.set_text(str(n), 0.0, flags=LoadFlags.NO_HINTING)
270270

271271
threads = [
272272
threading.Thread(target=bad_idea, name=f"bad_thread_{j}", args=(j,))

lib/matplotlib/textpath.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from matplotlib.font_manager import (
99
FontProperties, get_font, fontManager as _fontManager
1010
)
11-
from matplotlib.ft2font import LOAD_NO_HINTING, LOAD_TARGET_LIGHT
11+
from matplotlib.ft2font import LoadFlags
1212
from matplotlib.mathtext import MathTextParser
1313
from matplotlib.path import Path
1414
from matplotlib.texmanager import TexManager
@@ -37,7 +37,7 @@ def _get_font(self, prop):
3737
return font
3838

3939
def _get_hinting_flag(self):
40-
return LOAD_NO_HINTING
40+
return LoadFlags.NO_HINTING
4141

4242
def _get_char_id(self, font, ccode):
4343
"""
@@ -61,7 +61,7 @@ def get_text_width_height_descent(self, s, prop, ismath):
6161
return width * scale, height * scale, descent * scale
6262

6363
font = self._get_font(prop)
64-
font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
64+
font.set_text(s, 0.0, flags=LoadFlags.NO_HINTING)
6565
w, h = font.get_width_height()
6666
w /= 64.0 # convert from subpixels
6767
h /= 64.0
@@ -190,7 +190,7 @@ def get_glyphs_mathtext(self, prop, s, glyph_map=None,
190190
if char_id not in glyph_map:
191191
font.clear()
192192
font.set_size(self.FONT_SCALE, self.DPI)
193-
font.load_char(ccode, flags=LOAD_NO_HINTING)
193+
font.load_char(ccode, flags=LoadFlags.NO_HINTING)
194194
glyph_map_new[char_id] = font.get_path()
195195

196196
xpositions.append(ox)
@@ -241,11 +241,11 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
241241
glyph_name_or_index = text.glyph_name_or_index
242242
if isinstance(glyph_name_or_index, str):
243243
index = font.get_name_index(glyph_name_or_index)
244-
font.load_glyph(index, flags=LOAD_TARGET_LIGHT)
244+
font.load_glyph(index, flags=LoadFlags.TARGET_LIGHT)
245245
elif isinstance(glyph_name_or_index, int):
246246
self._select_native_charmap(font)
247247
font.load_char(
248-
glyph_name_or_index, flags=LOAD_TARGET_LIGHT)
248+
glyph_name_or_index, flags=LoadFlags.TARGET_LIGHT)
249249
else: # Should not occur.
250250
raise TypeError(f"Glyph spec of unexpected type: "
251251
f"{glyph_name_or_index!r}")

0 commit comments

Comments
 (0)
0