Repository: matplotlib/matplotlib
File: lib/matplotlib/_afm.py (Python)

Code before:

    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: 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.0
        namelast = ''
        miny = 1_000_000_000
        maxy = 0
        left = 0
        for c in s:
            if c == '\n':
                continue
            name = uni2type1.get(ord(c), f"uni{ord(c):04X}")
            try:
                wx, _, bbox = self._metrics_by_name[name]
            except KeyError:
                name = 'question'
                wx, _, bbox = self._metrics_by_name[name]
            total_width += wx
            total_width += self._kern.get((namelast, name), 0)
            l, b, w, h = bbox
            left = min(left, l)
            miny = min(miny, b)
            maxy = max(maxy, b + h)

            namelast = name

        return left, miny, total_width, maxy - miny, -miny

    def get_glyph_name(self, glyph_ind: int) -> str:  # For consistency with FT2Font.
        """Get the name of the glyph, i.e., ord(';') is 'semicolon'."""
        return self._metrics[glyph_ind].name

    def get_char_index(self, c: int) -> int:  # For consistency with FT2Font.
        """
        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

    def get_width_char(self, c: int) -> float:
        """Get the width of the character code from the character metric WX field."""
        return self._metrics[c].width

Review comment (bug):
I'm uncertain if `WX` is the only thing that can be a float, or that's a parsing bug.

Code after:

    return kern_data, composites


class AFM:

    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: 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.0
        namelast = ''
        miny = 1_000_000_000
        maxy = 0
        left = 0
        for c in s:
            if c == '\n':
                continue
            name = uni2type1.get(ord(c), f"uni{ord(c):04X}")
            try:
                wx, _, bbox = self._metrics_by_name[name]
            except KeyError:
                name = 'question'
                wx, _, bbox = self._metrics_by_name[name]
            total_width += wx + self._kern.get((namelast, name), 0)
            l, b, w, h = bbox
            left = min(left, l)
            miny = min(miny, b)
            maxy = max(maxy, b + h)

            namelast = name

        return left, miny, total_width, maxy - miny, -miny

    def get_glyph_name(self, glyph_ind: int) -> str:  # For consistency with FT2Font.
        """Get the name of the glyph, i.e., ord(';') is 'semicolon'."""
        return self._metrics[glyph_ind].name

    def get_char_index(self, c: int) -> int:  # For consistency with FT2Font.
        """
        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