kopia lustrzana https://github.com/peterhinch/micropython-font-to-py
Document handling of bitmapped font files.
rodzic
0b253aa68a
commit
4e07ed605b
|
@ -1,15 +1,20 @@
|
|||
# font_to_py.py
|
||||
# 1. font_to_py.py
|
||||
|
||||
Convert a font file to Python source code. Python font files provide a much
|
||||
faster way to access glyphs than the principal alternative which is a random
|
||||
access file on the filesystem.
|
||||
This PC utility converts an industry standard font file to Python source code.
|
||||
|
||||
Another benefit is that they can save large amounts of RAM on resource-limited
|
||||
targets: the font file may be incorporated into a firmware build such that it
|
||||
occupies flash memory rather than scarce RAM. Python code built into firmware
|
||||
is known as frozen bytecode.
|
||||
Python font files offer advantages on microcontroller platforms running
|
||||
MicroPython. They provide a much faster way to render glyphs than the principal
|
||||
alternative which is a random access binary file on the filesystem.
|
||||
|
||||
## Recent revisions
|
||||
The format of the Python font file is designed to save large amounts of RAM on
|
||||
resource-limited targets: the font file may be incorporated into a firmware
|
||||
build such that it occupies flash memory rather than scarce RAM. Python code
|
||||
built into firmware is known as frozen bytecode.
|
||||
|
||||
## 1.1 Recent revisions
|
||||
|
||||
1 Feb 2021 V0.4 With thanks to @enigmaniac for the suggestion and code ideas.
|
||||
1. Now supports `bdf` and `pcf` font files for better results at small sizes.
|
||||
|
||||
17 Oct 2019 V0.33 With thanks to Stephen Irons (@ironss).
|
||||
1. Fix bug where input rather than output filename was checked.
|
||||
|
@ -32,7 +37,7 @@ API is unchanged.
|
|||
|
||||
###### [Main README](./README.md)
|
||||
|
||||
# Dependencies
|
||||
# 2. Dependencies
|
||||
|
||||
The utility requires Python 3.2 or greater, also `freetype` which may be
|
||||
installed using `pip3`. On Linux (you may need a root prompt):
|
||||
|
@ -42,13 +47,15 @@ installed using `pip3`. On Linux (you may need a root prompt):
|
|||
# pip3 install freetype-py
|
||||
```
|
||||
|
||||
# Usage
|
||||
# 3. Usage
|
||||
|
||||
`font_to_py.py` is a command line utility written in Python 3. It is run on a
|
||||
PC. It takes as input a font file with a `ttf` or `otf` extension and a
|
||||
required height in pixels and outputs a Python 3 source file. The pixel layout
|
||||
is determined by command arguments. By default fonts are stored in variable
|
||||
pitch form. This may be overidden by a command line argument.
|
||||
required height in pixels and outputs a Python 3 source file. Alternatively it
|
||||
will accept a `bdf` or `pcf` source file (which includes a height definition).
|
||||
The pixel layout is determined by command arguments. By default fonts are
|
||||
stored in variable pitch form. This may be overidden by a command line
|
||||
argument.
|
||||
|
||||
By default the printable ASCII character set (ordinal values 32 to 126
|
||||
inclusive) is supported (i.e. not including control characters). Command line
|
||||
|
@ -65,16 +72,18 @@ Examples of usage to produce Python fonts with a height of 23 pixels:
|
|||
$ font_to_py.py FreeSans.ttf 23 myfont.py
|
||||
$ font_to_py.py -k extended FreeSans.ttf 23 my_extended_font.py
|
||||
```
|
||||
## Arguments
|
||||
## 3.1 Arguments
|
||||
|
||||
### Mandatory positional arguments:
|
||||
### 3.1.1 Mandatory positional arguments:
|
||||
|
||||
1. Font file path. Must be a ttf or otf file.
|
||||
2. Height in pixels.
|
||||
2. Height in pixels. In the case of `bdf` or `pcf` files a height of 0 should
|
||||
be specified as the height is retrieved from the file.
|
||||
3. Output file path. Filename must have a .py extension (unless writing a
|
||||
binary font).
|
||||
binary font). A warning is output if the output filename does not have a .py
|
||||
extension as the creation of a binary font file may not be intended.
|
||||
|
||||
### Optional arguments:
|
||||
### 3.1.2 Optional arguments:
|
||||
|
||||
* -f or --fixed If specified, all characters will have the same width. By
|
||||
default fonts are assumed to be variable pitch.
|
||||
|
@ -121,29 +130,32 @@ pitch result. A better apearance would be achieved by using a font designed as
|
|||
monospaced.
|
||||
|
||||
There have been reports that producing fonts with Unicode characters outside
|
||||
the ASCII set from ttf files is unreliable. If expected results are not
|
||||
achieved, use an otf font. I have successfully created Cyrillic and extended
|
||||
the ASCII set from `ttf` files is unreliable. If expected results are not
|
||||
achieved, use an `otf` font. I have successfully created Cyrillic and extended
|
||||
fonts from a `ttf`, so I suspect the issue may be source fonts lacking the
|
||||
required glyphs.
|
||||
|
||||
The `-i` or `--iterate` argument. For specialist applications. Specifying this
|
||||
causes a generator function `glyphs` to be included in the Python font file. A
|
||||
generator instantiated with this will yield `bitmap`, `height`, and `width` for
|
||||
every glyph in the font.
|
||||
### 3.1.3 The -i or --iterate arg
|
||||
|
||||
### Output
|
||||
This is for specialist applications; it causes a generator function `glyphs` to
|
||||
be included in the Python font file. A generator instantiated with this will
|
||||
yield `bitmap`, `height`, and `width` for every glyph in the font.
|
||||
|
||||
The specified height is a target. The algorithm gets as close to the target
|
||||
height as possible (usually within one pixel). The actual height achieved is
|
||||
displayed on completion, along with the width of the widest character.
|
||||
### 3.1.4 The height arg
|
||||
|
||||
A warning is output if the output filename does not have a .py extension as the
|
||||
creation of a binary font file may not be intended.
|
||||
In the case of scalable `ttf` or `otf` source files the specified height is a
|
||||
target. The algorithm gets as close to the target height as possible (usually
|
||||
within one pixel). The actual height achieved is displayed on completion, along
|
||||
with the width of the widest character.
|
||||
|
||||
## The font file
|
||||
If a `bdf` or `pcf` bitmapped font is specified, the `height` arg should be 0.
|
||||
A nonzero value will cause a warning message to be printed and the value will
|
||||
be ignored.
|
||||
|
||||
## 3.2 The font file
|
||||
|
||||
Assume that the you have employed the utility to create a file `myfont.py`. In
|
||||
your code you will issue
|
||||
your code you will issue:
|
||||
|
||||
```python
|
||||
import myfont
|
||||
|
@ -154,9 +166,14 @@ to render strings on demand. A practical example may be studied
|
|||
[here](./writer/writer_demo.py).
|
||||
The detailed layout of the Python file may be seen [here](./writer/DRIVERS.md).
|
||||
|
||||
### Python font files
|
||||
# 4. Python font files
|
||||
|
||||
These start with a comment which is the command line used to create the font.
|
||||
Users of the `Writer` or `CWriter` classes or of
|
||||
[nano-gui](https://github.com/peterhinch/micropython-nano-gui) do not need to
|
||||
study the file format. These details are provided for those wishing to access
|
||||
Python font files directly.
|
||||
|
||||
Files start with a comment which is the command line used to create the font.
|
||||
|
||||
They include the following functions:
|
||||
1. `height()` Height of bitmaps in pixels (all are the same height).
|
||||
|
@ -177,7 +194,7 @@ They include the following functions:
|
|||
See [this link](https://stackoverflow.com/questions/27631736/meaning-of-top-ascent-baseline-descent-bottom-and-leading-in-androids-font)
|
||||
for an explanation of `baseline`.
|
||||
|
||||
### Binary font files
|
||||
# 5. Binary font files
|
||||
|
||||
There is an option to create a binary font file, specified with a `-b` or
|
||||
`--binary` command line argument. In this instance the output filename must
|
||||
|
@ -197,7 +214,7 @@ Only the following optional arguments are valid:
|
|||
* -x or --xmap.
|
||||
* -r or --reverse.
|
||||
|
||||
# Dependencies, links and licence
|
||||
# 6. Dependencies, links and licence
|
||||
|
||||
The code is released under the MIT licence. The `font_to_py.py` utility
|
||||
requires Python 3.2 or later.
|
||||
|
|
37
README.md
37
README.md
|
@ -4,9 +4,11 @@ This repository defines a method of creating and deploying fonts for use with
|
|||
MicroPython display drivers. A PC utility renders industry standard font files
|
||||
as a bitmap in the form of Python sourcecode. A MicroPython module enables such
|
||||
files to be displayed on devices with suitable device drivers. These include
|
||||
OLED displays using the SSD1306 chip and the official device driver.
|
||||
OLED displays using the SSD1306 chip and the official device driver. Compatible
|
||||
drivers for a variety of display technologies are available as part of the
|
||||
[nano-gui repository](https://github.com/peterhinch/micropython-nano-gui).
|
||||
|
||||
# Introduction
|
||||
# 1. Introduction
|
||||
|
||||
MicroPython platforms generally have limited RAM, but more abundant storage in
|
||||
the form of flash memory. Font files tend to be relatively large. The
|
||||
|
@ -29,7 +31,7 @@ The resultant file is usable with two varieties of display device drivers:
|
|||
2. Drivers for displays where the frame buffer is implemented in the display
|
||||
device hardware.
|
||||
|
||||
# Solution
|
||||
# 2. Solution
|
||||
|
||||
This comprises three components, links to docs below:
|
||||
|
||||
|
@ -41,12 +43,13 @@ This comprises three components, links to docs below:
|
|||
device drivers. Provides details of the font file format and information on
|
||||
ensuring comptibility with the `Writer` classes.
|
||||
|
||||
# font_to_py.py
|
||||
# 3. font_to_py.py
|
||||
|
||||
This command line utility is written in Python 3 and runs on a PC. It takes
|
||||
as input a font file in `ttf` or `otf` form together with a height in pixels
|
||||
and outputs a Python source file containing the font as a bitmap. Fixed and
|
||||
variable pitch rendering are supported. The design has the following aims:
|
||||
This command line utility is written in Python 3 and runs on a PC. To convert
|
||||
a scalable font to Python the utility takes input a font file in `ttf` or `otf`
|
||||
form together with a height in pixels and outputs a Python source file
|
||||
containing the font as a bitmap. Fixed and variable pitch rendering are
|
||||
supported. The design has the following aims:
|
||||
|
||||
* Independence of specific display hardware.
|
||||
* The path from font file to Python code to be fully open source.
|
||||
|
@ -58,24 +61,26 @@ The second is achieved by using Freetype and the Freetype Python bindings. Its
|
|||
use is documented [here](./FONT_TO_PY.md). This also details measurements of
|
||||
RAM usage when importing fonts stored as frozen bytecode.
|
||||
|
||||
# Limitations
|
||||
## 3.1 Small fonts
|
||||
|
||||
Converting scalable `ttf` or `otf` files programmatically works best for larger
|
||||
fonts. For small fonts it is best to use hand-designed bitmapped font files.
|
||||
These are now supported: `bdf` or `pcf` font files may be converted to Python
|
||||
source in the same format as files originating from scalable fonts.
|
||||
|
||||
## 3.2 Limitations
|
||||
|
||||
Kerning is not supported. Fonts are one bit per pixel. Colour displays are
|
||||
supported by the `CWriter` class which adds colour information at the rendering
|
||||
stage. This assumes that all pixels of a character are coloured identically.
|
||||
|
||||
Converting font files programmatically works best for larger fonts. For small
|
||||
fonts, like the 8*8 default used by the SSD1306 driver, it is best to use
|
||||
hand-designed binary font files: these are optiised for rendering at a specific
|
||||
size.
|
||||
|
||||
By default the `font_to_py.py` utility produces the ASCII character set from
|
||||
`chr(32)` to `chr(126)` inclusive. Command line options enable the character
|
||||
set to be modified to include arbitrary Unicode characters. Alternative sets
|
||||
may be specified such as for non-English languages. Efficient support is now
|
||||
provided for sparse character sets.
|
||||
|
||||
# Font file interface
|
||||
# 4. Font file interface
|
||||
|
||||
A font file is imported in the usual way e.g. `import font14`. Python font
|
||||
files contain the following functions. These return values defined by the
|
||||
|
@ -103,6 +108,6 @@ The `font_to_py.py` utility allows a default glyph to be specified (typically
|
|||
The `min_ch` and `max_ch` functions are mainly relevant to contiguous character
|
||||
sets.
|
||||
|
||||
# Licence
|
||||
# 5. Licence
|
||||
|
||||
All code is released under the MIT licence.
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
|
||||
# Some code adapted from Daniel Bader's work at the following URL
|
||||
# http://dbader.org/blog/monochrome-font-rendering-with-freetype-and-python
|
||||
# With thanks to Stephen Irons @ironss for various improvements.
|
||||
# With thanks to Stephen Irons @ironss for various improvements, also to
|
||||
# @enigmaniac for ideas around handling `bdf` and `pcf` files.
|
||||
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2016-2019 Peter Hinch
|
||||
# Copyright (c) 2016-2021 Peter Hinch
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -46,7 +47,7 @@ MAXCHAR = 126 # 94 chars
|
|||
|
||||
# Lines are broken with \ for readability.
|
||||
|
||||
class ByteWriter(object):
|
||||
class ByteWriter:
|
||||
bytes_per_line = 16
|
||||
|
||||
def __init__(self, stream, varname):
|
||||
|
@ -92,7 +93,7 @@ def var_write(stream, name, value):
|
|||
# FONT HANDLING
|
||||
|
||||
|
||||
class Bitmap(object):
|
||||
class Bitmap:
|
||||
"""
|
||||
A 2D bitmap image represented as a list of byte values. Each byte indicates
|
||||
the state of a single pixel in the bitmap. A value of 0 indicates that the
|
||||
|
@ -166,7 +167,7 @@ class Bitmap(object):
|
|||
row += 1
|
||||
|
||||
|
||||
class Glyph(object):
|
||||
class Glyph:
|
||||
def __init__(self, pixels, width, height, top, left, advance_width):
|
||||
self.bitmap = Bitmap(width, height, pixels)
|
||||
|
||||
|
@ -495,7 +496,6 @@ def write_func(stream, name, arg):
|
|||
|
||||
def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar,
|
||||
maxchar, defchar, charset, iterate, bitmapped):
|
||||
# fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset, bitmapped)
|
||||
try:
|
||||
fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset, bitmapped)
|
||||
except freetype.ft_errors.FT_Exception:
|
||||
|
@ -576,8 +576,8 @@ def quit(msg):
|
|||
print(msg)
|
||||
sys.exit(1)
|
||||
|
||||
DESC = """font_to_py.py
|
||||
Utility to convert ttf or otf font files to Python source.
|
||||
DESC = """font_to_py.py V0.4.0
|
||||
Utility to convert ttf, otf, bdf and pcf font files to Python source.
|
||||
Sample usage:
|
||||
font_to_py.py FreeSans.ttf 23 freesans.py
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# V0.35 Sept 2020 Fast rendering option for color displays
|
||||
|
||||
# Released under the MIT License (MIT). See LICENSE.
|
||||
# Copyright (c) 2019-2020 Peter Hinch
|
||||
# Copyright (c) 2019-2021 Peter Hinch
|
||||
|
||||
# A Writer supports rendering text to a Display instance in a given font.
|
||||
# Multiple Writer instances may be created, each rendering a font to the
|
||||
|
|
Ładowanie…
Reference in New Issue