Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
BdfFontFile.py124 linesDownload Raw Back to PIL
1#
2# The Python Imaging Library
3# $Id$
4#
5# bitmap distribution font (bdf) file parser
6#
7# history:
8# 1996-05-16 fl   created (as bdf2pil)
9# 1997-08-25 fl   converted to FontFile driver
10# 2001-05-25 fl   removed bogus __init__ call
11# 2002-11-20 fl   robustification (from Kevin Cazabon, Dmitry Vasiliev)
12# 2003-04-22 fl   more robustification (from Graham Dumpleton)
13#
14# Copyright (c) 1997-2003 by Secret Labs AB.
15# Copyright (c) 1997-2003 by Fredrik Lundh.
16#
17# See the README file for information on usage and redistribution.
18#
19
20"""
21Parse X Bitmap Distribution Format (BDF)
22"""
23
24from __future__ import annotations
25
26from typing import BinaryIO
27
28from . import FontFile, Image
29
30
31def bdf_char(
32    f: BinaryIO,
33) -> (
34    tuple[
35        str,
36        int,
37        tuple[tuple[int, int], tuple[int, int, int, int], tuple[int, int, int, int]],
38        Image.Image,
39    ]
40    | None
41):
42    # skip to STARTCHAR
43    while True:
44        s = f.readline()
45        if not s:
46            return None
47        if s.startswith(b"STARTCHAR"):
48            break
49    id = s[9:].strip().decode("ascii")
50
51    # load symbol properties
52    props = {}
53    while True:
54        s = f.readline()
55        if not s or s.startswith(b"BITMAP"):
56            break
57        i = s.find(b" ")
58        props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")
59
60    # load bitmap
61    bitmap = bytearray()
62    while True:
63        s = f.readline()
64        if not s or s.startswith(b"ENDCHAR"):
65            break
66        bitmap += s[:-1]
67
68    # The word BBX
69    # followed by the width in x (BBw), height in y (BBh),
70    # and x and y displacement (BBxoff0, BByoff0)
71    # of the lower left corner from the origin of the character.
72    width, height, x_disp, y_disp = (int(p) for p in props["BBX"].split())
73
74    # The word DWIDTH
75    # followed by the width in x and y of the character in device pixels.
76    dwx, dwy = (int(p) for p in props["DWIDTH"].split())
77
78    bbox = (
79        (dwx, dwy),
80        (x_disp, -y_disp - height, width + x_disp, -y_disp),
81        (0, 0, width, height),
82    )
83
84    try:
85        im = Image.frombytes("1", (width, height), bitmap, "hex", "1")
86    except ValueError:
87        # deal with zero-width characters
88        im = Image.new("1", (width, height))
89
90    return id, int(props["ENCODING"]), bbox, im
91
92
93class BdfFontFile(FontFile.FontFile):
94    """Font file plugin for the X11 BDF format."""
95
96    def __init__(self, fp: BinaryIO) -> None:
97        super().__init__()
98
99        s = fp.readline()
100        if not s.startswith(b"STARTFONT 2.1"):
101            msg = "not a valid BDF file"
102            raise SyntaxError(msg)
103
104        props = {}
105        comments = []
106
107        while True:
108            s = fp.readline()
109            if not s or s.startswith(b"ENDPROPERTIES"):
110                break
111            i = s.find(b" ")
112            props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")
113            if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
114                if s.find(b"LogicalFontDescription") < 0:
115                    comments.append(s[i + 1 : -1].decode("ascii"))
116
117        while True:
118            c = bdf_char(fp)
119            if not c:
120                break
121            id, ch, (xy, dst, src), im = c
122            if 0 <= ch < len(self.glyph):
123                self.glyph[ch] = xy, dst, src, im
124 
codekingpro/portable-devtools · Team Ai