mirror of
https://github.com/slavfox/Cozette.git
synced 2024-07-14 10:50:22 +03:00
Start work on build scripts
This commit is contained in:
parent
708fdeadc7
commit
e2c0edf539
56
.gitignore
vendored
Normal file
56
.gitignore
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
docs/_build/
|
||||
target/
|
||||
.python-version
|
||||
__pypackages__/
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
.ropeproject
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
.idea
|
||||
*.iml
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
19
Pipfile
Normal file
19
Pipfile
Normal file
@ -0,0 +1,19 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
black = "*"
|
||||
mypy = "*"
|
||||
|
||||
[packages]
|
||||
numpy = "*"
|
||||
Pillow = "*"
|
||||
fonttools = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.8"
|
||||
|
||||
[pipenv]
|
||||
allow_prereleases = true
|
215
Pipfile.lock
generated
Normal file
215
Pipfile.lock
generated
Normal file
@ -0,0 +1,215 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "11679fbbfbfe6ca9cf64b908f74c67c912a0b96bff52aa6f34ff7528e5b9f449"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.8"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"fonttools": {
|
||||
"hashes": [
|
||||
"sha256:0c16d5da7846a92aedcb448277d13d3b729f7de48a917768d97ebd0d17067d7f",
|
||||
"sha256:bd93818f304b7f0d087e8ca9b5b3ed0819a68fb6c1a4763134a92bb046c2c31b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.3.0"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:1786a08236f2c92ae0e70423c45e1e62788ed33028f94ca99c4df03f5be6b3c6",
|
||||
"sha256:17aa7a81fe7599a10f2b7d95856dc5cf84a4eefa45bc96123cbbc3ebc568994e",
|
||||
"sha256:20b26aaa5b3da029942cdcce719b363dbe58696ad182aff0e5dcb1687ec946dc",
|
||||
"sha256:2d75908ab3ced4223ccba595b48e538afa5ecc37405923d1fea6906d7c3a50bc",
|
||||
"sha256:39d2c685af15d3ce682c99ce5925cc66efc824652e10990d2462dfe9b8918c6a",
|
||||
"sha256:56bc8ded6fcd9adea90f65377438f9fea8c05fcf7c5ba766bef258d0da1554aa",
|
||||
"sha256:590355aeade1a2eaba17617c19edccb7db8d78760175256e3cf94590a1a964f3",
|
||||
"sha256:70a840a26f4e61defa7bdf811d7498a284ced303dfbc35acb7be12a39b2aa121",
|
||||
"sha256:77c3bfe65d8560487052ad55c6998a04b654c2fbc36d546aef2b2e511e760971",
|
||||
"sha256:9537eecf179f566fd1c160a2e912ca0b8e02d773af0a7a1120ad4f7507cd0d26",
|
||||
"sha256:9acdf933c1fd263c513a2df3dceecea6f3ff4419d80bf238510976bf9bcb26cd",
|
||||
"sha256:ae0975f42ab1f28364dcda3dde3cf6c1ddab3e1d4b2909da0cb0191fa9ca0480",
|
||||
"sha256:b3af02ecc999c8003e538e60c89a2b37646b39b688d4e44d7373e11c2debabec",
|
||||
"sha256:b6ff59cee96b454516e47e7721098e6ceebef435e3e21ac2d6c3b8b02628eb77",
|
||||
"sha256:b765ed3930b92812aa698a455847141869ef755a87e099fddd4ccf9d81fffb57",
|
||||
"sha256:c98c5ffd7d41611407a1103ae11c8b634ad6a43606eca3e2a5a269e5d6e8eb07",
|
||||
"sha256:cf7eb6b1025d3e169989416b1adcd676624c2dbed9e3bcb7137f51bfc8cc2572",
|
||||
"sha256:d92350c22b150c1cae7ebb0ee8b5670cc84848f6359cf6b5d8f86617098a9b73",
|
||||
"sha256:e422c3152921cece8b6a2fb6b0b4d73b6579bd20ae075e7d15143e711f3ca2ca",
|
||||
"sha256:e840f552a509e3380b0f0ec977e8124d0dc34dc0e68289ca28f4d7c1d0d79474",
|
||||
"sha256:f3d0a94ad151870978fb93538e95411c83899c9dc63e6fb65542f769568ecfa5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.18.1"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:0a628977ac2e01ca96aaae247ec2bd38e729631ddf2221b4b715446fd45505be",
|
||||
"sha256:4d9ed9a64095e031435af120d3c910148067087541131e82b3e8db302f4c8946",
|
||||
"sha256:54ebae163e8412aff0b9df1e88adab65788f5f5b58e625dc5c7f51eaf14a6837",
|
||||
"sha256:5bfef0b1cdde9f33881c913af14e43db69815c7e8df429ceda4c70a5e529210f",
|
||||
"sha256:5f3546ceb08089cedb9e8ff7e3f6a7042bb5b37c2a95d392fb027c3e53a2da00",
|
||||
"sha256:5f7ae9126d16194f114435ebb79cc536b5682002a4fa57fa7bb2cbcde65f2f4d",
|
||||
"sha256:62a889aeb0a79e50ecf5af272e9e3c164148f4bd9636cc6bcfa182a52c8b0533",
|
||||
"sha256:7406f5a9b2fd966e79e6abdaf700585a4522e98d6559ce37fc52e5c955fade0a",
|
||||
"sha256:8453f914f4e5a3d828281a6628cf517832abfa13ff50679a4848926dac7c0358",
|
||||
"sha256:87269cc6ce1e3dee11f23fa515e4249ae678dbbe2704598a51cee76c52e19cda",
|
||||
"sha256:875358310ed7abd5320f21dd97351d62de4929b0426cdb1eaa904b64ac36b435",
|
||||
"sha256:8ac6ce7ff3892e5deaab7abaec763538ffd011f74dc1801d93d3c5fc541feee2",
|
||||
"sha256:91b710e3353aea6fc758cdb7136d9bbdcb26b53cefe43e2cba953ac3ee1d3313",
|
||||
"sha256:9d2ba4ed13af381233e2d810ff3bab84ef9f18430a9b336ab69eaf3cd24299ff",
|
||||
"sha256:a62ec5e13e227399be73303ff301f2865bf68657d15ea50b038d25fc41097317",
|
||||
"sha256:ab76e5580b0ed647a8d8d2d2daee170e8e9f8aad225ede314f684e297e3643c2",
|
||||
"sha256:bf4003aa538af3f4205c5fac56eacaa67a6dd81e454ffd9e9f055fff9f1bc614",
|
||||
"sha256:bf598d2e37cf8edb1a2f26ed3fb255191f5232badea4003c16301cb94ac5bdd0",
|
||||
"sha256:c18f70dc27cc5d236f10e7834236aff60aadc71346a5bc1f4f83a4b3abee6386",
|
||||
"sha256:c5ed816632204a2fc9486d784d8e0d0ae754347aba99c811458d69fcdfd2a2f9",
|
||||
"sha256:dc058b7833184970d1248135b8b0ab702e6daa833be14035179f2acb78ff5636",
|
||||
"sha256:ff3797f2f16bf9d17d53257612da84dd0758db33935777149b3334c01ff68865"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.0.0"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
|
||||
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
|
||||
],
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
|
||||
"sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
|
||||
],
|
||||
"version": "==19.3.0"
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b",
|
||||
"sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==19.10b0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
|
||||
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
|
||||
],
|
||||
"version": "==7.0"
|
||||
},
|
||||
"mypy": {
|
||||
"hashes": [
|
||||
"sha256:0a9a45157e532da06fe56adcfef8a74629566b607fa2c1ac0122d1ff995c748a",
|
||||
"sha256:2c35cae79ceb20d47facfad51f952df16c2ae9f45db6cb38405a3da1cf8fc0a7",
|
||||
"sha256:4b9365ade157794cef9685791032521233729cb00ce76b0ddc78749abea463d2",
|
||||
"sha256:53ea810ae3f83f9c9b452582261ea859828a9ed666f2e1ca840300b69322c474",
|
||||
"sha256:634aef60b4ff0f650d3e59d4374626ca6153fcaff96ec075b215b568e6ee3cb0",
|
||||
"sha256:7e396ce53cacd5596ff6d191b47ab0ea18f8e0ec04e15d69728d530e86d4c217",
|
||||
"sha256:7eadc91af8270455e0d73565b8964da1642fe226665dd5c9560067cd64d56749",
|
||||
"sha256:7f672d02fffcbace4db2b05369142e0506cdcde20cea0e07c7c2171c4fd11dd6",
|
||||
"sha256:85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf",
|
||||
"sha256:87c556fb85d709dacd4b4cb6167eecc5bbb4f0a9864b69136a0d4640fdc76a36",
|
||||
"sha256:a6bd44efee4dc8c3324c13785a9dc3519b3ee3a92cada42d2b57762b7053b49b",
|
||||
"sha256:c6d27bd20c3ba60d5b02f20bd28e20091d6286a699174dfad515636cb09b5a72",
|
||||
"sha256:e2bb577d10d09a2d8822a042a23b8d62bc3b269667c9eb8e60a6edfa000211b1",
|
||||
"sha256:f97a605d7c8bc2c6d1172c2f0d5a65b24142e11a58de689046e62c2d632ca8c1"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.761"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
|
||||
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
|
||||
],
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:163b0632d4e31cef212976cf57b43d9fd6b0bac6e67c26015d611a647d5e7424",
|
||||
"sha256:562aa70af2e0d434367d9790ad37aed893de47f1693e4201fd1d3dca15d19b96"
|
||||
],
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:07b39bf943d3d2fe63d46281d8504f8df0ff3fe4c57e13d1656737950e53e525",
|
||||
"sha256:0932941cdfb3afcbc26cc3bcf7c3f3d73d5a9b9c56955d432dbf8bbc147d4c5b",
|
||||
"sha256:0e182d2f097ea8549a249040922fa2b92ae28be4be4895933e369a525ba36576",
|
||||
"sha256:10671601ee06cf4dc1bc0b4805309040bb34c9af423c12c379c83d7895622bb5",
|
||||
"sha256:23e2c2c0ff50f44877f64780b815b8fd2e003cda9ce817a7fd00dea5600c84a0",
|
||||
"sha256:26ff99c980f53b3191d8931b199b29d6787c059f2e029b2b0c694343b1708c35",
|
||||
"sha256:27429b8d74ba683484a06b260b7bb00f312e7c757792628ea251afdbf1434003",
|
||||
"sha256:3e77409b678b21a056415da3a56abfd7c3ad03da71f3051bbcdb68cf44d3c34d",
|
||||
"sha256:4e8f02d3d72ca94efc8396f8036c0d3bcc812aefc28ec70f35bb888c74a25161",
|
||||
"sha256:4eae742636aec40cf7ab98171ab9400393360b97e8f9da67b1867a9ee0889b26",
|
||||
"sha256:6a6ae17bf8f2d82d1e8858a47757ce389b880083c4ff2498dba17c56e6c103b9",
|
||||
"sha256:6a6ba91b94427cd49cd27764679024b14a96874e0dc638ae6bdd4b1a3ce97be1",
|
||||
"sha256:7bcd322935377abcc79bfe5b63c44abd0b29387f267791d566bbb566edfdd146",
|
||||
"sha256:98b8ed7bb2155e2cbb8b76f627b2fd12cf4b22ab6e14873e8641f266e0fb6d8f",
|
||||
"sha256:bd25bb7980917e4e70ccccd7e3b5740614f1c408a642c245019cff9d7d1b6149",
|
||||
"sha256:d0f424328f9822b0323b3b6f2e4b9c90960b24743d220763c7f07071e0778351",
|
||||
"sha256:d58e4606da2a41659c84baeb3cfa2e4c87a74cec89a1e7c56bee4b956f9d7461",
|
||||
"sha256:e3cd21cc2840ca67de0bbe4071f79f031c81418deb544ceda93ad75ca1ee9f7b",
|
||||
"sha256:e6c02171d62ed6972ca8631f6f34fa3281d51db8b326ee397b9c83093a6b7242",
|
||||
"sha256:e7c7661f7276507bce416eaae22040fd91ca471b5b33c13f8ff21137ed6f248c",
|
||||
"sha256:ecc6de77df3ef68fee966bb8cb4e067e84d4d1f397d0ef6fce46913663540d77"
|
||||
],
|
||||
"version": "==2020.1.8"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
|
||||
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
|
||||
],
|
||||
"version": "==0.10.0"
|
||||
},
|
||||
"typed-ast": {
|
||||
"hashes": [
|
||||
"sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
|
||||
"sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
|
||||
"sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
|
||||
"sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
|
||||
"sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
|
||||
"sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
|
||||
"sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
|
||||
"sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
|
||||
"sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
|
||||
"sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
|
||||
"sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
|
||||
"sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
|
||||
"sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
|
||||
"sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
|
||||
"sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
|
||||
"sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
|
||||
"sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
|
||||
"sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
|
||||
"sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
|
||||
"sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
|
||||
"sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
|
||||
],
|
||||
"version": "==1.4.1"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:091ecc894d5e908ac75209f10d5b4f118fbdb2eb1ede6a63544054bb1edb41f2",
|
||||
"sha256:910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d",
|
||||
"sha256:cf8b63fedea4d89bab840ecbb93e75578af28f76f66c35889bd7065f5af88575"
|
||||
],
|
||||
"version": "==3.7.4.1"
|
||||
}
|
||||
}
|
||||
}
|
51
build.py
Normal file
51
build.py
Normal file
@ -0,0 +1,51 @@
|
||||
from pathlib import Path
|
||||
from cozette_builder.imagegen import save_sample, save_charlist
|
||||
|
||||
SAMPLE_TEXT = """
|
||||
$BLUE$┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃ $MAGENTA$♡$NC$ $FG$Cozette$NC$ $MAGENTA$♡$BLUE$ ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ $WHITE$A B C D E F G H I J K L M $BLUE$│
|
||||
│ $WHITE$N O P Q R S T U V W X Y Z $BLUE$│
|
||||
╞═══════════════════════════╡
|
||||
│ 1 2 3 4 5 6 7 8 9 0 │
|
||||
╞═══════════════════════════╡
|
||||
│ $WHITE$a b c d e f g h i j k l m $BLUE$│
|
||||
│ $WHITE$n o p q r s t u v w x y z $BLUE$│
|
||||
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
|
||||
│ $RED$() [] {} <> ? / \ : " ' ;$BLUE$ │
|
||||
│ $RED$! @ # $ % ^ & * _ = + - |$BLUE$ │
|
||||
│ , . ` ~$BLUE$ │
|
||||
╰───────────────────────────╯
|
||||
$YELLOW$
|
||||
|
||||
$BLUE$│ $FG$╔═══════════════╗
|
||||
$BLUE$└──$FG$║ $GREEN$✓ ✔ $YELLOW$✕ ✖ $MAGENTA$✗ ✘ $FG$ ║$BLUE$▒
|
||||
$FG$║ $BLUE$ $FG$║$BLUE$▒
|
||||
$FG$╚═══════════════╝$BLUE$▒
|
||||
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
||||
|
||||
|
||||
$GREEN$Pchnąć w tę łódź jeża lub
|
||||
ósm skrzyń fig.
|
||||
|
||||
Eĥoŝanĝo ĉiuĵaŭde.
|
||||
|
||||
Příliš žluťoučký kůň
|
||||
úpěl ďábelské ódy.
|
||||
|
||||
$FG$♠ ♣ $MAGENTA$♥ ♦
|
||||
"""
|
||||
REPO_ROOT = Path(__file__).resolve().parent
|
||||
|
||||
def save_images():
|
||||
bdfpath = REPO_ROOT / "Cozette8" / "Cozette-10.bdf"
|
||||
|
||||
save_charlist(bdfpath, REPO_ROOT / "img" / "characters.png")
|
||||
|
||||
save_sample(
|
||||
"Clozette", SAMPLE_TEXT, REPO_ROOT / "img" / "sample.png",
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
save_images()
|
0
cozette_builder/__init__.py
Normal file
0
cozette_builder/__init__.py
Normal file
0
cozette_builder/bdf/__init__.py
Normal file
0
cozette_builder/bdf/__init__.py
Normal file
88
cozette_builder/bdf/bdffont.py
Normal file
88
cozette_builder/bdf/bdffont.py
Normal file
@ -0,0 +1,88 @@
|
||||
from __future__ import annotations
|
||||
from typing import (
|
||||
Iterable,
|
||||
Union,
|
||||
Literal,
|
||||
NamedTuple,
|
||||
Dict,
|
||||
List,
|
||||
TextIO,
|
||||
Tuple,
|
||||
)
|
||||
import numpy as np
|
||||
|
||||
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 = np.pad(bits, [[0, 0], [bbx.x, 0]])[
|
||||
bbx.y : bbx.y + bbx.h, bbx.x : bbx.x + bbx.w
|
||||
]
|
||||
self.meta = 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 parse_char(bdfstream: TextIO):
|
||||
specs = {}
|
||||
while not (line := bdfstream.readline()).startswith("BITMAP"):
|
||||
parts = line.split(maxsplit=1)
|
||||
specs[parts[0]] = parts[1]
|
||||
bitmap = []
|
||||
while not (line := bdfstream.readline()).startswith("ENDCHAR"):
|
||||
bitmap.append(int(line.strip(), 16))
|
||||
return specs, bitmap
|
||||
|
||||
|
||||
class BdfFont:
|
||||
def __init__(self, metadata: List[str], glyphs: Dict[int, BdfGlyph]):
|
||||
self.metadata: List[str] = metadata
|
||||
self.glyphs: Dict[int, BdfGlyph] = glyphs
|
||||
|
||||
@classmethod
|
||||
def from_bdf(cls, bdfstream: TextIO):
|
||||
metadata = []
|
||||
while not (line := bdfstream.readline()).startswith("CHARS "):
|
||||
metadata.append(line)
|
||||
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)
|
124
cozette_builder/imagegen.py
Normal file
124
cozette_builder/imagegen.py
Normal file
@ -0,0 +1,124 @@
|
||||
import subprocess
|
||||
from typing import Tuple, Dict, Optional
|
||||
from shlex import quote
|
||||
from pathlib import Path
|
||||
from cozette_builder.bdf.bdffont import BdfFont
|
||||
import textwrap
|
||||
import tempfile
|
||||
|
||||
Color = Tuple[int, int, int]
|
||||
|
||||
|
||||
def hex_to_rgb(color: str) -> Color:
|
||||
h = int(color, 16)
|
||||
return h >> 16, (h >> 8) & 0x00FF, h & 0x0000FF
|
||||
|
||||
|
||||
Palette = Dict[str, Optional[Color]]
|
||||
|
||||
|
||||
default_palette: Palette = dict(
|
||||
fg=hex_to_rgb("feffff"),
|
||||
bg=hex_to_rgb("2d2b33"),
|
||||
black=hex_to_rgb("383640"),
|
||||
red=hex_to_rgb("a09ebb"),
|
||||
green=hex_to_rgb("92b6b1"),
|
||||
yellow=hex_to_rgb("edaf97"),
|
||||
blue=hex_to_rgb("8789c0"),
|
||||
magenta=hex_to_rgb("e47b66"),
|
||||
cyan=hex_to_rgb("6b9080"),
|
||||
white=hex_to_rgb("969a97"),
|
||||
nc=None,
|
||||
)
|
||||
|
||||
# Todo: rewrite this to use files instead of a string
|
||||
def save_sample(
|
||||
font: str,
|
||||
sample: str,
|
||||
output_path: Path,
|
||||
fgcolor: str = "#abb2bf",
|
||||
bgcolor: str = "#282c34",
|
||||
palette: Palette = None,
|
||||
):
|
||||
if palette is None:
|
||||
palette = default_palette
|
||||
colored, stripped = colored_and_stripped_text(sample, palette)
|
||||
|
||||
lines = stripped.splitlines()
|
||||
h, w = len(lines), max(len(line) for line in lines)
|
||||
with tempfile.NamedTemporaryFile("w", delete=False) as f:
|
||||
f.write(colored)
|
||||
fp = f.name
|
||||
cmd = quote(
|
||||
f"tput civis &&"
|
||||
f"cat {fp} && sleep 0 && "
|
||||
f"import -window $WINDOWID {output_path}"
|
||||
)
|
||||
subprocess.run(
|
||||
[
|
||||
"xterm",
|
||||
"-fg",
|
||||
fgcolor,
|
||||
"-bg",
|
||||
bgcolor,
|
||||
"-fa",
|
||||
font,
|
||||
"-geometry",
|
||||
f"{w}x{h}",
|
||||
"-dc",
|
||||
"-e",
|
||||
f"bash -c {cmd}",
|
||||
],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
Path(fp).unlink()
|
||||
|
||||
|
||||
def color_escape_seq(color: Color = None):
|
||||
if color is None:
|
||||
return f"\033[38;0m"
|
||||
return f"\033[38;2;{color[0]};{color[1]};{color[2]}m"
|
||||
|
||||
|
||||
def colored_and_stripped_text(text: str, palette: Palette) -> Tuple[str, str]:
|
||||
colored_text = text
|
||||
stripped_text = text
|
||||
for color in palette.keys():
|
||||
# The PyCharm MyPy plugin throws a fit at `palette.get(color)` because
|
||||
# it doesn't know that palette.get returns an Optional[Color], PyCharm
|
||||
# itself throws a fit here because of
|
||||
# https://youtrack.jetbrains.com/issue/PY-40439, and it sometimes
|
||||
# forgets that `palette` has a `.get` method, so ignore all those
|
||||
# warnings:
|
||||
# noinspection Mypy, PyTypedDict, PyUnresolvedReferences
|
||||
colored_text = colored_text.replace(
|
||||
f"${color.upper()}$", color_escape_seq(palette[color])
|
||||
)
|
||||
stripped_text = stripped_text.replace(f"${color.upper()}$", "")
|
||||
return colored_text, stripped_text
|
||||
|
||||
|
||||
# Todo: write a fill() that ignores character codes
|
||||
|
||||
|
||||
def save_charlist(bdf_font: Path, output_path: Path):
|
||||
with bdf_font.open() as f:
|
||||
bdf = BdfFont.from_bdf(f)
|
||||
save_sample(
|
||||
"Clozette",
|
||||
textwrap.fill(
|
||||
"".join(
|
||||
chr(c)
|
||||
for c in bdf.codepoints
|
||||
if c >= 32
|
||||
and c
|
||||
not in (
|
||||
127,
|
||||
# dumb as shit workaround for a weird bug
|
||||
0x26A1,
|
||||
)
|
||||
)
|
||||
),
|
||||
output_path,
|
||||
)
|
Binary file not shown.
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
img/sample.png
BIN
img/sample.png
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.3 KiB |
@ -1,36 +1,34 @@
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃ ♡ Cozette ♡ ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ A B C D E F G H I J K L M │
|
||||
│ N O P Q R S T U V W X Y Z │
|
||||
╞═══════════════════════════╡
|
||||
│ 1 2 3 4 5 6 7 8 9 0 │
|
||||
╞═══════════════════════════╡
|
||||
│ a b c d e f g h i j k l m │
|
||||
│ n o p q r s t u v w x y z │
|
||||
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
|
||||
│ () [] {} <> ? / \ : " ' ; │
|
||||
│ ! @ # $ % ^ & * _ = + - | │
|
||||
│ , . ` ~ │
|
||||
╰───────────────────────────╯
|
||||
|
||||
|
||||
│ ╔═══════════════╗
|
||||
└──║ ✓ ✔ ✕ ✖ ✗ ✘ ║▒
|
||||
║ ║▒
|
||||
╚═══════════════╝▒
|
||||
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
||||
$BLUE$┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃ $MAGENTA$♡$NC$ $FG$Cozette$NC$ $MAGENTA$♡$BLUE$ ┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ $WHITE$A B C D E F G H I J K L M $BLUE$│
|
||||
│ $WHITE$N O P Q R S T U V W X Y Z $BLUE$│
|
||||
╞═══════════════════════════╡
|
||||
│ 1 2 3 4 5 6 7 8 9 0 │
|
||||
╞═══════════════════════════╡
|
||||
│ $WHITE$a b c d e f g h i j k l m $BLUE$│
|
||||
│ $WHITE$n o p q r s t u v w x y z $BLUE$│
|
||||
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
|
||||
│ $RED$() [] {} <> ? / \ : " ' ;$BLUE$ │
|
||||
│ $RED$! @ # $ % ^ & * _ = + - |$BLUE$ │
|
||||
│ , . ` ~$BLUE$ │
|
||||
╰───────────────────────────╯
|
||||
$YELLOW$
|
||||
|
||||
$BLUE$│ $FG$╔═══════════════╗
|
||||
$BLUE$└──$FG$║ $GREEN$✓ ✔ $YELLOW$✕ ✖ $MAGENTA$✗ ✘ $FG$ ║$BLUE$▒
|
||||
$FG$║ $BLUE$ $FG$║$BLUE$▒
|
||||
$FG$╚═══════════════╝$BLUE$▒
|
||||
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
||||
|
||||
|
||||
Pchnąć w tę łódź jeża lub
|
||||
ósm skrzyń fig.
|
||||
$GREEN$Pchnąć w tę łódź jeża lub
|
||||
ósm skrzyń fig.
|
||||
|
||||
Eĥoŝanĝo ĉiuĵaŭde.
|
||||
|
||||
Příliš žluťoučký kůň
|
||||
úpěl ďábelské ódy.
|
||||
|
||||
♠ ♣ ♥ ♦
|
||||
Eĥoŝanĝo ĉiuĵaŭde.
|
||||
|
||||
Příliš žluťoučký kůň
|
||||
úpěl ďábelské ódy.
|
||||
|
||||
$FG$♠ ♣ $MAGENTA$♥ ♦
|
||||
|
Loading…
Reference in New Issue
Block a user