API Reference¶
Read, manipulate and write bitmap fonts in the Bitmap Distribution Format.
To get started, use bdflib.reader.read_bdf()
to load a BDF file and
create a bdflib.model.Font
object, or just create one yourself from
scratch.
Modify the font by tinkering with it directly, or by using the helpers in
bdflib.effects
and bdflib.glyph_combining
.
When you’re done, you can use bdflib.writer.write_bdf()
to write your
font back out to a BDF file.
bdflib.model
¶
Classes that represent a bitmap font, with its glyphs and metadata.
-
class
bdflib.model.
Font
(name, ptSize, xdpi, ydpi)[source]¶ Bases:
object
Represents the entire font and font-global properties.
Parameters: Instances of this class can be used like
dict
instances.bytes
keys refer to the font’s properties and are associated withbytes
instances, whileint
keys refer to the code-points the font supports, and are associated withGlyph
instances.>>> myfont = Font( ... b"My Font", ... ptSize=12, ... xdpi=96, ... ydpi=96, ... ) >>> myfont[b"POINT_SIZE"] 12 >>> a_glyph = myfont.new_glyph_from_data( ... "capital A", ... codepoint=65, ... ) >>> a_glyph == myfont[65] True
Note
Some properties (the name, point-size and resolutions) are required, and although they can be examined via the
dict
interface, they cannot be removed with thedel
statement.-
add_comment
(comment)[source]¶ Add one or more lines of text to the font’s comment field.
Parameters: comment (bytes) – Human-readable text to add to the comment, ASCII encoded. It may include newline characters. The added text will begin on a new line.
-
codepoints
()[source]¶ Returns the codepoints that this font has glyphs for.
These codepoints can be used with the regular dict syntax to retrieve the associated glyphs
Returns: Supported codepoints Return type: iterable of Glyph
-
copy
()[source]¶ Returns a deep copy of this font.
The new font, along with all of its properties and glyphs, may be modified without affecting this font.
Returns: A new, independent copy of this Font Return type: Font
-
get_comments
()[source]¶ Retrieve the lines of the font’s comment field.
Returns: The comment text, ASCII encoded. Return type: list
ofbytes
-
glyphs
= []¶ (iterable of
Glyph
) All the glyphs in this font, even the ones with no associated codepoint.
-
new_glyph_from_data
(name, data=None, bbX=0, bbY=0, bbW=0, bbH=0, advance=0, codepoint=None)[source]¶ Add a new
Glyph
to this font.This method’s arguments are passed to the
Glyph
constructor.If you include the
codepoint
parameter, the codepoint will be included in the result ofcodepoints()
and you will be able to look up the glyph by codepoint later. Otherwise, it will only be available via theglyphs
property.Returns: the newly-created Glyph Return type: Glyph
Raises: GlyphExists – if an existing glyph is already associated with the requested codepoint.
-
-
class
bdflib.model.
Glyph
(name, data=None, bbX=0, bbY=0, bbW=0, bbH=0, advance=0, codepoint=None)[source]¶ Bases:
object
Represents a font glyph and associated properties.
Parameters: - name (bytes) – The name of this glyph, ASCII encoded.
- data (iterable of
bytes
) – the bitmap data for the glyph, as ASCII encoded hexadecimal digits. - bbX (int) – The left-most edge of the glyph’s bounding box, in pixels.
- bbY (int) – The bottom-most edge of the glyph’s bounding box, in pixels.
- bbW (int) – The glyph’s bounding-box extends this many pixels right of
bbX
(must be >= 0). - bbH (int) – The glyph’s bounding-box extends this many pixels upward
from
bbY
(must be >= 0). - advance (int) – After drawing this glyph, the next glyph will be drawn this many pixels to the right.
- codepoint (int) – The Unicode codepoint that this glyph represents.
The glyph bitmap data is an iterable of
bytes
, where the first item represents the top row of pixels, the next item represents the next row of pixels, and so forth. There should bebbH
items in total. Each item is one or more hexadecimal digits representing the pixels of that row: the first digit represents the leftmost four pixels (most significant bit to the left), the next digit represents the next four pixels, and so forth. IfbbW
is not an integer multiple of 4, the row should be padded with 0 bits.For example, let’s say we want to render a capital A, like so:
.###. #...# ##### #...#
We encode that pattern in binary, pad to a multiple of four bits, and convert to hexadecimal:
>>> raw_data = [ ... 0b01110000, ... 0b10001000, ... 0b11111000, ... 0b10001000, ... ] >>> for each in raw_data: ... print("{:X}".format(each)) 70 88 F8 88
Therefore, to create a glyph representing that image:
>>> my_glyph = Glyph( ... name=b"capital A", ... data=[b'70', b'88', b'F8', b'88'], ... bbW=5, ... bbH=4, ... advance=6, ... codepoint=65, ... )
To aid debugging, the
Glyph
class has a__str__
method that renders the glyph on a grid, with the glyph origin marked:>>> print(my_glyph) |###. #...# ##### #---#
The glyph origin isn’t actually visible because it’s underneath the lower left corner of the glyph, but you can see the X axis across the bottom and the Y axis up the left.
-
data
¶ (
list
ofint
) Glyph bitmap data.Unlike the format passed to the constructor and returned from
get_data()
, this uses a more Python-friendly format:>>> my_glyph = Glyph( ... name=b"capital A", ... data=[b'70', b'88', b'F8', b'88'], ... bbW=5, ... bbH=4, ... ) >>> for row in my_glyph.data: ... print("{:05b}".format(row)) 10001 11111 10001 01110
Each item of the
.data
property is aint
bbW bits wide, representing the pixels of a single row. The first item in.data
is the lowest row in the glyph, so that list indices increase in the same direction as pixel coordinates.If you want to get the actual coordinates of the glyph’s drawn pixels (for example, to draw the glyph onto an image), the easiest way is to use a loop like this:
ink_coords = [ (x, y) for x in range(my_glyph.bbW) for y in range(my_glyph.bbH) if my_glyph.data[y] & (1 << (my_glyph.bbW - x - 1) ]
You might also want to look at
iter_pixels()
.
-
get_ascent
()[source]¶ Returns the distance from the Y axis to the highest point of the glyph.
This is zero if no part of the glyph is above the Y axis.
Returns: The ascent of this glyph. Return type: int
-
get_bounding_box
()[source]¶ Returns the position and dimensions of the glyph’s bounding box.
Returns: The left, bottom, width and height of the bounding box, as passed to the constructor. Return type: tuple
ofint
,int
,int
,int
-
get_data
()[source]¶ Returns the glyph’s bitmap data.
This may use a different amount of padding than the value originally passed to the constructor, and hexadecimal digits may be upper-case instead of lower-case, but the meaning should be the same.
See also the
iter_pixels()
method, which gives you abool
for each pixel, and the underlying storage in thedata
property.Returns: Hex-encoded bitmap data Return type: list
ofbytes
-
get_descent
()[source]¶ Returns the distance from the Y axis to the lowest point of the glyph.
This is zero if no part of the glyph is below the Y axis.
Returns: The descent of this glyph. Return type: int
-
iter_pixels
()[source]¶ Yields the state of pixels within the bounding box.
This method returns an iterable of
bbH
rows, from the top of the glyph (large X values) to the bottom (small X values). Each row is an iterable ofbbW
booleans, from left to right. Each boolean isTrue
if that pixel should be drawn, and otherwiseFalse
.Alternatively, you can obtain the glyph data in BDF format with
get_data()
, or access the raw bitmap via thedata
property.Returns: the state of each pixel Return type: iterable of iterable of bool
bdflib.reader
¶
-
bdflib.reader.
read_bdf
(raw_iterable)[source]¶ Read a BDF-format font from the given source.
Parameters: raw_iterable (iterable of bytes
) – Each item should be a single line of the BDF file, ASCII encoded.Returns: the resulting font object Return type: Font
If you want to read an actual file, make sure you use the ‘b’ flag so you get bytes instead of text:
font = bdflib.reader.read_bdf(open(path, 'rb'))
bdflib.writer
¶
-
bdflib.writer.
write_bdf
(font, stream)[source]¶ Write a BDF-format font to the given stream.
Parameters: - font (Font) – The font to write to the given stream.
- stream – The stream that will receive the font.
stream
must be an object with at.write()
method that takes abytes
. If you want to write to an actual file, make sure you use the ‘b’ flag:bdflib.writer.write_bdf(font, open(path, 'wb'))
bdflib.effects
¶
Automatically generate visual variants of a font.
-
bdflib.effects.
embolden
(font, maintain_spacing=True)[source]¶ Create a bold version of a font by widening each glyph.
Parameters: Returns: A copy of
font
, with each glyph emboldened.Return type: To embolden a glyph, it is drawn over itself one pixel to the right, making each vertical stroke one pixel wider.
-
bdflib.effects.
merge
(base, custom)[source]¶ Create a new font by choosing glyphs from two other fonts.
Parameters: Returns: A font where each glyph comes from
base
orcustom
.For any given codepoint, the resulting font will use the corresponding glyph from
custom
if there is one, falling back to the glyph frombase
. The new font’s properties and other metadata are all copied fromcustom
.
bdflib.glyph_combining
¶
Tools for building glyphs by combining other glyphs.
Unicode has a lot of “pre-combined” code-points that are the combination of a normal code-point and a combining code-point, like how U+014D LATIN SMALL LETTER O WITH MACRON is the combination of U+006F LATIN SMALL LETTER O with U+0304 COMBINING MACRON. Given glyphs for their individual components, glyphs for pre-combined code-points can be automatically generated.
An example of using this module to generate pre-combined glyphs:
decompositions = build_unicode_decompositions()
filler = FontFiller(myfont, decompositions)
filler.add_decomposable_glyphs_to_font()
-
class
bdflib.glyph_combining.
FontFiller
(font, decompositions)[source]¶ Bases:
object
Build pre-combined glyphs from available component glyphs.
Parameters: - font (Font) – Any pre-combined glyphs will be added to this font.
- decompositions – A dict mapping pre-combined characters to their
components, as returned by
build_unicode_decompositions()
.
Call
add_decomposable_glyphs_to_font()
on an instance of this class to add as many pre-combined glyphs as possible.-
add_decomposable_glyphs_to_font
()[source]¶ Adds all the glyphs that can be built to the given font.
This calls
add_glyph_to_font()
for each key in the decompositions passed to the class constructor.
-
add_glyph_to_font
(char)[source]¶ Add the glyph representing char to the given font, if it can be built.
Parameters: char (unicode) – A single-codepoint Unicode string, whose glyph should be generated (if possible) and added to the font passed to the class constructor. Returns: True
if the font now contains a glyph for that character,False
otherwise.This method may return
True
if a glyph was generated, or if the font already contained the required glyph.This method may return
False
if:- the decompositions passed to the class constructor do not include any components for
char
- the font passed to the class constructor is missing glyphs for one or more of
char
’s components, and they could not be generated - one of
char
’s components uses a combining class this code doesn’t understand
- the decompositions passed to the class constructor do not include any components for
-
bdflib.glyph_combining.
build_unicode_decompositions
()[source]¶ Returns a dictionary mapping unicode characters to their components.
Returns: a mapping from pre-combined characters to their components. Return type: dict
mappingunicode
tolist
oftuple
ofunicode
,int
Each key in the resulting dict is a single-character Unicode string, and each value is a list of single-character Unicode strings and their combining classes, the components of the key. For example, one of the items in the result should be:
u"\N{LATIN SMALL LETTER O WITH MACRON}": [ (u"o", 0), (u"\N{COMBINING MACRON}", 230), ]
(where 0 indicates a regular base character, and 230 means the glyph is drawn above the base glyph. See https://www.unicode.org/reports/tr44/#Canonical_Combining_Class_Values for details.)
This function obtains information about combining characters from Python’s
unicodedata
standard library module. It also properly handles “soft-dotted” characters “i” and “j” where pre-combined glyphs should be built from the dotless versions of those characters.