Exemple #1
0
    def _read_file(input: io.BufferedIOBase) -> Optional[Font]:
        lines: typing.List[str] = [x for x in input.readlines()]
        lines = [x for x in lines if not x.startswith("Comment")]
        lines = [x[:-1] if x.endswith("\n") else x for x in lines]

        # check first/last line
        if not lines[0].startswith("StartFontMetrics") or not lines[
                -1].startswith("EndFontMetrics"):
            return None

        out_font = Font()

        # FontDescriptor
        out_font_descriptor = FontDescriptor().set_parent(
            out_font)  # type: ignore [attr-defined]
        out_font_descriptor[
            "FontName"] = AdobeFontMetrics._find_and_parse_as_string(
                lines, "FontName")
        out_font_descriptor[
            "FontFamily"] = AdobeFontMetrics._find_and_parse_as_string(
                lines, "FamilyName")
        # FontStretch
        # FontWeight
        # Flags
        # FontBBox
        # ItalicAngle
        out_font_descriptor[
            "Ascent"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "Ascender")
        out_font_descriptor[
            "Descent"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "Descender")
        # Leading
        out_font_descriptor[
            "CapHeight"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "CapHeight")
        out_font_descriptor[
            "XHeight"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "XHeight")
        # StemV
        out_font_descriptor[
            "StemV"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "StemV")
        # StemH
        out_font_descriptor[
            "StemH"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "StemH")
        # AvgWidth
        out_font_descriptor[
            "AvgWidth"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "AvgWidth")
        # MaxWidth
        out_font_descriptor[
            "MaxWidth"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "MaxWidth")
        # MissingWidth
        out_font_descriptor[
            "MissingWidth"] = AdobeFontMetrics._find_and_parse_as_float(
                lines, "MissingWidth")
        # FontFile
        # FontFile2
        # FontFile3
        out_font_descriptor[
            "CharSet"] = AdobeFontMetrics._find_and_parse_as_integer(
                lines, "Characters")

        # Font
        out_font["Type"] = "Font"
        out_font["Subtype"] = "Type1"
        out_font["Name"] = out_font_descriptor["FontName"]
        out_font["BaseFont"] = out_font_descriptor["FontName"]

        widths = List().set_parent(out_font)  # type: ignore [attr-defined]
        avg_char_width: float = 0
        avg_char_width_norm: float = 0
        first_char = None
        last_char = None

        char_metrics_lines = lines[
            lines.index([x for x in lines
                         if x.startswith("StartCharMetrics")][0]
                        ):lines.index("EndCharMetrics") + 1]
        char_metrics_lines = char_metrics_lines[1:-1]
        for cml in char_metrics_lines:
            tmp = {
                y.split(" ")[0]: y.split(" ")[1]
                for y in [x.strip() for x in cml.split(";")] if " " in y
            }

            # determine char
            ch = -1
            if "C" in tmp:
                ch = int(tmp["C"])
            if "CH" in tmp:
                ch = int(tmp["CH"][1:-1], 16)

            if (first_char is None or ch < first_char) and ch != -1:
                first_char = ch
            if (last_char is None or ch > last_char) and ch != -1:
                last_char = ch

            w = float(tmp["WX"])
            if ch != -1 and w != 0:
                avg_char_width += w
                avg_char_width_norm += 1

            widths.append(Decimal(w))

        assert first_char is not None
        assert last_char is not None

        out_font["FirstChar"] = Decimal(first_char)
        out_font["LastChar"] = Decimal(last_char)
        out_font["Widths"] = widths

        if out_font_descriptor["AvgWidth"] is None:
            out_font_descriptor["AvgWidth"] = round(
                Decimal(avg_char_width / avg_char_width_norm), 2)
        if out_font_descriptor["MaxWidth"] is None:
            out_font_descriptor["MaxWidth"] = max(widths)
        out_font["FontDescriptor"] = out_font_descriptor

        # return
        return out_font