Merge pull request #97 from slavfox/build_tools

HiDpi variants, better CozetteVector
This commit is contained in:
Slavfox 2023-06-11 05:06:31 +02:00 committed by GitHub
commit 112add28d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 604 additions and 572 deletions

View File

@ -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
View File

@ -6,6 +6,7 @@ __pycache__/
build/
develop-eggs/
dist/
deps/
downloads/
eggs/
.eggs/

View File

@ -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

View File

@ -18,7 +18,7 @@ setuptools = "*"
pip = "*"
[requires]
python_version = "3.10"
python_version = ">=3.10"
[pipenv]
allow_prereleases = true

594
Pipfile.lock generated
View File

@ -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"
}
}
}

View File

@ -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
View 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
View File

@ -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()

View File

@ -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
View 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"))

View 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

View File

@ -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})")

View File

@ -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 wizards 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 82 KiB