diff --git a/.appveyor.yml b/.appveyor.yml index c3fcb0ea9591..3e3a3b884d18 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -60,6 +60,26 @@ install: - micromamba env create -f environment.yml python=%PYTHON_VERSION% pywin32 - micromamba activate mpl-dev +before_test: + - git config --global user.name 'Matplotlib' + - git config --global user.email 'nobody@matplotlib.org' + - git fetch https://github.com/QuLogic/matplotlib.git text-overhaul-figures:text-overhaul-figures + - git merge --no-commit text-overhaul-figures || true + # If there are any conflicts in baseline images, then pick "ours", + # which should be the updated images in the PR. + - ps: | + $conflicts = git diff --name-only --diff-filter=U ` + lib/matplotlib/tests/baseline_images ` + lib/mpl_toolkits/*/tests/baseline_images + if ($conflicts) { + git checkout --ours -- $conflicts + git add -- $conflicts + } + git status + # If committing fails, there were conflicts other than the baseline images, + # which should not be allowed to happen, and should fail the build. + - git commit -m "Preload test images from branch text-overhaul-figures" + test_script: # Now build the thing.. - set LINK=/LIBPATH:%cd%\lib diff --git a/.github/workflows/cibuildwheel.yml b/.github/workflows/cibuildwheel.yml index dcbccf97f638..1d47fb6c35d8 100644 --- a/.github/workflows/cibuildwheel.yml +++ b/.github/workflows/cibuildwheel.yml @@ -142,6 +142,10 @@ jobs: name: cibw-sdist path: dist/ + - name: Purge Strawberry Perl + if: startsWith(matrix.os, 'windows-') + run: Remove-Item -Recurse C:\Strawberry + - name: Build wheels for CPython 3.14 uses: pypa/cibuildwheel@352e01339f0a173aa2a3eb57f01492e341e83865 # v3.1.3 with: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e965819628be..343d497a4696 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -95,6 +95,25 @@ jobs: fetch-depth: 0 persist-credentials: false + - name: Preload test images + run: | + git config --global user.name 'Matplotlib' + git config --global user.email 'nobody@matplotlib.org' + git fetch https://github.com/QuLogic/matplotlib.git text-overhaul-figures:text-overhaul-figures + git merge --no-commit text-overhaul-figures || true + # If there are any conflicts in baseline images, then pick "ours", + # which should be the updated images in the PR. + conflicts=$(git diff --name-only --diff-filter=U \ + lib/matplotlib/tests/baseline_images \ + lib/mpl_toolkits/*/tests/baseline_images) + if [ -n "${conflicts}" ]; then + git checkout --ours -- ${conflicts} + git add -- ${conflicts} + fi + # If committing fails, there were conflicts other than the baseline images, + # which should not be allowed to happen, and should fail the build. + git commit -m 'Preload test images from branch text-overhaul-figures' + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 11499188509e..e140b084b6a6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,13 +20,13 @@ repos: - id: check-docstring-first exclude: lib/matplotlib/typing.py # docstring used for attribute flagged by check - id: end-of-file-fixer - exclude_types: [svg] + exclude_types: [diff, svg] - id: mixed-line-ending - id: name-tests-test args: ["--pytest-test-first"] - id: no-commit-to-branch # Default is master and main. - id: trailing-whitespace - exclude_types: [svg] + exclude_types: [diff, svg] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.15.0 hooks: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d68a9d36f0d3..eef71162f9cb 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -68,6 +68,25 @@ stages: architecture: 'x64' displayName: 'Use Python $(python.version)' + - bash: | + git config --global user.name 'Matplotlib' + git config --global user.email 'nobody@matplotlib.org' + git fetch https://github.com/QuLogic/matplotlib.git text-overhaul-figures:text-overhaul-figures + git merge --no-commit text-overhaul-figures || true + # If there are any conflicts in baseline images, then pick "ours", + # which should be the updated images in the PR. + conflicts=$(git diff --name-only --diff-filter=U \ + lib/matplotlib/tests/baseline_images \ + lib/mpl_toolkits/*/tests/baseline_images) + if [ -n "${conflicts}" ]; then + git checkout --ours -- ${conflicts} + git add -- ${conflicts} + fi + # If committing fails, there were conflicts other than the baseline images, + # which should not be allowed to happen, and should fail the build. + git commit -m 'Preload test images from branch text-overhaul-figures' + displayName: Preload test images + - bash: | choco install ninja displayName: 'Install dependencies' diff --git a/doc/api/next_api_changes/behavior/30318-ES.rst b/doc/api/next_api_changes/behavior/30318-ES.rst new file mode 100644 index 000000000000..805901dcb21d --- /dev/null +++ b/doc/api/next_api_changes/behavior/30318-ES.rst @@ -0,0 +1,9 @@ +FT2Font no longer sets a default size +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the interest of handling non-scalable fonts and reducing font initialization, the +`.FT2Font` constructor no longer sets a default size. Non-scalable fonts are sometimes +used for bitmap-backed emoji fonts. + +If metrics are important (i.e., if you are loading character glyphs, or setting a text +string), then explicitly call `.FT2Font.set_size` beforehand. diff --git a/doc/api/next_api_changes/deprecations/30322-ES.rst b/doc/api/next_api_changes/deprecations/30322-ES.rst new file mode 100644 index 000000000000..b9c4964e58c8 --- /dev/null +++ b/doc/api/next_api_changes/deprecations/30322-ES.rst @@ -0,0 +1,7 @@ +Font kerning factor is deprecated +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to internal changes to support complex text rendering, the kerning factor on fonts is +no longer used. Setting the ``text.kerning_factor`` rcParam (which existed only for +backwards-compatibility) to any value other than None is deprecated, and the rcParam will +be removed in the future. diff --git a/doc/api/next_api_changes/deprecations/30329-ES.rst b/doc/api/next_api_changes/deprecations/30329-ES.rst new file mode 100644 index 000000000000..8d5060c4821b --- /dev/null +++ b/doc/api/next_api_changes/deprecations/30329-ES.rst @@ -0,0 +1,4 @@ +``font_manager.is_opentype_cff_font`` is deprecated +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There is no replacement. diff --git a/doc/api/next_api_changes/development/30143-ES.rst b/doc/api/next_api_changes/development/30143-ES.rst new file mode 100644 index 000000000000..2d79ad6bbe9d --- /dev/null +++ b/doc/api/next_api_changes/development/30143-ES.rst @@ -0,0 +1,7 @@ +Glyph indices now typed distinctly from character codes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Previously, character codes and glyph indices were both typed as `int`, which means you +could mix and match them erroneously. While the character code can't be made a distinct +type (because it's used for `chr`/`ord`), typing glyph indices as a distinct type means +these can't be fully swapped. diff --git a/doc/missing-references.json b/doc/missing-references.json index 1a3693c990e5..e89439b90483 100644 --- a/doc/missing-references.json +++ b/doc/missing-references.json @@ -126,10 +126,12 @@ "doc/docstring of matplotlib.ft2font.PyCapsule.set_text:1" ], "numpy.typing.NDArray": [ + "doc/docstring of matplotlib.ft2font.pybind11_detail_function_record_v1_system_libstdcpp_gxx_abi_1xxx_use_cxx11_abi_1.get_image:1", "doc/docstring of matplotlib.ft2font.pybind11_detail_function_record_v1_system_libstdcpp_gxx_abi_1xxx_use_cxx11_abi_1.set_text:1" ], "numpy.uint8": [ - ":1" + ":1", + "doc/docstring of matplotlib.ft2font.pybind11_detail_function_record_v1_system_libstdcpp_gxx_abi_1xxx_use_cxx11_abi_1.get_image:1" ] }, "py:obj": { diff --git a/doc/release/prev_whats_new/whats_new_3.2.0.rst b/doc/release/prev_whats_new/whats_new_3.2.0.rst index 4fcba4e5a0fc..ac37695989bc 100644 --- a/doc/release/prev_whats_new/whats_new_3.2.0.rst +++ b/doc/release/prev_whats_new/whats_new_3.2.0.rst @@ -54,26 +54,15 @@ triangle meshes. Kerning adjustments now use correct values ------------------------------------------ -Due to an error in how kerning adjustments were applied, previous versions of -Matplotlib would under-correct kerning. This version will now correctly apply -kerning (for fonts supported by FreeType). To restore the old behavior (e.g., -for test images), you may set :rc:`text.kerning_factor` to 6 (instead of 0). -Other values have undefined behavior. - -.. plot:: - - import matplotlib.pyplot as plt - - # Use old kerning values: - plt.rcParams['text.kerning_factor'] = 6 - fig, ax = plt.subplots() - ax.text(0.0, 0.05, 'BRAVO\nAWKWARD\nVAT\nW.Test', fontsize=56) - ax.set_title('Before (text.kerning_factor = 6)') - -Note how the spacing between characters is uniform between their bounding boxes -(above). With corrected kerning (below), slanted characters (e.g., AV or VA) -will be spaced closer together, as well as various other character pairs, -depending on font support (e.g., T and e, or the period after the W). +Due to an error in how kerning adjustments were applied, previous versions of Matplotlib +would under-correct kerning. This version will now correctly apply kerning (for fonts +supported by FreeType). To restore the old behavior (e.g., for test images), you may set +the ``text.kerning_factor`` rcParam to 6 (instead of 0). Other values have undefined +behavior. + +With corrected kerning (below), slanted characters (e.g., AV or VA) will be spaced closer +together, as well as various other character pairs, depending on font support (e.g., T +and e, or the period after the W). .. plot:: diff --git a/extern/meson.build b/extern/meson.build index 5463183a9099..7f7c2511c3d5 100644 --- a/extern/meson.build +++ b/extern/meson.build @@ -13,11 +13,20 @@ else # must match the value in `lib/matplotlib.__init__.py`. Also update the docs # in `docs/devel/dependencies.rst`. Bump the cache key in # `.circleci/config.yml` when changing requirements. - LOCAL_FREETYPE_VERSION = '2.6.1' + LOCAL_FREETYPE_VERSION = '2.13.3' freetype_proj = subproject( f'freetype-@LOCAL_FREETYPE_VERSION@', - default_options: ['default_library=static']) + default_options: [ + 'default_library=static', + 'brotli=disabled', + 'bzip2=disabled', + 'harfbuzz=disabled', + 'mmap=auto', + 'png=disabled', + 'tests=disabled', + 'zlib=internal', + ]) freetype_dep = freetype_proj.get_variable('freetype_dep') endif diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index dc3555fd7969..651936dc19c2 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -754,6 +754,8 @@ def __setitem__(self, key, val): cval = valid_key(val) except ValueError as ve: raise ValueError(f"Key {key}: {ve}") from None + if key == "text.kerning_factor" and cval is not None: + _api.warn_deprecated("3.11", name="text.kerning_factor", obj_type="rcParam") self._set(key, cval) def __getitem__(self, key): @@ -1332,7 +1334,7 @@ def _val_or_rc(val, *rc_names): def _init_tests(): # The version of FreeType to install locally for running the tests. This must match # the value in `meson.build`. - LOCAL_FREETYPE_VERSION = '2.6.1' + LOCAL_FREETYPE_VERSION = '2.13.3' from matplotlib import ft2font if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or diff --git a/lib/matplotlib/_afm.py b/lib/matplotlib/_afm.py index 9094206c2d7c..3d7f7a44baca 100644 --- a/lib/matplotlib/_afm.py +++ b/lib/matplotlib/_afm.py @@ -27,17 +27,19 @@ being used. """ -from collections import namedtuple +import inspect import logging import re +from typing import BinaryIO, NamedTuple, TypedDict, cast from ._mathtext_data import uni2type1 +from .ft2font import CharacterCodeType, GlyphIndexType _log = logging.getLogger(__name__) -def _to_int(x): +def _to_int(x: bytes | str) -> int: # Some AFM files have floats where we are expecting ints -- there is # probably a better way to handle this (support floats, round rather than # truncate). But I don't know what the best approach is now and this @@ -46,7 +48,7 @@ def _to_int(x): return int(float(x)) -def _to_float(x): +def _to_float(x: bytes | str) -> float: # Some AFM files use "," instead of "." as decimal separator -- this # shouldn't be ambiguous (unless someone is wicked enough to use "," as # thousands separator...). @@ -57,27 +59,56 @@ def _to_float(x): return float(x.replace(',', '.')) -def _to_str(x): +def _to_str(x: bytes) -> str: return x.decode('utf8') -def _to_list_of_ints(s): +def _to_list_of_ints(s: bytes) -> list[int]: s = s.replace(b',', b' ') return [_to_int(val) for val in s.split()] -def _to_list_of_floats(s): +def _to_list_of_floats(s: bytes | str) -> list[float]: return [_to_float(val) for val in s.split()] -def _to_bool(s): +def _to_bool(s: bytes) -> bool: if s.lower().strip() in (b'false', b'0', b'no'): return False else: return True -def _parse_header(fh): +class FontMetricsHeader(TypedDict, total=False): + StartFontMetrics: float + FontName: str + FullName: str + FamilyName: str + Weight: str + ItalicAngle: float + IsFixedPitch: bool + FontBBox: list[int] + UnderlinePosition: float + UnderlineThickness: float + Version: str + # Some AFM files have non-ASCII characters (which are not allowed by the spec). + # Given that there is actually no public API to even access this field, just return + # it as straight bytes. + Notice: bytes + EncodingScheme: str + CapHeight: float # Is the second version a mistake, or + Capheight: float # do some AFM files contain 'Capheight'? -JKS + XHeight: float + Ascender: float + Descender: float + StdHW: float + StdVW: float + StartCharMetrics: int + CharacterSet: str + Characters: int + + +def _parse_header(fh: BinaryIO) -> FontMetricsHeader: """ Read the font metrics header (up to the char metrics). @@ -98,34 +129,15 @@ def _parse_header(fh): * '-168 -218 1000 898' -> [-168, -218, 1000, 898] """ header_converters = { - b'StartFontMetrics': _to_float, - b'FontName': _to_str, - b'FullName': _to_str, - b'FamilyName': _to_str, - b'Weight': _to_str, - b'ItalicAngle': _to_float, - b'IsFixedPitch': _to_bool, - b'FontBBox': _to_list_of_ints, - b'UnderlinePosition': _to_float, - b'UnderlineThickness': _to_float, - b'Version': _to_str, - # Some AFM files have non-ASCII characters (which are not allowed by - # the spec). Given that there is actually no public API to even access - # this field, just return it as straight bytes. - b'Notice': lambda x: x, - b'EncodingScheme': _to_str, - b'CapHeight': _to_float, # Is the second version a mistake, or - b'Capheight': _to_float, # do some AFM files contain 'Capheight'? -JKS - b'XHeight': _to_float, - b'Ascender': _to_float, - b'Descender': _to_float, - b'StdHW': _to_float, - b'StdVW': _to_float, - b'StartCharMetrics': _to_int, - b'CharacterSet': _to_str, - b'Characters': _to_int, + bool: _to_bool, + bytes: lambda x: x, + float: _to_float, + int: _to_int, + list[int]: _to_list_of_ints, + str: _to_str, } - d = {} + header_value_types = inspect.get_annotations(FontMetricsHeader) + d: FontMetricsHeader = {} first_line = True for line in fh: line = line.rstrip() @@ -147,14 +159,16 @@ def _parse_header(fh): else: val = b'' try: - converter = header_converters[key] - except KeyError: + key_str = _to_str(key) + value_type = header_value_types[key_str] + except (KeyError, UnicodeDecodeError): _log.error("Found an unknown keyword in AFM header (was %r)", key) continue try: - d[key] = converter(val) + converter = header_converters[value_type] + d[key_str] = converter(val) # type: ignore[literal-required] except ValueError: - _log.error('Value error parsing header in AFM: %s, %s', key, val) + _log.error('Value error parsing header in AFM: %r, %r', key, val) continue if key == b'StartCharMetrics': break @@ -163,8 +177,8 @@ def _parse_header(fh): return d -CharMetrics = namedtuple('CharMetrics', 'width, name, bbox') -CharMetrics.__doc__ = """ +class CharMetrics(NamedTuple): + """ Represents the character metrics of a single character. Notes @@ -172,13 +186,20 @@ def _parse_header(fh): The fields do currently only describe a subset of character metrics information defined in the AFM standard. """ + + width: float + name: str + bbox: tuple[int, int, int, int] + + CharMetrics.width.__doc__ = """The character width (WX).""" CharMetrics.name.__doc__ = """The character name (N).""" CharMetrics.bbox.__doc__ = """ The bbox of the character (B) as a tuple (*llx*, *lly*, *urx*, *ury*).""" -def _parse_char_metrics(fh): +def _parse_char_metrics(fh: BinaryIO) -> tuple[dict[CharacterCodeType, CharMetrics], + dict[str, CharMetrics]]: """ Parse the given filehandle for character metrics information. @@ -198,12 +219,12 @@ def _parse_char_metrics(fh): """ required_keys = {'C', 'WX', 'N', 'B'} - ascii_d = {} - name_d = {} - for line in fh: + ascii_d: dict[CharacterCodeType, CharMetrics] = {} + name_d: dict[str, CharMetrics] = {} + for bline in fh: # We are defensively letting values be utf8. The spec requires # ascii, but there are non-compliant fonts in circulation - line = _to_str(line.rstrip()) # Convert from byte-literal + line = _to_str(bline.rstrip()) if line.startswith('EndCharMetrics'): return ascii_d, name_d # Split the metric line into a dictionary, keyed by metric identifiers @@ -214,8 +235,9 @@ def _parse_char_metrics(fh): num = _to_int(vals['C']) wx = _to_float(vals['WX']) name = vals['N'] - bbox = _to_list_of_floats(vals['B']) - bbox = list(map(int, bbox)) + bbox = tuple(map(int, _to_list_of_floats(vals['B']))) + if len(bbox) != 4: + raise RuntimeError(f'Bad parse: bbox has {len(bbox)} elements, should be 4') metrics = CharMetrics(wx, name, bbox) # Workaround: If the character name is 'Euro', give it the # corresponding character code, according to WinAnsiEncoding (see PDF @@ -230,7 +252,7 @@ def _parse_char_metrics(fh): raise RuntimeError('Bad parse') -def _parse_kern_pairs(fh): +def _parse_kern_pairs(fh: BinaryIO) -> dict[tuple[str, str], float]: """ Return a kern pairs dictionary. @@ -242,12 +264,11 @@ def _parse_kern_pairs(fh): d['A', 'y'] = -50 """ - line = next(fh) if not line.startswith(b'StartKernPairs'): - raise RuntimeError('Bad start of kern pairs data: %s' % line) + raise RuntimeError(f'Bad start of kern pairs data: {line!r}') - d = {} + d: dict[tuple[str, str], float] = {} for line in fh: line = line.rstrip() if not line: @@ -257,21 +278,26 @@ def _parse_kern_pairs(fh): return d vals = line.split() if len(vals) != 4 or vals[0] != b'KPX': - raise RuntimeError('Bad kern pairs line: %s' % line) + raise RuntimeError(f'Bad kern pairs line: {line!r}') c1, c2, val = _to_str(vals[1]), _to_str(vals[2]), _to_float(vals[3]) d[(c1, c2)] = val raise RuntimeError('Bad kern pairs parse') -CompositePart = namedtuple('CompositePart', 'name, dx, dy') -CompositePart.__doc__ = """ - Represents the information on a composite element of a composite char.""" +class CompositePart(NamedTuple): + """Represents the information on a composite element of a composite char.""" + + name: bytes + dx: float + dy: float + + CompositePart.name.__doc__ = """Name of the part, e.g. 'acute'.""" CompositePart.dx.__doc__ = """x-displacement of the part from the origin.""" CompositePart.dy.__doc__ = """y-displacement of the part from the origin.""" -def _parse_composites(fh): +def _parse_composites(fh: BinaryIO) -> dict[bytes, list[CompositePart]]: """ Parse the given filehandle for composites information. @@ -292,11 +318,11 @@ def _parse_composites(fh): will be represented as:: - composites['Aacute'] = [CompositePart(name='A', dx=0, dy=0), - CompositePart(name='acute', dx=160, dy=170)] + composites[b'Aacute'] = [CompositePart(name=b'A', dx=0, dy=0), + CompositePart(name=b'acute', dx=160, dy=170)] """ - composites = {} + composites: dict[bytes, list[CompositePart]] = {} for line in fh: line = line.rstrip() if not line: @@ -306,6 +332,9 @@ def _parse_composites(fh): vals = line.split(b';') cc = vals[0].split() name, _num_parts = cc[1], _to_int(cc[2]) + if len(vals) != _num_parts + 2: # First element is 'CC', last is empty. + raise RuntimeError(f'Bad composites parse: expected {_num_parts} parts, ' + f'but got {len(vals) - 2}') pccParts = [] for s in vals[1:-1]: pcc = s.split() @@ -316,7 +345,8 @@ def _parse_composites(fh): raise RuntimeError('Bad composites parse') -def _parse_optional(fh): +def _parse_optional(fh: BinaryIO) -> tuple[dict[tuple[str, str], float], + dict[bytes, list[CompositePart]]]: """ Parse the optional fields for kern pair data and composites. @@ -329,44 +359,38 @@ def _parse_optional(fh): A dict containing composite information. May be empty. See `._parse_composites`. """ - optional = { - b'StartKernData': _parse_kern_pairs, - b'StartComposites': _parse_composites, - } - - d = {b'StartKernData': {}, - b'StartComposites': {}} + kern_data: dict[tuple[str, str], float] = {} + composites: dict[bytes, list[CompositePart]] = {} for line in fh: line = line.rstrip() if not line: continue - key = line.split()[0] - - if key in optional: - d[key] = optional[key](fh) + match line.split()[0]: + case b'StartKernData': + kern_data = _parse_kern_pairs(fh) + case b'StartComposites': + composites = _parse_composites(fh) - return d[b'StartKernData'], d[b'StartComposites'] + return kern_data, composites class AFM: - def __init__(self, fh): + def __init__(self, fh: BinaryIO): """Parse the AFM file in file object *fh*.""" self._header = _parse_header(fh) self._metrics, self._metrics_by_name = _parse_char_metrics(fh) self._kern, self._composite = _parse_optional(fh) - def get_str_bbox_and_descent(self, s): + def get_str_bbox_and_descent(self, s: str) -> tuple[int, int, float, int, int]: """Return the string bounding box and the maximal descent.""" if not len(s): return 0, 0, 0, 0, 0 - total_width = 0 - namelast = None - miny = 1e9 + total_width = 0.0 + namelast = '' + miny = 1_000_000_000 maxy = 0 left = 0 - if not isinstance(s, str): - s = _to_str(s) for c in s: if c == '\n': continue @@ -386,50 +410,52 @@ def get_str_bbox_and_descent(self, s): return left, miny, total_width, maxy - miny, -miny - def get_glyph_name(self, glyph_ind): # For consistency with FT2Font. + def get_glyph_name(self, # For consistency with FT2Font. + glyph_ind: GlyphIndexType) -> str: """Get the name of the glyph, i.e., ord(';') is 'semicolon'.""" - return self._metrics[glyph_ind].name + return self._metrics[cast(CharacterCodeType, glyph_ind)].name - def get_char_index(self, c): # For consistency with FT2Font. + def get_char_index(self, # For consistency with FT2Font. + c: CharacterCodeType) -> GlyphIndexType: """ Return the glyph index corresponding to a character code point. Note, for AFM fonts, we treat the glyph index the same as the codepoint. """ - return c + return cast(GlyphIndexType, c) - def get_width_char(self, c): + def get_width_char(self, c: CharacterCodeType) -> float: """Get the width of the character code from the character metric WX field.""" return self._metrics[c].width - def get_width_from_char_name(self, name): + def get_width_from_char_name(self, name: str) -> float: """Get the width of the character from a type1 character name.""" return self._metrics_by_name[name].width - def get_kern_dist_from_name(self, name1, name2): + def get_kern_dist_from_name(self, name1: str, name2: str) -> float: """ Return the kerning pair distance (possibly 0) for chars *name1* and *name2*. """ return self._kern.get((name1, name2), 0) - def get_fontname(self): + def get_fontname(self) -> str: """Return the font name, e.g., 'Times-Roman'.""" - return self._header[b'FontName'] + return self._header['FontName'] @property - def postscript_name(self): # For consistency with FT2Font. + def postscript_name(self) -> str: # For consistency with FT2Font. return self.get_fontname() - def get_fullname(self): + def get_fullname(self) -> str: """Return the font full name, e.g., 'Times-Roman'.""" - name = self._header.get(b'FullName') + name = self._header.get('FullName') if name is None: # use FontName as a substitute - name = self._header[b'FontName'] + name = self._header['FontName'] return name - def get_familyname(self): + def get_familyname(self) -> str: """Return the font family name, e.g., 'Times'.""" - name = self._header.get(b'FamilyName') + name = self._header.get('FamilyName') if name is not None: return name @@ -440,26 +466,26 @@ def get_familyname(self): return re.sub(extras, '', name) @property - def family_name(self): # For consistency with FT2Font. + def family_name(self) -> str: # For consistency with FT2Font. """The font family name, e.g., 'Times'.""" return self.get_familyname() - def get_weight(self): + def get_weight(self) -> str: """Return the font weight, e.g., 'Bold' or 'Roman'.""" - return self._header[b'Weight'] + return self._header['Weight'] - def get_angle(self): + def get_angle(self) -> float: """Return the fontangle as float.""" - return self._header[b'ItalicAngle'] + return self._header['ItalicAngle'] - def get_capheight(self): + def get_capheight(self) -> float: """Return the cap height as float.""" - return self._header[b'CapHeight'] + return self._header['CapHeight'] - def get_xheight(self): + def get_xheight(self) -> float: """Return the xheight as float.""" - return self._header[b'XHeight'] + return self._header['XHeight'] - def get_underline_thickness(self): + def get_underline_thickness(self) -> float: """Return the underline thickness as float.""" - return self._header[b'UnderlineThickness'] + return self._header['UnderlineThickness'] diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index 2258c63e1bc2..234e5a238436 100644 --- a/lib/matplotlib/_mathtext.py +++ b/lib/matplotlib/_mathtext.py @@ -38,7 +38,8 @@ if T.TYPE_CHECKING: from collections.abc import Iterable - from .ft2font import Glyph + from .ft2font import CharacterCodeType, Glyph + ParserElement.enable_packrat() _log = logging.getLogger("matplotlib.mathtext") @@ -48,7 +49,7 @@ # FONTS -def get_unicode_index(symbol: str) -> int: # Publicly exported. +def get_unicode_index(symbol: str) -> CharacterCodeType: # Publicly exported. r""" Return the integer index (from the Unicode table) of *symbol*. @@ -86,7 +87,7 @@ class VectorParse(NamedTuple): width: float height: float depth: float - glyphs: list[tuple[FT2Font, float, int, float, float]] + glyphs: list[tuple[FT2Font, float, CharacterCodeType, float, float]] rects: list[tuple[float, float, float, float]] VectorParse.__module__ = "matplotlib.mathtext" @@ -213,7 +214,7 @@ class FontInfo(NamedTuple): fontsize: float postscript_name: str metrics: FontMetrics - num: int + num: CharacterCodeType glyph: Glyph offset: float @@ -366,7 +367,7 @@ def _get_offset(self, font: FT2Font, glyph: Glyph, fontsize: float, return 0. def _get_glyph(self, fontname: str, font_class: str, - sym: str) -> tuple[FT2Font, int, bool]: + sym: str) -> tuple[FT2Font, CharacterCodeType, bool]: raise NotImplementedError # The return value of _get_info is cached per-instance. @@ -426,7 +427,9 @@ def get_kern(self, font1: str, fontclass1: str, sym1: str, fontsize1: float, info1 = self._get_info(font1, fontclass1, sym1, fontsize1, dpi) info2 = self._get_info(font2, fontclass2, sym2, fontsize2, dpi) font = info1.font - return font.get_kerning(info1.num, info2.num, Kerning.DEFAULT) / 64 + return font.get_kerning(font.get_char_index(info1.num), + font.get_char_index(info2.num), + Kerning.DEFAULT) / 64 return super().get_kern(font1, fontclass1, sym1, fontsize1, font2, fontclass2, sym2, fontsize2, dpi) @@ -460,7 +463,7 @@ def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlag _slanted_symbols = set(r"\int \oint".split()) def _get_glyph(self, fontname: str, font_class: str, - sym: str) -> tuple[FT2Font, int, bool]: + sym: str) -> tuple[FT2Font, CharacterCodeType, bool]: font = None if fontname in self.fontmap and sym in latex_to_bakoma: basename, num = latex_to_bakoma[sym] @@ -552,7 +555,7 @@ class UnicodeFonts(TruetypeFonts): # Some glyphs are not present in the `cmr10` font, and must be brought in # from `cmsy10`. Map the Unicode indices of those glyphs to the indices at # which they are found in `cmsy10`. - _cmr10_substitutions = { + _cmr10_substitutions: dict[CharacterCodeType, CharacterCodeType] = { 0x00D7: 0x00A3, # Multiplication sign. 0x2212: 0x00A1, # Minus sign. } @@ -595,11 +598,11 @@ def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlag _slanted_symbols = set(r"\int \oint".split()) def _map_virtual_font(self, fontname: str, font_class: str, - uniindex: int) -> tuple[str, int]: + uniindex: CharacterCodeType) -> tuple[str, CharacterCodeType]: return fontname, uniindex def _get_glyph(self, fontname: str, font_class: str, - sym: str) -> tuple[FT2Font, int, bool]: + sym: str) -> tuple[FT2Font, CharacterCodeType, bool]: try: uniindex = get_unicode_index(sym) found_symbol = True @@ -608,8 +611,7 @@ def _get_glyph(self, fontname: str, font_class: str, found_symbol = False _log.warning("No TeX to Unicode mapping for %a.", sym) - fontname, uniindex = self._map_virtual_font( - fontname, font_class, uniindex) + fontname, uniindex = self._map_virtual_font(fontname, font_class, uniindex) new_fontname = fontname @@ -694,7 +696,7 @@ def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlag self.fontmap[name] = fullpath def _get_glyph(self, fontname: str, font_class: str, - sym: str) -> tuple[FT2Font, int, bool]: + sym: str) -> tuple[FT2Font, CharacterCodeType, bool]: # Override prime symbol to use Bakoma. if sym == r'\prime': return self.bakoma._get_glyph(fontname, font_class, sym) @@ -784,7 +786,7 @@ def __init__(self, default_font_prop: FontProperties, load_glyph_flags: LoadFlag self.fontmap[name] = fullpath def _map_virtual_font(self, fontname: str, font_class: str, - uniindex: int) -> tuple[str, int]: + uniindex: CharacterCodeType) -> tuple[str, CharacterCodeType]: # Handle these "fonts" that are actually embedded in # other fonts. font_mapping = stix_virtual_fonts.get(fontname) @@ -1171,7 +1173,7 @@ def __init__(self, elements: T.Sequence[Node]): self.glue_sign = 0 # 0: normal, -1: shrinking, 1: stretching self.glue_order = 0 # The order of infinity (0 - 3) for the glue - def __repr__(self): + def __repr__(self) -> str: return "{}[{}]".format( super().__repr__(), self.width, self.height, diff --git a/lib/matplotlib/_mathtext_data.py b/lib/matplotlib/_mathtext_data.py index 5819ee743044..0451791e9f26 100644 --- a/lib/matplotlib/_mathtext_data.py +++ b/lib/matplotlib/_mathtext_data.py @@ -3,9 +3,12 @@ """ from __future__ import annotations -from typing import overload +from typing import TypeAlias, overload -latex_to_bakoma = { +from .ft2font import CharacterCodeType + + +latex_to_bakoma: dict[str, tuple[str, CharacterCodeType]] = { '\\__sqrt__' : ('cmex10', 0x70), '\\bigcap' : ('cmex10', 0x5c), '\\bigcup' : ('cmex10', 0x5b), @@ -241,7 +244,7 @@ # Automatically generated. -type12uni = { +type12uni: dict[str, CharacterCodeType] = { 'aring' : 229, 'quotedblright' : 8221, 'V' : 86, @@ -475,7 +478,7 @@ # for key in sd: # print("{0:24} : {1: dict[str, float]: ... @property - def index(self) -> int: ... # type: ignore[override] + def index(self) -> GlyphIndexType: ... # type: ignore[override] @property - def glyph_name_or_index(self) -> int | str: ... + def glyph_name_or_index(self) -> GlyphIndexType | str: ... class Dvi: file: io.BufferedReader diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index ab6b495631de..79e088b85998 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -1539,7 +1539,7 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default, return _cached_realpath(result) -@lru_cache +@_api.deprecated("3.11") def is_opentype_cff_font(filename): """ Return whether the given font is a Postscript Compact Font Format Font diff --git a/lib/matplotlib/ft2font.pyi b/lib/matplotlib/ft2font.pyi index a413cd3c1a76..a4ddc84358c1 100644 --- a/lib/matplotlib/ft2font.pyi +++ b/lib/matplotlib/ft2font.pyi @@ -1,6 +1,6 @@ from enum import Enum, Flag import sys -from typing import BinaryIO, Literal, TypedDict, final, overload, cast +from typing import BinaryIO, Literal, NewType, TypeAlias, TypedDict, cast, final, overload from typing_extensions import Buffer # < Py 3.12 import numpy as np @@ -9,6 +9,12 @@ from numpy.typing import NDArray __freetype_build_type__: str __freetype_version__: str +# We can't change the type hints for standard library chr/ord, so character codes are a +# simple type alias. +CharacterCodeType: TypeAlias = int +# But glyph indices are internal, so use a distinct type hint. +GlyphIndexType = NewType('GlyphIndexType', int) + class FaceFlags(Flag): SCALABLE = cast(int, ...) FIXED_SIZES = cast(int, ...) @@ -191,7 +197,7 @@ class FT2Font(Buffer): hinting_factor: int = ..., *, _fallback_list: list[FT2Font] | None = ..., - _kerning_factor: int = ... + _kerning_factor: int | None = ... ) -> None: ... if sys.version_info[:2] >= (3, 12): def __buffer__(self, flags: int) -> memoryview: ... @@ -202,13 +208,13 @@ class FT2Font(Buffer): ) -> None: ... def draw_glyphs_to_bitmap(self, antialiased: bool = ...) -> None: ... def get_bitmap_offset(self) -> tuple[int, int]: ... - def get_char_index(self, codepoint: int) -> int: ... - def get_charmap(self) -> dict[int, int]: ... + def get_char_index(self, codepoint: CharacterCodeType) -> GlyphIndexType: ... + def get_charmap(self) -> dict[CharacterCodeType, GlyphIndexType]: ... def get_descent(self) -> int: ... - def get_glyph_name(self, index: int) -> str: ... + def get_glyph_name(self, index: GlyphIndexType) -> str: ... def get_image(self) -> NDArray[np.uint8]: ... - def get_kerning(self, left: int, right: int, mode: Kerning) -> int: ... - def get_name_index(self, name: str) -> int: ... + def get_kerning(self, left: GlyphIndexType, right: GlyphIndexType, mode: Kerning) -> int: ... + def get_name_index(self, name: str) -> GlyphIndexType: ... def get_num_glyphs(self) -> int: ... def get_path(self) -> tuple[NDArray[np.float64], NDArray[np.int8]]: ... def get_ps_font_info( @@ -230,8 +236,8 @@ class FT2Font(Buffer): @overload def get_sfnt_table(self, name: Literal["pclt"]) -> _SfntPcltDict | None: ... def get_width_height(self) -> tuple[int, int]: ... - def load_char(self, charcode: int, flags: LoadFlags = ...) -> Glyph: ... - def load_glyph(self, glyphindex: int, flags: LoadFlags = ...) -> Glyph: ... + def load_char(self, charcode: CharacterCodeType, flags: LoadFlags = ...) -> Glyph: ... + def load_glyph(self, glyphindex: GlyphIndexType, flags: LoadFlags = ...) -> Glyph: ... def select_charmap(self, i: int) -> None: ... def set_charmap(self, i: int) -> None: ... def set_size(self, ptsize: float, dpi: float) -> None: ... diff --git a/lib/matplotlib/mpl-data/matplotlibrc b/lib/matplotlib/mpl-data/matplotlibrc index 83e567a414c9..223eed396535 100644 --- a/lib/matplotlib/mpl-data/matplotlibrc +++ b/lib/matplotlib/mpl-data/matplotlibrc @@ -301,15 +301,14 @@ ## ("native" is a synonym.) ## - force_autohint: Use FreeType's auto-hinter. ("auto" is a synonym.) ## - no_hinting: Disable hinting. ("none" is a synonym.) -#text.hinting: force_autohint +#text.hinting: default -#text.hinting_factor: 8 # Specifies the amount of softness for hinting in the +#text.hinting_factor: 1 # Specifies the amount of softness for hinting in the # horizontal direction. A value of 1 will hint to full # pixels. A value of 2 will hint to half pixels etc. -#text.kerning_factor: 0 # Specifies the scaling factor for kerning values. This - # is provided solely to allow old test images to remain - # unchanged. Set to 6 to obtain previous behavior. - # Values other than 0 or 6 have no defined meaning. +#text.kerning_factor: None # Specifies the scaling factor for kerning values. Values + # other than 0, 6, or None have no defined meaning. + # This setting is deprecated. #text.antialiased: True # If True (default), the text will be antialiased. # This only affects raster outputs. #text.parse_math: True # Use mathtext if there is an even number of unescaped diff --git a/lib/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle b/lib/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle index abd972925871..3dc92f832b20 100644 --- a/lib/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle @@ -1,8 +1,9 @@ # This patch should go on top of the "classic" style and exists solely to avoid # changing baseline images. -text.kerning_factor : 6 - ytick.alignment: center_baseline hatch.color: edge + +text.hinting: default +text.hinting_factor: 1 diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 80d25659888e..b4224d169815 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -1042,7 +1042,7 @@ def _convert_validator_spec(key, conv): "text.hinting": ["default", "no_autohint", "force_autohint", "no_hinting", "auto", "native", "either", "none"], "text.hinting_factor": validate_int, - "text.kerning_factor": validate_int, + "text.kerning_factor": validate_int_or_None, "text.antialiased": validate_bool, "text.parse_math": validate_bool, diff --git a/lib/matplotlib/testing/__init__.py b/lib/matplotlib/testing/__init__.py index 904ee5d73db4..8803dab6266c 100644 --- a/lib/matplotlib/testing/__init__.py +++ b/lib/matplotlib/testing/__init__.py @@ -19,8 +19,15 @@ def set_font_settings_for_testing(): mpl.rcParams['font.family'] = 'DejaVu Sans' - mpl.rcParams['text.hinting'] = 'none' - mpl.rcParams['text.hinting_factor'] = 8 + # We've changed the default for ourselves here, but for backwards-compatibility, use + # the old setting if not called in our own tests (which would set + # `_called_from_pytest` from our `conftest.py`). + if getattr(mpl, '_called_from_pytest', False): + mpl.rcParams['text.hinting'] = 'default' + mpl.rcParams['text.hinting_factor'] = 1 + else: + mpl.rcParams['text.hinting'] = 'none' + mpl.rcParams['text.hinting_factor'] = 8 def set_reproducibility_for_testing(): diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_21.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_21.svg index 6967f80a1186..a7195c665c14 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_21.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_21.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:36.846948 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,721 +26,752 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.png index 0317cb99e1c0..c2076843da4a 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.png and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.svg index 9d57faac5f18..09dd81f56563 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_23.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:33.031781 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,297 +26,317 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - + - - - + - + - - + - - - - + - - - - - - - - - - - - - - - - - - - - - +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_21.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_21.svg index 90f9b2cec969..b6236288603d 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_21.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_21.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:40.551077 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,437 +26,467 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.png index d6802f84bfda..5a615d92e166 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.png and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.svg index 77ded780c3f1..4d7fdcc30954 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_23.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:40.658346 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,268 +26,288 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - + - - - + - - + - - + - - + - + - - - - - - - - - - - - - - - - - - - - - +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_27.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_27.svg index 7a7b7ec42c25..e73b1c5e872b 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_27.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_27.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:39.585869 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,190 +26,202 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - - + - - - + - - - + - - - - - - - - - - - - - - +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_46.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_46.svg index 0846b552246a..ca0439485b08 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_46.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_46.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:40.642097 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,115 +26,121 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - - - + - - - - - - +M 1381 2969 +Q 1594 3256 1914 3420 +Q 2234 3584 2584 3584 +Q 3122 3584 3439 3221 +Q 3756 2859 3756 2241 +Q 3756 1734 3570 1259 +Q 3384 784 3041 416 +Q 2816 172 2522 40 +Q 2228 -91 1906 -91 +Q 1566 -91 1316 65 +Q 1066 222 909 531 +L 806 0 +L 231 0 +L 1178 4863 +L 1753 4863 +L 1381 2969 +z +" transform="scale(0.015625)"/> + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_49.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_49.svg index 24db824fd37c..8287a2338258 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_49.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_49.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:40.896681 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,103 +26,109 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - - - + + - + - - - - - - - - - - +" transform="scale(0.015625)"/> + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_60.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_60.svg index 189491319c10..0bbef213526f 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_60.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_60.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:39.508765 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,209 +26,220 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - + + - + - - - + - - + - - - - - - - - - - - - - +M 1959 2075 +Q 2384 2075 2632 2365 +Q 2881 2656 2881 3163 +Q 2881 3666 2632 3958 +Q 2384 4250 1959 4250 +Q 1534 4250 1286 3958 +Q 1038 3666 1038 3163 +Q 1038 2656 1286 2365 +Q 1534 2075 1959 2075 +z +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_21.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_21.svg index e0721c9e47a4..3e7c6dc1c42c 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_21.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_21.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:40.642033 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,493 +26,524 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.png index b405dd438309..c8bae48383aa 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.png and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.svg index 13ec8213ff31..ced57fed3b2b 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_23.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:40.725227 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,278 +26,298 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - + - - - + - + - + - - - + - - + - - - - - - - - - - - - - - - - - - - - - +M 3022 2063 +Q 3016 2534 2758 2815 +Q 2500 3097 2075 3097 +Q 1594 3097 1305 2825 +Q 1016 2553 972 2059 +L 3022 2063 +z +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_60.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_60.svg index a4fb4be582a4..cd7dfc34183b 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_60.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_60.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:42.172241 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,223 +26,234 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - + - + - - - + - - + - + - - - - - - - - - - - - +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_21.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_21.svg index 4623754e2963..045cc829e0cf 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_21.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_21.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:38.874726 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,531 +26,562 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.png index 1923648b80a3..d0233a4ee7a0 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.png and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.svg index bc6756feadc8..8184565aaf2a 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_23.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:38.959357 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,284 +26,304 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - + - - - + - - + - - + - - - + - - - - - - - - - - - - - - - - - - - - - +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_21.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_21.svg index d61317816ad6..c3dd8722b044 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_21.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_21.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:38.040182 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,435 +26,466 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.png index a86119004e62..6f816c2ee723 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.png and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.svg index 4e129aa6c87d..50bdb38d37b1 100644 --- a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.svg +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_23.svg @@ -1,12 +1,23 @@ - - + + + + + + 2025-07-24T15:42:38.119948 + image/svg+xml + + + Matplotlib v3.11.0.dev1119+gc6e6904896.d20250724, https://matplotlib.org/ + + + + + - + @@ -15,269 +26,289 @@ L 378 54 L 378 0 L 0 0 z -" style="fill:#ffffff;"/> +" style="fill: #ffffff"/> - - + + - + - - - + - + - - + - - - + - - + - - - - - - - - - - - - - - - - - - - - +" transform="scale(0.015625)"/> + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_text/rotation_anchor.png b/lib/matplotlib/tests/baseline_images/test_text/rotation_anchor.png new file mode 100644 index 000000000000..3dad1f9a19f7 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_text/rotation_anchor.png differ diff --git a/lib/matplotlib/tests/test_afm.py b/lib/matplotlib/tests/test_afm.py index 80cf8ac60feb..bc1d587baf6b 100644 --- a/lib/matplotlib/tests/test_afm.py +++ b/lib/matplotlib/tests/test_afm.py @@ -47,20 +47,20 @@ def test_parse_header(): fh = BytesIO(AFM_TEST_DATA) header = _afm._parse_header(fh) assert header == { - b'StartFontMetrics': 2.0, - b'FontName': 'MyFont-Bold', - b'EncodingScheme': 'FontSpecific', - b'FullName': 'My Font Bold', - b'FamilyName': 'Test Fonts', - b'Weight': 'Bold', - b'ItalicAngle': 0.0, - b'IsFixedPitch': False, - b'UnderlinePosition': -100, - b'UnderlineThickness': 56.789, - b'Version': '001.000', - b'Notice': b'Copyright \xa9 2017 No one.', - b'FontBBox': [0, -321, 1234, 369], - b'StartCharMetrics': 3, + 'StartFontMetrics': 2.0, + 'FontName': 'MyFont-Bold', + 'EncodingScheme': 'FontSpecific', + 'FullName': 'My Font Bold', + 'FamilyName': 'Test Fonts', + 'Weight': 'Bold', + 'ItalicAngle': 0.0, + 'IsFixedPitch': False, + 'UnderlinePosition': -100, + 'UnderlineThickness': 56.789, + 'Version': '001.000', + 'Notice': b'Copyright \xa9 2017 No one.', + 'FontBBox': [0, -321, 1234, 369], + 'StartCharMetrics': 3, } @@ -69,20 +69,23 @@ def test_parse_char_metrics(): _afm._parse_header(fh) # position metrics = _afm._parse_char_metrics(fh) assert metrics == ( - {0: (250.0, 'space', [0, 0, 0, 0]), - 42: (1141.0, 'foo', [40, 60, 800, 360]), - 99: (583.0, 'bar', [40, -10, 543, 210]), - }, - {'space': (250.0, 'space', [0, 0, 0, 0]), - 'foo': (1141.0, 'foo', [40, 60, 800, 360]), - 'bar': (583.0, 'bar', [40, -10, 543, 210]), - }) + { + 0: _afm.CharMetrics(250.0, 'space', (0, 0, 0, 0)), + 42: _afm.CharMetrics(1141.0, 'foo', (40, 60, 800, 360)), + 99: _afm.CharMetrics(583.0, 'bar', (40, -10, 543, 210)), + }, + { + 'space': _afm.CharMetrics(250.0, 'space', (0, 0, 0, 0)), + 'foo': _afm.CharMetrics(1141.0, 'foo', (40, 60, 800, 360)), + 'bar': _afm.CharMetrics(583.0, 'bar', (40, -10, 543, 210)), + } + ) def test_get_familyname_guessed(): fh = BytesIO(AFM_TEST_DATA) font = _afm.AFM(fh) - del font._header[b'FamilyName'] # remove FamilyName, so we have to guess + del font._header['FamilyName'] # remove FamilyName, so we have to guess assert font.get_familyname() == 'My Font' diff --git a/lib/matplotlib/tests/test_artist.py b/lib/matplotlib/tests/test_artist.py index 1367701ffe3e..d891609d4eb3 100644 --- a/lib/matplotlib/tests/test_artist.py +++ b/lib/matplotlib/tests/test_artist.py @@ -217,9 +217,6 @@ def test_remove(): @image_comparison(["default_edges.png"], remove_text=True, style='default') def test_default_edges(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2) ax1.plot(np.arange(10), np.arange(10), 'x', diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 0c445f86d9aa..1e34d14380af 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -8299,8 +8299,8 @@ def test_normal_axes(): # test the axis bboxes target = [ - [123.375, 75.88888888888886, 983.25, 33.0], - [85.51388888888889, 99.99999999999997, 53.375, 993.0] + [124.0, 76.89, 982.0, 32.0], + [86.89, 100.5, 52.0, 992.0], ] for nn, b in enumerate(bbaxis): targetbb = mtransforms.Bbox.from_bounds(*target[nn]) @@ -8320,7 +8320,7 @@ def test_normal_axes(): targetbb = mtransforms.Bbox.from_bounds(*target) assert_array_almost_equal(bbax.bounds, targetbb.bounds, decimal=2) - target = [85.5138, 75.88888, 1021.11, 1017.11] + target = [86.89, 76.89, 1019.11, 1015.61] targetbb = mtransforms.Bbox.from_bounds(*target) assert_array_almost_equal(bbtb.bounds, targetbb.bounds, decimal=2) diff --git a/lib/matplotlib/tests/test_bbox_tight.py b/lib/matplotlib/tests/test_bbox_tight.py index 431ca70bf7ea..2ae94abcd7b2 100644 --- a/lib/matplotlib/tests/test_bbox_tight.py +++ b/lib/matplotlib/tests/test_bbox_tight.py @@ -47,7 +47,7 @@ def test_bbox_inches_tight(text_placeholders): @image_comparison(['bbox_inches_tight_suptile_legend'], savefig_kwarg={'bbox_inches': 'tight'}, - tol=0 if platform.machine() == 'x86_64' else 0.02) + tol=0 if platform.machine() == 'x86_64' else 0.022) def test_bbox_inches_tight_suptile_legend(): plt.plot(np.arange(10), label='a straight line') plt.legend(bbox_to_anchor=(0.9, 1), loc='upper left') diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index c5890a2963b3..900e184c6741 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -814,7 +814,7 @@ def test_tightbbox(): ax.set_xlim(0, 1) t = ax.text(1., 0.5, 'This dangles over end') renderer = fig.canvas.get_renderer() - x1Nom0 = 9.035 # inches + x1Nom0 = 8.9875 # inches assert abs(t.get_tightbbox(renderer).x1 - x1Nom0 * fig.dpi) < 2 assert abs(ax.get_tightbbox(renderer).x1 - x1Nom0 * fig.dpi) < 2 assert abs(fig.get_tightbbox(renderer).x1 - x1Nom0) < 0.05 @@ -1376,7 +1376,8 @@ def test_subfigure_dpi(): @image_comparison(['test_subfigure_ss.png'], style='mpl20', - savefig_kwarg={'facecolor': 'teal'}, tol=0.02) + savefig_kwarg={'facecolor': 'teal'}, + tol=0.022) def test_subfigure_ss(): # test assigning the subfigure via subplotspec np.random.seed(19680801) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index 24421b8e30b3..b15647644e04 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -67,12 +67,14 @@ def test_json_serialization(tmp_path): def test_otf(): fname = '/usr/share/fonts/opentype/freefont/FreeMono.otf' if Path(fname).exists(): - assert is_opentype_cff_font(fname) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert is_opentype_cff_font(fname) for f in fontManager.ttflist: if 'otf' in f.fname: with open(f.fname, 'rb') as fd: res = fd.read(4) == b'OTTO' - assert res == is_opentype_cff_font(f.fname) + with pytest.warns(mpl.MatplotlibDeprecationWarning): + assert res == is_opentype_cff_font(f.fname) @pytest.mark.skipif(sys.platform == "win32" or not has_fclist, diff --git a/lib/matplotlib/tests/test_ft2font.py b/lib/matplotlib/tests/test_ft2font.py index 8b448e17b7fd..6b405287e5d7 100644 --- a/lib/matplotlib/tests/test_ft2font.py +++ b/lib/matplotlib/tests/test_ft2font.py @@ -1,6 +1,7 @@ import itertools import io from pathlib import Path +from typing import cast import numpy as np import pytest @@ -168,6 +169,12 @@ def test_ft2font_invalid_args(tmp_path): # kerning_factor argument. with pytest.raises(TypeError, match='incompatible constructor arguments'): ft2font.FT2Font(file, _kerning_factor=1.3) + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match='text.kerning_factor rcParam was deprecated .+ 3.11'): + mpl.rcParams['text.kerning_factor'] = 0 + with pytest.warns(mpl.MatplotlibDeprecationWarning, + match='_kerning_factor parameter was deprecated .+ 3.11'): + ft2font.FT2Font(file, _kerning_factor=123) def test_ft2font_clear(): @@ -188,8 +195,8 @@ def test_ft2font_clear(): def test_ft2font_set_size(): file = fm.findfont('DejaVu Sans') - # Default is 12pt @ 72 dpi. - font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=1) + font = ft2font.FT2Font(file, hinting_factor=1) + font.set_size(12, 72) font.set_text('ABabCDcd') orig = font.get_width_height() font.set_size(24, 72) @@ -235,7 +242,7 @@ def enc(name): assert unic == after # This is just a random sample from FontForge. - glyph_names = { + glyph_names = cast(dict[str, ft2font.GlyphIndexType], { 'non-existent-glyph-name': 0, 'plusminus': 115, 'Racute': 278, @@ -247,7 +254,7 @@ def enc(name): 'uni2A02': 4464, 'u1D305': 5410, 'u1F0A1': 5784, - } + }) for name, index in glyph_names.items(): assert font.get_name_index(name) == index if name == 'non-existent-glyph-name': @@ -708,16 +715,16 @@ def test_ft2font_get_sfnt_table(font_name, header): @pytest.mark.parametrize('left, right, unscaled, unfitted, default', [ # These are all the same class. - ('A', 'A', 57, 248, 256), ('A', 'À', 57, 248, 256), ('A', 'Á', 57, 248, 256), - ('A', 'Â', 57, 248, 256), ('A', 'Ã', 57, 248, 256), ('A', 'Ä', 57, 248, 256), + ('A', 'A', 57, 247, 256), ('A', 'À', 57, 247, 256), ('A', 'Á', 57, 247, 256), + ('A', 'Â', 57, 247, 256), ('A', 'Ã', 57, 247, 256), ('A', 'Ä', 57, 247, 256), # And a few other random ones. - ('D', 'A', -36, -156, -128), ('T', '.', -243, -1056, -1024), + ('D', 'A', -36, -156, -128), ('T', '.', -243, -1055, -1024), ('X', 'C', -149, -647, -640), ('-', 'J', 114, 495, 512), ]) def test_ft2font_get_kerning(left, right, unscaled, unfitted, default): file = fm.findfont('DejaVu Sans') # With unscaled, these settings should produce exact values found in FontForge. - font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font = ft2font.FT2Font(file, hinting_factor=1) font.set_size(100, 100) assert font.get_kerning(font.get_char_index(ord(left)), font.get_char_index(ord(right)), @@ -756,7 +763,8 @@ def test_ft2font_get_kerning(left, right, unscaled, unfitted, default): def test_ft2font_set_text(): file = fm.findfont('DejaVu Sans') - font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font = ft2font.FT2Font(file, hinting_factor=1) + font.set_size(12, 72) xys = font.set_text('') np.testing.assert_array_equal(xys, np.empty((0, 2))) assert font.get_width_height() == (0, 0) @@ -777,7 +785,8 @@ def test_ft2font_set_text(): def test_ft2font_loading(): file = fm.findfont('DejaVu Sans') - font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font = ft2font.FT2Font(file, hinting_factor=1) + font.set_size(12, 72) for glyph in [font.load_char(ord('M')), font.load_glyph(font.get_char_index(ord('M')))]: assert glyph is not None @@ -817,12 +826,14 @@ def test_ft2font_drawing(): ]) expected *= 255 file = fm.findfont('DejaVu Sans') - font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font = ft2font.FT2Font(file, hinting_factor=1) + font.set_size(12, 72) font.set_text('M') font.draw_glyphs_to_bitmap(antialiased=False) image = font.get_image() np.testing.assert_array_equal(image, expected) - font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font = ft2font.FT2Font(file, hinting_factor=1) + font.set_size(12, 72) glyph = font.load_char(ord('M')) image = np.zeros(expected.shape, np.uint8) font.draw_glyph_to_bitmap(image, -1, 1, glyph, antialiased=False) @@ -831,7 +842,8 @@ def test_ft2font_drawing(): def test_ft2font_get_path(): file = fm.findfont('DejaVu Sans') - font = ft2font.FT2Font(file, hinting_factor=1, _kerning_factor=0) + font = ft2font.FT2Font(file, hinting_factor=1) + font.set_size(12, 72) vertices, codes = font.get_path() assert vertices.shape == (0, 2) assert codes.shape == (0, ) diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index 61fae63a298e..b0698936a23a 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -258,9 +258,6 @@ def test_legend_expand(): @image_comparison(['hatching'], remove_text=True, style='default') def test_hatching(): # Remove legend texts when this image is regenerated. - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig, ax = plt.subplots() # Patches @@ -484,10 +481,10 @@ def test_figure_legend_outside(): todos += ['left ' + pos for pos in ['lower', 'center', 'upper']] todos += ['right ' + pos for pos in ['lower', 'center', 'upper']] - upperext = [20.347556, 27.722556, 790.583, 545.499] - lowerext = [20.347556, 71.056556, 790.583, 588.833] - leftext = [151.681556, 27.722556, 790.583, 588.833] - rightext = [20.347556, 27.722556, 659.249, 588.833] + upperext = [20.722556, 26.722556, 790.333, 545.999] + lowerext = [20.722556, 70.056556, 790.333, 589.333] + leftext = [152.056556, 26.722556, 790.333, 589.333] + rightext = [20.722556, 26.722556, 658.999, 589.333] axbb = [upperext, upperext, upperext, lowerext, lowerext, lowerext, leftext, leftext, leftext, diff --git a/lib/matplotlib/tests/test_mathtext.py b/lib/matplotlib/tests/test_mathtext.py index 39c28dc9228c..4fc04a627dd5 100644 --- a/lib/matplotlib/tests/test_mathtext.py +++ b/lib/matplotlib/tests/test_mathtext.py @@ -568,14 +568,14 @@ def test_box_repr(): _mathtext.DejaVuSansFonts(fm.FontProperties(), LoadFlags.NO_HINTING), fontsize=12, dpi=100)) assert s == textwrap.dedent("""\ - Hlist[ + Hlist[ Hlist[], - Hlist[ - Hlist[ - Vlist[ - HCentered[ + Hlist[ + Hlist[ + Vlist[ + HCentered[ Glue, - Hlist[ + Hlist[ `1`, k2.36, ], @@ -584,9 +584,9 @@ def test_box_repr(): Vbox, Hrule, Vbox, - HCentered[ + HCentered[ Glue, - Hlist[ + Hlist[ `2`, k2.02, ], diff --git a/lib/matplotlib/tests/test_polar.py b/lib/matplotlib/tests/test_polar.py index 4f9e63380490..547bd560de1c 100644 --- a/lib/matplotlib/tests/test_polar.py +++ b/lib/matplotlib/tests/test_polar.py @@ -330,7 +330,7 @@ def test_get_tightbbox_polar(): fig.canvas.draw() bb = ax.get_tightbbox(fig.canvas.get_renderer()) assert_allclose( - bb.extents, [107.7778, 29.2778, 539.7847, 450.7222], rtol=1e-03) + bb.extents, [108.27778, 28.7778, 539.7222, 451.2222], rtol=1e-03) @check_figures_equal() diff --git a/lib/matplotlib/tests/test_text.py b/lib/matplotlib/tests/test_text.py index 02cecea1c6c6..9d943fa9df13 100644 --- a/lib/matplotlib/tests/test_text.py +++ b/lib/matplotlib/tests/test_text.py @@ -139,9 +139,6 @@ def test_multiline(): @image_comparison(['multiline2'], style='mpl20') def test_multiline2(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig, ax = plt.subplots() ax.set_xlim(0, 1.4) @@ -301,6 +298,22 @@ def test_alignment(): ax.set_yticks([]) +@image_comparison(baseline_images=['rotation_anchor.png'], style='mpl20', + remove_text=True) +def test_rotation_mode_anchor(): + fig, ax = plt.subplots() + + ax.plot([0, 1], lw=0) + ax.axvline(.5, linewidth=.5, color='.5') + ax.axhline(.5, linewidth=.5, color='.5') + + N = 4 + for r in range(N): + ax.text(.5, .5, 'pP', color=f'C{r}', size=100, + rotation=r/N*360, rotation_mode='anchor', + verticalalignment='center_baseline') + + @image_comparison(['axes_titles.png']) def test_axes_titles(): # Related to issue #3327 @@ -678,8 +691,6 @@ def test_annotation_units(fig_test, fig_ref): @image_comparison(['large_subscript_title.png'], style='mpl20') def test_large_subscript_title(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 plt.rcParams['axes.titley'] = None fig, axs = plt.subplots(1, 2, figsize=(9, 2.5), constrained_layout=True) @@ -716,7 +727,7 @@ def test_wrap(x, rotation, halign): def test_mathwrap(): - fig = plt.figure(figsize=(6, 4)) + fig = plt.figure(figsize=(5, 4)) s = r'This is a very $\overline{\mathrm{long}}$ line of Mathtext.' text = fig.text(0, 0.5, s, size=40, wrap=True) fig.canvas.draw() diff --git a/lib/mpl_toolkits/axisartist/tests/test_axis_artist.py b/lib/mpl_toolkits/axisartist/tests/test_axis_artist.py index d44a61b6dd4a..7caf4fc21683 100644 --- a/lib/mpl_toolkits/axisartist/tests/test_axis_artist.py +++ b/lib/mpl_toolkits/axisartist/tests/test_axis_artist.py @@ -26,9 +26,6 @@ def test_ticks(): @image_comparison(['axis_artist_labelbase.png'], style='default') def test_labelbase(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig, ax = plt.subplots() ax.plot([0.5], [0.5], "o") @@ -43,9 +40,6 @@ def test_labelbase(): @image_comparison(['axis_artist_ticklabels.png'], style='default') def test_ticklabels(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig, ax = plt.subplots() ax.xaxis.set_visible(False) @@ -78,9 +72,6 @@ def test_ticklabels(): @image_comparison(['axis_artist.png'], style='default') def test_axis_artist(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig, ax = plt.subplots() ax.xaxis.set_visible(False) diff --git a/lib/mpl_toolkits/axisartist/tests/test_axislines.py b/lib/mpl_toolkits/axisartist/tests/test_axislines.py index a1485d4f436b..c371d6453932 100644 --- a/lib/mpl_toolkits/axisartist/tests/test_axislines.py +++ b/lib/mpl_toolkits/axisartist/tests/test_axislines.py @@ -9,9 +9,6 @@ @image_comparison(['SubplotZero.png'], style='default') def test_SubplotZero(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig = plt.figure() ax = SubplotZero(fig, 1, 1, 1) @@ -30,9 +27,6 @@ def test_SubplotZero(): @image_comparison(['Subplot.png'], style='default') def test_Subplot(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig = plt.figure() ax = Subplot(fig, 1, 1, 1) diff --git a/lib/mpl_toolkits/axisartist/tests/test_floating_axes.py b/lib/mpl_toolkits/axisartist/tests/test_floating_axes.py index feb667af013e..3dd4309d199e 100644 --- a/lib/mpl_toolkits/axisartist/tests/test_floating_axes.py +++ b/lib/mpl_toolkits/axisartist/tests/test_floating_axes.py @@ -69,9 +69,6 @@ def test_curvelinear3(): # remove when image is regenerated. @image_comparison(['curvelinear4.png'], style='default', tol=0.9) def test_curvelinear4(): - # Remove this line when this test image is regenerated. - plt.rcParams['text.kerning_factor'] = 6 - fig = plt.figure(figsize=(5, 5)) tr = (mtransforms.Affine2D().scale(np.pi / 180, 1) + diff --git a/lib/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py b/lib/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py index 7d6554782fe6..f58a42471680 100644 --- a/lib/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py +++ b/lib/mpl_toolkits/axisartist/tests/test_grid_helper_curvelinear.py @@ -135,11 +135,8 @@ def test_polar_box(): ax1.grid(True) -# Remove tol & kerning_factor when this test image is regenerated. -@image_comparison(['axis_direction.png'], style='default', tol=0.13) +@image_comparison(['axis_direction.png'], style='default', tol=0.04) def test_axis_direction(): - plt.rcParams['text.kerning_factor'] = 6 - fig = plt.figure(figsize=(5, 5)) # PolarAxes.PolarTransform takes radian. However, we want our coordinate diff --git a/pyproject.toml b/pyproject.toml index cf8503a0f3fe..3c85f83cc2a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ requires-python = ">=3.11" [project.optional-dependencies] # Should be a copy of the build dependencies below. dev = [ - "meson-python>=0.13.1,!=0.17.*", + "meson-python>=0.13.2,!=0.17.*", "pybind11>=2.13.2,!=2.13.3", "setuptools_scm>=7", # Not required by us but setuptools_scm without a version, cso _if_ @@ -72,7 +72,7 @@ build-backend = "mesonpy" requires = [ # meson-python 0.17.x breaks symlinks in sdists. You can remove this pin if # you really need it and aren't using an sdist. - "meson-python>=0.13.1,!=0.17.*", + "meson-python>=0.13.2,!=0.17.*", "pybind11>=2.13.2,!=2.13.3", "setuptools_scm>=7", ] diff --git a/requirements/testing/minver.txt b/requirements/testing/minver.txt index ee55f6c7b1bf..3b6aea9e7ca3 100644 --- a/requirements/testing/minver.txt +++ b/requirements/testing/minver.txt @@ -5,7 +5,7 @@ cycler==0.10 fonttools==4.22.0 importlib-resources==3.2.0 kiwisolver==1.3.2 -meson-python==0.13.1 +meson-python==0.13.2 meson==1.1.0 numpy==1.25.0 packaging==20.0 diff --git a/src/_path.h b/src/_path.h index c03703776760..1b54426c7e81 100644 --- a/src/_path.h +++ b/src/_path.h @@ -1066,38 +1066,25 @@ void quad2cubic(double x0, double y0, void __add_number(double val, char format_code, int precision, std::string& buffer) { - if (precision == -1) { - // Special-case for compat with old ttconv code, which *truncated* - // values with a cast to int instead of rounding them as printf - // would do. The only point where non-integer values arise is from - // quad2cubic conversion (as we already perform a first truncation - // on Python's side), which can introduce additional floating point - // error (by adding 2/3 delta-x and then 1/3 delta-x), so compensate by - // first rounding to the closest 1/3 and then truncating. - char str[255]; - PyOS_snprintf(str, 255, "%d", (int)(round(val * 3)) / 3); - buffer += str; - } else { - char *str = PyOS_double_to_string( - val, format_code, precision, Py_DTSF_ADD_DOT_0, nullptr); - // Delete trailing zeros and decimal point - char *c = str + strlen(str) - 1; // Start at last character. - // Rewind through all the zeros and, if present, the trailing decimal - // point. Py_DTSF_ADD_DOT_0 ensures we won't go past the start of str. - while (*c == '0') { - --c; - } - if (*c == '.') { - --c; - } - try { - buffer.append(str, c + 1); - } catch (std::bad_alloc& e) { - PyMem_Free(str); - throw e; - } + char *str = PyOS_double_to_string( + val, format_code, precision, Py_DTSF_ADD_DOT_0, nullptr); + // Delete trailing zeros and decimal point + char *c = str + strlen(str) - 1; // Start at last character. + // Rewind through all the zeros and, if present, the trailing decimal + // point. Py_DTSF_ADD_DOT_0 ensures we won't go past the start of str. + while (*c == '0') { + --c; + } + if (*c == '.') { + --c; + } + try { + buffer.append(str, c + 1); + } catch (std::bad_alloc& e) { PyMem_Free(str); + throw e; } + PyMem_Free(str); } diff --git a/src/ft2font.cpp b/src/ft2font.cpp index da1bd19dca57..ebb7d5204d80 100644 --- a/src/ft2font.cpp +++ b/src/ft2font.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -207,38 +206,43 @@ FT2Font::get_path(std::vector &vertices, std::vector &cod codes.push_back(CLOSEPOLY); } -FT2Font::FT2Font(FT_Open_Args &open_args, - long hinting_factor_, - std::vector &fallback_list, - FT2Font::WarnFunc warn, bool warn_if_used) - : ft_glyph_warn(warn), warn_if_used(warn_if_used), image({1, 1}), face(nullptr), +FT2Font::FT2Font(long hinting_factor_, std::vector &fallback_list, + bool warn_if_used) + : warn_if_used(warn_if_used), image({1, 1}), face(nullptr), fallbacks(fallback_list), hinting_factor(hinting_factor_), // set default kerning factor to 0, i.e., no kerning manipulation kerning_factor(0) { clear(); +} + +FT2Font::~FT2Font() +{ + close(); +} + +void FT2Font::open(FT_Open_Args &open_args) +{ FT_CHECK(FT_Open_Face, _ft2Library, &open_args, 0, &face); if (open_args.stream != nullptr) { face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; } - try { - set_size(12., 72.); // Set a default fontsize 12 pt at 72dpi. - } catch (...) { - FT_Done_Face(face); - throw; - } - // Set fallbacks - std::copy(fallback_list.begin(), fallback_list.end(), std::back_inserter(fallbacks)); } -FT2Font::~FT2Font() +void FT2Font::close() { + // This should be idempotent, in case a user manually calls close before the + // destructor does. Note for example, that PyFT2Font _does_ call this before the + // base destructor to ensure internal pointers are cleared early enough. + for (auto & glyph : glyphs) { FT_Done_Glyph(glyph); } + glyphs.clear(); if (face) { FT_Done_Face(face); + face = nullptr; } } @@ -253,7 +257,6 @@ void FT2Font::clear() } glyphs.clear(); - glyph_to_font.clear(); char_to_font.clear(); for (auto & fallback : fallbacks) { @@ -287,35 +290,13 @@ void FT2Font::select_charmap(unsigned long i) FT_CHECK(FT_Select_Charmap, face, (FT_Encoding)i); } -int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, - bool fallback = false) -{ - if (fallback && glyph_to_font.find(left) != glyph_to_font.end() && - glyph_to_font.find(right) != glyph_to_font.end()) { - FT2Font *left_ft_object = glyph_to_font[left]; - FT2Font *right_ft_object = glyph_to_font[right]; - if (left_ft_object != right_ft_object) { - // we do not know how to do kerning between different fonts - return 0; - } - // if left_ft_object is the same as right_ft_object, - // do the exact same thing which set_text does. - return right_ft_object->get_kerning(left, right, mode, false); - } - else - { - FT_Vector delta; - return get_kerning(left, right, mode, delta); - } -} - -int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, - FT_Vector &delta) +int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode) { if (!FT_HAS_KERNING(face)) { return 0; } + FT_Vector delta; if (!FT_Get_Kerning(face, left, right, mode, &delta)) { return (int)(delta.x) / (hinting_factor << kerning_factor); } else { @@ -364,7 +345,7 @@ void FT2Font::set_text( std::set glyph_seen_fonts; FT2Font *ft_object_with_glyph = this; bool was_found = load_char_with_fallback(ft_object_with_glyph, glyph_index, glyphs, - char_to_font, glyph_to_font, codepoint, flags, + char_to_font, codepoint, flags, charcode_error, glyph_error, glyph_seen_fonts, false); if (!was_found) { ft_glyph_warn((FT_ULong)codepoint, glyph_seen_fonts); @@ -372,8 +353,7 @@ void FT2Font::set_text( // come back to top-most font ft_object_with_glyph = this; char_to_font[codepoint] = ft_object_with_glyph; - glyph_to_font[glyph_index] = ft_object_with_glyph; - ft_object_with_glyph->load_glyph(glyph_index, flags, ft_object_with_glyph, false); + ft_object_with_glyph->load_glyph(glyph_index, flags); } else if (ft_object_with_glyph->warn_if_used) { ft_glyph_warn((FT_ULong)codepoint, glyph_seen_fonts); } @@ -383,8 +363,7 @@ void FT2Font::set_text( ft_object_with_glyph->has_kerning() && // if the font knows how to kern previous && glyph_index // and we really have 2 glyphs ) { - FT_Vector delta; - pen.x += ft_object_with_glyph->get_kerning(previous, glyph_index, FT_KERNING_DEFAULT, delta); + pen.x += ft_object_with_glyph->get_kerning(previous, glyph_index, FT_KERNING_DEFAULT); } // extract glyph image and store it in our table @@ -434,7 +413,7 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool FT_Error charcode_error, glyph_error; FT2Font *ft_object_with_glyph = this; bool was_found = load_char_with_fallback(ft_object_with_glyph, final_glyph_index, - glyphs, char_to_font, glyph_to_font, + glyphs, char_to_font, charcode, flags, charcode_error, glyph_error, glyph_seen_fonts, true); if (!was_found) { @@ -493,7 +472,6 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph, FT_UInt &final_glyph_index, std::vector &parent_glyphs, std::unordered_map &parent_char_to_font, - std::unordered_map &parent_glyph_to_font, long charcode, FT_Int32 flags, FT_Error &charcode_error, @@ -523,7 +501,6 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph, // need to store this for anytime a character is loaded from a parent // FT2Font object or to generate a mapping of individual characters to fonts ft_object_with_glyph = this; - parent_glyph_to_font[final_glyph_index] = this; parent_char_to_font[charcode] = this; parent_glyphs.push_back(thisGlyph); return true; @@ -532,7 +509,7 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph, for (auto & fallback : fallbacks) { bool was_found = fallback->load_char_with_fallback( ft_object_with_glyph, final_glyph_index, parent_glyphs, - parent_char_to_font, parent_glyph_to_font, charcode, flags, + parent_char_to_font, charcode, flags, charcode_error, glyph_error, glyph_seen_fonts, override); if (was_found) { return true; @@ -542,21 +519,6 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph, } } -void FT2Font::load_glyph(FT_UInt glyph_index, - FT_Int32 flags, - FT2Font *&ft_object, - bool fallback = false) -{ - // cache is only for parent FT2Font - if (fallback && glyph_to_font.find(glyph_index) != glyph_to_font.end()) { - ft_object = glyph_to_font[glyph_index]; - } else { - ft_object = this; - } - - ft_object->load_glyph(glyph_index, flags); -} - void FT2Font::load_glyph(FT_UInt glyph_index, FT_Int32 flags) { FT_CHECK(FT_Load_Glyph, face, glyph_index, flags); @@ -581,10 +543,9 @@ FT_UInt FT2Font::get_char_index(FT_ULong charcode, bool fallback = false) return FT_Get_Char_Index(ft_object->get_face(), charcode); } -void FT2Font::get_width_height(long *width, long *height) +std::tuple FT2Font::get_width_height() { - *width = advance; - *height = bbox.yMax - bbox.yMin; + return {advance, bbox.yMax - bbox.yMin}; } long FT2Font::get_descent() @@ -592,10 +553,9 @@ long FT2Font::get_descent() return -bbox.yMin; } -void FT2Font::get_bitmap_offset(long *x, long *y) +std::tuple FT2Font::get_bitmap_offset() { - *x = bbox.xMin; - *y = 0; + return {bbox.xMin, 0}; } void FT2Font::draw_glyphs_to_bitmap(bool antialiased) @@ -644,15 +604,11 @@ void FT2Font::draw_glyph_to_bitmap( draw_bitmap(im, &bitmap->bitmap, x + bitmap->left, y); } -void FT2Font::get_glyph_name(unsigned int glyph_number, std::string &buffer, - bool fallback = false) +std::string FT2Font::get_glyph_name(unsigned int glyph_number) { - if (fallback && glyph_to_font.find(glyph_number) != glyph_to_font.end()) { - // cache is only for parent FT2Font - FT2Font *ft_object = glyph_to_font[glyph_number]; - ft_object->get_glyph_name(glyph_number, buffer, false); - return; - } + std::string buffer; + buffer.resize(128); + if (!FT_HAS_GLYPH_NAMES(face)) { /* Note that this generated name must match the name that is generated by ttconv in ttfont_CharStrings_getname. */ @@ -669,6 +625,8 @@ void FT2Font::get_glyph_name(unsigned int glyph_number, std::string &buffer, buffer.resize(len); } } + + return buffer; } long FT2Font::get_name_index(char *name) diff --git a/src/ft2font.h b/src/ft2font.h index 6676a7dd4818..80bc490f4bad 100644 --- a/src/ft2font.h +++ b/src/ft2font.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -96,44 +97,40 @@ extern FT_Library _ft2Library; class FT2Font { - typedef void (*WarnFunc)(FT_ULong charcode, std::set family_names); - public: - FT2Font(FT_Open_Args &open_args, long hinting_factor, - std::vector &fallback_list, - WarnFunc warn, bool warn_if_used); + FT2Font(long hinting_factor, std::vector &fallback_list, + bool warn_if_used); virtual ~FT2Font(); + void open(FT_Open_Args &open_args); + void close(); void clear(); void set_size(double ptsize, double dpi); void set_charmap(int i); void select_charmap(unsigned long i); void set_text(std::u32string_view codepoints, double angle, FT_Int32 flags, std::vector &xys); - int get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, bool fallback); - int get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode, FT_Vector &delta); + int get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode); void set_kerning_factor(int factor); void load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool fallback); bool load_char_with_fallback(FT2Font *&ft_object_with_glyph, FT_UInt &final_glyph_index, std::vector &parent_glyphs, std::unordered_map &parent_char_to_font, - std::unordered_map &parent_glyph_to_font, long charcode, FT_Int32 flags, FT_Error &charcode_error, FT_Error &glyph_error, std::set &glyph_seen_fonts, bool override); - void load_glyph(FT_UInt glyph_index, FT_Int32 flags, FT2Font *&ft_object, bool fallback); void load_glyph(FT_UInt glyph_index, FT_Int32 flags); - void get_width_height(long *width, long *height); - void get_bitmap_offset(long *x, long *y); + std::tuple get_width_height(); + std::tuple get_bitmap_offset(); long get_descent(); void draw_glyphs_to_bitmap(bool antialiased); void draw_glyph_to_bitmap( py::array_t im, int x, int y, size_t glyphInd, bool antialiased); - void get_glyph_name(unsigned int glyph_number, std::string &buffer, bool fallback); + std::string get_glyph_name(unsigned int glyph_number); long get_name_index(char *name); FT_UInt get_char_index(FT_ULong charcode, bool fallback); void get_path(std::vector &vertices, std::vector &codes); @@ -169,15 +166,15 @@ class FT2Font return FT_HAS_KERNING(face); } + protected: + virtual void ft_glyph_warn(FT_ULong charcode, std::set family_names) = 0; private: - WarnFunc ft_glyph_warn; bool warn_if_used; py::array_t image; FT_Face face; FT_Vector pen; /* untransformed origin */ std::vector glyphs; std::vector fallbacks; - std::unordered_map glyph_to_font; std::unordered_map char_to_font; FT_BBox bbox; FT_Pos advance; diff --git a/src/ft2font_wrapper.cpp b/src/ft2font_wrapper.cpp index ca2db6aa0e5b..99023836b001 100644 --- a/src/ft2font_wrapper.cpp +++ b/src/ft2font_wrapper.cpp @@ -331,16 +331,35 @@ PyGlyph_get_bbox(PyGlyph *self) * FT2Font * */ -struct PyFT2Font +class PyFT2Font final : public FT2Font { - FT2Font *x; + public: + using FT2Font::FT2Font; + py::object py_file; FT_StreamRec stream; py::list fallbacks; ~PyFT2Font() { - delete this->x; + // Because destructors are called from subclass up to base class, we need to + // explicitly close the font here. Otherwise, the instance attributes here will + // be destroyed before the font itself, but those are used in the close callback. + close(); + } + + void ft_glyph_warn(FT_ULong charcode, std::set family_names) + { + std::set::iterator it = family_names.begin(); + std::stringstream ss; + ss<<*it; + while(++it != family_names.end()){ + ss<<", "<<*it; + } + + auto text_helpers = py::module_::import("matplotlib._text_helpers"); + auto warn_on_missing_glyph = text_helpers.attr("warn_on_missing_glyph"); + warn_on_missing_glyph(charcode, ss.str()); } }; @@ -402,21 +421,6 @@ close_file_callback(FT_Stream stream) PyErr_Restore(type, value, traceback); } -static void -ft_glyph_warn(FT_ULong charcode, std::set family_names) -{ - std::set::iterator it = family_names.begin(); - std::stringstream ss; - ss<<*it; - while(++it != family_names.end()){ - ss<<", "<<*it; - } - - auto text_helpers = py::module_::import("matplotlib._text_helpers"); - auto warn_on_missing_glyph = text_helpers.attr("warn_on_missing_glyph"); - warn_on_missing_glyph(charcode, ss.str()); -} - const char *PyFT2Font_init__doc__ = R"""( Parameters ---------- @@ -432,12 +436,6 @@ const char *PyFT2Font_init__doc__ = R"""( .. warning:: This API is both private and provisional: do not use it directly. - _kerning_factor : int, optional - Used to adjust the degree of kerning. - - .. warning:: - This API is private: do not use it directly. - _warn_if_used : bool, optional Used to trigger missing glyph warnings. @@ -448,14 +446,37 @@ const char *PyFT2Font_init__doc__ = R"""( static PyFT2Font * PyFT2Font_init(py::object filename, long hinting_factor = 8, std::optional> fallback_list = std::nullopt, - int kerning_factor = 0, bool warn_if_used = false) + std::optional kerning_factor = std::nullopt, + bool warn_if_used = false) { if (hinting_factor <= 0) { throw py::value_error("hinting_factor must be greater than 0"); } + if (kerning_factor) { + auto api = py::module_::import("matplotlib._api"); + auto warn = api.attr("warn_deprecated"); + warn("since"_a="3.11", "name"_a="_kerning_factor", "obj_type"_a="parameter"); + } else { + kerning_factor = 0; + } + + std::vector fallback_fonts; + if (fallback_list) { + // go through fallbacks to add them to our lists + std::copy(fallback_list->begin(), fallback_list->end(), + std::back_inserter(fallback_fonts)); + } + + auto self = new PyFT2Font(hinting_factor, fallback_fonts, warn_if_used); + self->set_kerning_factor(*kerning_factor); + + if (fallback_list) { + // go through fallbacks to add them to our lists + for (auto item : *fallback_list) { + self->fallbacks.append(item); + } + } - PyFT2Font *self = new PyFT2Font(); - self->x = nullptr; memset(&self->stream, 0, sizeof(FT_StreamRec)); self->stream.base = nullptr; self->stream.size = 0x7fffffff; // Unknown size. @@ -467,18 +488,6 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8, open_args.flags = FT_OPEN_STREAM; open_args.stream = &self->stream; - std::vector fallback_fonts; - if (fallback_list) { - // go through fallbacks to add them to our lists - for (auto item : *fallback_list) { - self->fallbacks.append(item); - // Also (locally) cache the underlying FT2Font objects. As long as - // the Python objects are kept alive, these pointer are good. - FT2Font *fback = item->x; - fallback_fonts.push_back(fback); - } - } - if (py::isinstance(filename) || py::isinstance(filename)) { self->py_file = py::module_::import("io").attr("open")(filename, "rb"); self->stream.close = &close_file_callback; @@ -497,10 +506,7 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8, self->stream.close = nullptr; } - self->x = new FT2Font(open_args, hinting_factor, fallback_fonts, ft_glyph_warn, - warn_if_used); - - self->x->set_kerning_factor(kerning_factor); + self->open(open_args); return self; } @@ -518,12 +524,6 @@ PyFT2Font_fname(PyFT2Font *self) const char *PyFT2Font_clear__doc__ = "Clear all the glyphs, reset for a new call to `.set_text`."; -static void -PyFT2Font_clear(PyFT2Font *self) -{ - self->x->clear(); -} - const char *PyFT2Font_set_size__doc__ = R"""( Set the size of the text. @@ -535,12 +535,6 @@ const char *PyFT2Font_set_size__doc__ = R"""( The DPI used for rendering the text. )"""; -static void -PyFT2Font_set_size(PyFT2Font *self, double ptsize, double dpi) -{ - self->x->set_size(ptsize, dpi); -} - const char *PyFT2Font_set_charmap__doc__ = R"""( Make the i-th charmap current. @@ -559,12 +553,6 @@ const char *PyFT2Font_set_charmap__doc__ = R"""( .get_charmap )"""; -static void -PyFT2Font_set_charmap(PyFT2Font *self, int i) -{ - self->x->set_charmap(i); -} - const char *PyFT2Font_select_charmap__doc__ = R"""( Select a charmap by its FT_Encoding number. @@ -583,12 +571,6 @@ const char *PyFT2Font_select_charmap__doc__ = R"""( .get_charmap )"""; -static void -PyFT2Font_select_charmap(PyFT2Font *self, unsigned long i) -{ - self->x->select_charmap(i); -} - const char *PyFT2Font_get_kerning__doc__ = R"""( Get the kerning between two glyphs. @@ -618,7 +600,6 @@ static int PyFT2Font_get_kerning(PyFT2Font *self, FT_UInt left, FT_UInt right, std::variant mode_or_int) { - bool fallback = true; FT_Kerning_Mode mode; if (auto value = std::get_if(&mode_or_int)) { @@ -636,7 +617,7 @@ PyFT2Font_get_kerning(PyFT2Font *self, FT_UInt left, FT_UInt right, throw py::type_error("mode must be Kerning or int"); } - return self->x->get_kerning(left, right, mode, fallback); + return self->get_kerning(left, right, mode); } const char *PyFT2Font_get_fontmap__doc__ = R"""( @@ -670,7 +651,7 @@ PyFT2Font_get_fontmap(PyFT2Font *self, std::u32string text) py::object target_font; int index; - if (self->x->get_char_fallback_index(code, index)) { + if (self->get_char_fallback_index(code, index)) { if (index >= 0) { target_font = self->fallbacks[index]; } else { @@ -732,7 +713,7 @@ PyFT2Font_set_text(PyFT2Font *self, std::u32string_view text, double angle = 0.0 throw py::type_error("flags must be LoadFlags or int"); } - self->x->set_text(text, angle, static_cast(flags), xys); + self->set_text(text, angle, static_cast(flags), xys); py::ssize_t dims[] = { static_cast(xys.size()) / 2, 2 }; py::array_t result(dims); @@ -744,12 +725,6 @@ PyFT2Font_set_text(PyFT2Font *self, std::u32string_view text, double angle = 0.0 const char *PyFT2Font_get_num_glyphs__doc__ = "Return the number of loaded glyphs."; -static size_t -PyFT2Font_get_num_glyphs(PyFT2Font *self) -{ - return self->x->get_num_glyphs(); -} - const char *PyFT2Font_load_char__doc__ = R"""( Load character in current fontfile and set glyph. @@ -799,7 +774,7 @@ PyFT2Font_load_char(PyFT2Font *self, long charcode, throw py::type_error("flags must be LoadFlags or int"); } - self->x->load_char(charcode, static_cast(flags), ft_object, fallback); + self->load_char(charcode, static_cast(flags), ft_object, fallback); return PyGlyph_from_FT2Font(ft_object); } @@ -834,8 +809,6 @@ static PyGlyph * PyFT2Font_load_glyph(PyFT2Font *self, FT_UInt glyph_index, std::variant flags_or_int = LoadFlags::FORCE_AUTOHINT) { - bool fallback = true; - FT2Font *ft_object = nullptr; LoadFlags flags; if (auto value = std::get_if(&flags_or_int)) { @@ -853,9 +826,9 @@ PyFT2Font_load_glyph(PyFT2Font *self, FT_UInt glyph_index, throw py::type_error("flags must be LoadFlags or int"); } - self->x->load_glyph(glyph_index, static_cast(flags), ft_object, fallback); + self->load_glyph(glyph_index, static_cast(flags)); - return PyGlyph_from_FT2Font(ft_object); + return PyGlyph_from_FT2Font(self); } const char *PyFT2Font_get_width_height__doc__ = R"""( @@ -875,16 +848,6 @@ const char *PyFT2Font_get_width_height__doc__ = R"""( .get_descent )"""; -static py::tuple -PyFT2Font_get_width_height(PyFT2Font *self) -{ - long width, height; - - self->x->get_width_height(&width, &height); - - return py::make_tuple(width, height); -} - const char *PyFT2Font_get_bitmap_offset__doc__ = R"""( Get the (x, y) offset for the bitmap if ink hangs left or below (0, 0). @@ -902,16 +865,6 @@ const char *PyFT2Font_get_bitmap_offset__doc__ = R"""( .get_descent )"""; -static py::tuple -PyFT2Font_get_bitmap_offset(PyFT2Font *self) -{ - long x, y; - - self->x->get_bitmap_offset(&x, &y); - - return py::make_tuple(x, y); -} - const char *PyFT2Font_get_descent__doc__ = R"""( Get the descent of the current string set by `.set_text`. @@ -929,12 +882,6 @@ const char *PyFT2Font_get_descent__doc__ = R"""( .get_width_height )"""; -static long -PyFT2Font_get_descent(PyFT2Font *self) -{ - return self->x->get_descent(); -} - const char *PyFT2Font_draw_glyphs_to_bitmap__doc__ = R"""( Draw the glyphs that were loaded by `.set_text` to the bitmap. @@ -950,12 +897,6 @@ const char *PyFT2Font_draw_glyphs_to_bitmap__doc__ = R"""( .draw_glyph_to_bitmap )"""; -static void -PyFT2Font_draw_glyphs_to_bitmap(PyFT2Font *self, bool antialiased = true) -{ - self->x->draw_glyphs_to_bitmap(antialiased); -} - const char *PyFT2Font_draw_glyph_to_bitmap__doc__ = R"""( Draw a single glyph to the bitmap at pixel locations x, y. @@ -990,7 +931,7 @@ PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, py::buffer &image, auto xd = _double_to_("x", vxd); auto yd = _double_to_("y", vyd); - self->x->draw_glyph_to_bitmap( + self->draw_glyph_to_bitmap( py::array_t{image}, xd, yd, glyph->glyphInd, antialiased); } @@ -1018,17 +959,6 @@ const char *PyFT2Font_get_glyph_name__doc__ = R"""( .get_name_index )"""; -static py::str -PyFT2Font_get_glyph_name(PyFT2Font *self, unsigned int glyph_number) -{ - std::string buffer; - bool fallback = true; - - buffer.resize(128); - self->x->get_glyph_name(glyph_number, buffer, fallback); - return buffer; -} - const char *PyFT2Font_get_charmap__doc__ = R"""( Return a mapping of character codes to glyph indices in the font. @@ -1047,10 +977,10 @@ PyFT2Font_get_charmap(PyFT2Font *self) { py::dict charmap; FT_UInt index; - FT_ULong code = FT_Get_First_Char(self->x->get_face(), &index); + FT_ULong code = FT_Get_First_Char(self->get_face(), &index); while (index != 0) { charmap[py::cast(code)] = py::cast(index); - code = FT_Get_Next_Char(self->x->get_face(), code, &index); + code = FT_Get_Next_Char(self->get_face(), code, &index); } return charmap; } @@ -1062,6 +992,8 @@ const char *PyFT2Font_get_char_index__doc__ = R"""( ---------- codepoint : int A character code point in the current charmap (which defaults to Unicode.) + _fallback : bool + Whether to enable fallback fonts while searching for a character. Returns ------- @@ -1076,14 +1008,6 @@ const char *PyFT2Font_get_char_index__doc__ = R"""( .get_name_index )"""; -static FT_UInt -PyFT2Font_get_char_index(PyFT2Font *self, FT_ULong ccode) -{ - bool fallback = true; - - return self->x->get_char_index(ccode, fallback); -} - const char *PyFT2Font_get_sfnt__doc__ = R"""( Load the entire SFNT names table. @@ -1100,17 +1024,17 @@ const char *PyFT2Font_get_sfnt__doc__ = R"""( static py::dict PyFT2Font_get_sfnt(PyFT2Font *self) { - if (!(self->x->get_face()->face_flags & FT_FACE_FLAG_SFNT)) { + if (!(self->get_face()->face_flags & FT_FACE_FLAG_SFNT)) { throw py::value_error("No SFNT name table"); } - size_t count = FT_Get_Sfnt_Name_Count(self->x->get_face()); + size_t count = FT_Get_Sfnt_Name_Count(self->get_face()); py::dict names; for (FT_UInt j = 0; j < count; ++j) { FT_SfntName sfnt; - FT_Error error = FT_Get_Sfnt_Name(self->x->get_face(), j, &sfnt); + FT_Error error = FT_Get_Sfnt_Name(self->get_face(), j, &sfnt); if (error) { throw py::value_error("Could not get SFNT name"); @@ -1145,12 +1069,6 @@ const char *PyFT2Font_get_name_index__doc__ = R"""( .get_glyph_name )"""; -static long -PyFT2Font_get_name_index(PyFT2Font *self, char *glyphname) -{ - return self->x->get_name_index(glyphname); -} - const char *PyFT2Font_get_ps_font_info__doc__ = R"""( Return the information in the PS Font Info structure. @@ -1175,7 +1093,7 @@ PyFT2Font_get_ps_font_info(PyFT2Font *self) { PS_FontInfoRec fontinfo; - FT_Error error = FT_Get_PS_Font_Info(self->x->get_face(), &fontinfo); + FT_Error error = FT_Get_PS_Font_Info(self->get_face(), &fontinfo); if (error) { throw py::value_error("Could not get PS font info"); } @@ -1227,7 +1145,7 @@ PyFT2Font_get_sfnt_table(PyFT2Font *self, std::string tagname) return std::nullopt; } - void *table = FT_Get_Sfnt_Table(self->x->get_face(), tag); + void *table = FT_Get_Sfnt_Table(self->get_face(), tag); if (!table) { return std::nullopt; } @@ -1410,7 +1328,7 @@ PyFT2Font_get_path(PyFT2Font *self) std::vector vertices; std::vector codes; - self->x->get_path(vertices, codes); + self->get_path(vertices, codes); py::ssize_t length = codes.size(); py::ssize_t vertices_dims[2] = { length, 2 }; @@ -1439,12 +1357,6 @@ const char *PyFT2Font_get_image__doc__ = R"""( .get_path )"""; -static py::array -PyFT2Font_get_image(PyFT2Font *self) -{ - return self->x->get_image(); -} - const char *PyFT2Font__get_type1_encoding_vector__doc__ = R"""( Return a list mapping CharString indices of a Type 1 font to FreeType glyph indices. @@ -1456,7 +1368,7 @@ const char *PyFT2Font__get_type1_encoding_vector__doc__ = R"""( static std::array PyFT2Font__get_type1_encoding_vector(PyFT2Font *self) { - auto face = self->x->get_face(); + auto face = self->get_face(); auto indices = std::array{}; for (auto i = 0u; i < indices.size(); ++i) { auto len = FT_Get_PS_Font_Value(face, PS_DICT_ENCODING_ENTRY, i, nullptr, 0); @@ -1609,15 +1521,15 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used()) PyFT2Font__doc__) .def(py::init(&PyFT2Font_init), "filename"_a, "hinting_factor"_a=8, py::kw_only(), - "_fallback_list"_a=py::none(), "_kerning_factor"_a=0, + "_fallback_list"_a=py::none(), "_kerning_factor"_a=py::none(), "_warn_if_used"_a=false, PyFT2Font_init__doc__) - .def("clear", &PyFT2Font_clear, PyFT2Font_clear__doc__) - .def("set_size", &PyFT2Font_set_size, "ptsize"_a, "dpi"_a, + .def("clear", &PyFT2Font::clear, PyFT2Font_clear__doc__) + .def("set_size", &PyFT2Font::set_size, "ptsize"_a, "dpi"_a, PyFT2Font_set_size__doc__) - .def("set_charmap", &PyFT2Font_set_charmap, "i"_a, + .def("set_charmap", &PyFT2Font::set_charmap, "i"_a, PyFT2Font_set_charmap__doc__) - .def("select_charmap", &PyFT2Font_select_charmap, "i"_a, + .def("select_charmap", &PyFT2Font::select_charmap, "i"_a, PyFT2Font_select_charmap__doc__) .def("get_kerning", &PyFT2Font_get_kerning, "left"_a, "right"_a, "mode"_a, PyFT2Font_get_kerning__doc__) @@ -1626,19 +1538,20 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used()) PyFT2Font_set_text__doc__) .def("_get_fontmap", &PyFT2Font_get_fontmap, "string"_a, PyFT2Font_get_fontmap__doc__) - .def("get_num_glyphs", &PyFT2Font_get_num_glyphs, PyFT2Font_get_num_glyphs__doc__) + .def("get_num_glyphs", &PyFT2Font::get_num_glyphs, + PyFT2Font_get_num_glyphs__doc__) .def("load_char", &PyFT2Font_load_char, "charcode"_a, "flags"_a=LoadFlags::FORCE_AUTOHINT, PyFT2Font_load_char__doc__) .def("load_glyph", &PyFT2Font_load_glyph, "glyph_index"_a, "flags"_a=LoadFlags::FORCE_AUTOHINT, PyFT2Font_load_glyph__doc__) - .def("get_width_height", &PyFT2Font_get_width_height, + .def("get_width_height", &PyFT2Font::get_width_height, PyFT2Font_get_width_height__doc__) - .def("get_bitmap_offset", &PyFT2Font_get_bitmap_offset, + .def("get_bitmap_offset", &PyFT2Font::get_bitmap_offset, PyFT2Font_get_bitmap_offset__doc__) - .def("get_descent", &PyFT2Font_get_descent, PyFT2Font_get_descent__doc__) - .def("draw_glyphs_to_bitmap", &PyFT2Font_draw_glyphs_to_bitmap, + .def("get_descent", &PyFT2Font::get_descent, PyFT2Font_get_descent__doc__) + .def("draw_glyphs_to_bitmap", &PyFT2Font::draw_glyphs_to_bitmap, py::kw_only(), "antialiased"_a=true, PyFT2Font_draw_glyphs_to_bitmap__doc__); // The generated docstring uses an unqualified "Buffer" as type hint, @@ -1654,26 +1567,27 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used()) PyFT2Font_draw_glyph_to_bitmap__doc__); } cls - .def("get_glyph_name", &PyFT2Font_get_glyph_name, "index"_a, + .def("get_glyph_name", &PyFT2Font::get_glyph_name, "index"_a, PyFT2Font_get_glyph_name__doc__) .def("get_charmap", &PyFT2Font_get_charmap, PyFT2Font_get_charmap__doc__) - .def("get_char_index", &PyFT2Font_get_char_index, "codepoint"_a, + .def("get_char_index", &PyFT2Font::get_char_index, + "codepoint"_a, py::kw_only(), "_fallback"_a=true, PyFT2Font_get_char_index__doc__) .def("get_sfnt", &PyFT2Font_get_sfnt, PyFT2Font_get_sfnt__doc__) - .def("get_name_index", &PyFT2Font_get_name_index, "name"_a, + .def("get_name_index", &PyFT2Font::get_name_index, "name"_a, PyFT2Font_get_name_index__doc__) .def("get_ps_font_info", &PyFT2Font_get_ps_font_info, PyFT2Font_get_ps_font_info__doc__) .def("get_sfnt_table", &PyFT2Font_get_sfnt_table, "name"_a, PyFT2Font_get_sfnt_table__doc__) .def("get_path", &PyFT2Font_get_path, PyFT2Font_get_path__doc__) - .def("get_image", &PyFT2Font_get_image, PyFT2Font_get_image__doc__) + .def("get_image", &PyFT2Font::get_image, PyFT2Font_get_image__doc__) .def("_get_type1_encoding_vector", &PyFT2Font__get_type1_encoding_vector, PyFT2Font__get_type1_encoding_vector__doc__) .def_property_readonly( "postscript_name", [](PyFT2Font *self) { - if (const char *name = FT_Get_Postscript_Name(self->x->get_face())) { + if (const char *name = FT_Get_Postscript_Name(self->get_face())) { return name; } else { return "UNAVAILABLE"; @@ -1681,11 +1595,11 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used()) }, "PostScript name of the font.") .def_property_readonly( "num_faces", [](PyFT2Font *self) { - return self->x->get_face()->num_faces; + return self->get_face()->num_faces; }, "Number of faces in file.") .def_property_readonly( "family_name", [](PyFT2Font *self) { - if (const char *name = self->x->get_face()->family_name) { + if (const char *name = self->get_face()->family_name) { return name; } else { return "UNAVAILABLE"; @@ -1693,7 +1607,7 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used()) }, "Face family name.") .def_property_readonly( "style_name", [](PyFT2Font *self) { - if (const char *name = self->x->get_face()->style_name) { + if (const char *name = self->get_face()->style_name) { return name; } else { return "UNAVAILABLE"; @@ -1701,80 +1615,83 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used()) }, "Style name.") .def_property_readonly( "face_flags", [](PyFT2Font *self) { - return static_cast(self->x->get_face()->face_flags); + return static_cast(self->get_face()->face_flags); }, "Face flags; see `.FaceFlags`.") .def_property_readonly( "style_flags", [](PyFT2Font *self) { - return static_cast(self->x->get_face()->style_flags & 0xffff); + return static_cast(self->get_face()->style_flags & 0xffff); }, "Style flags; see `.StyleFlags`.") .def_property_readonly( "num_named_instances", [](PyFT2Font *self) { - return (self->x->get_face()->style_flags & 0x7fff0000) >> 16; + return (self->get_face()->style_flags & 0x7fff0000) >> 16; }, "Number of named instances in the face.") .def_property_readonly( "num_glyphs", [](PyFT2Font *self) { - return self->x->get_face()->num_glyphs; + return self->get_face()->num_glyphs; }, "Number of glyphs in the face.") .def_property_readonly( "num_fixed_sizes", [](PyFT2Font *self) { - return self->x->get_face()->num_fixed_sizes; + return self->get_face()->num_fixed_sizes; }, "Number of bitmap in the face.") .def_property_readonly( "num_charmaps", [](PyFT2Font *self) { - return self->x->get_face()->num_charmaps; + return self->get_face()->num_charmaps; }, "Number of charmaps in the face.") .def_property_readonly( "scalable", [](PyFT2Font *self) { - return bool(FT_IS_SCALABLE(self->x->get_face())); + return bool(FT_IS_SCALABLE(self->get_face())); }, "Whether face is scalable; attributes after this one " "are only defined for scalable faces.") .def_property_readonly( "units_per_EM", [](PyFT2Font *self) { - return self->x->get_face()->units_per_EM; + return self->get_face()->units_per_EM; }, "Number of font units covered by the EM.") .def_property_readonly( "bbox", [](PyFT2Font *self) { - FT_BBox bbox = self->x->get_face()->bbox; + FT_BBox bbox = self->get_face()->bbox; return py::make_tuple(bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax); }, "Face global bounding box (xmin, ymin, xmax, ymax).") .def_property_readonly( "ascender", [](PyFT2Font *self) { - return self->x->get_face()->ascender; + return self->get_face()->ascender; }, "Ascender in 26.6 units.") .def_property_readonly( "descender", [](PyFT2Font *self) { - return self->x->get_face()->descender; + return self->get_face()->descender; }, "Descender in 26.6 units.") .def_property_readonly( "height", [](PyFT2Font *self) { - return self->x->get_face()->height; + return self->get_face()->height; }, "Height in 26.6 units; used to compute a default line spacing " "(baseline-to-baseline distance).") .def_property_readonly( "max_advance_width", [](PyFT2Font *self) { - return self->x->get_face()->max_advance_width; + return self->get_face()->max_advance_width; }, "Maximum horizontal cursor advance for all glyphs.") .def_property_readonly( "max_advance_height", [](PyFT2Font *self) { - return self->x->get_face()->max_advance_height; + return self->get_face()->max_advance_height; }, "Maximum vertical cursor advance for all glyphs.") .def_property_readonly( "underline_position", [](PyFT2Font *self) { - return self->x->get_face()->underline_position; + return self->get_face()->underline_position; }, "Vertical position of the underline bar.") .def_property_readonly( "underline_thickness", [](PyFT2Font *self) { - return self->x->get_face()->underline_thickness; + return self->get_face()->underline_thickness; }, "Thickness of the underline bar.") .def_property_readonly( "fname", &PyFT2Font_fname, "The original filename for this object.") .def_buffer([](PyFT2Font &self) -> py::buffer_info { - return self.x->get_image().request(); + return self.get_image().request(); }); m.attr("__freetype_version__") = version_string; m.attr("__freetype_build_type__") = FREETYPE_BUILD_TYPE; + auto py_int = py::module_::import("builtins").attr("int"); + m.attr("CharacterCodeType") = py_int; + m.attr("GlyphIndexType") = py_int; m.def("__getattr__", ft2font__getattr__); } diff --git a/subprojects/freetype-2.13.3.wrap b/subprojects/freetype-2.13.3.wrap new file mode 100644 index 000000000000..68f688a35861 --- /dev/null +++ b/subprojects/freetype-2.13.3.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = freetype-2.13.3 +source_url = https://download.savannah.gnu.org/releases/freetype/freetype-2.13.3.tar.xz +source_fallback_url = https://downloads.sourceforge.net/project/freetype/freetype2/2.13.3/freetype-2.13.3.tar.xz +source_filename = freetype-2.13.3.tar.xz +source_hash = 0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 + +# https://gitlab.freedesktop.org/freetype/freetype/-/commit/34aed655f1696da774b5cdd4c5effb312153232f +diff_files = freetype-34aed655f1696da774b5cdd4c5effb312153232f.patch + +[provide] +freetype2 = freetype_dep +freetype = freetype_dep diff --git a/subprojects/freetype-2.6.1.wrap b/subprojects/freetype-2.6.1.wrap deleted file mode 100644 index 763362b84df0..000000000000 --- a/subprojects/freetype-2.6.1.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -source_url = https://download.savannah.gnu.org/releases/freetype/freetype-old/freetype-2.6.1.tar.gz -source_fallback_url = https://downloads.sourceforge.net/project/freetype/freetype2/2.6.1/freetype-2.6.1.tar.gz -source_filename = freetype-2.6.1.tar.gz -source_hash = 0a3c7dfbda6da1e8fce29232e8e96d987ababbbf71ebc8c75659e4132c367014 - -patch_directory = freetype-2.6.1-meson - -[provide] -freetype-2.6.1 = freetype_dep diff --git a/subprojects/packagefiles/freetype-2.6.1-meson/LICENSE.build b/subprojects/packagefiles/freetype-2.6.1-meson/LICENSE.build deleted file mode 100644 index ec288041f388..000000000000 --- a/subprojects/packagefiles/freetype-2.6.1-meson/LICENSE.build +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2018 The Meson development team - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/subprojects/packagefiles/freetype-2.6.1-meson/builds/unix/ftconfig.h.in b/subprojects/packagefiles/freetype-2.6.1-meson/builds/unix/ftconfig.h.in deleted file mode 100644 index 400f3a2a5bf2..000000000000 --- a/subprojects/packagefiles/freetype-2.6.1-meson/builds/unix/ftconfig.h.in +++ /dev/null @@ -1,498 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftconfig.in */ -/* */ -/* UNIX-specific configuration file (specification only). */ -/* */ -/* Copyright 1996-2015 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This header file contains a number of macro definitions that are used */ - /* by the rest of the engine. Most of the macros here are automatically */ - /* determined at compile time, and you should not need to change it to */ - /* port FreeType, except to compile the library with a non-ANSI */ - /* compiler. */ - /* */ - /* Note however that if some specific modifications are needed, we */ - /* advise you to place a modified copy in your build directory. */ - /* */ - /* The build directory is usually `builds/', and contains */ - /* system-specific files that are always included first when building */ - /* the library. */ - /* */ - /*************************************************************************/ - -/* MESON: based on unix/ftconfig.in with but meson-friendly configuration defines */ - -#ifndef FTCONFIG_H_ -#define FTCONFIG_H_ - -#include -#include FT_CONFIG_OPTIONS_H -#include FT_CONFIG_STANDARD_LIBRARY_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled to suit a specific system. The current */ - /* ones are defaults used to compile FreeType in an ANSI C environment */ - /* (16bit compilers are also supported). Copy this file to your own */ - /* `builds/' directory, and edit it to port the engine. */ - /* */ - /*************************************************************************/ - - -#define HAVE_UNISTD_H @HAVE_UNISTD_H@ -#define HAVE_FCNTL_H @HAVE_FCNTL_H@ -#define HAVE_STDINT_H @HAVE_STDINT_H@ - - - /* There are systems (like the Texas Instruments 'C54x) where a `char' */ - /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ - /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ - /* is probably unexpected. */ - /* */ - /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ - /* `char' type. */ - -#ifndef FT_CHAR_BIT -#define FT_CHAR_BIT CHAR_BIT -#endif - - -#undef FT_USE_AUTOCONF_SIZEOF_TYPES -#ifdef FT_USE_AUTOCONF_SIZEOF_TYPES - -#undef SIZEOF_INT -#undef SIZEOF_LONG -#define FT_SIZEOF_INT SIZEOF_INT -#define FT_SIZEOF_LONG SIZEOF_LONG - -#else /* !FT_USE_AUTOCONF_SIZEOF_TYPES */ - - /* Following cpp computation of the bit length of int and long */ - /* is copied from default include/freetype/config/ftconfig.h. */ - /* If any improvement is required for this file, it should be */ - /* applied to the original header file for the builders that */ - /* do not use configure script. */ - - /* The size of an `int' type. */ -#if FT_UINT_MAX == 0xFFFFUL -#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) -#elif FT_UINT_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) -#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL -#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) -#else -#error "Unsupported size of `int' type!" -#endif - - /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ - /* DM642) is recognized but avoided. */ -#if FT_ULONG_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) -#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL -#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) -#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL -#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) -#else -#error "Unsupported size of `long' type!" -#endif - -#endif /* !FT_USE_AUTOCONF_SIZEOF_TYPES */ - - - /* FT_UNUSED is a macro used to indicate that a given parameter is not */ - /* used -- this is only used to get rid of unpleasant compiler warnings */ -#ifndef FT_UNUSED -#define FT_UNUSED( arg ) ( (arg) = (arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* AUTOMATIC CONFIGURATION MACROS */ - /* */ - /* These macros are computed from the ones defined above. Don't touch */ - /* their definition, unless you know precisely what you are doing. No */ - /* porter should need to mess with them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Mac support */ - /* */ - /* This is the only necessary change, so it is defined here instead */ - /* providing a new configuration file. */ - /* */ -#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) - /* no Carbon frameworks for 64bit 10.4.x */ - /* AvailabilityMacros.h is available since Mac OS X 10.2, */ - /* so guess the system version by maximum errno before inclusion */ -#include -#ifdef ECANCELED /* defined since 10.2 */ -#include "AvailabilityMacros.h" -#endif -#if defined( __LP64__ ) && \ - ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) -/undef FT_MACINTOSH -#endif - -#elif defined( __SC__ ) || defined( __MRC__ ) - /* Classic MacOS compilers */ -#include "ConditionalMacros.h" -#if TARGET_OS_MAC -#define FT_MACINTOSH 1 -#endif - -#endif - - - /* Fix compiler warning with sgi compiler */ -#if defined( __sgi ) && !defined( __GNUC__ ) -#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) -#pragma set woff 3505 -#endif -#endif - - - /*************************************************************************/ - /* */ - /*
*/ - /* basic_types */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int16 */ - /* */ - /* */ - /* A typedef for a 16bit signed integer type. */ - /* */ - typedef signed short FT_Int16; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt16 */ - /* */ - /* */ - /* A typedef for a 16bit unsigned integer type. */ - /* */ - typedef unsigned short FT_UInt16; - - /* */ - - - /* this #if 0 ... #endif clause is for documentation purposes */ -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int32 */ - /* */ - /* */ - /* A typedef for a 32bit signed integer type. The size depends on */ - /* the configuration. */ - /* */ - typedef signed XXX FT_Int32; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt32 */ - /* */ - /* A typedef for a 32bit unsigned integer type. The size depends on */ - /* the configuration. */ - /* */ - typedef unsigned XXX FT_UInt32; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int64 */ - /* */ - /* A typedef for a 64bit signed integer type. The size depends on */ - /* the configuration. Only defined if there is real 64bit support; */ - /* otherwise, it gets emulated with a structure (if necessary). */ - /* */ - typedef signed XXX FT_Int64; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt64 */ - /* */ - /* A typedef for a 64bit unsigned integer type. The size depends on */ - /* the configuration. Only defined if there is real 64bit support; */ - /* otherwise, it gets emulated with a structure (if necessary). */ - /* */ - typedef unsigned XXX FT_UInt64; - - /* */ - -#endif - -#if FT_SIZEOF_INT == 4 - - typedef signed int FT_Int32; - typedef unsigned int FT_UInt32; - -#elif FT_SIZEOF_LONG == 4 - - typedef signed long FT_Int32; - typedef unsigned long FT_UInt32; - -#else -#error "no 32bit type found -- please check your configuration files" -#endif - - - /* look up an integer type that is at least 32 bits */ -#if FT_SIZEOF_INT >= 4 - - typedef int FT_Fast; - typedef unsigned int FT_UFast; - -#elif FT_SIZEOF_LONG >= 4 - - typedef long FT_Fast; - typedef unsigned long FT_UFast; - -#endif - - - /* determine whether we have a 64-bit int type for platforms without */ - /* Autoconf */ -#if FT_SIZEOF_LONG == 8 - - /* FT_LONG64 must be defined if a 64-bit type is available */ -#define FT_LONG64 -#define FT_INT64 long -#define FT_UINT64 unsigned long - - /*************************************************************************/ - /* */ - /* A 64-bit data type may create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ - /* types if __STDC__ is defined. You can however ignore this rule */ - /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ - /* */ -#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) - -#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ - - /* this compiler provides the __int64 type */ -#define FT_LONG64 -#define FT_INT64 __int64 -#define FT_UINT64 unsigned __int64 - -#elif defined( __BORLANDC__ ) /* Borland C++ */ - - /* XXXX: We should probably check the value of __BORLANDC__ in order */ - /* to test the compiler version. */ - - /* this compiler provides the __int64 type */ -#define FT_LONG64 -#define FT_INT64 __int64 -#define FT_UINT64 unsigned __int64 - -#elif defined( __WATCOMC__ ) /* Watcom C++ */ - - /* Watcom doesn't provide 64-bit data types */ - -#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ - -#define FT_LONG64 -#define FT_INT64 long long int -#define FT_UINT64 unsigned long long int - -#elif defined( __GNUC__ ) - - /* GCC provides the `long long' type */ -#define FT_LONG64 -#define FT_INT64 long long int -#define FT_UINT64 unsigned long long int - -#endif /* _MSC_VER */ - -#endif /* FT_SIZEOF_LONG == 8 */ - -#ifdef FT_LONG64 - typedef FT_INT64 FT_Int64; - typedef FT_UINT64 FT_UInt64; -#endif - - - /*************************************************************************/ - /* */ - /* miscellaneous */ - /* */ - /*************************************************************************/ - - -#define FT_BEGIN_STMNT do { -#define FT_END_STMNT } while ( 0 ) -#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT - - - /* typeof condition taken from gnulib's `intprops.h' header file */ -#if ( __GNUC__ >= 2 || \ - defined( __IBM__TYPEOF__ ) || \ - ( __SUNPRO_C >= 0x5110 && !__STDC__ ) ) -#define FT_TYPEOF( type ) (__typeof__ (type)) -#else -#define FT_TYPEOF( type ) /* empty */ -#endif - - -#ifdef FT_MAKE_OPTION_SINGLE_OBJECT - -#define FT_LOCAL( x ) static x -#define FT_LOCAL_DEF( x ) static x - -#else - -#ifdef __cplusplus -#define FT_LOCAL( x ) extern "C" x -#define FT_LOCAL_DEF( x ) extern "C" x -#else -#define FT_LOCAL( x ) extern x -#define FT_LOCAL_DEF( x ) x -#endif - -#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ - -#define FT_LOCAL_ARRAY( x ) extern const x -#define FT_LOCAL_ARRAY_DEF( x ) const x - - -#ifndef FT_BASE - -#ifdef __cplusplus -#define FT_BASE( x ) extern "C" x -#else -#define FT_BASE( x ) extern x -#endif - -#endif /* !FT_BASE */ - - -#ifndef FT_BASE_DEF - -#ifdef __cplusplus -#define FT_BASE_DEF( x ) x -#else -#define FT_BASE_DEF( x ) x -#endif - -#endif /* !FT_BASE_DEF */ - - -#ifndef FT_EXPORT - -#ifdef __cplusplus -#define FT_EXPORT( x ) extern "C" x -#else -#define FT_EXPORT( x ) extern x -#endif - -#endif /* !FT_EXPORT */ - - -#ifndef FT_EXPORT_DEF - -#ifdef __cplusplus -#define FT_EXPORT_DEF( x ) extern "C" x -#else -#define FT_EXPORT_DEF( x ) extern x -#endif - -#endif /* !FT_EXPORT_DEF */ - - -#ifndef FT_EXPORT_VAR - -#ifdef __cplusplus -#define FT_EXPORT_VAR( x ) extern "C" x -#else -#define FT_EXPORT_VAR( x ) extern x -#endif - -#endif /* !FT_EXPORT_VAR */ - - /* The following macros are needed to compile the library with a */ - /* C++ compiler and with 16bit compilers. */ - /* */ - - /* This is special. Within C++, you must specify `extern "C"' for */ - /* functions which are used via function pointers, and you also */ - /* must do that for structures which contain function pointers to */ - /* assure C linkage -- it's not possible to have (local) anonymous */ - /* functions which are accessed by (global) function pointers. */ - /* */ - /* */ - /* FT_CALLBACK_DEF is used to _define_ a callback function. */ - /* */ - /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ - /* contains pointers to callback functions. */ - /* */ - /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ - /* that contains pointers to callback functions. */ - /* */ - /* */ - /* Some 16bit compilers have to redefine these macros to insert */ - /* the infamous `_cdecl' or `__fastcall' declarations. */ - /* */ -#ifndef FT_CALLBACK_DEF -#ifdef __cplusplus -#define FT_CALLBACK_DEF( x ) extern "C" x -#else -#define FT_CALLBACK_DEF( x ) static x -#endif -#endif /* FT_CALLBACK_DEF */ - -#ifndef FT_CALLBACK_TABLE -#ifdef __cplusplus -#define FT_CALLBACK_TABLE extern "C" -#define FT_CALLBACK_TABLE_DEF extern "C" -#else -#define FT_CALLBACK_TABLE extern -#define FT_CALLBACK_TABLE_DEF /* nothing */ -#endif -#endif /* FT_CALLBACK_TABLE */ - - -FT_END_HEADER - - -#endif /* FTCONFIG_H_ */ - - -/* END */ diff --git a/subprojects/packagefiles/freetype-2.6.1-meson/include/freetype/config/ftoption.h.in b/subprojects/packagefiles/freetype-2.6.1-meson/include/freetype/config/ftoption.h.in deleted file mode 100644 index 5df84c706800..000000000000 --- a/subprojects/packagefiles/freetype-2.6.1-meson/include/freetype/config/ftoption.h.in +++ /dev/null @@ -1,886 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2015 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef FTOPTION_H_ -#define FTOPTION_H_ - - -#include - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H */ - /* #include */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is . */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Uncomment the line below if you want to activate sub-pixel rendering */ - /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ - /* */ - /* Note that this feature is covered by several Microsoft patents */ - /* and should not be activated in any default build of the library. */ - /* */ - /* This macro has no impact on the FreeType API, only on its */ - /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ - /* the original size in case this macro isn't defined; however, each */ - /* triplet of subpixels has R=G=B. */ - /* */ - /* This is done to allow FreeType clients to run unmodified, forcing */ - /* them to display normal gray-level anti-aliased glyphs. */ - /* */ -/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - - /*************************************************************************/ - /* */ - /* Many compilers provide a non-ANSI 64-bit data type that can be used */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 - - - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ -/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - - - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ -#define FT_CONFIG_OPTION_INLINE_MULFIX - - - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#define FT_CONFIG_OPTION_USE_LZW - - - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ -#define FT_CONFIG_OPTION_USE_ZLIB - - - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -#mesondefine FT_CONFIG_OPTION_SYSTEM_ZLIB - - - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#mesondefine FT_CONFIG_OPTION_USE_BZIP2 - - - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ -/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - - - /*************************************************************************/ - /* */ - /* PNG bitmap support. */ - /* */ - /* FreeType now handles loading color bitmap glyphs in the PNG format. */ - /* This requires help from the external libpng library. Uncompressed */ - /* color bitmaps do not need any external libraries and will be */ - /* supported regardless of this configuration. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#mesondefine FT_CONFIG_OPTION_USE_PNG - - - /*************************************************************************/ - /* */ - /* HarfBuzz support. */ - /* */ - /* FreeType uses the HarfBuzz library to improve auto-hinting of */ - /* OpenType fonts. If available, many glyphs not directly addressable */ - /* by a font's character map will be hinted also. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -#mesondefine FT_CONFIG_OPTION_USE_HARFBUZZ - - - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ - /* */ - /* FT_EXPORT( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT and */ - /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ -#define FT_CONFIG_OPTION_MAC_FONTS - - - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ -#ifdef FT_CONFIG_OPTION_MAC_FONTS -#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#endif - - - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ -#define FT_CONFIG_OPTION_INCREMENTAL - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384L - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ -#define FT_MAX_MODULES 32 - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_DEBUG_LEVEL_ERROR */ -/* #define FT_DEBUG_LEVEL_TRACE */ - - - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* af_glyph_hints_get_num_segments */ - /* af_glyph_hints_get_segment_offset */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_DEBUG_AUTOFIT */ - - - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_DEBUG_MEMORY */ - - - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ -#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS - - - /*************************************************************************/ - /* */ - /* Position Independent Code */ - /* */ - /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ - /* constants will be moved into a struct and additional intialization */ - /* code will be used. */ - /* */ - /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. */ - /* */ -#mesondefine FT_CONFIG_OPTION_PIC - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `ftsnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ -#define TT_CONFIG_CMAP_FORMAT_0 -#define TT_CONFIG_CMAP_FORMAT_2 -#define TT_CONFIG_CMAP_FORMAT_4 -#define TT_CONFIG_CMAP_FORMAT_6 -#define TT_CONFIG_CMAP_FORMAT_8 -#define TT_CONFIG_CMAP_FORMAT_10 -#define TT_CONFIG_CMAP_FORMAT_12 -#define TT_CONFIG_CMAP_FORMAT_13 -#define TT_CONFIG_CMAP_FORMAT_14 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ -#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ - /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ - /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ - /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ - /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ - /* */ - /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* http://www.microsoft.com/typography/otspec/glyf.htm */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ - /* */ -#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ -#define TT_CONFIG_OPTION_GX_VAR_SUPPORT - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ -#define TT_CONFIG_OPTION_BDF - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 256 - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** C F F D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ - /* possible to set up the default values of the four control points that */ - /* define the stem darkening behaviour of the (new) CFF engine. For */ - /* more details please read the documentation of the */ - /* `darkening-parameters' property of the cff driver module (file */ - /* `ftcffdrv.h'), which allows the control at run-time. */ - /* */ - /* Do *not* undefine these macros! */ - /* */ -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 - -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 - -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 - -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 -#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 - - - /*************************************************************************/ - /* */ - /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the cff driver module. */ - /* */ -/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ -#define AF_CONFIG_OPTION_CJK - - /*************************************************************************/ - /* */ - /* Compile autofit module with Indic script support. */ - /* */ -#define AF_CONFIG_OPTION_INDIC - - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is active only if the rendering mode is */ - /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ - /* `warping' property of the auto-hinter (see file `ftautoh.h' for more */ - /* information; by default it is switched off). */ - /* */ -#define AF_CONFIG_OPTION_USE_WARPER - - /* */ - - - /* - * This macro is obsolete. Support has been removed in FreeType - * version 2.5. - */ -/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ - - - /* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. - */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER -#endif - - - /* - * Check CFF darkening parameters. The checks are the same as in function - * `cff_property_set' in file `cffdrivr.c'. - */ -#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ - \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ - \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ - \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ - CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 -#error "Invalid CFF darkening parameters!" -#endif - -FT_END_HEADER - - -#endif /* FTOPTION_H_ */ - - -/* END */ diff --git a/subprojects/packagefiles/freetype-2.6.1-meson/meson.build b/subprojects/packagefiles/freetype-2.6.1-meson/meson.build deleted file mode 100644 index 9a5180ef7586..000000000000 --- a/subprojects/packagefiles/freetype-2.6.1-meson/meson.build +++ /dev/null @@ -1,193 +0,0 @@ -project('freetype2', 'c', - version: '2.6.1', - license: '(FTL OR GPL-2.0-or-later) AND BSD-3-Clause AND MIT AND MIT-Modern-Variant AND Zlib', - license_files: [ - 'docs/LICENSE.TXT', - 'docs/FTL.TXT', - 'docs/GPLv2.TXT', - ], - meson_version: '>=1.1.0') - -# NOTE about FreeType versions -# There are 3 versions numbers associated with each releases: -# - official release number (eg. 2.6.1) - accessible via -# FREETYPE_{MAJOR,MINOR,PATCH} macros from FT_FREETYPE_H -# - libtool-specific version number, this is what is returned by -# freetype-config --version / pkg-config --modversion (eg. 22.1.16) -# - the platform-specific shared object version number (eg. 6.16.1) -# See https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/VERSIONS.TXT -# for more information -release_version = meson.project_version() -libtool_version = '18.1.12' -so_version = '6.12.1' -so_soversion = '6' - -pkgmod = import('pkgconfig') - -cc = meson.get_compiler('c') - -base_sources = [ - 'src/autofit/autofit.c', - 'src/base/ftbase.c', - 'src/base/ftbbox.c', - 'src/base/ftbdf.c', - 'src/base/ftbitmap.c', - 'src/base/ftcid.c', - 'src/base/ftfntfmt.c', - 'src/base/ftfstype.c', - 'src/base/ftgasp.c', - 'src/base/ftglyph.c', - 'src/base/ftgxval.c', - 'src/base/ftinit.c', - 'src/base/ftlcdfil.c', - 'src/base/ftmm.c', - 'src/base/ftotval.c', - 'src/base/ftpatent.c', - 'src/base/ftpfr.c', - 'src/base/ftstroke.c', - 'src/base/ftsynth.c', - 'src/base/ftsystem.c', - 'src/base/fttype1.c', - 'src/base/ftwinfnt.c', - 'src/bdf/bdf.c', - 'src/bzip2/ftbzip2.c', - 'src/cache/ftcache.c', - 'src/cff/cff.c', - 'src/cid/type1cid.c', - 'src/gzip/ftgzip.c', - 'src/lzw/ftlzw.c', - 'src/pcf/pcf.c', - 'src/pfr/pfr.c', - 'src/psaux/psaux.c', - 'src/pshinter/pshinter.c', - 'src/psnames/psnames.c', - 'src/raster/raster.c', - 'src/sfnt/sfnt.c', - 'src/smooth/smooth.c', - 'src/truetype/truetype.c', - 'src/type1/type1.c', - 'src/type42/type42.c', - 'src/winfonts/winfnt.c', -] - -ft2build_h = [ - 'include/ft2build.h', -] - -ft_headers = [ - 'include/freetype/freetype.h', - 'include/freetype/ftadvanc.h', - 'include/freetype/ftautoh.h', - 'include/freetype/ftbbox.h', - 'include/freetype/ftbdf.h', - 'include/freetype/ftbitmap.h', - 'include/freetype/ftbzip2.h', - 'include/freetype/ftcache.h', - 'include/freetype/ftcffdrv.h', - 'include/freetype/ftchapters.h', - 'include/freetype/ftcid.h', - 'include/freetype/fterrdef.h', - 'include/freetype/fterrors.h', - 'include/freetype/ftfntfmt.h', - 'include/freetype/ftgasp.h', - 'include/freetype/ftglyph.h', - 'include/freetype/ftgxval.h', - 'include/freetype/ftgzip.h', - 'include/freetype/ftimage.h', - 'include/freetype/ftincrem.h', - 'include/freetype/ftlcdfil.h', - 'include/freetype/ftlist.h', - 'include/freetype/ftlzw.h', - 'include/freetype/ftmac.h', - 'include/freetype/ftmm.h', - 'include/freetype/ftmodapi.h', - 'include/freetype/ftmoderr.h', - 'include/freetype/ftotval.h', - 'include/freetype/ftoutln.h', - 'include/freetype/ftpfr.h', - 'include/freetype/ftrender.h', - 'include/freetype/ftsizes.h', - 'include/freetype/ftsnames.h', - 'include/freetype/ftstroke.h', - 'include/freetype/ftsynth.h', - 'include/freetype/ftsystem.h', - 'include/freetype/fttrigon.h', - 'include/freetype/ftttdrv.h', - 'include/freetype/fttypes.h', - 'include/freetype/ftwinfnt.h', - 'include/freetype/t1tables.h', - 'include/freetype/ttnameid.h', - 'include/freetype/tttables.h', - 'include/freetype/tttags.h', - 'include/freetype/ttunpat.h', -] - -ft_config_headers = [ - 'include/freetype/config/ftconfig.h', - 'include/freetype/config/ftheader.h', - 'include/freetype/config/ftmodule.h', - 'include/freetype/config/ftoption.h', - 'include/freetype/config/ftstdlib.h', -] - -if host_machine.system() == 'windows' - base_sources += [ - 'builds/windows/ftdebug.c', - ] -else - base_sources += [ - 'src/base/ftdebug.c', - ] -endif - -c_args = [ - '-DFT2_BUILD_LIBRARY', - '-DFT_CONFIG_CONFIG_H=', - '-DFT_CONFIG_OPTIONS_H=' -] - -check_headers = [] - -if ['linux', 'darwin', 'cygwin'].contains(host_machine.system()) - check_headers += [ - ['unistd.h'], - ['fcntl.h'], - ['stdint.h'], - ] - ftconfig_h_in = files('builds/unix/ftconfig.h.in') -else - ftconfig_h_in = files('include/freetype/config/ftconfig.h') -endif - -conf = configuration_data() -deps = [] -incbase = include_directories(['include']) - -foreach check : check_headers - name = check[0] - - if cc.has_header(name) - conf.set('HAVE_@0@'.format(name.to_upper().underscorify()), 1) - endif -endforeach - -configure_file(input: ftconfig_h_in, - output: 'ftconfig.h', - configuration: conf) - -ft_config_headers += [configure_file(input: 'include/freetype/config/ftoption.h.in', - output: 'ftoption.h', - configuration: conf)] - -libfreetype = static_library('freetype', base_sources, - include_directories: incbase, - dependencies: deps, - c_args: c_args, - gnu_symbol_visibility: 'inlineshidden', -) - -freetype_dep = declare_dependency( - link_with: libfreetype, - include_directories : incbase, - dependencies: deps, -) diff --git a/subprojects/packagefiles/freetype-2.6.1-meson/src/gzip/zconf.h b/subprojects/packagefiles/freetype-2.6.1-meson/src/gzip/zconf.h deleted file mode 100644 index d88a82a2eec8..000000000000 --- a/subprojects/packagefiles/freetype-2.6.1-meson/src/gzip/zconf.h +++ /dev/null @@ -1,284 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2002 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef _ZCONF_H -#define _ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateReset z_inflateReset -# define compress z_compress -# define compress2 z_compress2 -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table - -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif -#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) -# ifndef __32BIT__ -# define __32BIT__ -# endif -#endif -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif - -/* WinCE doesn't have errno.h */ -#ifdef _WIN32_WCE -# define NO_ERRNO_H -#endif - - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#if defined(MSDOS) && !defined(__32BIT__) -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) -# define STDC -#endif -#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) -# ifndef STDC -# define STDC -# endif -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Old Borland C and LCC incorrectly complains about missing returns: */ -#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) -# define NEED_DUMMY_RETURN -#endif - -#if defined(__LCC__) -# define NEED_DUMMY_RETURN -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -#endif -#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) -# ifndef __32BIT__ -# define SMALL_MEDIUM -# define FAR _far -# endif -#endif - -/* Compile with -DZLIB_DLL for Windows DLL support */ -#if defined(ZLIB_DLL) -# if defined(_WINDOWS) || defined(WINDOWS) -# ifdef FAR -# undef FAR -# endif -# include -# define ZEXPORT(x) x WINAPI -# ifdef WIN32 -# define ZEXPORTVA(x) x WINAPIV -# else -# define ZEXPORTVA(x) x FAR _cdecl _export -# endif -# endif -# if defined (__BORLANDC__) -# if (__BORLANDC__ >= 0x0500) && defined (WIN32) -# include -# define ZEXPORT(x) x __declspec(dllexport) WINAPI -# define ZEXPORTRVA(x) x __declspec(dllexport) WINAPIV -# else -# if defined (_Windows) && defined (__DLL__) -# define ZEXPORT(x) x _export -# define ZEXPORTVA(x) x _export -# endif -# endif -# endif -#endif - - -#ifndef ZEXPORT -# define ZEXPORT(x) static x -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA(x) static x -#endif -#ifndef ZEXTERN -# define ZEXTERN(x) static x -#endif -#ifndef ZEXTERNDEF -# define ZEXTERNDEF(x) static x -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#ifdef HAVE_UNISTD_H -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(inflate_blocks,"INBL") -# pragma map(inflate_blocks_new,"INBLNE") -# pragma map(inflate_blocks_free,"INBLFR") -# pragma map(inflate_blocks_reset,"INBLRE") -# pragma map(inflate_codes_free,"INCOFR") -# pragma map(inflate_codes,"INCO") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_flush,"INFLU") -# pragma map(inflate_mask,"INMA") -# pragma map(inflate_set_dictionary,"INSEDI2") -# pragma map(inflate_copyright,"INCOPY") -# pragma map(inflate_trees_bits,"INTRBI") -# pragma map(inflate_trees_dynamic,"INTRDY") -# pragma map(inflate_trees_fixed,"INTRFI") -# pragma map(inflate_trees_free,"INTRFR") -#endif - -#endif /* _ZCONF_H */ diff --git a/subprojects/packagefiles/freetype-34aed655f1696da774b5cdd4c5effb312153232f.patch b/subprojects/packagefiles/freetype-34aed655f1696da774b5cdd4c5effb312153232f.patch new file mode 100644 index 000000000000..c00baa702f65 --- /dev/null +++ b/subprojects/packagefiles/freetype-34aed655f1696da774b5cdd4c5effb312153232f.patch @@ -0,0 +1,36 @@ +From 34aed655f1696da774b5cdd4c5effb312153232f Mon Sep 17 00:00:00 2001 +From: Benoit Pierre +Date: Sat, 12 Oct 2024 10:49:46 +0000 +Subject: [PATCH] * meson.build: Fix `bzip2` option handling. + +--- + meson.build | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/meson.build b/meson.build +index 72b7f9900..2e8d5355e 100644 +--- a/meson.build ++++ b/meson.build +@@ -320,11 +320,16 @@ else + endif + + # BZip2 support. +-bzip2_dep = dependency('bzip2', required: false) ++bzip2_dep = dependency( ++ 'bzip2', ++ required: get_option('bzip2').disabled() ? get_option('bzip2') : false, ++) + if not bzip2_dep.found() +- bzip2_dep = cc.find_library('bz2', ++ bzip2_dep = cc.find_library( ++ 'bz2', + has_headers: ['bzlib.h'], +- required: get_option('bzip2')) ++ required: get_option('bzip2'), ++ ) + endif + + if bzip2_dep.found() +-- +GitLab +
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy