1
0
mirror of https://gitlab.com/MisterBiggs/bdfparse.git synced 2025-06-16 14:36:40 +00:00

Compare commits

..

13 Commits

Author SHA1 Message Date
0e82fef264 update repo address 2019-07-18 19:47:20 -07:00
5eefdb3ce1 updated char list 2019-07-18 19:46:37 -07:00
4eeaecf193 added more characters 2019-07-18 17:42:07 -07:00
65e188c764 Added more chars for word function 2019-07-18 14:27:19 -07:00
a49ce715cc Finally got package working 2019-07-17 00:25:08 -07:00
83c3284e91 updating again 2019-07-16 21:08:57 -07:00
217ff46bd7 added more chars to word function 2019-07-16 21:07:14 -07:00
295c9207a5 updated docs for new version 2019-07-16 20:12:48 -07:00
7df856e3d6 renaming package 2019-07-16 19:46:59 -07:00
7c587789ec init can just be an empty file 2019-07-16 19:46:03 -07:00
77f1ac9696 Fixed name in copyright 2019-07-16 19:38:56 -07:00
7c82d87248 updated to new version 2019-07-16 19:25:45 -07:00
7ff36f34eb changed code to classes 2019-07-16 19:22:40 -07:00
6 changed files with 269 additions and 195 deletions

View File

@ -5,20 +5,42 @@ This project takes a .bdf file and turns it into a [NumPy](https://www.numpy.org
## Usage
```python
import numpy as np
import matplotlib.pyplot as plt
from bdfparse import Font
font = parse_chars("9x18.bdf")
matrix = font["A"]
text = "nson"
font = Font('9x18.bdf')
for letter in text:
matrix = np.concatenate((matrix, font[letter]), axis=1)
plt.imshow(matrix)
plt.show()
print(font.word('Hi'))
```
Which outputs:
```python
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0]
[0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0]
[0 0 1 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
```
Or you can use matplotlib to make the output a bit prettier.
```python
import matplotlib.pyplot as plt
plt.imshow(font.word('Anson'))
```
![Example of code output that reads Anson.](example.png)

View File

@ -1 +0,0 @@
name = "bdf_to_numpy"

View File

@ -1,180 +0,0 @@
import numpy as np
import matplotlib.pyplot as plt
def parse_properties(bdfFile):
properties = {"COMMENT": []}
with open(bdfFile, "r") as bdf:
line = bdf.readline()
while not line.startswith("STARTCHAR"):
if line.startswith("COMMENT"):
properties["COMMENT"].append(
line.replace("COMMENT", "").replace("\n", "")
)
if line.startswith("FONT"):
properties["FONT"] = line.replace("FONT", "").replace("\n", "")
if line.startswith("SIZE"):
properties["SIZE"] = line.replace("SIZE", "").replace("\n", "")
if line.startswith("FONTBOUNDINGBOX"):
properties["FONTBOUNDINGBOX"] = [
int(x)
for x in (
line.replace("FONTBOUNDINGBOX ", "").replace("\n", "").split()
)
]
if line.startswith("STARTPROPERTIES"):
properties["STARTPROPERTIES"] = line.replace(
"STARTPROPERTIES", ""
).replace("\n", "")
if line.startswith("FONTNAME_REGISTRY"):
properties["FONTNAME_REGISTRY"] = line.replace(
"FONTNAME_REGISTRY", ""
).replace("\n", "")
if line.startswith("FOUNDRY"):
properties["FOUNDRY"] = line.replace("FOUNDRY", "").replace("\n", "")
if line.startswith("FAMILY_NAME"):
properties["FAMILY_NAME"] = line.replace("FAMILY_NAME", "").replace(
"\n", ""
)
if line.startswith("WEIGHT_NAME"):
properties["WEIGHT_NAME"] = line.replace("WEIGHT_NAME", "").replace(
"\n", ""
)
if line.startswith("SLANT"):
properties["SLANT"] = line.replace("SLANT", "").replace("\n", "")
if line.startswith("SETWIDTH_NAME"):
properties["SETWIDTH_NAME"] = line.replace("SETWIDTH_NAME", "").replace(
"\n", ""
)
if line.startswith("ADD_STYLE_NAME"):
properties["ADD_STYLE_NAME"] = line.replace(
"ADD_STYLE_NAME", ""
).replace("\n", "")
if line.startswith("PIXEL_SIZE"):
properties["PIXEL_SIZE"] = line.replace("PIXEL_SIZE", "").replace(
"\n", ""
)
if line.startswith("POINT_SIZE"):
properties["POINT_SIZE"] = line.replace("POINT_SIZE", "").replace(
"\n", ""
)
if line.startswith("RESOLUTION_X"):
properties["RESOLUTION_X"] = line.replace("RESOLUTION_X", "").replace(
"\n", ""
)
if line.startswith("RESOLUTION_Y"):
properties["RESOLUTION_Y"] = line.replace("RESOLUTION_Y", "").replace(
"\n", ""
)
if line.startswith("SPACING"):
properties["SPACING"] = line.replace("SPACING", "").replace("\n", "")
if line.startswith("AVERAGE_WIDTH"):
properties["AVERAGE_WIDTH"] = line.replace("AVERAGE_WIDTH", "").replace(
"\n", ""
)
if line.startswith("CHARSET_REGISTRY"):
properties["CHARSET_REGISTRY"] = line.replace(
"CHARSET_REGISTRY", ""
).replace("\n", "")
if line.startswith("CHARSET_ENCODING"):
properties["CHARSET_ENCODING"] = line.replace(
"CHARSET_ENCODING", ""
).replace("\n", "")
if line.startswith("DEFAULT_CHAR"):
properties["DEFAULT_CHAR"] = line.replace("DEFAULT_CHAR", "").replace(
"\n", ""
)
if line.startswith("FONT_DESCENT"):
properties["FONT_DESCENT"] = line.replace("FONT_DESCENT", "").replace(
"\n", ""
)
if line.startswith("FONT_ASCENT"):
properties["FONT_ASCENT"] = line.replace("FONT_ASCENT", "").replace(
"\n", ""
)
if line.startswith("COPYRIGHT"):
properties["COPYRIGHT"] = line.replace("COPYRIGHT", "").replace(
"\n", ""
)
if line.startswith("CAP_HEIGHT"):
properties["CAP_HEIGHT"] = line.replace("CAP_HEIGHT", "").replace(
"\n", ""
)
if line.startswith("X_HEIGHT"):
properties["X_HEIGHT"] = line.replace("X_HEIGHT", "").replace("\n", "")
if line.startswith("_GBDFED_INFO"):
properties["_GBDFED_INFO"] = line.replace("_GBDFED_INFO", "").replace(
"\n", ""
)
line = bdf.readline()
return properties
def from_hex(values, columns):
return np.array(
[list(f"{int(row[:2], 16):0>{columns}b}") for row in values.split("\n")],
dtype=int,
)
def parse_chars(bdfFile):
font = {}
props = parse_properties(bdfFile)
cols = props["FONTBOUNDINGBOX"][0]
rows = props["FONTBOUNDINGBOX"][1]
with open(bdfFile, "r") as bdf:
line = bdf.readline()
# Go through file until chars start.
while not line.startswith("CHARS "):
line = bdf.readline()
characters = int(line.split(" ")[1])
for character in range(characters):
line = bdf.readline()
char = line.split(" ")[1].replace("\n", "")
while not line.startswith("BITMAP"):
line = bdf.readline()
bits = ""
for row in range(rows):
bits += bdf.readline()
font[char] = from_hex(bits.strip(), cols)
if bdf.readline().startswith("ENDFONT"):
return font
return font

1
bdfparse/__init__.py Normal file
View File

@ -0,0 +1 @@
from .bdfparse import Font

232
bdfparse/bdfparse.py Normal file
View File

@ -0,0 +1,232 @@
import numpy as np
class Font:
def __init__(self, bdfFile):
self.properties = self.parse_properties(bdfFile)
self.chars = self.parse_chars(bdfFile)
self.cols = self.properties["FONTBOUNDINGBOX"][0]
self.rows = self.properties["FONTBOUNDINGBOX"][1]
self.shape = (self.rows, self.cols)
self.charNames = {
" ": "space",
"-": "minus",
"+": "plus",
"0": "zero",
"1": "one",
"2": "two",
"3": "three",
"4": "four",
"5": "five",
"6": "six",
"7": "seven",
"8": "eight",
"9": "nine",
"!": "exclam",
"@": "at",
"#": "numbersign",
"$": "dollar",
"%": "percent",
"&": "ampersand",
"*": "asterisk",
"(": "parenleft",
")": "parenright",
",": "comma",
".": "period",
"/": "slash",
"?": "question",
}
def parse_properties(self, bdfFile):
properties = {"COMMENT": []}
with open(bdfFile, "r") as bdf:
line = bdf.readline()
while not line.startswith("STARTCHAR"):
if line.startswith("COMMENT"):
properties["COMMENT"].append(
line.replace("COMMENT", "").replace("\n", "")
)
if line.startswith("FONT"):
properties["FONT"] = line.replace("FONT", "").replace("\n", "")
if line.startswith("SIZE"):
properties["SIZE"] = line.replace("SIZE", "").replace("\n", "")
if line.startswith("FONTBOUNDINGBOX"):
properties["FONTBOUNDINGBOX"] = [
int(x)
for x in (
line.replace("FONTBOUNDINGBOX ", "")
.replace("\n", "")
.split()
)
]
if line.startswith("STARTPROPERTIES"):
properties["STARTPROPERTIES"] = line.replace(
"STARTPROPERTIES", ""
).replace("\n", "")
if line.startswith("FONTNAME_REGISTRY"):
properties["FONTNAME_REGISTRY"] = line.replace(
"FONTNAME_REGISTRY", ""
).replace("\n", "")
if line.startswith("FOUNDRY"):
properties["FOUNDRY"] = line.replace("FOUNDRY", "").replace(
"\n", ""
)
if line.startswith("FAMILY_NAME"):
properties["FAMILY_NAME"] = line.replace("FAMILY_NAME", "").replace(
"\n", ""
)
if line.startswith("WEIGHT_NAME"):
properties["WEIGHT_NAME"] = line.replace("WEIGHT_NAME", "").replace(
"\n", ""
)
if line.startswith("SLANT"):
properties["SLANT"] = line.replace("SLANT", "").replace("\n", "")
if line.startswith("SETWIDTH_NAME"):
properties["SETWIDTH_NAME"] = line.replace(
"SETWIDTH_NAME", ""
).replace("\n", "")
if line.startswith("ADD_STYLE_NAME"):
properties["ADD_STYLE_NAME"] = line.replace(
"ADD_STYLE_NAME", ""
).replace("\n", "")
if line.startswith("PIXEL_SIZE"):
properties["PIXEL_SIZE"] = line.replace("PIXEL_SIZE", "").replace(
"\n", ""
)
if line.startswith("POINT_SIZE"):
properties["POINT_SIZE"] = line.replace("POINT_SIZE", "").replace(
"\n", ""
)
if line.startswith("RESOLUTION_X"):
properties["RESOLUTION_X"] = line.replace(
"RESOLUTION_X", ""
).replace("\n", "")
if line.startswith("RESOLUTION_Y"):
properties["RESOLUTION_Y"] = line.replace(
"RESOLUTION_Y", ""
).replace("\n", "")
if line.startswith("SPACING"):
properties["SPACING"] = line.replace("SPACING", "").replace(
"\n", ""
)
if line.startswith("AVERAGE_WIDTH"):
properties["AVERAGE_WIDTH"] = line.replace(
"AVERAGE_WIDTH", ""
).replace("\n", "")
if line.startswith("CHARSET_REGISTRY"):
properties["CHARSET_REGISTRY"] = line.replace(
"CHARSET_REGISTRY", ""
).replace("\n", "")
if line.startswith("CHARSET_ENCODING"):
properties["CHARSET_ENCODING"] = line.replace(
"CHARSET_ENCODING", ""
).replace("\n", "")
if line.startswith("DEFAULT_CHAR"):
properties["DEFAULT_CHAR"] = line.replace(
"DEFAULT_CHAR", ""
).replace("\n", "")
if line.startswith("FONT_DESCENT"):
properties["FONT_DESCENT"] = line.replace(
"FONT_DESCENT", ""
).replace("\n", "")
if line.startswith("FONT_ASCENT"):
properties["FONT_ASCENT"] = line.replace("FONT_ASCENT", "").replace(
"\n", ""
)
if line.startswith("COPYRIGHT"):
properties["COPYRIGHT"] = line.replace("COPYRIGHT", "").replace(
"\n", ""
)
if line.startswith("CAP_HEIGHT"):
properties["CAP_HEIGHT"] = line.replace("CAP_HEIGHT", "").replace(
"\n", ""
)
if line.startswith("X_HEIGHT"):
properties["X_HEIGHT"] = line.replace("X_HEIGHT", "").replace(
"\n", ""
)
if line.startswith("_GBDFED_INFO"):
properties["_GBDFED_INFO"] = line.replace(
"_GBDFED_INFO", ""
).replace("\n", "")
line = bdf.readline()
return properties
def parse_chars(self, bdfFile):
font = {}
cols = self.properties["FONTBOUNDINGBOX"][0]
rows = self.properties["FONTBOUNDINGBOX"][1]
with open(bdfFile, "r") as bdf:
line = bdf.readline()
# Go through file until chars start.
while not line.startswith("CHARS "):
line = bdf.readline()
characters = int(line.split(" ")[1])
for character in range(characters):
line = bdf.readline()
char = line.split(" ")[1].replace("\n", "")
while not line.startswith("BITMAP"):
line = bdf.readline()
bits = ""
for row in range(rows):
bits += bdf.readline()
font[char] = self.from_hex(bits.strip(), cols)
if bdf.readline().startswith("ENDFONT"):
return font
return font
def from_hex(self, values, columns):
return np.array(
[list(f"{int(row[:2], 16):0>{columns}b}") for row in values.split("\n")],
dtype=int,
)
def word(self, word: str):
matrix = np.zeros(self.shape)
for char in word:
if char in self.charNames.keys():
arr = self.chars[self.charNames[char]]
else:
arr = self.chars[char]
matrix = np.concatenate((matrix, arr), axis=1)
return matrix[:, self.cols :]

View File

@ -1,4 +1,4 @@
# Copyright (c) 2019 albig
# Copyright (c) 2019 Anson Biggs
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
@ -9,14 +9,14 @@ with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="bdf-to-numpy",
version="2019.1",
name="bdfparse",
version="2019.8",
author="Anson Biggs",
author_email="anson@ansonbiggs.com",
description="A package for reading .bdf files into NumPy arrays.",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://gitlab.com/MisterBiggs/bdf-to-numpy",
url="https://gitlab.com/MisterBiggs/bdfparse",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3.7",