Skip to content

Commit

Permalink
Merge pull request #58 from isacben/bitmap-font-type-annotations
Browse files Browse the repository at this point in the history
Added Type Annotations
  • Loading branch information
tekktrik committed Jun 9, 2022
2 parents 511e0d8 + 781b2d3 commit b656b2b
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 29 deletions.
21 changes: 14 additions & 7 deletions adafruit_bitmap_font/bdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
"""

try:
from typing import Union, Optional, Tuple, Iterable
from io import FileIO
from displayio import Bitmap
except ImportError:
pass

import gc
from fontio import Glyph
from .glyph_cache import GlyphCache
Expand All @@ -33,7 +40,7 @@
class BDF(GlyphCache):
"""Loads glyphs from a BDF file in the given bitmap_class."""

def __init__(self, f, bitmap_class):
def __init__(self, f: FileIO, bitmap_class: Bitmap) -> None:
super().__init__()
self.file = f
self.name = f
Expand All @@ -50,7 +57,7 @@ def __init__(self, f, bitmap_class):
self._descent = None

@property
def descent(self):
def descent(self) -> Optional[int]:
"""The number of pixels below the baseline of a typical descender"""
if self._descent is None:
self.file.seek(0)
Expand All @@ -66,7 +73,7 @@ def descent(self):
return self._descent

@property
def ascent(self):
def ascent(self) -> Optional[int]:
"""The number of pixels above the baseline of a typical ascender"""
if self._ascent is None:
self.file.seek(0)
Expand All @@ -81,7 +88,7 @@ def ascent(self):

return self._ascent

def _verify_bounding_box(self):
def _verify_bounding_box(self) -> None:
"""Private function to verify FOUNTBOUNDINGBOX parameter
This function will parse the first 10 lines of the font source
file to verify the value or raise an exception in case is not found
Expand All @@ -105,15 +112,15 @@ def _verify_bounding_box(self):
"Source file does not have the FOUNTBOUNDINGBOX parameter"
) from error

def _readline_file(self):
def _readline_file(self) -> str:
line = self.file.readline()
return str(line, "utf-8")

def get_bounding_box(self):
def get_bounding_box(self) -> Tuple[int, int, int, int]:
"""Return the maximum glyph size as a 4-tuple of: width, height, x_offset, y_offset"""
return self._boundingbox

def load_glyphs(self, code_points):
def load_glyphs(self, code_points: Union[int, str, Iterable[int]]) -> None:
# pylint: disable=too-many-statements,too-many-branches,too-many-nested-blocks,too-many-locals
metadata = True
character = False
Expand Down
15 changes: 13 additions & 2 deletions adafruit_bitmap_font/bitmap_font.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,24 @@
"""

try:
from typing import Optional, Union
from displayio import Bitmap
from . import bdf
from . import pcf
from . import ttf
except ImportError:
pass

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Bitmap_Font.git"


def load_font(filename, bitmap=None):
def load_font(
filename: str, bitmap: Optional[Bitmap] = None
) -> Union[bdf.BDF, pcf.PCF, ttf.TTF]:
"""Loads a font file. Returns None if unsupported."""
# pylint: disable=import-outside-toplevel, consider-using-with
# pylint: disable=import-outside-toplevel, redefined-outer-name, consider-using-with
if not bitmap:
import displayio

Expand Down
12 changes: 9 additions & 3 deletions adafruit_bitmap_font/glyph_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
"""

try:
from typing import Union, Iterable
from fontio import Glyph
except ImportError:
pass

import gc

__version__ = "0.0.0-auto.0"
Expand All @@ -31,13 +37,13 @@
class GlyphCache:
"""Caches glyphs loaded by a subclass."""

def __init__(self):
def __init__(self) -> None:
self._glyphs = {}

def load_glyphs(self, code_points):
def load_glyphs(self, code_points: Union[int, str, Iterable[int]]) -> None:
"""Loads displayio.Glyph objects into the GlyphCache from the font."""

def get_glyph(self, code_point):
def get_glyph(self, code_point: int) -> Glyph:
"""Returns a displayio.Glyph for the given code point or None is unsupported."""
if code_point in self._glyphs:
return self._glyphs[code_point]
Expand Down
32 changes: 19 additions & 13 deletions adafruit_bitmap_font/pcf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@
"""

try:
from typing import Union, Tuple, Iterator, Iterable
from io import FileIO
from displayio import Bitmap as displayioBitmap
except ImportError:
pass

from collections import namedtuple
import gc
import struct
from micropython import const

from fontio import Glyph
from .glyph_cache import GlyphCache

Expand Down Expand Up @@ -96,7 +102,7 @@
class PCF(GlyphCache):
"""Loads glyphs from a PCF file in the given bitmap_class."""

def __init__(self, f, bitmap_class):
def __init__(self, f: FileIO, bitmap_class: displayioBitmap) -> None:
super().__init__()
self.file = f
self.name = f
Expand Down Expand Up @@ -133,27 +139,27 @@ def __init__(self, f, bitmap_class):
)

@property
def ascent(self):
def ascent(self) -> int:
"""The number of pixels above the baseline of a typical ascender"""
return self._ascent

@property
def descent(self):
def descent(self) -> int:
"""The number of pixels below the baseline of a typical descender"""
return self._descent

def get_bounding_box(self):
def get_bounding_box(self) -> Tuple[int, int, int, int]:
"""Return the maximum glyph size as a 4-tuple of: width, height, x_offset, y_offset"""
return self._bounding_box

def _read(self, format_):
def _read(self, format_: str) -> Tuple:
size = struct.calcsize(format_)
if size != len(self.buffer):
self.buffer = bytearray(size)
self.file.readinto(self.buffer)
return struct.unpack_from(format_, self.buffer)

def _seek_table(self, table):
def _seek_table(self, table: Table) -> int:
self.file.seek(table.offset)
(format_,) = self._read("<I")

Expand All @@ -162,13 +168,13 @@ def _seek_table(self, table):

return format_

def _read_encoding_table(self):
def _read_encoding_table(self) -> Encoding:
encoding = self.tables[_PCF_BDF_ENCODINGS]
self._seek_table(encoding)

return Encoding(*self._read(">hhhhh"))

def _read_bitmap_table(self):
def _read_bitmap_table(self) -> Bitmap:
bitmaps = self.tables[_PCF_BITMAPS]
format_ = self._seek_table(bitmaps)

Expand All @@ -177,7 +183,7 @@ def _read_bitmap_table(self):
bitmap_sizes = self._read(">4I")
return Bitmap(glyph_count, bitmap_sizes[format_ & 3])

def _read_metrics(self, compressed_metrics):
def _read_metrics(self, compressed_metrics: bool) -> Metrics:
if compressed_metrics:
(
left_side_bearing,
Expand Down Expand Up @@ -210,7 +216,7 @@ def _read_metrics(self, compressed_metrics):
attributes,
)

def _read_accelerator_tables(self):
def _read_accelerator_tables(self) -> Accelerators:
# pylint: disable=too-many-locals
accelerators = self.tables.get(_PCF_BDF_ACCELERATORS)
if not accelerators:
Expand Down Expand Up @@ -260,7 +266,7 @@ def _read_accelerator_tables(self):
ink_maxbounds,
)

def _read_properties(self):
def _read_properties(self) -> Iterator[Tuple[bytes, Union[bytes, int]]]:
property_table_offset = self.tables[_PCF_PROPERTIES]["offset"]
self.file.seek(property_table_offset)
(format_,) = self._read("<I")
Expand Down Expand Up @@ -291,7 +297,7 @@ def _read_properties(self):
else:
yield (string_map[name_offset], value)

def load_glyphs(self, code_points):
def load_glyphs(self, code_points: Union[int, str, Iterable[int]]) -> None:
# pylint: disable=too-many-statements,too-many-branches,too-many-nested-blocks,too-many-locals
if isinstance(code_points, int):
code_points = (code_points,)
Expand Down
12 changes: 9 additions & 3 deletions adafruit_bitmap_font/ttf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,26 @@
# pylint: skip-file
# Remove the above when TTF is actually supported.

import struct
try:
from typing import Tuple
from io import FileIO
from displayio import Bitmap
except ImportError:
pass

import struct

# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html


class TTF:
def __init__(self, f, bitmap):
def __init__(self, f: FileIO, bitmap: Bitmap) -> None:
f.seek(0)
self.file = f

self.characters = {}

def read(format):
def read(format: str) -> Tuple:
s = struct.calcsize(format)
return struct.unpack_from(format, f.read(s))

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
# SPDX-License-Identifier: Unlicense

Adafruit-Blinka
Adafruit-Blinka-displayio
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
# Author details
author="Adafruit Industries",
author_email="circuitpython@adafruit.com",
install_requires=["Adafruit-Blinka"],
install_requires=[
"Adafruit-Blinka",
"Adafruit-Blinka-displayio",
],
# Choose your license
license="MIT",
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
Expand Down

0 comments on commit b656b2b

Please sign in to comment.