Skip to content

Added Type Annotations #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions adafruit_bitmap_font/bdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,15 @@

"""

try:
from typing import Union, Optional, Tuple
except ImportError:
pass

import gc
from io import FileIO
from fontio import Glyph
from displayio import Bitmap
from .glyph_cache import GlyphCache

__version__ = "0.0.0-auto.0"
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, set]) -> None:
# pylint: disable=too-many-statements,too-many-branches,too-many-nested-blocks,too-many-locals
metadata = True
character = False
Expand Down
24 changes: 14 additions & 10 deletions adafruit_bitmap_font/bitmap_font.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,34 @@

"""

try:
from typing import Optional, Union
except ImportError:
pass

from displayio import Bitmap
from . import bdf
from . import pcf
from . import ttf

__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, None]:
"""Loads a font file. Returns None if unsupported."""
# pylint: disable=import-outside-toplevel, consider-using-with
if not bitmap:
import displayio

bitmap = displayio.Bitmap
bitmap = Bitmap
font_file = open(filename, "rb")
first_four = font_file.read(4)
if filename.endswith("bdf") and first_four == b"STAR":
from . import bdf

return bdf.BDF(font_file, bitmap)
if filename.endswith("pcf") and first_four == b"\x01fcp":
from . import pcf

return pcf.PCF(font_file, bitmap)
if filename.endswith("ttf") and first_four == b"\x00\x01\x00\x00":
from . import ttf

return ttf.TTF(font_file, bitmap)

raise ValueError("Unknown magic number %r" % first_four)
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,7 +22,13 @@

"""

try:
from typing import Union, Optional
except ImportError:
pass

import gc
from fontio import Glyph

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Bitmap_Font.git"
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, set]) -> None:
"""Loads displayio.Glyph objects into the GlyphCache from the font."""

def get_glyph(self, code_point):
def get_glyph(self, code_point: int) -> Optional[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,12 +22,18 @@

"""

try:
from typing import Union, Generator
except ImportError:
pass

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

from fontio import Glyph
from displayio import Bitmap as displayioBitmap
from .glyph_cache import GlyphCache

try:
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:
"""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: dict) -> 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) -> Generator[tuple, None, None]:
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, set]) -> 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
7 changes: 4 additions & 3 deletions adafruit_bitmap_font/ttf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@
# Remove the above when TTF is actually supported.

import struct

from io import FileIO
from displayio import Bitmap

# 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
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# Uncomment the below if you use native CircuitPython modules such as
# digitalio, micropython and busio. List the modules you use. Without it, the
# autodoc module docs will fail to generate with a warning.
autodoc_mock_imports = ["fontio"]
autodoc_mock_imports = ["displayio", "fontio"]


intersphinx_mapping = {
Expand Down