mirror of
https://github.com/slavfox/Cozette.git
synced 2024-10-03 20:07:52 +03:00
HiDpi builds
This commit is contained in:
parent
ab2dd8252e
commit
8d457f31a1
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
pacman -Syyu --noconfirm
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pacman -S --noconfirm base git tar which zip libffi
|
||||
pacman -S --noconfirm base git tar which zip libffi jre17-openjdk wget
|
||||
- name: Install python
|
||||
run: |
|
||||
pacman -S --noconfirm python python-pipenv python-setuptools
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@ __pycache__/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
deps/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
|
19
CHANGELOG.md
19
CHANGELOG.md
@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog], and this project adheres to
|
||||
[Semantic Versioning].
|
||||
|
||||
## [1.19.2-hidpi]
|
||||
|
||||
### Added
|
||||
|
||||
- Bold and HiDpi variants
|
||||
|
||||
### Changed
|
||||
|
||||
- TTF fonts should work slightly better now.
|
||||
- Rewrote the build system to use [monobit](https://github.com/robhagemans/monobit) and [bitsnpicas](https://github.com/kreativekorp/bitsnpicas/releases/download/v2.0/BitsNPicas.jar).
|
||||
|
||||
## [1.19.2]
|
||||
|
||||
GitHub Copilot CLI update.
|
||||
@ -2087,9 +2098,11 @@ Still broken on Windows.
|
||||
|
||||
[keep a changelog]: https://keepachangelog.com/en/1.0.0/
|
||||
[semantic versioning]: https://semver.org/spec/v2.0.0.html
|
||||
[unreleased]: https://github.com/slavfox/Cozette/compare/v.1.19.1...HEAD
|
||||
[1.19.1]: https://github.com/slavfox/Cozette/compare/v.1.19.0...1.19.1
|
||||
[1.19.0]: https://github.com/slavfox/Cozette/compare/v.1.18.1...1.19.0
|
||||
[unreleased]: https://github.com/slavfox/Cozette/compare/v.1.19.2-hidpi...HEAD
|
||||
[1.19.2-hidpi]: https://github.com/slavfox/Cozette/compare/v.1.19.2...v.1.19.2-hidpi
|
||||
[1.19.2]: https://github.com/slavfox/Cozette/compare/v.1.19.1...v.1.19.2
|
||||
[1.19.1]: https://github.com/slavfox/Cozette/compare/v.1.19.0...v.1.19.1
|
||||
[1.19.0]: https://github.com/slavfox/Cozette/compare/v.1.18.1...v.1.19.0
|
||||
[1.18.1]: https://github.com/slavfox/Cozette/compare/v.1.18.0...v.1.18.1
|
||||
[1.18.0]: https://github.com/slavfox/Cozette/compare/v.1.17.2...v.1.18.0
|
||||
[1.17.2]: https://github.com/slavfox/Cozette/compare/v.1.17.1...v.1.17.2
|
||||
|
2
Pipfile
2
Pipfile
@ -18,7 +18,7 @@ setuptools = "*"
|
||||
pip = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
||||
python_version = ">=3.10"
|
||||
|
||||
[pipenv]
|
||||
allow_prereleases = true
|
||||
|
594
Pipfile.lock
generated
594
Pipfile.lock
generated
@ -1,296 +1,308 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "d9ae6b5214a7df96080a597497b5a387714b75c3c6df7819fc3f8fbf6a3cf1a4"
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "76b77df64095b616dbd9abb16e3ba36fd6d047b8b6856c0de254570811c76f02"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": ">=3.10"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
"default": {
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44",
|
||||
"sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'",
|
||||
"version": "==0.4.6"
|
||||
},
|
||||
"crayons": {
|
||||
"hashes": [
|
||||
"sha256:bd33b7547800f2cfbd26b38431f9e64b487a7de74a947b0fafc89b45a601813f",
|
||||
"sha256:e73ad105c78935d71fe454dd4b85c5c437ba199294e7ffd3341842bc683654b1"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.4.0"
|
||||
},
|
||||
"fonttools": {
|
||||
"hashes": [
|
||||
"sha256:106caf6167c4597556b31a8d9175a3fdc0356fdcd70ab19973c3b0d4c893c461",
|
||||
"sha256:dba8d7cdb8e2bac1b3da28c5ed5960de09e59a2fe7e63bb73f5a59e57b0430d2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.39.4"
|
||||
},
|
||||
"gitdb": {
|
||||
"hashes": [
|
||||
"sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a",
|
||||
"sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.0.10"
|
||||
},
|
||||
"gitpython": {
|
||||
"hashes": [
|
||||
"sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573",
|
||||
"sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.1.31"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:04847257662eef90599a1beca30c757d8e562aa8c7d64e91ea465f299469075d",
|
||||
"sha256:06bae17a3629416eb5bae3a429655dc075561206b6d3c1ddfa38b51f273bae5c",
|
||||
"sha256:1365157813810cfda2be9518806bf32f6b5f56e5e501d8299e3b681d53e405e2",
|
||||
"sha256:165b0fb4d5b6349eef7b909be2d61a673bc6e75e0eec43776eea3222385a9d11",
|
||||
"sha256:1bed69508b3b97dd3fb8c439352881c1bd232a0c8dd1e11d8df4e68046d434cf",
|
||||
"sha256:20dd2352806eb229bc79c4fa308431eaf1721c66f7928950ee0381df98a2d269",
|
||||
"sha256:224e8862a1cd357eede831b270b9e6c51d2cbc2bb5cc2e2b8d0c76d52cbd1edc",
|
||||
"sha256:236c8ff573c02677b873e0934419c8e9873bd2b35aaba885170b7b43cb26d5da",
|
||||
"sha256:416da35914d2fecc3afd31127b1eb1a283df33292cfcb453e1c8fb46d52611a1",
|
||||
"sha256:472bdc3ade289d3efa331738b1daa5a529eef0550650f5d5d2eadb936a2f83a5",
|
||||
"sha256:48e33b46b7db13de75dd0c1c919b8b297b5d7a4dc50b181066977ee17bed7cc3",
|
||||
"sha256:5e7ba92ad63ffded03400d5038af89f7788843794c77ad1a37522fa69762b06f",
|
||||
"sha256:7261d100c9bf722057fd5b9cd5b48f2973b17792b41e689eeaf9b55843cd1afd",
|
||||
"sha256:763fca81a8d8beb6bf4b9a9bbf4045b0c134c15ea66c81d26e5b8683b1861293",
|
||||
"sha256:7cf92c2bfbaf7bd52df1a21e56e8d34cff711594498ecbd02a39df3aaada763b",
|
||||
"sha256:8aad2f86d2036622af1e1eb9db94e26618f42a571e02583fa72d5b1983782bf8",
|
||||
"sha256:9a18d2c173a44e48e72614748df5624875439af2d352a416b9f3840583ad9efb",
|
||||
"sha256:a0dab69ef25ccabf6f066a4902e238767cbbe52bc5ff90aa99514f87812ba76a",
|
||||
"sha256:a4a9f1eaa63b5e35e23e5465ed59746b0a680eb5b5da06f2d432f828d32b26c1",
|
||||
"sha256:b1a22ae597ee1d0e2336044854b33965fd92e731efe3c2ab965826e02cca2a8c",
|
||||
"sha256:bd1de5d7ab75cdf56f2247aace7940dfd0a8fd048e07808358d8fca604f1d102",
|
||||
"sha256:dfe2e3845c3b630f6617f9e8a15c8a1cbaf452c9fa32c71ec0a77d09548cd662",
|
||||
"sha256:f59080829bbfe46660a201fc17315a4e8ec6e4499ee745bab3df61866f63e771",
|
||||
"sha256:f64b730004e500f836f6405ad5cd36d309b6ac065366a0855860155f23eb2ad5",
|
||||
"sha256:f8cbdb428d848f03a4f6f534284cf7fb168a6ec0e742357bf65ad268316906ea"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.25.0rc1"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1",
|
||||
"sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba",
|
||||
"sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a",
|
||||
"sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799",
|
||||
"sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51",
|
||||
"sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb",
|
||||
"sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5",
|
||||
"sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270",
|
||||
"sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6",
|
||||
"sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47",
|
||||
"sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf",
|
||||
"sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e",
|
||||
"sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b",
|
||||
"sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66",
|
||||
"sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865",
|
||||
"sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec",
|
||||
"sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c",
|
||||
"sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1",
|
||||
"sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38",
|
||||
"sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906",
|
||||
"sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705",
|
||||
"sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef",
|
||||
"sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc",
|
||||
"sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f",
|
||||
"sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf",
|
||||
"sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392",
|
||||
"sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d",
|
||||
"sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe",
|
||||
"sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32",
|
||||
"sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5",
|
||||
"sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7",
|
||||
"sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44",
|
||||
"sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d",
|
||||
"sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3",
|
||||
"sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625",
|
||||
"sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e",
|
||||
"sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829",
|
||||
"sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089",
|
||||
"sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3",
|
||||
"sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78",
|
||||
"sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96",
|
||||
"sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964",
|
||||
"sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597",
|
||||
"sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99",
|
||||
"sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a",
|
||||
"sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140",
|
||||
"sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7",
|
||||
"sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16",
|
||||
"sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903",
|
||||
"sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1",
|
||||
"sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296",
|
||||
"sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572",
|
||||
"sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115",
|
||||
"sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a",
|
||||
"sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd",
|
||||
"sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4",
|
||||
"sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1",
|
||||
"sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb",
|
||||
"sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa",
|
||||
"sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a",
|
||||
"sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569",
|
||||
"sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c",
|
||||
"sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf",
|
||||
"sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082",
|
||||
"sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062",
|
||||
"sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==9.5.0"
|
||||
},
|
||||
"pip": {
|
||||
"hashes": [
|
||||
"sha256:0e7c86f486935893c708287b30bd050a36ac827ec7fe5e43fe7cb198dd835fba",
|
||||
"sha256:3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==23.1.2"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f",
|
||||
"sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==67.8.0"
|
||||
},
|
||||
"smmap": {
|
||||
"hashes": [
|
||||
"sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94",
|
||||
"sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==5.0.0"
|
||||
}
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da",
|
||||
"sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==0.4.5"
|
||||
},
|
||||
"crayons": {
|
||||
"hashes": [
|
||||
"sha256:bd33b7547800f2cfbd26b38431f9e64b487a7de74a947b0fafc89b45a601813f",
|
||||
"sha256:e73ad105c78935d71fe454dd4b85c5c437ba199294e7ffd3341842bc683654b1"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.4.0"
|
||||
},
|
||||
"fonttools": {
|
||||
"hashes": [
|
||||
"sha256:4606e1a88ee1f6699d182fea9511bd9a8a915d913eab4584e5226da1180fcce7",
|
||||
"sha256:fff6b752e326c15756c819fe2fe7ceab69f96a1dbcfe8911d0941cdb49905007"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.37.1"
|
||||
},
|
||||
"gitdb": {
|
||||
"hashes": [
|
||||
"sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd",
|
||||
"sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.0.9"
|
||||
},
|
||||
"gitpython": {
|
||||
"hashes": [
|
||||
"sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704",
|
||||
"sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.1.27"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:17e5226674f6ea79e14e3b91bfbc153fdf3ac13f5cc54ee7bc8fdbe820a32da0",
|
||||
"sha256:2bd879d3ca4b6f39b7770829f73278b7c5e248c91d538aab1e506c628353e47f",
|
||||
"sha256:4f41f5bf20d9a521f8cab3a34557cd77b6f205ab2116651f12959714494268b0",
|
||||
"sha256:5593f67e66dea4e237f5af998d31a43e447786b2154ba1ad833676c788f37cde",
|
||||
"sha256:5e28cd64624dc2354a349152599e55308eb6ca95a13ce6a7d5679ebff2962913",
|
||||
"sha256:633679a472934b1c20a12ed0c9a6c9eb167fbb4cb89031939bfd03dd9dbc62b8",
|
||||
"sha256:806970e69106556d1dd200e26647e9bee5e2b3f1814f9da104a943e8d548ca38",
|
||||
"sha256:806cc25d5c43e240db709875e947076b2826f47c2c340a5a2f36da5bb10c58d6",
|
||||
"sha256:8247f01c4721479e482cc2f9f7d973f3f47810cbc8c65e38fd1bbd3141cc9842",
|
||||
"sha256:8ebf7e194b89bc66b78475bd3624d92980fca4e5bb86dda08d677d786fefc414",
|
||||
"sha256:8ecb818231afe5f0f568c81f12ce50f2b828ff2b27487520d85eb44c71313b9e",
|
||||
"sha256:8f9d84a24889ebb4c641a9b99e54adb8cab50972f0166a3abc14c3b93163f074",
|
||||
"sha256:909c56c4d4341ec8315291a105169d8aae732cfb4c250fbc375a1efb7a844f8f",
|
||||
"sha256:9b83d48e464f393d46e8dd8171687394d39bc5abfe2978896b77dc2604e8635d",
|
||||
"sha256:ac987b35df8c2a2eab495ee206658117e9ce867acf3ccb376a19e83070e69418",
|
||||
"sha256:b78d00e48261fbbd04aa0d7427cf78d18401ee0abd89c7559bbf422e5b1c7d01",
|
||||
"sha256:b8b97a8a87cadcd3f94659b4ef6ec056261fa1e1c3317f4193ac231d4df70215",
|
||||
"sha256:bd5b7ccae24e3d8501ee5563e82febc1771e73bd268eef82a1e8d2b4d556ae66",
|
||||
"sha256:bdc02c0235b261925102b1bd586579b7158e9d0d07ecb61148a1799214a4afd5",
|
||||
"sha256:be6b350dfbc7f708d9d853663772a9310783ea58f6035eec649fb9c4371b5389",
|
||||
"sha256:c403c81bb8ffb1c993d0165a11493fd4bf1353d258f6997b3ee288b0a48fce77",
|
||||
"sha256:cf8c6aed12a935abf2e290860af8e77b26a042eb7f2582ff83dc7ed5f963340c",
|
||||
"sha256:d98addfd3c8728ee8b2c49126f3c44c703e2b005d4a95998e2167af176a9e722",
|
||||
"sha256:dc76bca1ca98f4b122114435f83f1fcf3c0fe48e4e6f660e07996abf2f53903c",
|
||||
"sha256:dec198619b7dbd6db58603cd256e092bcadef22a796f778bf87f8592b468441d",
|
||||
"sha256:df28dda02c9328e122661f399f7655cdcbcf22ea42daa3650a26bce08a187450",
|
||||
"sha256:e603ca1fb47b913942f3e660a15e55a9ebca906857edfea476ae5f0fe9b457d5",
|
||||
"sha256:ecfdd68d334a6b97472ed032b5b37a30d8217c097acfff15e8452c710e775524"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.23.2"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927",
|
||||
"sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14",
|
||||
"sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc",
|
||||
"sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58",
|
||||
"sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60",
|
||||
"sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76",
|
||||
"sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c",
|
||||
"sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac",
|
||||
"sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490",
|
||||
"sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1",
|
||||
"sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f",
|
||||
"sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d",
|
||||
"sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f",
|
||||
"sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069",
|
||||
"sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402",
|
||||
"sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885",
|
||||
"sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e",
|
||||
"sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be",
|
||||
"sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8",
|
||||
"sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff",
|
||||
"sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da",
|
||||
"sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004",
|
||||
"sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f",
|
||||
"sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20",
|
||||
"sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d",
|
||||
"sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c",
|
||||
"sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544",
|
||||
"sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9",
|
||||
"sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3",
|
||||
"sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04",
|
||||
"sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c",
|
||||
"sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5",
|
||||
"sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4",
|
||||
"sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb",
|
||||
"sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4",
|
||||
"sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c",
|
||||
"sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467",
|
||||
"sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e",
|
||||
"sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421",
|
||||
"sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b",
|
||||
"sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8",
|
||||
"sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb",
|
||||
"sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3",
|
||||
"sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf",
|
||||
"sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1",
|
||||
"sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a",
|
||||
"sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28",
|
||||
"sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0",
|
||||
"sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1",
|
||||
"sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8",
|
||||
"sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd",
|
||||
"sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4",
|
||||
"sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8",
|
||||
"sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f",
|
||||
"sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013",
|
||||
"sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59",
|
||||
"sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc",
|
||||
"sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==9.2.0"
|
||||
},
|
||||
"pip": {
|
||||
"hashes": [
|
||||
"sha256:3fd1929db052f056d7a998439176d3333fa1b3f6c1ad881de1885c0717608a4b",
|
||||
"sha256:b61a374b5bc40a6e982426aede40c9b5a08ff20e640f5b56977f4f91fed1e39a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==22.2.2"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82",
|
||||
"sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==65.3.0"
|
||||
},
|
||||
"smmap": {
|
||||
"hashes": [
|
||||
"sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94",
|
||||
"sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==5.0.0"
|
||||
"develop": {
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5",
|
||||
"sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915",
|
||||
"sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326",
|
||||
"sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940",
|
||||
"sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b",
|
||||
"sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30",
|
||||
"sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c",
|
||||
"sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c",
|
||||
"sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab",
|
||||
"sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27",
|
||||
"sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2",
|
||||
"sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961",
|
||||
"sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9",
|
||||
"sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb",
|
||||
"sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70",
|
||||
"sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331",
|
||||
"sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2",
|
||||
"sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266",
|
||||
"sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d",
|
||||
"sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6",
|
||||
"sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b",
|
||||
"sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925",
|
||||
"sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8",
|
||||
"sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4",
|
||||
"sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==23.3.0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:0ec8b74806e80fec33e6e7ba89d35e17b3eb1c4c74316ea44cf877cc26e8b118",
|
||||
"sha256:cde11e804641edbe1b6b95d56582eb541f27eebc77864c6015545944bb0e9c76"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==6.0.0b2"
|
||||
},
|
||||
"mypy": {
|
||||
"hashes": [
|
||||
"sha256:1c4c42c60a8103ead4c1c060ac3cdd3ff01e18fddce6f1016e08939647a0e703",
|
||||
"sha256:44797d031a41516fcf5cbfa652265bb994e53e51994c1bd649ffcd0c3a7eccbf",
|
||||
"sha256:473117e310febe632ddf10e745a355714e771ffe534f06db40702775056614c4",
|
||||
"sha256:4c99c3ecf223cf2952638da9cd82793d8f3c0c5fa8b6ae2b2d9ed1e1ff51ba85",
|
||||
"sha256:550a8b3a19bb6589679a7c3c31f64312e7ff482a816c96e0cecec9ad3a7564dd",
|
||||
"sha256:658fe7b674769a0770d4b26cb4d6f005e88a442fe82446f020be8e5f5efb2fae",
|
||||
"sha256:6e33bb8b2613614a33dff70565f4c803f889ebd2f859466e42b46e1df76018dd",
|
||||
"sha256:6e42d29e324cdda61daaec2336c42512e59c7c375340bd202efa1fe0f7b8f8ca",
|
||||
"sha256:74bc9b6e0e79808bf8678d7678b2ae3736ea72d56eede3820bd3849823e7f305",
|
||||
"sha256:76ec771e2342f1b558c36d49900dfe81d140361dd0d2df6cd71b3db1be155409",
|
||||
"sha256:7d23370d2a6b7a71dc65d1266f9a34e4cde9e8e21511322415db4b26f46f6b8c",
|
||||
"sha256:87df44954c31d86df96c8bd6e80dfcd773473e877ac6176a8e29898bfb3501cb",
|
||||
"sha256:8c5979d0deb27e0f4479bee18ea0f83732a893e81b78e62e2dda3e7e518c92ee",
|
||||
"sha256:95d8d31a7713510685b05fbb18d6ac287a56c8f6554d88c19e73f724a445448a",
|
||||
"sha256:a22435632710a4fcf8acf86cbd0d69f68ac389a3892cb23fbad176d1cddaf228",
|
||||
"sha256:a8763e72d5d9574d45ce5881962bc8e9046bf7b375b0abf031f3e6811732a897",
|
||||
"sha256:c1eb485cea53f4f5284e5baf92902cd0088b24984f4209e25981cc359d64448d",
|
||||
"sha256:c5d2cc54175bab47011b09688b418db71403aefad07cbcd62d44010543fc143f",
|
||||
"sha256:cbc07246253b9e3d7d74c9ff948cd0fd7a71afcc2b77c7f0a59c26e9395cb152",
|
||||
"sha256:d0b6c62206e04061e27009481cb0ec966f7d6172b5b936f3ead3d74f29fe3dcf",
|
||||
"sha256:ddae0f39ca146972ff6bb4399f3b2943884a774b8771ea0a8f50e971f5ea5ba8",
|
||||
"sha256:e1f4d16e296f5135624b34e8fb741eb0eadedca90862405b1f1fde2040b9bd11",
|
||||
"sha256:e86c2c6852f62f8f2b24cb7a613ebe8e0c7dc1402c61d36a609174f63e0ff017",
|
||||
"sha256:ebc95f8386314272bbc817026f8ce8f4f0d2ef7ae44f947c4664efac9adec929",
|
||||
"sha256:f9dca1e257d4cc129517779226753dbefb4f2266c4eaad610fc15c6a7e14283e",
|
||||
"sha256:faff86aa10c1aa4a10e1a301de160f3d8fc8703b88c7e98de46b531ff1276a9a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
|
||||
"sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==1.0.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61",
|
||||
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==23.1"
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687",
|
||||
"sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.11.1"
|
||||
},
|
||||
"platformdirs": {
|
||||
"hashes": [
|
||||
"sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed",
|
||||
"sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.5.3"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26",
|
||||
"sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.6.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90",
|
||||
"sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c",
|
||||
"sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78",
|
||||
"sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4",
|
||||
"sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee",
|
||||
"sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e",
|
||||
"sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e",
|
||||
"sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6",
|
||||
"sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9",
|
||||
"sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c",
|
||||
"sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256",
|
||||
"sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f",
|
||||
"sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2",
|
||||
"sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c",
|
||||
"sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b",
|
||||
"sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807",
|
||||
"sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf",
|
||||
"sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def",
|
||||
"sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad",
|
||||
"sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d",
|
||||
"sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849",
|
||||
"sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69",
|
||||
"sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==22.6.0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7",
|
||||
"sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.10.1"
|
||||
},
|
||||
"mypy": {
|
||||
"hashes": [
|
||||
"sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655",
|
||||
"sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9",
|
||||
"sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3",
|
||||
"sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6",
|
||||
"sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0",
|
||||
"sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58",
|
||||
"sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103",
|
||||
"sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09",
|
||||
"sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417",
|
||||
"sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56",
|
||||
"sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2",
|
||||
"sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856",
|
||||
"sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0",
|
||||
"sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8",
|
||||
"sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27",
|
||||
"sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5",
|
||||
"sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71",
|
||||
"sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27",
|
||||
"sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe",
|
||||
"sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca",
|
||||
"sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf",
|
||||
"sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9",
|
||||
"sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.971"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
|
||||
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
|
||||
],
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a",
|
||||
"sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"
|
||||
],
|
||||
"version": "==0.9.0"
|
||||
},
|
||||
"platformdirs": {
|
||||
"hashes": [
|
||||
"sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788",
|
||||
"sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.5.2"
|
||||
},
|
||||
"tomli": {
|
||||
"hashes": [
|
||||
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
|
||||
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
|
||||
],
|
||||
"markers": "python_full_version < '3.11.0a7'",
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02",
|
||||
"sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
53
README.md
53
README.md
@ -21,6 +21,7 @@ A bitmap programming font optimized for coziness.
|
||||
- [Dmenu](#dmenu)
|
||||
- [VSCode, general GUI applications](#vscode-general-gui-applications)
|
||||
- [Kitty](#kitty)
|
||||
- [Variants](#variants)
|
||||
- [Roadmap](#roadmap)
|
||||
- [Recommended alternatives](#recommended-alternatives)
|
||||
- [Character map](#character-map)
|
||||
@ -53,31 +54,40 @@ A nicer character map that includes the codepoints can be found at
|
||||
|
||||
### [You can get Cozette over at the Releases tab]!
|
||||
|
||||
Cozette is distributed in two main variants: bitmap and vector.
|
||||
## Variants and Sizes
|
||||
|
||||
Cozette is distributed in three main variants: normal and hi-dpi (upscaled 2x) bitmaps
|
||||
(`.bdf`, `.otb`, `.psf`, and `.fnt`), and vectors (`.ttf`).
|
||||
|
||||
Font scaling varies wildly from system to system, and sometimes even from
|
||||
program to program and font format to format. On my system (Linux), `cozette.otb`
|
||||
looks right at 13pts; `cozette_hidpi.otb` looks right at 26pts and downscales
|
||||
quite elegantly to 10pts; `CozetteVector` doesn't look right at any size (technically,
|
||||
it will look right specifically at 9.4pts on a 100dpi screen on Linux, but pixel-perfect
|
||||
bitmap fonts are a massive headache, treated differently by every OS, that I'm not quite sure how to solve)
|
||||
|
||||
Bitmap fonts are, effectively, just that - bitmaps. They scale terribly, but
|
||||
look nice and sharp (and pixel-perfect) at one specific point
|
||||
size. Vector fonts scale well, but in this case, might look ugly at
|
||||
smaller point sizes because of antialiasing issues and the like.
|
||||
|
||||
<h3>
|
||||
The vector formats (CozetteVector) are provided as a compatibility feature.
|
||||
They look hideous. They don't contain any glyphs past U+FFFF.
|
||||
<h3>NOTE:</h3>
|
||||
The vector formats (`CozetteVector`) are provided as a compatibility feature.
|
||||
Rendering of vectorized bitmap-like fonts is <em>terrible</em> on virtually all operating systems.
|
||||
|
||||
If Cozette looks awful on your system, you probably have a vector version.
|
||||
<em>Please</em> use the bitmap formats (.otb) if you can.
|
||||
<em>Please</em> use the bitmap formats (`.otb`) if you can.
|
||||
|
||||
Issues with vector formats will <em>not</em> be fixed or addressed.
|
||||
Cozette is a bitmap font first and foremost.
|
||||
</h3>
|
||||
Issues with vector formats will almost certainly <em>not</em> be fixed or
|
||||
addressed; Cozette is a bitmap font first and foremost, and building a
|
||||
bitmap font that builds from a single source and looks good both in its intended,
|
||||
bitmap font as well as as the auto-vectorized format, on every OS, seems to be an unsolved problem.
|
||||
|
||||
### Linux
|
||||
|
||||
The preferred format is `.otb` (for bitmaps) or `.ttf`
|
||||
(for CozetteVector). To install the font, just throw it in your fonts directory
|
||||
(you probably want to follow your distro's instructions). On Ubuntu, if you
|
||||
don't want to reconsider your distro choice, you might need to
|
||||
(you probably want to follow your distro's instructions). On Ubuntu you might need to
|
||||
[specifically enable bitmap fonts].
|
||||
|
||||
**If you're on Arch**, [ifreund] made [an AUR package] for the .otb! Install it
|
||||
@ -183,12 +193,14 @@ implemented:
|
||||
many other CLI tools!
|
||||
- [x] Charmap including the code points (to make it easier for users to
|
||||
report issues/request additions)
|
||||
- [ ] Codepoints above U+FFFF in vector fonts
|
||||
- [x] Codepoints above U+FFFF in vector fonts
|
||||
- [x] Upscaled hi-dpi variant
|
||||
|
||||
# Recommended alternatives
|
||||
|
||||
Cozette is, intentionally, a very small font. If you're looking for other
|
||||
bitmap fonts with extra glyphs, a couple of my favorites are
|
||||
Cozette is, intentionally, a very small font. If neither the base nor the
|
||||
[HiDpi](#variants) version fit your needs, you might want to look at some
|
||||
other bitmap fonts with extra glyphs. A couple of my favorites are
|
||||
[Tamzen](https://github.com/sunaku/tamzen-font/)
|
||||
and [Envypn](https://github.com/Sorixelle/envypn-powerline). You might also
|
||||
find the [Tecate/bitmap-fonts repo](https://github.com/Tecate/bitmap-fonts)
|
||||
@ -204,30 +216,30 @@ look in Cozette, here is a screenshot of it:
|
||||
|
||||
# Building
|
||||
|
||||
If you want to build Cozette yourself, you'll need [FontForge]. Once you
|
||||
If you want to build Cozette yourself, you'll need [FontForge] and Java. Once you
|
||||
have that, just clone this repo, open `Cozette/Cozette.sfd` in FontForge,
|
||||
and go to _File → Generate Fonts..._.
|
||||
|
||||
To run the build scripts I use to prepare releases, first install Python 3.8
|
||||
To run the build scripts I use to prepare releases, first install Python (at least 3.8)
|
||||
and [pipenv]. For generating the images, you will also need `xorg-mkfontscale`
|
||||
and `xterm`.
|
||||
Then, install the dependencies and run `build.py fonts`:
|
||||
|
||||
```console
|
||||
$ pipenv install
|
||||
$ pipenv run python3.8 build.py fonts
|
||||
$ pipenv run python build.py fonts
|
||||
```
|
||||
|
||||
Then install the generated fonts, and run
|
||||
|
||||
```console
|
||||
$ pipenv run python3.8 build.py images
|
||||
$ pipenv run python build.py images
|
||||
```
|
||||
|
||||
Running
|
||||
|
||||
```console
|
||||
$ pipenv run python3.8 build.py changelog
|
||||
$ pipenv run python build.py changelog
|
||||
```
|
||||
|
||||
will output the changelog between your local version and the last tag.
|
||||
@ -238,10 +250,13 @@ Massive thanks to [ym1234] for helping me figure out how to make the font tables
|
||||
|
||||
Thanks to [autumn], [cpkio], [yoshiyoshyosh], and [klinegareth] for contributing characters!
|
||||
|
||||
# License
|
||||
# License & Acknowledgements
|
||||
|
||||
Cozette is licensed [MIT] 💜
|
||||
|
||||
Cozette's builds use [bdfscale](https://github.com/philj56/bdfscale) by [philj56](https://github.com/philj56) and
|
||||
[Bits'N'Picas](https://github.com/kreativekorp/bitsnpicas) by [Kreative Software](https://github.com/kreativekorp).
|
||||
|
||||
[dina]: https://www.dcmembers.com/jibsen/download/61/
|
||||
[proggy]: https://github.com/bluescan/proggyfonts
|
||||
[creep]: https://github.com/romeovs/creep
|
||||
|
9
bitsnpicas.sh
Executable file
9
bitsnpicas.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env sh
|
||||
BITSNPICAS_URL="https://github.com/kreativekorp/bitsnpicas/releases/download/v2.0/BitsNPicas.jar"
|
||||
mkdir -p deps
|
||||
if [ ! -f deps/BitsNPicas.jar ]; then
|
||||
echo "Downloading BitsNPicas.jar..."
|
||||
wget -O deps/BitsNPicas.jar $BITSNPICAS_URL
|
||||
echo "Done."
|
||||
fi
|
||||
java -jar deps/BitsNPicas.jar $@
|
125
build.py
125
build.py
@ -1,16 +1,15 @@
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from shlex import quote
|
||||
from shutil import copy, rmtree
|
||||
from shutil import rmtree
|
||||
from typing import Optional, Sequence, cast
|
||||
|
||||
import crayons # type: ignore
|
||||
|
||||
from cozette_builder.changeloggen import get_changelog
|
||||
from cozette_builder.hidpi import double_size
|
||||
from cozette_builder.imagegen import (
|
||||
add_margins,
|
||||
read_sample,
|
||||
@ -22,7 +21,6 @@ from cozette_builder.scanner import (
|
||||
print_codepoints_for_changelog,
|
||||
scan_for_codepoints,
|
||||
)
|
||||
from cozette_builder.ttfbuilder import TTFBuilder
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent
|
||||
BUILD_DIR = REPO_ROOT / "build"
|
||||
@ -43,7 +41,7 @@ class Generate:
|
||||
)
|
||||
|
||||
|
||||
def save_images(otbpath):
|
||||
def save_images():
|
||||
print(crayons.yellow("Saving character map"))
|
||||
save_charlist(FONTNAME, SFDPATH, REPO_ROOT / "img")
|
||||
|
||||
@ -82,43 +80,119 @@ def gen_bitmap_formats() -> Path:
|
||||
generate=[
|
||||
Generate("cozette.", bitmap_fmt="bdf"),
|
||||
Generate("cozette.", "otb"),
|
||||
Generate("cozette.", "psf"),
|
||||
Generate("cozette.", "fnt"),
|
||||
Generate("cozette_bitmap.ttf", "otb"),
|
||||
Generate("cozette_bitmap.dfont", "sbit"),
|
||||
Generate("cozette.dfont", "sbit"),
|
||||
],
|
||||
)
|
||||
rename_single(BUILD_DIR, "*.fnt", "cozette.fnt")
|
||||
bdfpath = rename_single(BUILD_DIR, "*.bdf", "cozette.bdf")
|
||||
return bdfpath
|
||||
return rename_single(BUILD_DIR, "*.bdf", "cozette.bdf")
|
||||
|
||||
|
||||
def fix_ttf(ttfpath: Path):
|
||||
outname = "CozetteVector"
|
||||
def fix_ttf(ttfpath: Path, name: str):
|
||||
print(crayons.yellow(f"Generating TTF for {name}..."))
|
||||
script = "; ".join(
|
||||
[
|
||||
f'Open("{ttfpath}")',
|
||||
"SelectWorthOutputting()",
|
||||
"RemoveOverlap()",
|
||||
"CorrectDirection()",
|
||||
"Simplify()",
|
||||
"Simplify(-1, 1.02)",
|
||||
"ScaleToEm(2048)",
|
||||
'RenameGlyphs("AGL with PUA")',
|
||||
'Reencode("unicode")',
|
||||
f'Generate("{outname}.dfont")',
|
||||
f'Generate("{outname}.otf.dfont")',
|
||||
f'Generate("{outname}.otf")',
|
||||
"ScaleToEm(1024)",
|
||||
f'Generate("{outname}.ttf")',
|
||||
f'SetTTFName(0x409, 3, "{name}")',
|
||||
f'SetTTFName(0x409, 11, "")',
|
||||
'SetTTFName(0x409, 13, "MIT")',
|
||||
'SetTTFName(0x409, 14, "https://opensource.org/licenses/MIT")',
|
||||
f'Generate("{name}.dfont")',
|
||||
f'Generate("{name}.otf")',
|
||||
f'Generate("{name}.ttf")',
|
||||
]
|
||||
)
|
||||
|
||||
# No idea why this doesn't work without shell=True
|
||||
subprocess.run(
|
||||
[f"fontforge -lang ff -c {quote(script)}"], cwd=BUILD_DIR, shell=True
|
||||
[f"fontforge -lang ff -c {quote(script)}"],
|
||||
cwd=BUILD_DIR,
|
||||
shell=True,
|
||||
check=True,
|
||||
)
|
||||
ttfpath.unlink()
|
||||
|
||||
|
||||
def make_hidpi(bdf_path: Path, out_path: Path):
|
||||
print(crayons.yellow("Generating hidpi font..."))
|
||||
with bdf_path.open() as i:
|
||||
with out_path.open("w") as o:
|
||||
double_size(i, o)
|
||||
print(crayons.green("Done!"))
|
||||
|
||||
|
||||
def gen_variants(bdf_path: Path):
|
||||
hidpi_path = BUILD_DIR / "cozette_hidpi.bdf"
|
||||
|
||||
def bnp_invoc_ttf(name: str, format: str):
|
||||
return [
|
||||
REPO_ROOT / "bitsnpicas.sh",
|
||||
"convertbitmap",
|
||||
"-f",
|
||||
format,
|
||||
"-o",
|
||||
BUILD_DIR / f"{name}_tmp.{format}",
|
||||
"-s",
|
||||
"Cozette",
|
||||
"-r",
|
||||
name,
|
||||
"-T",
|
||||
]
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
BUILD_DIR.parent / "bitsnpicas.sh",
|
||||
"convertbitmap",
|
||||
"-f",
|
||||
"psf",
|
||||
"-o",
|
||||
BUILD_DIR / f"cozette.psf",
|
||||
bdf_path,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(
|
||||
bnp_invoc_ttf("CozetteVector", "ttf") + [bdf_path], check=True
|
||||
)
|
||||
subprocess.run(
|
||||
bnp_invoc_ttf("CozetteVectorBold", "ttf") + ["-b", bdf_path],
|
||||
check=True,
|
||||
)
|
||||
print(crayons.yellow("Fixing TTF variants..."))
|
||||
fix_ttf(BUILD_DIR / "CozetteVector_tmp.ttf", "CozetteVector")
|
||||
fix_ttf(BUILD_DIR / "CozetteVectorBold_tmp.ttf", "CozetteVectorBold")
|
||||
print(crayons.green("Done!"))
|
||||
make_hidpi(bdf_path, hidpi_path)
|
||||
fontforge(
|
||||
open=hidpi_path,
|
||||
generate=[
|
||||
Generate(f"{hidpi_path.stem}.", "otb"),
|
||||
Generate(f"{hidpi_path.stem}.", "fnt"),
|
||||
Generate(f"{hidpi_path.stem}.dfont", "sbit"),
|
||||
],
|
||||
)
|
||||
rename_single(BUILD_DIR, "*-26.fnt", "cozette_hidpi.fnt")
|
||||
subprocess.run(
|
||||
[
|
||||
BUILD_DIR.parent / "bitsnpicas.sh",
|
||||
"convertbitmap",
|
||||
"-f",
|
||||
"psf",
|
||||
"-o",
|
||||
hidpi_path.with_suffix(".psf"),
|
||||
hidpi_path,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
subparsers = parser.add_subparsers(dest="action")
|
||||
@ -151,21 +225,16 @@ if __name__ == "__main__":
|
||||
)
|
||||
if args.action == "images":
|
||||
print(crayons.blue("Saving sample images..."))
|
||||
save_images(BUILD_DIR / "cozette.otb")
|
||||
save_images()
|
||||
print(crayons.green("Done!", bold=True))
|
||||
elif args.action == "fonts":
|
||||
rmtree(BUILD_DIR, ignore_errors=True)
|
||||
BUILD_DIR.mkdir(exist_ok=True)
|
||||
os.chdir(BUILD_DIR)
|
||||
print(crayons.blue("Building bitmap formats..."))
|
||||
bdfpath = gen_bitmap_formats()
|
||||
bdf_path = gen_bitmap_formats()
|
||||
print(crayons.green("Done!", bold=True))
|
||||
print(crayons.blue("Generating TTF..."))
|
||||
ttfbuilder = TTFBuilder.from_bdf_path(bdfpath)
|
||||
ttfbuilder.build("cozette-tmp.ttf")
|
||||
print(crayons.green("Done!", bold=True))
|
||||
print(crayons.blue("Fixing TTF..."))
|
||||
fix_ttf(Path("cozette-tmp.ttf"))
|
||||
print(crayons.blue("Building variants..."))
|
||||
gen_variants(bdf_path)
|
||||
print(crayons.green("Done!", bold=True))
|
||||
elif args.action == "changelog":
|
||||
get_changelog()
|
||||
|
@ -1,125 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import (
|
||||
Dict,
|
||||
Iterable,
|
||||
List,
|
||||
Literal,
|
||||
NamedTuple,
|
||||
TextIO,
|
||||
Tuple,
|
||||
Union,
|
||||
)
|
||||
|
||||
import numpy as np # type: ignore
|
||||
from fontTools.pens.ttGlyphPen import TTGlyphPen # type: ignore
|
||||
|
||||
Bit = Union[Literal[1], Literal[0]]
|
||||
|
||||
|
||||
class BBX(NamedTuple):
|
||||
w: int
|
||||
h: int
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
class BdfGlyph:
|
||||
def __init__(self, bits: np.array, meta: Dict[str, str]):
|
||||
|
||||
self.bbx = bbx = BBX(*[int(s) for s in meta["BBX"].split()])
|
||||
# this is probably wrong
|
||||
self.bits: np.array = bits[0 : bbx.h, 0 : bbx.w]
|
||||
self.metadata = meta
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, s: str, meta: Dict[str, str]) -> BdfGlyph:
|
||||
return cls.from_iterable((int(l, 16) for l in s.splitlines()), meta)
|
||||
|
||||
@classmethod
|
||||
def from_iterable(
|
||||
cls, values: Iterable[int], meta: Dict[str, str]
|
||||
) -> BdfGlyph:
|
||||
return BdfGlyph(
|
||||
np.unpackbits(
|
||||
np.array([[v] for v in values], dtype=np.uint8), axis=1
|
||||
),
|
||||
meta=meta,
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "\n".join(
|
||||
"".join("#" if ch else " " for ch in line) for line in self.bits
|
||||
)
|
||||
|
||||
def draw(self, ppp: float):
|
||||
pen = TTGlyphPen(None)
|
||||
for y, row in enumerate(reversed(self.bits)):
|
||||
for x, col in enumerate(row):
|
||||
if col:
|
||||
pen.moveTo(
|
||||
((x + self.bbx.x) * ppp, (y + self.bbx.y) * ppp)
|
||||
)
|
||||
pen.lineTo(
|
||||
((x + self.bbx.x + 1) * ppp, (y + self.bbx.y) * ppp)
|
||||
)
|
||||
pen.lineTo(
|
||||
(
|
||||
(x + self.bbx.x + 1) * ppp,
|
||||
(y + self.bbx.y + 1) * ppp,
|
||||
)
|
||||
)
|
||||
pen.lineTo(
|
||||
((x + self.bbx.x) * ppp, (y + self.bbx.y + 1) * ppp)
|
||||
)
|
||||
pen.lineTo(
|
||||
((x + self.bbx.x) * ppp, (y + self.bbx.y) * ppp)
|
||||
)
|
||||
pen.closePath()
|
||||
return pen.glyph()
|
||||
|
||||
def meta(self, k) -> List[str]:
|
||||
return self.metadata[k].strip('"').strip().split()
|
||||
|
||||
|
||||
def parse_char(bdfstream: TextIO) -> Tuple[Dict[str, str], List[int]]:
|
||||
specs = {}
|
||||
while not (line := bdfstream.readline()).startswith("BITMAP"):
|
||||
parts = line.split(maxsplit=1)
|
||||
specs[parts[0]] = parts[1].strip()
|
||||
bitmap = []
|
||||
while not (line := bdfstream.readline()).startswith("ENDCHAR"):
|
||||
bitmap.append(int(line.strip(), 16))
|
||||
return specs, bitmap
|
||||
|
||||
|
||||
class BdfFont:
|
||||
def __init__(self, metadata: Dict[str, str], glyphs: Dict[int, BdfGlyph]):
|
||||
self.metadata: Dict[str, str] = metadata
|
||||
self.glyphs: Dict[int, BdfGlyph] = glyphs
|
||||
|
||||
@classmethod
|
||||
def from_bdf(cls, bdfstream: TextIO):
|
||||
metadata = {}
|
||||
while not (line := bdfstream.readline()).startswith("CHARS "):
|
||||
try:
|
||||
k, val = line.split(maxsplit=1)
|
||||
metadata[k] = val.strip()
|
||||
except ValueError:
|
||||
pass
|
||||
glyphs = {}
|
||||
for i in range(int(line.split()[1])):
|
||||
meta, char = parse_char(bdfstream)
|
||||
glyphs[int(meta["ENCODING"])] = BdfGlyph.from_iterable(char, meta)
|
||||
return cls(metadata, glyphs)
|
||||
|
||||
@property
|
||||
def codepoints(self) -> Tuple[int, ...]:
|
||||
return tuple(self.glyphs.keys())
|
||||
|
||||
@property
|
||||
def str_codepoints(self) -> Tuple[str, ...]:
|
||||
return tuple(f"U+{i:X}" for i in self.glyphs)
|
||||
|
||||
def meta(self, k) -> List[str]:
|
||||
return self.metadata[k].strip('"').strip().split()
|
93
cozette_builder/hidpi.py
Normal file
93
cozette_builder/hidpi.py
Normal file
@ -0,0 +1,93 @@
|
||||
# Based on bdfscale by Philip Jones (https://github.com/philj56/bdfscale) under the MIT License; original license
|
||||
# included below:
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2019 Philip Jones
|
||||
#
|
||||
# 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.
|
||||
from io import StringIO
|
||||
from typing import TextIO
|
||||
|
||||
# Lines that need all numbers scaled
|
||||
scale_lines = [
|
||||
"SIZE",
|
||||
"FONTBOUNDINGBOX",
|
||||
"PIXEL_SIZE",
|
||||
"POINT_SIZE",
|
||||
"AVERAGE_WIDTH",
|
||||
"FONT_ASCENT",
|
||||
"FONT_DESCENT",
|
||||
"UNDERLINE_POSITION",
|
||||
"UNDERLINE_THICKNESS",
|
||||
"X_HEIGHT",
|
||||
"CAP_HEIGHT",
|
||||
"RAW_ASCENT",
|
||||
"RAW_DESCENT",
|
||||
"NORM_SPACE",
|
||||
"SUPERSCRIPT_",
|
||||
"SUBSCRIPT_",
|
||||
"FIGURE_WIDTH",
|
||||
"AVG_LOWERCASE_WIDTH",
|
||||
"AVG_UPPERCASE_WIDTH" "DWIDTH",
|
||||
# "SWIDTH",
|
||||
"BBX",
|
||||
"QUAD_WIDTH",
|
||||
]
|
||||
|
||||
|
||||
def double_size(src: TextIO, out: TextIO):
|
||||
bitmap = False
|
||||
for line in src.readlines():
|
||||
if line.startswith("ENDCHAR"):
|
||||
bitmap = False
|
||||
elif bitmap:
|
||||
line = line.strip()
|
||||
pad = len(line) % 2
|
||||
line = line + "0" * pad
|
||||
size = len(line) * 2
|
||||
|
||||
# Do the actual scaling
|
||||
binary = bin(int(line.strip(), 16))[2:]
|
||||
rescaled = "".join([x * 2 for x in binary])
|
||||
res = hex(int(rescaled, 2))[2:].upper()
|
||||
|
||||
line = "0" * (size - len(res)) + res # Pad out to desired length
|
||||
line = (line + "\n") * 2 # And correct number of lines
|
||||
elif any([line.startswith(x) for x in scale_lines]):
|
||||
words = line.split()
|
||||
for i, num in enumerate(words[1:]):
|
||||
words[i + 1] = str(int(num) * 2)
|
||||
line = " ".join(words) + "\n"
|
||||
elif line.startswith("SIZE "):
|
||||
words = line.strip().split()
|
||||
words[1] = str(int(words[1]) * 2)
|
||||
line = " ".join(words) + "\n"
|
||||
elif line.startswith("FONT "):
|
||||
xlfd = line[len("FONT ") :].strip().split("-")
|
||||
# PIXEL_SIZE
|
||||
xlfd[7] = f"{int(xlfd[7]) * 2}"
|
||||
# POINT_SIZE
|
||||
xlfd[8] = f"{int(xlfd[8]) * 2}"
|
||||
# AVERAGE_WIDTH
|
||||
xlfd[12] = f"{int(xlfd[12]) * 2}"
|
||||
line = "FONT " + "-".join(xlfd) + "\n"
|
||||
elif line.startswith("BITMAP"):
|
||||
bitmap = True
|
||||
out.write(line.replace("Cozette", "CozetteHiDpi"))
|
48
cozette_builder/hidpi_prefix.txt
Normal file
48
cozette_builder/hidpi_prefix.txt
Normal file
@ -0,0 +1,48 @@
|
||||
STARTFONT 2.1
|
||||
FONT -slavfox-CozetteHiDpi-Medium-R-Normal--26-240-75-75-M-120-ISO10646-1
|
||||
SIZE 24 75 75
|
||||
FONTBOUNDINGBOX 17 28 -5 -3
|
||||
COMMENT "Generated by fontforge, http://fontforge.sourceforge.net"
|
||||
COMMENT "(c) 2020-2023 Slavfox"
|
||||
STARTPROPERTIES 40
|
||||
FOUNDRY "slavfox"
|
||||
FAMILY_NAME "Cozette"
|
||||
WEIGHT_NAME "Medium"
|
||||
SLANT "R"
|
||||
SETWIDTH_NAME "Normal"
|
||||
ADD_STYLE_NAME ""
|
||||
PIXEL_SIZE 13
|
||||
POINT_SIZE 120
|
||||
RESOLUTION_X 75
|
||||
RESOLUTION_Y 75
|
||||
SPACING "M"
|
||||
AVERAGE_WIDTH 60
|
||||
CHARSET_REGISTRY "ISO10646"
|
||||
CHARSET_ENCODING "1"
|
||||
FONTNAME_REGISTRY ""
|
||||
FONT_NAME "Cozette"
|
||||
FACE_NAME "Cozette"
|
||||
COPYRIGHT "(c) 2020-2023 Slavfox"
|
||||
FONT_VERSION "1.192"
|
||||
FONT_ASCENT 10
|
||||
FONT_DESCENT 3
|
||||
UNDERLINE_POSITION -19
|
||||
UNDERLINE_THICKNESS 13
|
||||
X_HEIGHT 5
|
||||
CAP_HEIGHT 7
|
||||
DEFAULT_CHAR 0
|
||||
RAW_ASCENT 769
|
||||
RAW_DESCENT 230
|
||||
NORM_SPACE 6
|
||||
RELATIVE_WEIGHT 50
|
||||
RELATIVE_SETWIDTH 50
|
||||
SUPERSCRIPT_X 0
|
||||
SUPERSCRIPT_Y 2
|
||||
SUPERSCRIPT_SIZE 2
|
||||
SUBSCRIPT_X 0
|
||||
SUBSCRIPT_Y 2
|
||||
SUBSCRIPT_SIZE 2
|
||||
FIGURE_WIDTH 6
|
||||
AVG_LOWERCASE_WIDTH 60
|
||||
AVG_UPPERCASE_WIDTH 60
|
||||
ENDPROPERTIES
|
@ -1,6 +1,6 @@
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Dict, Iterable, List, Set
|
||||
from typing import Dict, List, Set
|
||||
from unicodedata import name as uniname, east_asian_width as eaw
|
||||
|
||||
UESCAPE = re.compile(r"\\[uU]([0-9A-Fa-f]{4,5})")
|
||||
|
@ -1,103 +0,0 @@
|
||||
from pathlib import Path
|
||||
|
||||
from fontTools.fontBuilder import FontBuilder, _panoseDefaults # type: ignore
|
||||
|
||||
from cozette_builder.bdffont import BdfFont
|
||||
|
||||
with (Path(__file__).resolve().parent.parent / "LICENSE").open() as f:
|
||||
LICENSE_TEXT = f.read()
|
||||
|
||||
|
||||
def get_version():
|
||||
cozette_path = (
|
||||
Path(__file__).resolve().parent.parent / "Cozette" / "Cozette.sfd"
|
||||
)
|
||||
with cozette_path.open() as f:
|
||||
for line in f:
|
||||
if line.startswith("Version:"):
|
||||
_, v = line.split()
|
||||
return v
|
||||
|
||||
|
||||
class TTFBuilder:
|
||||
@classmethod
|
||||
def from_bdf_path(cls, path: Path):
|
||||
with path.open() as f:
|
||||
bdf = BdfFont.from_bdf(f)
|
||||
return cls(bdf)
|
||||
|
||||
def __init__(self, bdf: BdfFont):
|
||||
self.bdf = bdf
|
||||
upm = 1000
|
||||
self.fb = FontBuilder(unitsPerEm=upm)
|
||||
self.ppp = upm / int(self.bdf.meta("SIZE")[0])
|
||||
w, h, startx, starty = self.bdf.meta("FONTBOUNDINGBOX")
|
||||
self.ascent = int(self.bdf.meta("FONT_ASCENT")[0])
|
||||
self.descent = int(self.bdf.meta("FONT_DESCENT")[0])
|
||||
self.w = int(w)
|
||||
self.h = int(h)
|
||||
self.startx = int(startx)
|
||||
self.starty = int(starty)
|
||||
|
||||
def build(self, output_path: str):
|
||||
glyph_names = {
|
||||
k: glyph.meta("STARTCHAR")[0]
|
||||
for k, glyph in self.bdf.glyphs.items()
|
||||
if k >= 0
|
||||
}
|
||||
ascent = round(self.ascent * self.ppp)
|
||||
descent = round(self.descent * self.ppp)
|
||||
|
||||
self.fb.setupGlyphOrder(list(glyph_names.values()))
|
||||
self.fb.setupCharacterMap(glyph_names)
|
||||
advance_widths = {
|
||||
name: int(self.bdf.glyphs[k].meta("SWIDTH")[0])
|
||||
for k, name in glyph_names.items()
|
||||
}
|
||||
family_name = "CozetteVector"
|
||||
style_name = "Regular"
|
||||
version = get_version()
|
||||
|
||||
# scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=IWS-Chapter08
|
||||
namestrings = {
|
||||
"familyName": {"en": family_name},
|
||||
"styleName": {"en": style_name},
|
||||
"uniqueFontIdentifier": f"fontBuilder: {family_name}.{style_name}",
|
||||
"fullName": family_name,
|
||||
"psName": f"{family_name}-{style_name}",
|
||||
"version": f"Version {version}",
|
||||
"copyright": "(c) 2020 Slavfox",
|
||||
"manufacturer": "Slavfox",
|
||||
"designer": "Slavfox",
|
||||
"description": "Programming bitmap font optimized for coziness",
|
||||
"vendorURL": "https://github.com/slavfox",
|
||||
"designerURL": "https://github.com/slavfox",
|
||||
"licenseDescription": LICENSE_TEXT,
|
||||
"licenseInfoURL": "https://opensource.org/licenses/MIT",
|
||||
"sampleText": "A wizard’s job is to vex chumps quickly in fog.",
|
||||
}
|
||||
self.fb.setupGlyf(
|
||||
{
|
||||
name: self.bdf.glyphs[k].draw(self.ppp)
|
||||
for k, name in glyph_names.items()
|
||||
}
|
||||
)
|
||||
metrics = {
|
||||
name: (w, self.fb.font["glyf"][name].xMin)
|
||||
for name, w in advance_widths.items()
|
||||
}
|
||||
self.fb.setupHorizontalMetrics(metrics)
|
||||
self.fb.setupHorizontalHeader(ascent=ascent, descent=-descent)
|
||||
self.fb.setupNameTable(namestrings)
|
||||
self.fb.setupOS2(
|
||||
sTypoAscender=ascent,
|
||||
usWinAscent=ascent,
|
||||
usWinDescent=descent,
|
||||
panose={
|
||||
**_panoseDefaults,
|
||||
"bFamilyType": 2, # Text and display
|
||||
"bProportion": 9, # Monospace
|
||||
},
|
||||
)
|
||||
self.fb.setupPost(isFixedPitch=1)
|
||||
self.fb.save(output_path)
|
Binary file not shown.
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 40 KiB |
BIN
img/charmap.png
BIN
img/charmap.png
Binary file not shown.
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 82 KiB |
Loading…
Reference in New Issue
Block a user