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