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
.
If you’re making a font intended for use with the X11 windowing system,
check out the helpers in bdflib.xlfd
.
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: bytes, ptSize: int, xdpi: int, ydpi: int)[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.ptSize 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
= None¶ All the glyphs in this font, even the ones with no associated codepoint.
-
name
= b''¶ The value of the FONT field in the BDF file
-
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.
-
property_names
()[source]¶ Returns the names of this font’s properties.
These names can be used with the regular dict syntax to retrieve the associated value.
Returns: Property names Return type: iterable of bytes
-
ptSize
= None¶ The font’s nominal size in PostScript points (1/72 of an inch), the first value in the SIZE field in the BDF file
-
xdpi
= None¶ The font’s horizontal resolution in dots-per-inch, the second value in the SIZE field in the BDF file
-
ydpi
= None¶ The font’s vertical resolution in dots-per-inch, the third value in the SIZE field in the BDF file
-
-
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 (
None
or iterable ofint
) – If provided, gives the initial bitmap for the glyph, see thedata
attribute below. - 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). If data is provided, each integer should be at most this many bits wide. - bbH (int) – The glyph’s bounding-box extends this many pixels upward
from
bbY
(must be >= 0). If data is provided, it should yield this many rows. - 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.
-
data
¶ (
list
ofint
) Glyph bitmap data.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.>>> my_glyph = Glyph( ... name=b"capital A", ... data=[ ... 0b10001, ... 0b11111, ... 0b10001, ... 0b01110, ... ], ... bbW=5, ... bbH=4, ... ) >>> for row in reversed(my_glyph.data): ... print("{:05b}".format(row)) 01110 10001 11111 10001
If you want to get the actual coordinates of the glyph’s drawn pixels, look at the
iter_pixels()
method.
-
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_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.-
missing_chars
¶ (
collections.Counter
) After callingadd_decomposable_glyphs_to_font()
, this attribute will record characters that could be used in combining sequences, but were missing from the input font. Adding the character with the highest count to the font will give you the biggest increase in Unicode coverage.
-
unknown_classes
¶ (
collections.Counter
) After calingadd_decomposable_glyphs_to_font()
, this attribute will record Unicode combining classes included in the decompositions paramater that bdflib does not yet support. If bdflib were extended to support these Unicode combining classes, we might be able to use them to create new glyphs.
-
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.
bdflib.xlfd
¶
Check fonts against the X Logical Font Descriptor conventions.
Fonts in the BDF format can be used for all kinds of things, but commonly they are used with the traditional X11 font APIs, built around X Logical Font Descriptors, which require certain custom properties be set.
To check a BDF font against the XLFD conventions,
use validate()
,
which returns a (hopefully empty) list of problems,
represented as subclasses of ValidationError
.
If the font is missing properties that can be automatically calculated,
fix()
will update the font as required.
For more information about these issues, see the official X Logical Font Description Conventions specification.
Helpful constants¶
Names for XLFD properties:
-
bdflib.xlfd.
FOUNDRY
¶ The organisation responsible for making the font, a namespace for
FAMILY_NAME
-
bdflib.xlfd.
FAMILY_NAME
¶ The human-readable name of the font, like “Times New” or “Helvetica”
-
bdflib.xlfd.
WEIGHT_NAME
¶ The human-readable name of the font’s weight, like “Bold” or “Thin”
-
bdflib.xlfd.
SLANT
¶ A code describing the slant style of the font, one of the values in
SLANT_VALUES
-
bdflib.xlfd.
SETWIDTH_NAME
¶ The human-reaadable name of the font’s width, like “Expanded” or “Ultracondensed”
-
bdflib.xlfd.
ADD_STYLE_NAME
¶ A human-readable name that further distinguishes this font from other similar fonts; an “additional style” if you will, like “Sans Serif” or “Outline”
-
bdflib.xlfd.
PIXEL_SIZE
¶ The vertical space required for a line of type, in pixels, usually (but not always) the sum of
FONT_ASCENT
andFONT_DESCENT
-
bdflib.xlfd.
POINT_SIZE
¶ The vertical space required for a line of type, in deci-points
-
bdflib.xlfd.
RESOLUTION_X
¶ The horizontal output resolution this font is intended for, in dots-per-inch
-
bdflib.xlfd.
RESOLUTION_Y
¶ The horizontal output resolution this font is intended for, in dots-per-inch
-
bdflib.xlfd.
SPACING
¶ A code describing the spacing of this font, one of the values in
SPACING_VALUES
below
-
bdflib.xlfd.
AVERAGE_WIDTH
¶ The average width of all the characters in this font, in deci-pixels.
-
bdflib.xlfd.
CHARSET_REGISTRY
¶ The organisation responsible for defining the character set encoding used by this font, a namespace for
CHARSET_ENCODING
-
bdflib.xlfd.
CHARSET_ENCODING
¶ The identifier for the character set encoding used by this font
-
bdflib.xlfd.
FONT_ASCENT
¶ The maxium height above the baseline that any glyph in this font touches, in pixels
-
bdflib.xlfd.
FONT_DESCENT
¶ The maxium depth below the baseline that any glyph in this font touches, in pixels
-
bdflib.xlfd.
DEFAULT_CHAR
¶ If the software using this font wants to draw a glyph that the font does not contain, the glyph with this encoding will be drawn instead
Values for the SLANT
property:
-
bdflib.xlfd.
SLANT_ROMAN
¶ This font is drawn with upright strokes
-
bdflib.xlfd.
SLANT_ITALIC
¶ This font is drawn leaning forward, often with curves or flourishes
-
bdflib.xlfd.
SLANT_OBLIQUE
¶ This font is the Roman variant, tilted forward
-
bdflib.xlfd.
SLANT_REVERSE_ITALIC
¶ This font is drawn leaning backward, often with curves or flourishes
-
bdflib.xlfd.
SLANT_REVERSE_OBLIQUE
¶ This font is the Roman variant, tilted backward
-
bdflib.xlfd.
SLANT_OTHER
¶ This font has a tilt that’s not any of the above
Values for the SPACING
property:
-
bdflib.xlfd.
SPACING_PROPORTIONAL
¶ Each glyph in this font takes space proportional to its natural width, so a character like “i” is narrow while “m” is wide
-
bdflib.xlfd.
SPACING_MONOSPACED
¶ Each glyph in this font takes exactly the same space, regardless of its natural width
-
bdflib.xlfd.
SPACING_CHARCELL
¶ Like
SPACING_MONOSPACED
, but in addition, no part of any glyph sticks out of the space allocated to it
Classes and functions¶
-
exception
bdflib.xlfd.
Contradiction
(name: bytes, prop_value: Union[bytes, int], xlfd_value: Union[bytes, int])[source]¶ Bases:
bdflib.xlfd.ValidationError
A value in the XLFD name contradicts a BDF property value
-
name
= None¶ The property name with conflicting values
-
prop_value
= None¶ The value associated with the BDF property
-
xlfd_value
= None¶ The value stored in the XLFD name
-
-
exception
bdflib.xlfd.
ExpectedBytestring
(name: bytes, value: int)[source]¶ Bases:
bdflib.xlfd.ValidationError
The value of a property should be a bytestring
-
name
= None¶ The name of the property whose value should be a bytestring
-
value
= None¶ The value that is not a bytestring
-
-
exception
bdflib.xlfd.
ExpectedEnumeratedValue
(name: bytes, value: Union[bytes, int], expected: Set[bytes])[source]¶ Bases:
bdflib.xlfd.ValidationError
The value of a property should be one of a fixed set of values
-
expected
= None¶ The set of possible values
-
name
= None¶ The name of the property with an invalid value
-
value
= None¶ The value that is not in the expected set
-
-
exception
bdflib.xlfd.
ExpectedInteger
(name: bytes, value: bytes)[source]¶ Bases:
bdflib.xlfd.ValidationError
The value of a property should be an integer
-
name
= None¶ The name of the property whose value should be an integer
-
value
= None¶ The value that is not an integer
-
-
exception
bdflib.xlfd.
MissingProperty
[source]¶ Bases:
bdflib.xlfd.ValidationError
The font is missing a property required by the XLFD conventions
-
exception
bdflib.xlfd.
NotAnXlfd
[source]¶ Bases:
bdflib.xlfd.ValidationError
The font’s name is not a valid XLFD string
-
exception
bdflib.xlfd.
ValidationError
[source]¶ Bases:
ValueError
Superclass of all problems detected by
validate()
-
bdflib.xlfd.
fix
(font: bdflib.model.Font) → None[source]¶ Add missing XLFD properties to a font, with default or calculated values
Any properties already present will be preserved, even if their values seem to be incorrect.
-
bdflib.xlfd.
validate
(font: bdflib.model.Font) → List[bdflib.xlfd.ValidationError][source]¶ Validate a font against the XLFD conventions
This function checks for missing, required properties, properties with the wrong type, the syntax of the font’s XLFD name and conflicts between the XLFD name and its properties.
All problems detected (not just the first) are returned in a list.