aboutsummaryrefslogtreecommitdiff
path: root/circuitpython/tools/bitmap_font
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2022-06-19 19:47:51 +0530
committerRaghuram Subramani <raghus2247@gmail.com>2022-06-19 19:47:51 +0530
commit4fd287655a72b9aea14cdac715ad5b90ed082ed2 (patch)
tree65d393bc0e699dd12d05b29ba568e04cea666207 /circuitpython/tools/bitmap_font
parent0150f70ce9c39e9e6dd878766c0620c85e47bed0 (diff)
add circuitpython code
Diffstat (limited to 'circuitpython/tools/bitmap_font')
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/__init__.py0
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/__init__.cpython-310.pycbin0 -> 209 bytes
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bdf.cpython-310.pycbin0 -> 2664 bytes
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bitmap_font.cpython-310.pycbin0 -> 1185 bytes
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/glyph_cache.cpython-310.pycbin0 -> 780 bytes
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/bdf.py109
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/bitmap_font.py44
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/glyph_cache.py16
-rw-r--r--circuitpython/tools/bitmap_font/adafruit_bitmap_font/pcf.py60
9 files changed, 229 insertions, 0 deletions
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__init__.py b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__init__.py
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/__init__.cpython-310.pyc b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..773613f
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/__init__.cpython-310.pyc
Binary files differ
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bdf.cpython-310.pyc b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bdf.cpython-310.pyc
new file mode 100644
index 0000000..b82f4ec
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bdf.cpython-310.pyc
Binary files differ
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bitmap_font.cpython-310.pyc b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bitmap_font.cpython-310.pyc
new file mode 100644
index 0000000..3b5b110
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/bitmap_font.cpython-310.pyc
Binary files differ
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/glyph_cache.cpython-310.pyc b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/glyph_cache.cpython-310.pyc
new file mode 100644
index 0000000..e0a6b94
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/__pycache__/glyph_cache.cpython-310.pyc
Binary files differ
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/bdf.py b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/bdf.py
new file mode 100644
index 0000000..1bf69f3
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/bdf.py
@@ -0,0 +1,109 @@
+from .glyph_cache import GlyphCache
+
+class BDF(GlyphCache):
+ def __init__(self, f, bitmap_class):
+ super().__init__()
+ self.file = f
+ self.name = f
+ self.file.seek(0)
+ self.bitmap_class = bitmap_class
+ line = self.file.readline()
+ line = str(line, "utf-8")
+ if not line or not line.startswith("STARTFONT 2.1"):
+ raise ValueError("Unsupported file version")
+
+ def get_bounding_box(self):
+ self.file.seek(0)
+ while True:
+ line = self.file.readline()
+ line = str(line, "utf-8")
+ if not line:
+ break
+
+ if line.startswith("FONTBOUNDINGBOX "):
+ _, x, y, dx, dy = line.split()
+ return (int(x), int(y), int(dx), int(dy))
+ return None
+
+ def load_glyphs(self, code_points):
+ metadata = True
+ character = False
+ code_point = None
+ rounded_x = 1
+ bytes_per_row = 1
+ desired_character = False
+ current_info = None
+ current_y = 0
+ total_remaining = len(code_points)
+
+ x, _, _, _ = self.get_bounding_box()
+ # create a scratch bytearray to load pixels into
+ scratch_row = memoryview(bytearray((((x-1)//32)+1) * 4))
+
+ self.file.seek(0)
+ while True:
+ line = self.file.readline()
+ if not line:
+ break
+ if line.startswith(b"CHARS "):
+ metadata = False
+ elif line.startswith(b"SIZE"):
+ _, self.point_size, self.x_resolution, self.y_resolution = line.split()
+ elif line.startswith(b"COMMENT"):
+ pass
+ elif line.startswith(b"STARTCHAR"):
+ # print(lineno, line.strip())
+ #_, character_name = line.split()
+ character = True
+ elif line.startswith(b"ENDCHAR"):
+ character = False
+ if desired_character:
+ self._glyphs[code_point] = current_info
+ if total_remaining == 0:
+ return
+ desired_character = False
+ elif line.startswith(b"BBX"):
+ if desired_character:
+ _, x, y, dx, dy = line.split()
+ x = int(x)
+ y = int(y)
+ dx = int(dx)
+ dy = int(dy)
+ current_info["bounds"] = (x, y, dx, dy)
+ current_info["bitmap"] = self.bitmap_class(x, y, 2)
+ elif line.startswith(b"BITMAP"):
+ if desired_character:
+ rounded_x = x // 8
+ if x % 8 > 0:
+ rounded_x += 1
+ bytes_per_row = rounded_x
+ if bytes_per_row % 4 > 0:
+ bytes_per_row += 4 - bytes_per_row % 4
+ current_y = 0
+ elif line.startswith(b"ENCODING"):
+ _, code_point = line.split()
+ code_point = int(code_point)
+ if code_point == code_points or code_point in code_points:
+ total_remaining -= 1
+ if code_point not in self._glyphs or not self._glyphs[code_point]:
+ desired_character = True
+ current_info = {"bitmap": None, "bounds": None, "shift": None}
+ elif line.startswith(b"DWIDTH"):
+ if desired_character:
+ _, shift_x, shift_y = line.split()
+ shift_x = int(shift_x)
+ shift_y = int(shift_y)
+ current_info["shift"] = (shift_x, shift_y)
+ elif line.startswith(b"SWIDTH"):
+ pass
+ elif character:
+ if desired_character:
+ bits = int(line.strip(), 16)
+ for i in range(rounded_x):
+ val = (bits >> ((rounded_x-i-1)*8)) & 0xFF
+ scratch_row[i] = val
+ current_info["bitmap"]._load_row(current_y, scratch_row[:bytes_per_row])
+ current_y += 1
+ elif metadata:
+ #print(lineno, line.strip())
+ pass
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/bitmap_font.py b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/bitmap_font.py
new file mode 100644
index 0000000..c536e98
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/bitmap_font.py
@@ -0,0 +1,44 @@
+import sys
+
+def load_font(filename, bitmap=None):
+ if not bitmap:
+ import displayio
+ bitmap = displayio.Bitmap
+ f = open(filename, "rb")
+ first_four = f.read(4)
+ #print(first_four)
+ if filename.endswith("bdf") and first_four == b"STAR":
+ from . import bdf
+ return bdf.BDF(f, bitmap)
+ elif filename.endswith("pcf") and first_four == b"\x01fcp":
+ import pcf
+ return pcf.PCF(f)
+ elif filename.endswith("ttf") and first_four == b"\x00\x01\x00\x00":
+ import ttf
+ return ttf.TTF(f)
+
+
+
+if __name__ == "__main__":
+ f = load_font(sys.argv[1])
+ # print(f.characters)
+ for c in "Adafruit CircuitPython":
+ o = ord(c)
+ if o not in f.characters:
+ continue
+ glyph = f.characters[o]
+ print(glyph)
+ for i in range(10):
+ for c in "Adafruit CircuitPython":
+ o = ord(c)
+ if o not in f.characters:
+ continue
+ glyph = f.characters[o]
+ # print(glyph)
+ shifted_i = i + (glyph["bounds"][1] - 8) + glyph["bounds"][3]
+ if 0 <= shifted_i < len(glyph["bitmap"]):
+ pixels = glyph["bitmap"][shifted_i]
+ else:
+ pixels = ""
+ print(pixels + " " * (glyph["shift"][0] - len(pixels)), end="")
+ print()
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/glyph_cache.py b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/glyph_cache.py
new file mode 100644
index 0000000..383596b
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/glyph_cache.py
@@ -0,0 +1,16 @@
+import gc
+
+class GlyphCache:
+ def __init__(self):
+ self._glyphs = {}
+
+ def get_glyph(self, code_point):
+ if code_point in self._glyphs:
+ return self._glyphs[code_point]
+
+ s = set()
+ s.add(code_point)
+ self._glyphs[code_point] = None
+ self.load_glyphs(s)
+ gc.collect()
+ return self._glyphs[code_point]
diff --git a/circuitpython/tools/bitmap_font/adafruit_bitmap_font/pcf.py b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/pcf.py
new file mode 100644
index 0000000..cb997e8
--- /dev/null
+++ b/circuitpython/tools/bitmap_font/adafruit_bitmap_font/pcf.py
@@ -0,0 +1,60 @@
+
+class BDF:
+ def __init__(self, f):
+ self.file = f
+
+ f.seek(0)
+
+ self.characters = {}
+
+ metadata = True
+ character = False
+ bitmap_lines_left = 0
+ bounds = None
+ bitmap = None
+ code_point = None
+ character_name = None
+ for lineno, line in enumerate(self.file.readlines()):
+ if lineno == 0 and not line.startswith("STARTFONT 2.1"):
+ raise ValueError("Unsupported file version")
+ if line.startswith("CHARS "):
+ metadata = False
+ if line.startswith("SIZE"):
+ _, self.point_size, self.x_resolution, self.y_resolution = line.split()
+ elif line.startswith("COMMENT"):
+ token, comment = line.split(" ", 1)
+ print(comment.strip("\n\""))
+ elif line.startswith("STARTCHAR"):
+ print(lineno, line.strip())
+ _, character_name = line.split()
+ character = True
+ elif line.startswith("ENDCHAR"):
+ character = False
+ elif line.startswith("BBX"):
+ _, x, y, dx, dy = line.split()
+ x = int(x)
+ y = int(y)
+ dx = int(dx)
+ dy = int(dy)
+ bounds = (x, y, dx, dy)
+ character = False
+ elif line.startswith("BITMAP"):
+ character = False
+ bitmap_lines_left = bounds[1]
+ bitmap = []
+ elif line.startswith("ENCODING"):
+ _, code_point = line.split()
+ code_point = int(code_point)
+ print(hex(code_point))
+ elif bitmap_lines_left > 0:
+ bits = int(line.strip(), 16)
+ shift = 8 - bounds[0]
+ bits >>= shift
+ pixels = ("{0:0" + str(bounds[0]) +"b}").format(bits).replace("0", " ")
+ bitmap.append(pixels)
+ bitmap_lines_left -= 1
+
+ if bitmap_lines_left == 0:
+ self.characters[code_point] = {"name": character_name, "bitmap": bitmap}
+ elif metadata:
+ print(lineno, line.strip())