Compare commits
45 commits
master
...
pcfmetrics
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8eb9d31dc | ||
|
|
2110f4412e | ||
|
|
2e3675c9b7 | ||
|
|
ef66fa7f18 | ||
|
|
cb5d9db61f | ||
|
|
f492447f75 | ||
|
|
706e9dd501 | ||
|
|
2548e3b4fe | ||
|
|
4b113f0504 | ||
|
|
e710870654 | ||
|
|
c6911a87bb | ||
|
|
1e386e9dc7 | ||
|
|
fb04741320 | ||
|
|
e768ab3b9c | ||
|
|
ee455f56d0 | ||
| 7da4b31e17 | |||
| 1724754e9c | |||
|
|
d96e66fb37 | ||
|
|
97c0318e15 | ||
|
|
2c6529dc45 | ||
|
|
af282529b9 | ||
|
|
da4fa0b415 | ||
| 6e57a8b9e9 | |||
| d379f1962e | |||
| 383fc039c5 | |||
| ceed4c2a88 | |||
|
|
6ae6e07484 | ||
| e15c7d1f5c | |||
| 84bf5208bb | |||
| e1634e1a59 | |||
| 7dcd40828e | |||
| e5d0839aca | |||
| 7869ef43be | |||
| 3c31cff165 | |||
| 7658511786 | |||
| 2bef623710 | |||
| 27648e7ab7 | |||
|
|
51e9a1fa2e | ||
|
|
8c1fa9b684 | ||
|
|
c38baeb932 | ||
|
|
7e153547f5 | ||
|
|
ca48d4afde | ||
|
|
1f46cc3a68 | ||
|
|
977edcbd88 | ||
|
|
2501072843 |
39 changed files with 22250 additions and 7579 deletions
32
.github/workflows/build.yml
vendored
32
.github/workflows/build.yml
vendored
|
|
@ -1,3 +1,7 @@
|
||||||
|
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
name: Build CI
|
name: Build CI
|
||||||
|
|
||||||
on: [pull_request, push]
|
on: [pull_request, push]
|
||||||
|
|
@ -38,20 +42,32 @@ jobs:
|
||||||
# (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.)
|
# (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.)
|
||||||
run: |
|
run: |
|
||||||
source actions-ci/install.sh
|
source actions-ci/install.sh
|
||||||
- name: Pip install pylint, black, & Sphinx
|
- name: Pip install pylint, Sphinx, pre-commit
|
||||||
run: |
|
run: |
|
||||||
pip install --force-reinstall pylint black==19.10b0 Sphinx sphinx-rtd-theme
|
pip install --force-reinstall pylint Sphinx sphinx-rtd-theme pre-commit
|
||||||
- name: Library version
|
- name: Library version
|
||||||
run: git describe --dirty --always --tags
|
run: git describe --dirty --always --tags
|
||||||
- name: Check formatting
|
- name: Pre-commit hooks
|
||||||
run: |
|
run: |
|
||||||
black --check --target-version=py35 .
|
pre-commit run --all-files
|
||||||
- name: PyLint
|
|
||||||
run: |
|
|
||||||
pylint $( find . -path './adafruit*.py' )
|
|
||||||
([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name,bad-whitespace $( find . -path "./examples/*.py" ))
|
|
||||||
- name: Build assets
|
- name: Build assets
|
||||||
run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location .
|
run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location .
|
||||||
|
- name: Archive bundles
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: bundles
|
||||||
|
path: ${{ github.workspace }}/bundles/
|
||||||
- name: Build docs
|
- name: Build docs
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
run: sphinx-build -E -W -b html . _build/html
|
run: sphinx-build -E -W -b html . _build/html
|
||||||
|
- name: Check For setup.py
|
||||||
|
id: need-pypi
|
||||||
|
run: |
|
||||||
|
echo ::set-output name=setup-py::$( find . -wholename './setup.py' )
|
||||||
|
- name: Build Python package
|
||||||
|
if: contains(steps.need-pypi.outputs.setup-py, 'setup.py')
|
||||||
|
run: |
|
||||||
|
pip install --upgrade setuptools wheel twine readme_renderer testresources
|
||||||
|
python setup.py sdist
|
||||||
|
python setup.py bdist_wheel --universal
|
||||||
|
twine check dist/*
|
||||||
|
|
|
||||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
|
|
@ -1,3 +1,7 @@
|
||||||
|
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
name: Release Actions
|
name: Release Actions
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -1,3 +1,7 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
*.mpy
|
*.mpy
|
||||||
.idea
|
.idea
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
@ -9,5 +13,4 @@ bundles
|
||||||
.eggs
|
.eggs
|
||||||
dist
|
dist
|
||||||
**/*.egg-info
|
**/*.egg-info
|
||||||
*.pcf
|
|
||||||
*.ttf
|
*.ttf
|
||||||
|
|
|
||||||
34
.pre-commit-config.yaml
Normal file
34
.pre-commit-config.yaml
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/python/black
|
||||||
|
rev: 20.8b1
|
||||||
|
hooks:
|
||||||
|
- id: black
|
||||||
|
- repo: https://github.com/fsfe/reuse-tool
|
||||||
|
rev: v0.12.1
|
||||||
|
hooks:
|
||||||
|
- id: reuse
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v2.3.0
|
||||||
|
hooks:
|
||||||
|
- id: check-yaml
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- repo: https://github.com/pycqa/pylint
|
||||||
|
rev: pylint-2.7.1
|
||||||
|
hooks:
|
||||||
|
- id: pylint
|
||||||
|
name: pylint (library code)
|
||||||
|
types: [python]
|
||||||
|
exclude: "^(docs/|examples/|setup.py$)"
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: pylint_examples
|
||||||
|
name: pylint (examples code)
|
||||||
|
description: Run pylint rules on "examples/*.py" files
|
||||||
|
entry: /usr/bin/env bash -c
|
||||||
|
args: ['([[ ! -d "examples" ]] || for example in $(find . -path "./examples/*.py"); do pylint --disable=missing-docstring,invalid-name $example; done)']
|
||||||
|
language: system
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
[MASTER]
|
[MASTER]
|
||||||
|
|
||||||
# A comma-separated list of package or module names from where C extensions may
|
# A comma-separated list of package or module names from where C extensions may
|
||||||
|
|
@ -246,7 +250,7 @@ ignore-comments=yes
|
||||||
ignore-docstrings=yes
|
ignore-docstrings=yes
|
||||||
|
|
||||||
# Ignore imports when computing similarities.
|
# Ignore imports when computing similarities.
|
||||||
ignore-imports=no
|
ignore-imports=yes
|
||||||
|
|
||||||
# Minimum lines number of a similarity.
|
# Minimum lines number of a similarity.
|
||||||
min-similarity-lines=4
|
min-similarity-lines=4
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
python:
|
python:
|
||||||
version: 3
|
version: 3
|
||||||
requirements_file: requirements.txt
|
requirements_file: requirements.txt
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2014 Coraline Ada Ehmke
|
||||||
|
SPDX-FileCopyrightText: 2019 Kattni Rembor for Adafruit Industries
|
||||||
|
SPDX-License-Identifier: CC-BY-4.0
|
||||||
|
-->
|
||||||
|
|
||||||
# Adafruit Community Code of Conduct
|
# Adafruit Community Code of Conduct
|
||||||
|
|
||||||
## Our Pledge
|
## Our Pledge
|
||||||
|
|
|
||||||
324
LICENSES/CC-BY-4.0.txt
Normal file
324
LICENSES/CC-BY-4.0.txt
Normal file
|
|
@ -0,0 +1,324 @@
|
||||||
|
Creative Commons Attribution 4.0 International Creative Commons Corporation
|
||||||
|
("Creative Commons") is not a law firm and does not provide legal services
|
||||||
|
or legal advice. Distribution of Creative Commons public licenses does not
|
||||||
|
create a lawyer-client or other relationship. Creative Commons makes its licenses
|
||||||
|
and related information available on an "as-is" basis. Creative Commons gives
|
||||||
|
no warranties regarding its licenses, any material licensed under their terms
|
||||||
|
and conditions, or any related information. Creative Commons disclaims all
|
||||||
|
liability for damages resulting from their use to the fullest extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and conditions
|
||||||
|
that creators and other rights holders may use to share original works of
|
||||||
|
authorship and other material subject to copyright and certain other rights
|
||||||
|
specified in the public license below. The following considerations are for
|
||||||
|
informational purposes only, are not exhaustive, and do not form part of our
|
||||||
|
licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are intended for use by
|
||||||
|
those authorized to give the public permission to use material in ways otherwise
|
||||||
|
restricted by copyright and certain other rights. Our licenses are irrevocable.
|
||||||
|
Licensors should read and understand the terms and conditions of the license
|
||||||
|
they choose before applying it. Licensors should also secure all rights necessary
|
||||||
|
before applying our licenses so that the public can reuse the material as
|
||||||
|
expected. Licensors should clearly mark any material not subject to the license.
|
||||||
|
This includes other CC-licensed material, or material used under an exception
|
||||||
|
or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public licenses, a licensor
|
||||||
|
grants the public permission to use the licensed material under specified
|
||||||
|
terms and conditions. If the licensor's permission is not necessary for any
|
||||||
|
reason–for example, because of any applicable exception or limitation to copyright–then
|
||||||
|
that use is not regulated by the license. Our licenses grant only permissions
|
||||||
|
under copyright and certain other rights that a licensor has authority to
|
||||||
|
grant. Use of the licensed material may still be restricted for other reasons,
|
||||||
|
including because others have copyright or other rights in the material. A
|
||||||
|
licensor may make special requests, such as asking that all changes be marked
|
||||||
|
or described. Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More considerations for the public
|
||||||
|
: wiki.creativecommons.org/Considerations_for_licensees Creative Commons Attribution
|
||||||
|
4.0 International Public License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree to
|
||||||
|
be bound by the terms and conditions of this Creative Commons Attribution
|
||||||
|
4.0 International Public License ("Public License"). To the extent this Public
|
||||||
|
License may be interpreted as a contract, You are granted the Licensed Rights
|
||||||
|
in consideration of Your acceptance of these terms and conditions, and the
|
||||||
|
Licensor grants You such rights in consideration of benefits the Licensor
|
||||||
|
receives from making the Licensed Material available under these terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
Section 1 – Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar Rights
|
||||||
|
that is derived from or based upon the Licensed Material and in which the
|
||||||
|
Licensed Material is translated, altered, arranged, transformed, or otherwise
|
||||||
|
modified in a manner requiring permission under the Copyright and Similar
|
||||||
|
Rights held by the Licensor. For purposes of this Public License, where the
|
||||||
|
Licensed Material is a musical work, performance, or sound recording, Adapted
|
||||||
|
Material is always produced where the Licensed Material is synched in timed
|
||||||
|
relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright and Similar
|
||||||
|
Rights in Your contributions to Adapted Material in accordance with the terms
|
||||||
|
and conditions of this Public License.
|
||||||
|
|
||||||
|
c. Copyright and Similar Rights means copyright and/or similar rights closely
|
||||||
|
related to copyright including, without limitation, performance, broadcast,
|
||||||
|
sound recording, and Sui Generis Database Rights, without regard to how the
|
||||||
|
rights are labeled or categorized. For purposes of this Public License, the
|
||||||
|
rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
|
||||||
|
|
||||||
|
d. Effective Technological Measures means those measures that, in the absence
|
||||||
|
of proper authority, may not be circumvented under laws fulfilling obligations
|
||||||
|
under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996,
|
||||||
|
and/or similar international agreements.
|
||||||
|
|
||||||
|
e. Exceptions and Limitations means fair use, fair dealing, and/or any other
|
||||||
|
exception or limitation to Copyright and Similar Rights that applies to Your
|
||||||
|
use of the Licensed Material.
|
||||||
|
|
||||||
|
f. Licensed Material means the artistic or literary work, database, or other
|
||||||
|
material to which the Licensor applied this Public License.
|
||||||
|
|
||||||
|
g. Licensed Rights means the rights granted to You subject to the terms and
|
||||||
|
conditions of this Public License, which are limited to all Copyright and
|
||||||
|
Similar Rights that apply to Your use of the Licensed Material and that the
|
||||||
|
Licensor has authority to license.
|
||||||
|
|
||||||
|
h. Licensor means the individual(s) or entity(ies) granting rights under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
i. Share means to provide material to the public by any means or process that
|
||||||
|
requires permission under the Licensed Rights, such as reproduction, public
|
||||||
|
display, public performance, distribution, dissemination, communication, or
|
||||||
|
importation, and to make material available to the public including in ways
|
||||||
|
that members of the public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
j. Sui Generis Database Rights means rights other than copyright resulting
|
||||||
|
from Directive 96/9/EC of the European Parliament and of the Council of 11
|
||||||
|
March 1996 on the legal protection of databases, as amended and/or succeeded,
|
||||||
|
as well as other essentially equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
k. You means the individual or entity exercising the Licensed Rights under
|
||||||
|
this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
Section 2 – Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License, the Licensor
|
||||||
|
hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive,
|
||||||
|
irrevocable license to exercise the Licensed Rights in the Licensed Material
|
||||||
|
to:
|
||||||
|
|
||||||
|
A. reproduce and Share the Licensed Material, in whole or in part; and
|
||||||
|
|
||||||
|
B. produce, reproduce, and Share Adapted Material.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions
|
||||||
|
and Limitations apply to Your use, this Public License does not apply, and
|
||||||
|
You do not need to comply with its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section 6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The Licensor authorizes
|
||||||
|
You to exercise the Licensed Rights in all media and formats whether now known
|
||||||
|
or hereafter created, and to make technical modifications necessary to do
|
||||||
|
so. The Licensor waives and/or agrees not to assert any right or authority
|
||||||
|
to forbid You from making technical modifications necessary to exercise the
|
||||||
|
Licensed Rights, including technical modifications necessary to circumvent
|
||||||
|
Effective Technological Measures. For purposes of this Public License, simply
|
||||||
|
making modifications authorized by this Section 2(a)(4) never produces Adapted
|
||||||
|
Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed
|
||||||
|
Material automatically receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
B. No downstream restrictions. You may not offer or impose any additional
|
||||||
|
or different terms or conditions on, or apply any Effective Technological
|
||||||
|
Measures to, the Licensed Material if doing so restricts exercise of the Licensed
|
||||||
|
Rights by any recipient of the Licensed Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or may be construed
|
||||||
|
as permission to assert or imply that You are, or that Your use of the Licensed
|
||||||
|
Material is, connected with, or sponsored, endorsed, or granted official status
|
||||||
|
by, the Licensor or others designated to receive attribution as provided in
|
||||||
|
Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not licensed under this
|
||||||
|
Public License, nor are publicity, privacy, and/or other similar personality
|
||||||
|
rights; however, to the extent possible, the Licensor waives and/or agrees
|
||||||
|
not to assert any such rights held by the Licensor to the limited extent necessary
|
||||||
|
to allow You to exercise the Licensed Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to collect royalties
|
||||||
|
from You for the exercise of the Licensed Rights, whether directly or through
|
||||||
|
a collecting society under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly reserves any right
|
||||||
|
to collect such royalties.
|
||||||
|
|
||||||
|
Section 3 – License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the following
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified form), You must:
|
||||||
|
|
||||||
|
A. retain the following if it is supplied by the Licensor with the Licensed
|
||||||
|
Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed Material and any others
|
||||||
|
designated to receive attribution, in any reasonable manner requested by the
|
||||||
|
Licensor (including by pseudonym if designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
|
||||||
|
|
||||||
|
B. indicate if You modified the Licensed Material and retain an indication
|
||||||
|
of any previous modifications; and
|
||||||
|
|
||||||
|
C. indicate the Licensed Material is licensed under this Public License, and
|
||||||
|
include the text of, or the URI or hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner
|
||||||
|
based on the medium, means, and context in which You Share the Licensed Material.
|
||||||
|
For example, it may be reasonable to satisfy the conditions by providing a
|
||||||
|
URI or hyperlink to a resource that includes the required information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the information required
|
||||||
|
by Section 3(a)(1)(A) to the extent reasonably practicable.
|
||||||
|
|
||||||
|
4. If You Share Adapted Material You produce, the Adapter's License You apply
|
||||||
|
must not prevent recipients of the Adapted Material from complying with this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
Section 4 – Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that apply to
|
||||||
|
Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract,
|
||||||
|
reuse, reproduce, and Share all or a substantial portion of the contents of
|
||||||
|
the database;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database contents in
|
||||||
|
a database in which You have Sui Generis Database Rights, then the database
|
||||||
|
in which You have Sui Generis Database Rights (but not its individual contents)
|
||||||
|
is Adapted Material; and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share all or
|
||||||
|
a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not replace
|
||||||
|
Your obligations under this Public License where the Licensed Rights include
|
||||||
|
other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. Unless otherwise separately undertaken by the Licensor, to the extent possible,
|
||||||
|
the Licensor offers the Licensed Material as-is and as-available, and makes
|
||||||
|
no representations or warranties of any kind concerning the Licensed Material,
|
||||||
|
whether express, implied, statutory, or other. This includes, without limitation,
|
||||||
|
warranties of title, merchantability, fitness for a particular purpose, non-infringement,
|
||||||
|
absence of latent or other defects, accuracy, or the presence or absence of
|
||||||
|
errors, whether or not known or discoverable. Where disclaimers of warranties
|
||||||
|
are not allowed in full or in part, this disclaimer may not apply to You.
|
||||||
|
|
||||||
|
b. To the extent possible, in no event will the Licensor be liable to You
|
||||||
|
on any legal theory (including, without limitation, negligence) or otherwise
|
||||||
|
for any direct, special, indirect, incidental, consequential, punitive, exemplary,
|
||||||
|
or other losses, costs, expenses, or damages arising out of this Public License
|
||||||
|
or use of the Licensed Material, even if the Licensor has been advised of
|
||||||
|
the possibility of such losses, costs, expenses, or damages. Where a limitation
|
||||||
|
of liability is not allowed in full or in part, this limitation may not apply
|
||||||
|
to You.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided above
|
||||||
|
shall be interpreted in a manner that, to the extent possible, most closely
|
||||||
|
approximates an absolute disclaimer and waiver of all liability.
|
||||||
|
|
||||||
|
Section 6 – Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and Similar Rights
|
||||||
|
licensed here. However, if You fail to comply with this Public License, then
|
||||||
|
Your rights under this Public License terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under Section
|
||||||
|
6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided it is cured
|
||||||
|
within 30 days of Your discovery of the violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, this Section 6(b) does not affect any right
|
||||||
|
the Licensor may have to seek remedies for Your violations of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
d. For the avoidance of doubt, the Licensor may also offer the Licensed Material
|
||||||
|
under separate terms or conditions or stop distributing the Licensed Material
|
||||||
|
at any time; however, doing so will not terminate this Public License.
|
||||||
|
|
||||||
|
e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
||||||
|
|
||||||
|
Section 7 – Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different terms or
|
||||||
|
conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the Licensed
|
||||||
|
Material not stated herein are separate from and independent of the terms
|
||||||
|
and conditions of this Public License.
|
||||||
|
|
||||||
|
Section 8 – Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and shall not
|
||||||
|
be interpreted to, reduce, limit, restrict, or impose conditions on any use
|
||||||
|
of the Licensed Material that could lawfully be made without permission under
|
||||||
|
this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is deemed
|
||||||
|
unenforceable, it shall be automatically reformed to the minimum extent necessary
|
||||||
|
to make it enforceable. If the provision cannot be reformed, it shall be severed
|
||||||
|
from this Public License without affecting the enforceability of the remaining
|
||||||
|
terms and conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no failure
|
||||||
|
to comply consented to unless expressly agreed to by the Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted as a limitation
|
||||||
|
upon, or waiver of, any privileges and immunities that apply to the Licensor
|
||||||
|
or You, including from the legal processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public licenses. Notwithstanding, Creative
|
||||||
|
Commons may elect to apply one of its public licenses to material it publishes
|
||||||
|
and in those instances will be considered the "Licensor." The text of the
|
||||||
|
Creative Commons public licenses is dedicated to the public domain under the
|
||||||
|
CC0 Public Domain Dedication. Except for the limited purpose of indicating
|
||||||
|
that material is shared under a Creative Commons public license or as otherwise
|
||||||
|
permitted by the Creative Commons policies published at creativecommons.org/policies,
|
||||||
|
Creative Commons does not authorize the use of the trademark "Creative Commons"
|
||||||
|
or any other trademark or logo of Creative Commons without its prior written
|
||||||
|
consent including, without limitation, in connection with any unauthorized
|
||||||
|
modifications to any of its public licenses or any other arrangements, understandings,
|
||||||
|
or agreements concerning use of licensed material. For the avoidance of doubt,
|
||||||
|
this paragraph does not form part of the public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
||||||
19
LICENSES/MIT.txt
Normal file
19
LICENSES/MIT.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
MIT License Copyright (c) <year> <copyright holders>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||||
|
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||||
|
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
105
LICENSES/OFL-1.1-RFN.txt
Normal file
105
LICENSES/OFL-1.1-RFN.txt
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
Version 1.1 - 26 February 2007
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
SIL Open Font License
|
||||||
|
=====================
|
||||||
|
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
--------
|
||||||
|
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
Definitions
|
||||||
|
-----------
|
||||||
|
|
||||||
|
`"Font Software"` refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
`"Reserved Font Name"` refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
`"Original Version"` refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
`"Modified Version"` refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
`"Author"` refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
Permission & Conditions
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1. Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2. Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3. No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4. The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5. The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
Termination
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
Disclaimer
|
||||||
|
----------
|
||||||
|
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
20
LICENSES/Unlicense.txt
Normal file
20
LICENSES/Unlicense.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute
|
||||||
|
this software, either in source code form or as a compiled binary, for any
|
||||||
|
purpose, commercial or non-commercial, and by any means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||||
|
software dedicate any and all copyright interest in the software to the public
|
||||||
|
domain. We make this dedication for the benefit of the public at large and
|
||||||
|
to the detriment of our heirs and successors. We intend this dedication to
|
||||||
|
be an overt act of relinquishment in perpetuity of all present and future
|
||||||
|
rights to this software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||||
|
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
||||||
|
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information,
|
||||||
|
please refer to <https://unlicense.org/>
|
||||||
15
README.rst
15
README.rst
|
|
@ -13,7 +13,7 @@ Introduction
|
||||||
:target: https://github.com/adafruit/Adafruit_CircuitPython_Bitmap_Font/actions/
|
:target: https://github.com/adafruit/Adafruit_CircuitPython_Bitmap_Font/actions/
|
||||||
:alt: Build Status
|
:alt: Build Status
|
||||||
|
|
||||||
Loads bitmap fonts into CircuitPython's displayio. BDF files are well supported. PCF and TTF
|
Loads bitmap fonts into CircuitPython's displayio. BDF and PCF files are well supported. TTF
|
||||||
support is not yet complete.
|
support is not yet complete.
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
|
|
@ -53,14 +53,23 @@ To install in a virtual environment in your current project:
|
||||||
Usage Example
|
Usage Example
|
||||||
=============
|
=============
|
||||||
|
|
||||||
.. code-block::python
|
.. code-block:: python
|
||||||
|
|
||||||
from adafruit_bitmap_font import bitmap_font
|
from adafruit_bitmap_font import bitmap_font
|
||||||
from displayio import Bitmap
|
from displayio import Bitmap
|
||||||
font = bitmap_font.load_font("scientifica-11.bdf", Bitmap)
|
font = bitmap_font.load_font("fonts/LeagueSpartan-Bold-16.bdf", Bitmap)
|
||||||
print(font.get_glyph(ord("A")))
|
print(font.get_glyph(ord("A")))
|
||||||
|
|
||||||
|
|
||||||
|
Creating Fonts
|
||||||
|
==============
|
||||||
|
|
||||||
|
See `this learn guide <https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display>`_ for more information about building custom fornt files
|
||||||
|
|
||||||
|
The command line tool :code:`otf2bdf` can be used make bdf files for use with this library.
|
||||||
|
|
||||||
|
The command line tool :code:`bdftopcf` can be used make pcf files for use with this library.
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
|
||||||
3
README.rst.license
Normal file
3
README.rst.license
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
||||||
|
|
||||||
|
SPDX-License-Identifier: MIT
|
||||||
|
|
@ -1,24 +1,7 @@
|
||||||
# The MIT License (MIT)
|
# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries
|
||||||
#
|
#
|
||||||
# Copyright (c) 2019 Scott Shawcroft for Adafruit Industries LLC
|
# SPDX-License-Identifier: MIT
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
"""
|
"""
|
||||||
`adafruit_bitmap_font.bdf`
|
`adafruit_bitmap_font.bdf`
|
||||||
====================================================
|
====================================================
|
||||||
|
|
@ -63,6 +46,41 @@ class BDF(GlyphCache):
|
||||||
self.point_size = None
|
self.point_size = None
|
||||||
self.x_resolution = None
|
self.x_resolution = None
|
||||||
self.y_resolution = None
|
self.y_resolution = None
|
||||||
|
self._ascent = None
|
||||||
|
self._descent = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def descent(self):
|
||||||
|
"""The number of pixels below the baseline of a typical descender"""
|
||||||
|
if self._descent is None:
|
||||||
|
self.file.seek(0)
|
||||||
|
while True:
|
||||||
|
line = self.file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
|
||||||
|
if line.startswith(b"FONT_DESCENT "):
|
||||||
|
self._descent = int(line.split()[1])
|
||||||
|
break
|
||||||
|
|
||||||
|
return self._descent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ascent(self):
|
||||||
|
"""The number of pixels above the baseline of a typical ascender"""
|
||||||
|
if self._ascent is None:
|
||||||
|
self.file.seek(0)
|
||||||
|
while True:
|
||||||
|
line = self.file.readline()
|
||||||
|
line = str(line, "utf-8")
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
|
||||||
|
if line.startswith("FONT_ASCENT "):
|
||||||
|
self._ascent = int(line.split()[1])
|
||||||
|
break
|
||||||
|
|
||||||
|
return self._ascent
|
||||||
|
|
||||||
def get_bounding_box(self):
|
def get_bounding_box(self):
|
||||||
"""Return the maximum glyph size as a 4-tuple of: width, height, x_offset, y_offset"""
|
"""Return the maximum glyph size as a 4-tuple of: width, height, x_offset, y_offset"""
|
||||||
|
|
@ -97,7 +115,7 @@ class BDF(GlyphCache):
|
||||||
remaining = code_points
|
remaining = code_points
|
||||||
else:
|
else:
|
||||||
remaining = set(code_points)
|
remaining = set(code_points)
|
||||||
for code_point in remaining:
|
for code_point in remaining.copy():
|
||||||
if code_point in self._glyphs and self._glyphs[code_point]:
|
if code_point in self._glyphs and self._glyphs[code_point]:
|
||||||
remaining.remove(code_point)
|
remaining.remove(code_point)
|
||||||
if not remaining:
|
if not remaining:
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,7 @@
|
||||||
# The MIT License (MIT)
|
# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries
|
||||||
#
|
#
|
||||||
# Copyright (c) 2019 Scott Shawcroft for Adafruit Industries LLC
|
# SPDX-License-Identifier: MIT
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
"""
|
"""
|
||||||
`adafruit_bitmap_font.bitmap_font`
|
`adafruit_bitmap_font.bitmap_font`
|
||||||
====================================================
|
====================================================
|
||||||
|
|
@ -57,11 +40,12 @@ def load_font(filename, bitmap=None):
|
||||||
|
|
||||||
return bdf.BDF(font_file, bitmap)
|
return bdf.BDF(font_file, bitmap)
|
||||||
if filename.endswith("pcf") and first_four == b"\x01fcp":
|
if filename.endswith("pcf") and first_four == b"\x01fcp":
|
||||||
import pcf
|
from . import pcf
|
||||||
|
|
||||||
return pcf.PCF(font_file)
|
return pcf.PCF(font_file, bitmap)
|
||||||
if filename.endswith("ttf") and first_four == b"\x00\x01\x00\x00":
|
if filename.endswith("ttf") and first_four == b"\x00\x01\x00\x00":
|
||||||
import ttf
|
from . import ttf
|
||||||
|
|
||||||
return ttf.TTF(font_file)
|
return ttf.TTF(font_file, bitmap)
|
||||||
return None
|
|
||||||
|
raise ValueError("Unknown magic number %r" % first_four)
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,7 @@
|
||||||
# The MIT License (MIT)
|
# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries
|
||||||
#
|
#
|
||||||
# Copyright (c) 2019 Scott Shawcroft for Adafruit Industries LLC
|
# SPDX-License-Identifier: MIT
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
"""
|
"""
|
||||||
`adafruit_bitmap_font.glyph_cache`
|
`adafruit_bitmap_font.glyph_cache`
|
||||||
====================================================
|
====================================================
|
||||||
|
|
|
||||||
|
|
@ -1,163 +1,391 @@
|
||||||
# pylint: skip-file
|
# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries
|
||||||
# Remove the above when PCF is actually supported.
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
from .glyph_cache import GlyphCache
|
"""
|
||||||
import displayio
|
`adafruit_bitmap_font.pcf`
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
Loads PCF format fonts.
|
||||||
|
|
||||||
|
* Author(s): Jeff Epler
|
||||||
|
|
||||||
|
Implementation Notes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
**Hardware:**
|
||||||
|
|
||||||
|
**Software and Dependencies:**
|
||||||
|
|
||||||
|
* Adafruit CircuitPython firmware for the supported boards:
|
||||||
|
https://github.com/adafruit/circuitpython/releases
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
import gc
|
||||||
import struct
|
import struct
|
||||||
|
from micropython import const
|
||||||
|
|
||||||
_PCF_PROPERTIES = 1 << 0
|
from fontio import Glyph
|
||||||
_PCF_ACCELERATORS = 1 << 1
|
from .glyph_cache import GlyphCache
|
||||||
_PCF_METRICS = 1 << 2
|
|
||||||
_PCF_BITMAPS = 1 << 3
|
|
||||||
_PCF_INK_METRICS = 1 << 4
|
|
||||||
_PCF_BDF_ENCODINGS = 1 << 5
|
|
||||||
_PCF_SWIDTHS = 1 << 6
|
|
||||||
_PCF_GLYPH_NAMES = 1 << 7
|
|
||||||
_PCF_BDF_ACCELERATORS = 1 << 8
|
|
||||||
|
|
||||||
_PCF_DEFAULT_FORMAT = 0x00000000
|
_PCF_PROPERTIES = const(1 << 0)
|
||||||
_PCF_INKBOUNDS = 0x00000200
|
_PCF_ACCELERATORS = const(1 << 1)
|
||||||
_PCF_ACCEL_W_INKBOUNDS = 0x00000100
|
_PCF_METRICS = const(1 << 2)
|
||||||
_PCF_COMPRESSED_METRICS = 0x00000100
|
_PCF_BITMAPS = const(1 << 3)
|
||||||
|
_PCF_INK_METRICS = const(1 << 4)
|
||||||
|
_PCF_BDF_ENCODINGS = const(1 << 5)
|
||||||
|
_PCF_SWIDTHS = const(1 << 6)
|
||||||
|
_PCF_GLYPH_NAMES = const(1 << 7)
|
||||||
|
_PCF_BDF_ACCELERATORS = const(1 << 8)
|
||||||
|
|
||||||
_PCF_GLYPH_PAD_MASK = 3 << 0 # See the bitmap table for explanation */
|
_PCF_DEFAULT_FORMAT = const(0x00000000)
|
||||||
_PCF_BYTE_MASK = 1 << 2 # If set then Most Sig Byte First */
|
_PCF_ACCEL_W_INKBOUNDS = const(0x00000100)
|
||||||
_PCF_BIT_MASK = 1 << 3 # If set then Most Sig Bit First */
|
_PCF_COMPRESSED_METRICS = const(0x00000100)
|
||||||
_PCF_SCAN_UNIT_MASK = 3 << 4
|
|
||||||
|
|
||||||
# https://fontforge.github.io/en-US/documentation/reference/pcf-format/
|
_PCF_GLYPH_PAD_MASK = const(3 << 0) # See the bitmap table for explanation */
|
||||||
|
_PCF_BYTE_MASK = const(1 << 2) # If set then Most Sig Byte First */
|
||||||
|
_PCF_BIT_MASK = const(1 << 3) # If set then Most Sig Bit First */
|
||||||
|
_PCF_SCAN_UNIT_MASK = const(3 << 4)
|
||||||
|
|
||||||
|
# https://fontforge.org/docs/techref/pcf-format.html
|
||||||
|
|
||||||
|
Table = namedtuple("Table", ("format", "size", "offset"))
|
||||||
|
Metrics = namedtuple(
|
||||||
|
"Metrics",
|
||||||
|
(
|
||||||
|
"left_side_bearing",
|
||||||
|
"right_side_bearing",
|
||||||
|
"character_width",
|
||||||
|
"character_ascent",
|
||||||
|
"character_descent",
|
||||||
|
"character_attributes",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
Accelerators = namedtuple(
|
||||||
|
"Accelerators",
|
||||||
|
(
|
||||||
|
"no_overlap",
|
||||||
|
"constant_metrics",
|
||||||
|
"terminal_font",
|
||||||
|
"constant_width",
|
||||||
|
"ink_inside",
|
||||||
|
"ink_metrics",
|
||||||
|
"draw_direction",
|
||||||
|
"font_ascent",
|
||||||
|
"font_descent",
|
||||||
|
"max_overlap",
|
||||||
|
"minbounds",
|
||||||
|
"maxbounds",
|
||||||
|
"ink_minbounds",
|
||||||
|
"ink_maxbounds",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
Encoding = namedtuple(
|
||||||
|
"Encoding", ("min_byte2", "max_byte2", "min_byte1", "max_byte1", "default_char")
|
||||||
|
)
|
||||||
|
Bitmap = namedtuple("Bitmap", ("glyph_count", "bitmap_sizes"))
|
||||||
|
|
||||||
|
|
||||||
class PCF(GlyphCache):
|
class PCF(GlyphCache):
|
||||||
def __init__(self, f):
|
"""Loads glyphs from a PCF file in the given bitmap_class."""
|
||||||
|
|
||||||
|
def __init__(self, f, bitmap_class):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.file = f
|
self.file = f
|
||||||
self.name = f
|
self.name = f
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
header, table_count = self.read("<4sI")
|
self.buffer = bytearray(1)
|
||||||
|
self.bitmap_class = bitmap_class
|
||||||
|
_, table_count = self._read("<4sI")
|
||||||
self.tables = {}
|
self.tables = {}
|
||||||
for _ in range(table_count):
|
for _ in range(table_count):
|
||||||
type, format, size, offset = self.read("<IIII")
|
type_, format_, size, offset = self._read("<IIII")
|
||||||
self.tables[type] = {"format": format, "size": size, "offset": offset}
|
self.tables[type_] = Table(format_, size, offset)
|
||||||
print(type)
|
|
||||||
|
|
||||||
def read(self, format):
|
bitmap_format = self.tables[_PCF_BITMAPS].format
|
||||||
s = struct.calcsize(format)
|
if bitmap_format != 0xE:
|
||||||
return struct.unpack_from(format, self.file.read(s))
|
raise NotImplementedError("Unsupported format %s" % bitmap_format)
|
||||||
|
|
||||||
|
self._accel = self._read_accelerator_tables()
|
||||||
|
self._encoding = self._read_encoding_table()
|
||||||
|
self._bitmaps = self._read_bitmap_table()
|
||||||
|
|
||||||
|
self._ascent = self._accel.font_ascent
|
||||||
|
self._descent = self._accel.font_descent
|
||||||
|
|
||||||
|
minbounds = self._accel.ink_minbounds
|
||||||
|
maxbounds = self._accel.ink_maxbounds
|
||||||
|
width = maxbounds.right_side_bearing - minbounds.left_side_bearing
|
||||||
|
height = maxbounds.character_ascent + maxbounds.character_descent
|
||||||
|
|
||||||
|
self._bounding_box = (
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
minbounds.left_side_bearing,
|
||||||
|
-maxbounds.character_descent,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ascent(self):
|
||||||
|
"""The number of pixels above the baseline of a typical ascender"""
|
||||||
|
return self._ascent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def descent(self):
|
||||||
|
"""The number of pixels below the baseline of a typical descender"""
|
||||||
|
return self._descent
|
||||||
|
|
||||||
def get_bounding_box(self):
|
def get_bounding_box(self):
|
||||||
|
"""Return the maximum glyph size as a 4-tuple of: width, height, x_offset, y_offset"""
|
||||||
|
return self._bounding_box
|
||||||
|
|
||||||
|
def _read(self, format_):
|
||||||
|
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):
|
||||||
|
self.file.seek(table.offset)
|
||||||
|
(format_,) = self._read("<I")
|
||||||
|
|
||||||
|
if format_ & _PCF_BYTE_MASK == 0:
|
||||||
|
raise RuntimeError("Only big endian supported")
|
||||||
|
|
||||||
|
return format_
|
||||||
|
|
||||||
|
def _read_encoding_table(self):
|
||||||
|
encoding = self.tables[_PCF_BDF_ENCODINGS]
|
||||||
|
self._seek_table(encoding)
|
||||||
|
|
||||||
|
return Encoding(*self._read(">hhhhh"))
|
||||||
|
|
||||||
|
def _read_bitmap_table(self):
|
||||||
|
bitmaps = self.tables[_PCF_BITMAPS]
|
||||||
|
format_ = self._seek_table(bitmaps)
|
||||||
|
|
||||||
|
(glyph_count,) = self._read(">I")
|
||||||
|
self.file.seek(bitmaps.offset + 8 + 4 * glyph_count)
|
||||||
|
bitmap_sizes = self._read(">4I")
|
||||||
|
return Bitmap(glyph_count, bitmap_sizes[format_ & 3])
|
||||||
|
|
||||||
|
def _read_metrics(self, compressed_metrics):
|
||||||
|
if compressed_metrics:
|
||||||
|
(
|
||||||
|
left_side_bearing,
|
||||||
|
right_side_bearing,
|
||||||
|
character_width,
|
||||||
|
character_ascent,
|
||||||
|
character_descent,
|
||||||
|
) = self._read("5B")
|
||||||
|
left_side_bearing -= 0x80
|
||||||
|
right_side_bearing -= 0x80
|
||||||
|
character_width -= 0x80
|
||||||
|
character_ascent -= 0x80
|
||||||
|
character_descent -= 0x80
|
||||||
|
attributes = 0
|
||||||
|
else:
|
||||||
|
(
|
||||||
|
left_side_bearing,
|
||||||
|
right_side_bearing,
|
||||||
|
character_width,
|
||||||
|
character_ascent,
|
||||||
|
character_descent,
|
||||||
|
attributes,
|
||||||
|
) = self._read(">5hH")
|
||||||
|
return Metrics(
|
||||||
|
left_side_bearing,
|
||||||
|
right_side_bearing,
|
||||||
|
character_width,
|
||||||
|
character_ascent,
|
||||||
|
character_descent,
|
||||||
|
attributes,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _read_accelerator_tables(self):
|
||||||
|
# pylint: disable=too-many-locals
|
||||||
|
accelerators = self.tables.get(_PCF_BDF_ACCELERATORS)
|
||||||
|
if not accelerators:
|
||||||
|
accelerators = self.tables.get(_PCF_ACCELERATORS)
|
||||||
|
if not accelerators:
|
||||||
|
raise RuntimeError("Accelerator table missing")
|
||||||
|
|
||||||
|
format_ = self._seek_table(accelerators)
|
||||||
|
has_inkbounds = format_ & _PCF_ACCEL_W_INKBOUNDS
|
||||||
|
|
||||||
|
(
|
||||||
|
no_overlap,
|
||||||
|
constant_metrics,
|
||||||
|
terminal_font,
|
||||||
|
constant_width,
|
||||||
|
ink_inside,
|
||||||
|
ink_metrics,
|
||||||
|
draw_direction,
|
||||||
|
_,
|
||||||
|
font_ascent,
|
||||||
|
font_descent,
|
||||||
|
max_overlap,
|
||||||
|
) = self._read(">BBBBBBBBIII")
|
||||||
|
minbounds = self._read_metrics(False)
|
||||||
|
maxbounds = self._read_metrics(False)
|
||||||
|
if has_inkbounds:
|
||||||
|
ink_minbounds = self._read_metrics(False)
|
||||||
|
ink_maxbounds = self._read_metrics(False)
|
||||||
|
else:
|
||||||
|
ink_minbounds = minbounds
|
||||||
|
ink_maxbounds = maxbounds
|
||||||
|
|
||||||
|
return Accelerators(
|
||||||
|
no_overlap,
|
||||||
|
constant_metrics,
|
||||||
|
terminal_font,
|
||||||
|
constant_width,
|
||||||
|
ink_inside,
|
||||||
|
ink_metrics,
|
||||||
|
draw_direction,
|
||||||
|
font_ascent,
|
||||||
|
font_descent,
|
||||||
|
max_overlap,
|
||||||
|
minbounds,
|
||||||
|
maxbounds,
|
||||||
|
ink_minbounds,
|
||||||
|
ink_maxbounds,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _read_properties(self):
|
||||||
property_table_offset = self.tables[_PCF_PROPERTIES]["offset"]
|
property_table_offset = self.tables[_PCF_PROPERTIES]["offset"]
|
||||||
self.file.seek(property_table_offset)
|
self.file.seek(property_table_offset)
|
||||||
(format,) = self.read("<I")
|
(format_,) = self._read("<I")
|
||||||
|
|
||||||
if format & _PCF_BYTE_MASK == 0:
|
if format_ & _PCF_BYTE_MASK == 0:
|
||||||
raise RuntimeError("Only big endian supported")
|
raise RuntimeError("Only big endian supported")
|
||||||
(nprops,) = self.read(">I")
|
(nprops,) = self._read(">I")
|
||||||
self.file.seek(property_table_offset + 8 + 9 * nprops)
|
self.file.seek(property_table_offset + 8 + 9 * nprops)
|
||||||
|
|
||||||
pos = self.file.tell()
|
pos = self.file.tell()
|
||||||
if pos % 4 > 0:
|
if pos % 4 > 0:
|
||||||
self.file.read(4 - pos % 4)
|
self.file.read(4 - pos % 4)
|
||||||
(string_size,) = self.read(">I")
|
(string_size,) = self._read(">I")
|
||||||
|
|
||||||
strings = self.file.read(string_size)
|
strings = self.file.read(string_size)
|
||||||
string_map = {}
|
string_map = {}
|
||||||
i = 0
|
i = 0
|
||||||
for s in strings.split(b"\x00"):
|
for value in strings.split(b"\x00"):
|
||||||
string_map[i] = s
|
string_map[i] = value
|
||||||
i += len(s) + 1
|
i += len(value) + 1
|
||||||
|
|
||||||
self.file.seek(property_table_offset + 8)
|
self.file.seek(property_table_offset + 8)
|
||||||
for _ in range(nprops):
|
for _ in range(nprops):
|
||||||
name_offset, isStringProp, value = self.read(">IBI")
|
name_offset, is_string_prop, value = self._read(">IBI")
|
||||||
|
|
||||||
if isStringProp:
|
if is_string_prop:
|
||||||
print(string_map[name_offset], string_map[value])
|
yield (string_map[name_offset], string_map[value])
|
||||||
else:
|
else:
|
||||||
print(string_map[name_offset], value)
|
yield (string_map[name_offset], value)
|
||||||
return None
|
|
||||||
|
|
||||||
def load_glyphs(self, code_points):
|
def load_glyphs(self, code_points):
|
||||||
metadata = True
|
# pylint: disable=too-many-statements,too-many-branches,too-many-nested-blocks,too-many-locals
|
||||||
character = False
|
if isinstance(code_points, int):
|
||||||
code_point = None
|
code_points = (code_points,)
|
||||||
rounded_x = 1
|
elif isinstance(code_points, str):
|
||||||
bytes_per_row = 1
|
code_points = [ord(c) for c in code_points]
|
||||||
desired_character = False
|
|
||||||
current_info = None
|
|
||||||
current_y = 0
|
|
||||||
total_remaining = len(code_points)
|
|
||||||
|
|
||||||
x, _, _, _ = self.get_bounding_box()
|
code_points = sorted(
|
||||||
# create a scratch bytearray to load pixels into
|
c for c in code_points if self._glyphs.get(c, None) is None
|
||||||
scratch_row = memoryview(bytearray((((x - 1) // 32) + 1) * 4))
|
)
|
||||||
|
if not code_points:
|
||||||
|
return
|
||||||
|
|
||||||
self.file.seek(0)
|
indices_offset = self.tables[_PCF_BDF_ENCODINGS].offset + 14
|
||||||
while True:
|
bitmap_offset_offsets = self.tables[_PCF_BITMAPS].offset + 8
|
||||||
line = self.file.readline()
|
first_bitmap_offset = self.tables[_PCF_BITMAPS].offset + 4 * (
|
||||||
if not line:
|
6 + self._bitmaps.glyph_count
|
||||||
break
|
)
|
||||||
if line.startswith(b"CHARS "):
|
metrics_compressed = self.tables[_PCF_METRICS].format & _PCF_COMPRESSED_METRICS
|
||||||
metadata = False
|
first_metric_offset = self.tables[_PCF_METRICS].offset + (
|
||||||
elif line.startswith(b"SIZE"):
|
6 if metrics_compressed else 8
|
||||||
_, self.point_size, self.x_resolution, self.y_resolution = line.split()
|
)
|
||||||
elif line.startswith(b"COMMENT"):
|
metrics_size = 5 if metrics_compressed else 12
|
||||||
pass
|
|
||||||
elif line.startswith(b"STARTCHAR"):
|
# These will each _tend to be_ forward reads in the file, at least
|
||||||
# print(lineno, line.strip())
|
# sometimes we'll benefit from oofatfs's 512 byte cache and avoid
|
||||||
# _, character_name = line.split()
|
# excess reads
|
||||||
character = True
|
indices = [None] * len(code_points)
|
||||||
elif line.startswith(b"ENDCHAR"):
|
for i, code_point in enumerate(code_points):
|
||||||
character = False
|
enc1 = (code_point >> 8) & 0xFF
|
||||||
if desired_character:
|
enc2 = code_point & 0xFF
|
||||||
self._glyphs[code_point] = current_info
|
|
||||||
if total_remaining == 0:
|
if enc1 < self._encoding.min_byte1 or enc1 > self._encoding.max_byte1:
|
||||||
return
|
continue
|
||||||
desired_character = False
|
if enc2 < self._encoding.min_byte2 or enc2 > self._encoding.max_byte2:
|
||||||
elif line.startswith(b"BBX"):
|
continue
|
||||||
if desired_character:
|
|
||||||
_, x, y, dx, dy = line.split()
|
encoding_idx = (
|
||||||
x = int(x)
|
(enc1 - self._encoding.min_byte1)
|
||||||
y = int(y)
|
* (self._encoding.max_byte2 - self._encoding.min_byte2 + 1)
|
||||||
dx = int(dx)
|
+ enc2
|
||||||
dy = int(dy)
|
- self._encoding.min_byte2
|
||||||
current_info["bounds"] = (x, y, dx, dy)
|
)
|
||||||
current_info["bitmap"] = displayio.Bitmap(x, y, 2)
|
self.file.seek(indices_offset + 2 * encoding_idx)
|
||||||
elif line.startswith(b"BITMAP"):
|
(glyph_idx,) = self._read(">H")
|
||||||
if desired_character:
|
if glyph_idx != 65535:
|
||||||
rounded_x = x // 8
|
indices[i] = glyph_idx
|
||||||
if x % 8 > 0:
|
|
||||||
rounded_x += 1
|
all_metrics = [None] * len(code_points)
|
||||||
bytes_per_row = rounded_x
|
for i, code_point in enumerate(code_points):
|
||||||
if bytes_per_row % 4 > 0:
|
index = indices[i]
|
||||||
bytes_per_row += 4 - bytes_per_row % 4
|
if index is None:
|
||||||
current_y = 0
|
continue
|
||||||
elif line.startswith(b"ENCODING"):
|
self.file.seek(first_metric_offset + metrics_size * index)
|
||||||
_, code_point = line.split()
|
all_metrics[i] = self._read_metrics(metrics_compressed)
|
||||||
code_point = int(code_point)
|
bitmap_offsets = [None] * len(code_points)
|
||||||
if code_point == code_points or code_point in code_points:
|
for i, code_point in enumerate(code_points):
|
||||||
total_remaining -= 1
|
index = indices[i]
|
||||||
if code_point not in self._glyphs:
|
if index is None:
|
||||||
desired_character = True
|
continue
|
||||||
current_info = {"bitmap": None, "bounds": None, "shift": None}
|
self.file.seek(bitmap_offset_offsets + 4 * index)
|
||||||
elif line.startswith(b"DWIDTH"):
|
(bitmap_offset,) = self._read(">I")
|
||||||
if desired_character:
|
bitmap_offsets[i] = bitmap_offset
|
||||||
_, shift_x, shift_y = line.split()
|
|
||||||
shift_x = int(shift_x)
|
# Batch creation of glyphs and bitmaps so that we need only gc.collect
|
||||||
shift_y = int(shift_y)
|
# once
|
||||||
current_info["shift"] = (shift_x, shift_y)
|
gc.collect()
|
||||||
elif line.startswith(b"SWIDTH"):
|
bitmaps = [None] * len(code_points)
|
||||||
pass
|
for i in range(len(all_metrics)): # pylint: disable=consider-using-enumerate
|
||||||
elif character:
|
metrics = all_metrics[i]
|
||||||
if desired_character:
|
if metrics is not None:
|
||||||
bits = int(line.strip(), 16)
|
width = metrics.right_side_bearing - metrics.left_side_bearing
|
||||||
for i in range(rounded_x):
|
height = metrics.character_ascent + metrics.character_descent
|
||||||
val = (bits >> ((rounded_x - i - 1) * 8)) & 0xFF
|
bitmap = bitmaps[i] = self.bitmap_class(width, height, 2)
|
||||||
scratch_row[i] = val
|
self._glyphs[code_points[i]] = Glyph(
|
||||||
current_info["bitmap"]._load_row(
|
bitmap,
|
||||||
current_y, scratch_row[:bytes_per_row]
|
0,
|
||||||
)
|
width,
|
||||||
current_y += 1
|
height,
|
||||||
elif metadata:
|
metrics.left_side_bearing,
|
||||||
# print(lineno, line.strip())
|
-metrics.character_descent,
|
||||||
pass
|
metrics.character_width,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
|
||||||
|
for i, code_point in enumerate(code_points):
|
||||||
|
metrics = all_metrics[i]
|
||||||
|
if metrics is None:
|
||||||
|
continue
|
||||||
|
self.file.seek(first_bitmap_offset + bitmap_offsets[i])
|
||||||
|
width = metrics.right_side_bearing - metrics.left_side_bearing
|
||||||
|
height = metrics.character_ascent + metrics.character_descent
|
||||||
|
|
||||||
|
bitmap = bitmaps[i]
|
||||||
|
words_per_row = (width + 31) // 32
|
||||||
|
buf = bytearray(4 * words_per_row)
|
||||||
|
start = 0
|
||||||
|
for _ in range(height):
|
||||||
|
self.file.readinto(buf)
|
||||||
|
for k in range(width):
|
||||||
|
if buf[k // 8] & (128 >> (k % 8)):
|
||||||
|
bitmap[start + k] = 1
|
||||||
|
start += width
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
# pylint: skip-file
|
# pylint: skip-file
|
||||||
# Remove the above when TTF is actually supported.
|
# Remove the above when TTF is actually supported.
|
||||||
|
|
||||||
|
|
@ -8,7 +12,7 @@ import struct
|
||||||
|
|
||||||
|
|
||||||
class TTF:
|
class TTF:
|
||||||
def __init__(self, f):
|
def __init__(self, f, bitmap):
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
self.file = f
|
self.file = f
|
||||||
|
|
||||||
|
|
|
||||||
3
docs/_static/favicon.ico.license
vendored
Normal file
3
docs/_static/favicon.ico.license
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
SPDX-FileCopyrightText: 2018 Phillip Torrone for Adafruit Industries
|
||||||
|
|
||||||
|
SPDX-License-Identifier: CC-BY-4.0
|
||||||
|
|
@ -10,5 +10,14 @@
|
||||||
.. automodule:: adafruit_bitmap_font.bdf
|
.. automodule:: adafruit_bitmap_font.bdf
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
.. automodule:: adafruit_bitmap_font.bitmap_font
|
||||||
|
:members:
|
||||||
|
|
||||||
.. automodule:: adafruit_bitmap_font.glyph_cache
|
.. automodule:: adafruit_bitmap_font.glyph_cache
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
.. automodule:: adafruit_bitmap_font.pcf
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. automodule:: adafruit_bitmap_font.ttf
|
||||||
|
:members:
|
||||||
|
|
|
||||||
3
docs/api.rst.license
Normal file
3
docs/api.rst.license
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# SPDX-FileCopyrightText: 2020 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
||||||
3
docs/examples.rst.license
Normal file
3
docs/examples.rst.license
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# SPDX-FileCopyrightText: 2020 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
3
docs/index.rst.license
Normal file
3
docs/index.rst.license
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# SPDX-FileCopyrightText: 2020 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This example runs on PyPortal, or any Circuit Python device
|
This example runs on PyPortal, or any Circuit Python device
|
||||||
with a built-in screen that is at least 320x240 pixels.
|
with a built-in screen that is at least 320x240 pixels.
|
||||||
|
|
@ -8,10 +11,19 @@ bitmap with pixels matching glyphs from a given String
|
||||||
|
|
||||||
|
|
||||||
import board
|
import board
|
||||||
from adafruit_bitmap_font import bitmap_font # pylint: disable=wrong-import-position
|
|
||||||
import displayio
|
import displayio
|
||||||
|
from adafruit_bitmap_font import bitmap_font
|
||||||
|
|
||||||
font = bitmap_font.load_font("fonts/Arial-16.bdf")
|
# use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.)
|
||||||
|
# see guide for setting up external displays (TFT / OLED breakouts, RGB matrices, etc.)
|
||||||
|
# https://learn.adafruit.com/circuitpython-display-support-using-displayio/display-and-display-bus
|
||||||
|
display = board.DISPLAY
|
||||||
|
|
||||||
|
# try uncommenting different font files if you like
|
||||||
|
font_file = "fonts/LeagueSpartan-Bold-16.bdf"
|
||||||
|
# font_file = "fonts/Junction-regular-24.pcf"
|
||||||
|
|
||||||
|
font = bitmap_font.load_font(font_file)
|
||||||
|
|
||||||
bitmap = displayio.Bitmap(320, 240, 2)
|
bitmap = displayio.Bitmap(320, 240, 2)
|
||||||
|
|
||||||
|
|
@ -59,7 +71,7 @@ group.x = 20
|
||||||
group.append(tile_grid)
|
group.append(tile_grid)
|
||||||
|
|
||||||
# Add the Group to the Display
|
# Add the Group to the Display
|
||||||
board.DISPLAY.show(group)
|
display.show(group)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
51
examples/bitmap_font_label_magtag.py
Normal file
51
examples/bitmap_font_label_magtag.py
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
This example uses addfruit_display_text.label to display text using a custom font
|
||||||
|
loaded by adafruit_bitmap_font.
|
||||||
|
Adapted for use on MagTag
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import board
|
||||||
|
from adafruit_display_text import label
|
||||||
|
from adafruit_bitmap_font import bitmap_font
|
||||||
|
|
||||||
|
# use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.)
|
||||||
|
# see guide for setting up external displays (TFT / OLED breakouts, RGB matrices, etc.)
|
||||||
|
# https://learn.adafruit.com/circuitpython-display-support-using-displayio/display-and-display-bus
|
||||||
|
display = board.DISPLAY
|
||||||
|
# wait until we can refresh the display
|
||||||
|
time.sleep(display.time_to_refresh)
|
||||||
|
|
||||||
|
# try uncommenting different font files if you like
|
||||||
|
font_file = "fonts/LeagueSpartan-Bold-16.bdf"
|
||||||
|
# font_file = "fonts/Junction-regular-24.pcf"
|
||||||
|
|
||||||
|
# Set text, font, and color
|
||||||
|
text = "HELLO WORLD\nbitmap_font example"
|
||||||
|
font = bitmap_font.load_font(font_file)
|
||||||
|
color = 0xFFFFFF
|
||||||
|
background_color = 0x999999
|
||||||
|
|
||||||
|
# Create the tet label
|
||||||
|
text_area = label.Label(
|
||||||
|
font,
|
||||||
|
text=text,
|
||||||
|
color=color,
|
||||||
|
background_color=background_color,
|
||||||
|
padding_top=3,
|
||||||
|
padding_bottom=3,
|
||||||
|
padding_right=4,
|
||||||
|
padding_left=4,
|
||||||
|
)
|
||||||
|
text_area.line_spacing = 1.0
|
||||||
|
# Set the location
|
||||||
|
text_area.x = 20
|
||||||
|
text_area.y = 20
|
||||||
|
|
||||||
|
# Show it and refresh
|
||||||
|
display.show(text_area)
|
||||||
|
display.refresh()
|
||||||
|
while True:
|
||||||
|
pass
|
||||||
|
|
@ -1,17 +1,27 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This example uses addfruit_display_text.label to display text using a custom font
|
This example uses addfruit_display_text.label to display text using a custom font
|
||||||
loaded by adafruit_bitmap_font
|
loaded by adafruit_bitmap_font
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import board
|
import board
|
||||||
from adafruit_bitmap_font import bitmap_font
|
|
||||||
from adafruit_display_text import label
|
from adafruit_display_text import label
|
||||||
|
from adafruit_bitmap_font import bitmap_font
|
||||||
|
|
||||||
|
# use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.)
|
||||||
|
# see guide for setting up external displays (TFT / OLED breakouts, RGB matrices, etc.)
|
||||||
|
# https://learn.adafruit.com/circuitpython-display-support-using-displayio/display-and-display-bus
|
||||||
display = board.DISPLAY
|
display = board.DISPLAY
|
||||||
|
|
||||||
|
# try uncommenting different font files if you like
|
||||||
|
font_file = "fonts/LeagueSpartan-Bold-16.bdf"
|
||||||
|
# font_file = "fonts/Junction-regular-24.pcf"
|
||||||
|
|
||||||
# Set text, font, and color
|
# Set text, font, and color
|
||||||
text = "HELLO WORLD"
|
text = "HELLO WORLD"
|
||||||
font = bitmap_font.load_font("fonts/Arial-16.bdf")
|
font = bitmap_font.load_font(font_file)
|
||||||
color = 0xFF00FF
|
color = 0xFF00FF
|
||||||
|
|
||||||
# Create the tet label
|
# Create the tet label
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
# Call this with the font file as the command line argument.
|
# Call this with the font file as the command line argument.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
@ -9,10 +12,13 @@ from adafruit_bitmap_font import bitmap_font # pylint: disable=wrong-import-pos
|
||||||
|
|
||||||
sys.path.append(os.path.join(sys.path[0], "../test"))
|
sys.path.append(os.path.join(sys.path[0], "../test"))
|
||||||
font = bitmap_font.load_font(sys.argv[1])
|
font = bitmap_font.load_font(sys.argv[1])
|
||||||
|
specimen = "Adafruit CircuitPython" if len(sys.argv) == 2 else sys.argv[2]
|
||||||
|
|
||||||
_, height, _, dy = font.get_bounding_box()
|
_, height, _, dy = font.get_bounding_box()
|
||||||
|
font.load_glyphs(specimen)
|
||||||
|
|
||||||
for y in range(height):
|
for y in range(height):
|
||||||
for c in "Adafruit CircuitPython":
|
for c in specimen:
|
||||||
glyph = font.get_glyph(ord(c))
|
glyph = font.get_glyph(ord(c))
|
||||||
if not glyph:
|
if not glyph:
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
8676
examples/fonts/Junction-regular-24.bdf
Normal file
8676
examples/fonts/Junction-regular-24.bdf
Normal file
File diff suppressed because it is too large
Load diff
3
examples/fonts/Junction-regular-24.bdf.license
Normal file
3
examples/fonts/Junction-regular-24.bdf.license
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# SPDX-FileCopyrightText: 2010, Caroline Hadilaksono <caroline@hadilaksono.com>, with Reserved Font Name: "Junction"
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: OFL-1.1-RFN
|
||||||
BIN
examples/fonts/Junction-regular-24.pcf
Normal file
BIN
examples/fonts/Junction-regular-24.pcf
Normal file
Binary file not shown.
3
examples/fonts/Junction-regular-24.pcf.license
Normal file
3
examples/fonts/Junction-regular-24.pcf.license
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# SPDX-FileCopyrightText: 2010, Caroline Hadilaksono <caroline@hadilaksono.com>, with Reserved Font Name: "Junction"
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: OFL-1.1-RFN
|
||||||
12458
examples/fonts/LeagueSpartan-Bold-16.bdf
Normal file
12458
examples/fonts/LeagueSpartan-Bold-16.bdf
Normal file
File diff suppressed because it is too large
Load diff
4
examples/fonts/LeagueSpartan-Bold-16.bdf.license
Normal file
4
examples/fonts/LeagueSpartan-Bold-16.bdf.license
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# SPDX-FileCopyrightText: 2016-2020, Tyler Finck
|
||||||
|
# SPDX-FileCopyrightText: 2014, Micah Rich <micah@micahrich.com>, with Reserved Font Name: "League Spartan".
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: OFL-1.1-RFN
|
||||||
|
|
@ -1 +1,5 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
Adafruit-Blinka
|
Adafruit-Blinka
|
||||||
|
|
|
||||||
4
setup.py
4
setup.py
|
|
@ -1,3 +1,7 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
"""A setuptools based setup module.
|
"""A setuptools based setup module.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
"""Implementation of minimal displayio subset for testing"""
|
||||||
|
|
||||||
|
# pylint: disable=all
|
||||||
class Bitmap:
|
class Bitmap:
|
||||||
def __init__(self, width, height, color_count):
|
def __init__(self, width, height, color_count):
|
||||||
self.width = width
|
self.width = width
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
"""Implementation of minimal fontio subset for testing"""
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
Glyph = collections.namedtuple(
|
Glyph = collections.namedtuple(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue