1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-25 03:34:05 +00:00

more work on font generator

This commit is contained in:
Steven Hugg 2018-09-01 11:02:51 -04:00
parent 4d478d72ce
commit a0f3a7e919
5 changed files with 348 additions and 211 deletions

281
package-lock.json generated
View File

@ -10,7 +10,7 @@
"integrity": "sha512-UGvzSQFkv0Oh2vjj30AfZructi7XvY0aRa1Y/vrgFq+tfrTMxtqQ9+s5liCYLJnrISc9LinEtOY5N8Ibrhj2Tg==",
"dev": true,
"requires": {
"@types/jquery": "2.0.49"
"@types/jquery": "*"
}
},
"@types/jquery": {
@ -19,6 +19,15 @@
"integrity": "sha512-/9xLnYmohN/vD2gDnLS4cym8TUmrJu7DvZa/LELKzZjdPsvWVJiedsdu2SXNtb/DA7FGimqL2g0IoyhbNKLl8g==",
"dev": true
},
"@types/w2ui": {
"version": "1.4.32",
"resolved": "https://registry.npmjs.org/@types/w2ui/-/w2ui-1.4.32.tgz",
"integrity": "sha512-K/VxxtmGRhMHMyiPL4rl+Drk74n21lXw+dlLD2ovaAN/QbiDpFxXdRKvBeDoU+XphKShHoAQC/WiIKl60ZZ2qA==",
"dev": true,
"requires": {
"@types/jquery": "*"
}
},
"abab": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz",
@ -37,7 +46,7 @@
"integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==",
"dev": true,
"requires": {
"acorn": "5.7.1"
"acorn": "^5.0.0"
}
},
"ajv": {
@ -46,10 +55,10 @@
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"dev": true,
"requires": {
"co": "4.6.0",
"fast-deep-equal": "1.1.0",
"fast-json-stable-stringify": "2.0.0",
"json-schema-traverse": "0.3.1"
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
}
},
"ansi-regex": {
@ -76,7 +85,7 @@
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"dev": true,
"requires": {
"safer-buffer": "2.1.2"
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
@ -128,7 +137,7 @@
"dev": true,
"optional": true,
"requires": {
"tweetnacl": "0.14.5"
"tweetnacl": "^0.14.3"
}
},
"bluebird": {
@ -143,7 +152,7 @@
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
@ -171,11 +180,11 @@
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"clipboard": {
@ -184,9 +193,9 @@
"integrity": "sha512-7yhQBmtN+uYZmfRjjVjKa0dZdWuabzpSKGtyQZN+9C8xlC788SSJjOHWh7tzurfwTqTD5UDYAhIv5fRJg3sHjQ==",
"dev": true,
"requires": {
"good-listener": "1.2.2",
"select": "1.1.2",
"tiny-emitter": "2.0.2"
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"co": {
@ -201,7 +210,7 @@
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"dev": true,
"requires": {
"delayed-stream": "1.0.0"
"delayed-stream": "~1.0.0"
}
},
"commander": {
@ -210,7 +219,7 @@
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
"dev": true,
"requires": {
"graceful-readlink": "1.0.1"
"graceful-readlink": ">= 1.0.0"
}
},
"concat-map": {
@ -237,7 +246,7 @@
"integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==",
"dev": true,
"requires": {
"cssom": "0.3.4"
"cssom": "0.3.x"
}
},
"dashdash": {
@ -246,7 +255,7 @@
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"dev": true,
"requires": {
"assert-plus": "1.0.0"
"assert-plus": "^1.0.0"
}
},
"data-urls": {
@ -255,9 +264,9 @@
"integrity": "sha512-0HdcMZzK6ubMUnsMmQmG0AcLQPvbvb47R0+7CCZQCYgcd8OUWG91CG7sM6GoXgjz+WLl4ArFzHtBMy/QqSF4eg==",
"dev": true,
"requires": {
"abab": "2.0.0",
"whatwg-mimetype": "2.1.0",
"whatwg-url": "7.0.0"
"abab": "^2.0.0",
"whatwg-mimetype": "^2.1.0",
"whatwg-url": "^7.0.0"
}
},
"deep-is": {
@ -284,7 +293,7 @@
"integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
"dev": true,
"requires": {
"webidl-conversions": "4.0.2"
"webidl-conversions": "^4.0.2"
}
},
"ecc-jsbn": {
@ -294,8 +303,8 @@
"dev": true,
"optional": true,
"requires": {
"jsbn": "0.1.1",
"safer-buffer": "2.1.2"
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"escape-string-regexp": {
@ -310,11 +319,11 @@
"integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==",
"dev": true,
"requires": {
"esprima": "3.1.3",
"estraverse": "4.2.0",
"esutils": "2.0.2",
"optionator": "0.8.2",
"source-map": "0.6.1"
"esprima": "^3.1.3",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
}
},
"esprima": {
@ -386,9 +395,9 @@
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"dev": true,
"requires": {
"asynckit": "0.4.0",
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"mime-types": "2.1.19"
"mime-types": "^2.1.12"
}
},
"fs.realpath": {
@ -403,7 +412,7 @@
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"dev": true,
"requires": {
"assert-plus": "1.0.0"
"assert-plus": "^1.0.0"
}
},
"good-listener": {
@ -412,7 +421,7 @@
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"dev": true,
"requires": {
"delegate": "3.2.0"
"delegate": "^3.1.2"
}
},
"graceful-readlink": {
@ -433,8 +442,8 @@
"integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
"dev": true,
"requires": {
"ajv": "5.5.2",
"har-schema": "2.0.0"
"ajv": "^5.3.0",
"har-schema": "^2.0.0"
}
},
"has-ansi": {
@ -443,7 +452,7 @@
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
"ansi-regex": "^2.0.0"
}
},
"he": {
@ -464,7 +473,7 @@
"integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
"dev": true,
"requires": {
"whatwg-encoding": "1.0.4"
"whatwg-encoding": "^1.0.1"
}
},
"http-signature": {
@ -473,9 +482,9 @@
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"dev": true,
"requires": {
"assert-plus": "1.0.0",
"jsprim": "1.4.1",
"sshpk": "1.14.2"
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"iconv-lite": {
@ -484,7 +493,7 @@
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
"dev": true,
"requires": {
"safer-buffer": "2.1.2"
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inflight": {
@ -493,8 +502,8 @@
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
@ -528,31 +537,31 @@
"integrity": "sha512-42RgZYXWwyClG0pN6Au7TExAQqRvzbtJhlcIvu58cJj4yr1bIbqZkgxHqn1btxKu80axZXPZLvldeTzg2auKow==",
"dev": true,
"requires": {
"abab": "2.0.0",
"acorn": "5.7.1",
"acorn-globals": "4.1.0",
"array-equal": "1.0.0",
"cssom": "0.3.4",
"cssstyle": "1.1.1",
"data-urls": "1.0.1",
"domexception": "1.0.1",
"escodegen": "1.11.0",
"html-encoding-sniffer": "1.0.2",
"nwsapi": "2.0.8",
"abab": "^2.0.0",
"acorn": "^5.7.1",
"acorn-globals": "^4.1.0",
"array-equal": "^1.0.0",
"cssom": ">= 0.3.2 < 0.4.0",
"cssstyle": "^1.0.0",
"data-urls": "^1.0.1",
"domexception": "^1.0.1",
"escodegen": "^1.11.0",
"html-encoding-sniffer": "^1.0.2",
"nwsapi": "^2.0.8",
"parse5": "5.1.0",
"pn": "1.1.0",
"request": "2.88.0",
"request-promise-native": "1.0.5",
"sax": "1.2.4",
"symbol-tree": "3.2.2",
"tough-cookie": "2.4.3",
"w3c-hr-time": "1.0.1",
"webidl-conversions": "4.0.2",
"whatwg-encoding": "1.0.4",
"whatwg-mimetype": "2.1.0",
"whatwg-url": "7.0.0",
"ws": "6.0.0",
"xml-name-validator": "3.0.0"
"pn": "^1.1.0",
"request": "^2.88.0",
"request-promise-native": "^1.0.5",
"sax": "^1.2.4",
"symbol-tree": "^3.2.2",
"tough-cookie": "^2.4.3",
"w3c-hr-time": "^1.0.1",
"webidl-conversions": "^4.0.2",
"whatwg-encoding": "^1.0.4",
"whatwg-mimetype": "^2.1.0",
"whatwg-url": "^7.0.0",
"ws": "^6.0.0",
"xml-name-validator": "^3.0.0"
}
},
"json-schema": {
@ -591,8 +600,8 @@
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"dev": true,
"requires": {
"prelude-ls": "1.1.2",
"type-check": "0.3.2"
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"lodash": {
@ -613,10 +622,10 @@
"integrity": "sha1-S9MHpk4FbGTWBSqRt+rlwmqopRY=",
"dev": true,
"requires": {
"chalk": "1.1.3",
"chalk": "^1.1.3",
"commander": "2.9.0",
"filepath": "1.1.0",
"pkginfo": "0.4.1"
"filepath": "~1.1.0",
"pkginfo": "~0.4.0"
}
},
"mime-db": {
@ -631,7 +640,7 @@
"integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
"dev": true,
"requires": {
"mime-db": "1.35.0"
"mime-db": "~1.35.0"
}
},
"minimatch": {
@ -640,7 +649,7 @@
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.11"
"brace-expansion": "^1.1.7"
}
},
"minimist": {
@ -710,12 +719,12 @@
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"growl": {
@ -736,7 +745,7 @@
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
"has-flag": "3.0.0"
"has-flag": "^3.0.0"
}
}
}
@ -765,7 +774,7 @@
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
"wrappy": "1"
}
},
"optionator": {
@ -774,12 +783,12 @@
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"dev": true,
"requires": {
"deep-is": "0.1.3",
"fast-levenshtein": "2.0.6",
"levn": "0.3.0",
"prelude-ls": "1.1.2",
"type-check": "0.3.2",
"wordwrap": "1.0.0"
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.4",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"wordwrap": "~1.0.0"
}
},
"parse5": {
@ -842,26 +851,26 @@
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"dev": true,
"requires": {
"aws-sign2": "0.7.0",
"aws4": "1.8.0",
"caseless": "0.12.0",
"combined-stream": "1.0.6",
"extend": "3.0.2",
"forever-agent": "0.6.1",
"form-data": "2.3.2",
"har-validator": "5.1.0",
"http-signature": "1.2.0",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.19",
"oauth-sign": "0.9.0",
"performance-now": "2.1.0",
"qs": "6.5.2",
"safe-buffer": "5.1.2",
"tough-cookie": "2.4.3",
"tunnel-agent": "0.6.0",
"uuid": "3.3.2"
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
}
},
"request-promise-core": {
@ -870,7 +879,7 @@
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
"dev": true,
"requires": {
"lodash": "4.17.10"
"lodash": "^4.13.1"
}
},
"request-promise-native": {
@ -880,8 +889,8 @@
"dev": true,
"requires": {
"request-promise-core": "1.1.1",
"stealthy-require": "1.1.1",
"tough-cookie": "2.4.3"
"stealthy-require": "^1.1.0",
"tough-cookie": ">=2.3.3"
}
},
"safe-buffer": {
@ -921,15 +930,15 @@
"integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
"dev": true,
"requires": {
"asn1": "0.2.4",
"assert-plus": "1.0.0",
"bcrypt-pbkdf": "1.0.2",
"dashdash": "1.14.1",
"ecc-jsbn": "0.1.2",
"getpass": "0.1.7",
"jsbn": "0.1.1",
"safer-buffer": "2.1.2",
"tweetnacl": "0.14.5"
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
"dashdash": "^1.12.0",
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
"stealthy-require": {
@ -944,7 +953,7 @@
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
"ansi-regex": "^2.0.0"
}
},
"supports-color": {
@ -971,8 +980,8 @@
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"dev": true,
"requires": {
"psl": "1.1.29",
"punycode": "1.4.1"
"psl": "^1.1.24",
"punycode": "^1.4.1"
},
"dependencies": {
"punycode": {
@ -989,7 +998,7 @@
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
"dev": true,
"requires": {
"punycode": "2.1.1"
"punycode": "^2.1.0"
}
},
"tunnel-agent": {
@ -998,7 +1007,7 @@
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"dev": true,
"requires": {
"safe-buffer": "5.1.2"
"safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
@ -1014,7 +1023,7 @@
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"dev": true,
"requires": {
"prelude-ls": "1.1.2"
"prelude-ls": "~1.1.2"
}
},
"typescript": {
@ -1035,9 +1044,9 @@
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"dev": true,
"requires": {
"assert-plus": "1.0.0",
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "1.3.0"
"extsprintf": "^1.2.0"
}
},
"w3c-hr-time": {
@ -1046,7 +1055,7 @@
"integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
"dev": true,
"requires": {
"browser-process-hrtime": "0.1.2"
"browser-process-hrtime": "^0.1.2"
}
},
"wavedrom-cli": {
@ -1082,9 +1091,9 @@
"integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
"dev": true,
"requires": {
"lodash.sortby": "4.7.0",
"tr46": "1.0.1",
"webidl-conversions": "4.0.2"
"lodash.sortby": "^4.7.0",
"tr46": "^1.0.1",
"webidl-conversions": "^4.0.2"
}
},
"wordwrap": {
@ -1105,7 +1114,7 @@
"integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==",
"dev": true,
"requires": {
"async-limiter": "1.0.0"
"async-limiter": "~1.0.0"
}
},
"xml-name-validator": {

View File

@ -6,6 +6,7 @@
"devDependencies": {
"@types/bootstrap": "^3.x",
"@types/jquery": "^2.x",
"@types/w2ui": "^1.4.32",
"atob": "^2.1.2",
"btoa": "^1.2.1",
"clipboard": "^2.0.1",

View File

@ -68,8 +68,7 @@ ScanLoop1a
lda #0
sta WSYNC
sta PF1
; Turn playfield reflection off, since our brick field
; will be drawn asymetrically (and turn score mode off)
; Turn playfield reflection off (and turn score mode off)
lda #%00010100 ; no reflection + ball priority + 2 pixel ball
sta CTRLPF

View File

@ -1,8 +1,13 @@
import { hex } from "../util";
var font;
var params = {
declare var FONTLIST : string;
var FONT_DEFAULT_PARAMS = {
bpp:1,
np:1,
wbytes:1,
width:8,
height:8,
@ -12,21 +17,88 @@ var params = {
xflip:false,
yflip:false,
msbfirst:false,
output:'c_nested',
};
var params;
var errors;
var previewCanvas = $("#previewCanvas");
var codeTextarea = $("#codeTextarea");
var paramsForm = $("#paramsForm");
function refreshPreset(item) {
console.log(item);
w2ui.toolbar.set('bpp', {value:'1'});
w2ui.toolbar.set('width', {value:'8'});
w2ui.toolbar.set('height', {value:'8'});
w2ui.toolbar.set('lochar', {value:'32'});
w2ui.toolbar.set('hichar', {value:'95'});
var FONT_PRESETS = {
_8x8: { },
apple2: { width:7 },
vcs: { output:'dasm', msbfirst:true },
mw8080bw: { rotate:true, flip:true, msbfirst:true },
nes: { np:2, msbfirst:true },
};
function loadPreset(preset_id) {
params = $.extend({}, FONT_DEFAULT_PARAMS, FONT_PRESETS[preset_id]);
refreshToolbar();
}
function updateToolbarValue(event, id:string) {
event.item = w2ui.toolbar.get(id);
event.item.value = event.target.value;
refreshToolbar(event);
}
function refreshToolbar(event?) {
// update params from toolbar item?
console.log(event);
if (event && event.item) {
switch (event.item.id) {
case 'width':
case 'height':
case 'lochar':
case 'hichar':
params[event.item.id] = parseInt(event.item.value);
break;
case 'rotate':
case 'xflip':
case 'yflip':
case 'msbfirst':
params[event.item.id] = event.item.checked;
break;
case 'bpp':
if (event.subItem)
params[event.item.id] = parseInt(event.subItem.text);
break;
case 'preset':
if (event.subItem)
loadPreset(event.subItem.id);
break;
case 'charsel':
if (event.subItem)
loadCharSel(event.subItem.id);
break;
}
}
// set derived params
params.wbytes = Math.floor((params.width*params.bpp+7)/8);
// set toolbar items
Object.keys(params).forEach(function(key) {
var val = params[key];
var item = w2ui.toolbar.get(key);
switch (item && item.type) {
case 'check': item.checked = val; break;
case 'html': item.value = val; break;
case 'menu-radio': item.selected = val; break;
}
});
w2ui.toolbar.refresh();
updateEncoding();
previewFont();
}
function loadCharSel(id) {
var toks = id.split('-');
params.lochar = parseInt(toks[0]);
params.hichar = parseInt(toks[1]);
}
function parseBDF(text) {
@ -80,12 +152,20 @@ function loadFont(rec) {
font.rec = rec;
font.path = path;
console.log(font);
updateEncoding();
previewFont();
codeTextarea.text(encodeFont());
});
}
function updateEncoding() {
if (font) {
codeTextarea.text(encodeFont());
}
}
function renderGlyph(glyph, putPixel) {
if (glyph.ord < params.lochar || glyph.ord > params.hichar)
return {w:8,h:8};
var w = glyph.bbx[0];
var h = glyph.bbx[1];
var dx = glyph.bbx[2];
@ -95,11 +175,14 @@ function renderGlyph(glyph, putPixel) {
if (glyph.bytes[glyph.bytes.length-y-1] & (0x800000 >> x)) {
var xx = x+dx;
var yy = y+dy;
/*
font.pixbounds[0] = Math.min(font.pixbounds[0], xx);
font.pixbounds[1] = Math.min(font.pixbounds[1], yy);
font.pixbounds[2] = Math.max(font.pixbounds[2], xx);
font.pixbounds[3] = Math.max(font.pixbounds[3], yy);
putPixel(xx, yy);
*/
if (xx >= 0 && yy >= 0 && xx < params.width && yy < params.height)
putPixel(xx, yy);
}
}
}
@ -107,7 +190,7 @@ function renderGlyph(glyph, putPixel) {
}
function drawChar(x0, y0, chord) {
var ctx = previewCanvas[0].getContext('2d');
var ctx = (previewCanvas[0] as any).getContext('2d');
ctx.fillStyle = "black";
var glyph = font.chars[chord];
if (glyph) {
@ -134,7 +217,8 @@ var TEST_SENTENCES = [
];
function previewFont() {
var ctx = previewCanvas[0].getContext('2d');
if (!font) return;
var ctx = (previewCanvas[0] as any).getContext('2d');
ctx.fillStyle = "white";
ctx.fillRect( 0, 0, 1024, 1024 );
var x = 8;
@ -151,11 +235,11 @@ function encodeGlyph(glyph, bytes) {
renderGlyph(glyph, function(x,y) {
//x -= font.pixbounds[0];
//y -= font.pixbounds[1];
if (params.yflip) { y = params.height-1-y; }
if (params.xflip ^ params.rotate) { x = params.width-1-x; }
if (params.rotate) {
var y2 = x; var x2 = y; x = x2; y = y2;
}
if (params.yflip) { y = params.height-1-y; }
if (params.xflip) { x = params.width-1-x; }
var xoutrange = (x < 0 || x >= params.width);
var youtrange = (y < 0 || y >= params.height);
if (xoutrange || youtrange) {
@ -173,23 +257,36 @@ function encodeGlyph(glyph, bytes) {
}
function encodeFont() {
var s = '/* ' + JSON.stringify(params) + JSON.stringify(font.bounds) + JSON.stringify(font.pixbounds) + ' */\n';
s += "#define LOCHAR " + params.lochar + "\n";
s += "#define HICHAR " + params.hichar + "\n";
s += "#define FONT_HEIGHT " + params.height + "\n";
s += "const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT] = {\n";
var s = '';
if (params.output.startsWith('c_')) {
//s += '/* ' + JSON.stringify(params) + JSON.stringify(font.bounds) + JSON.stringify(font.pixbounds) + ' */\n';
s += "#define LOCHAR " + params.lochar + "\n";
s += "#define HICHAR " + params.hichar + "\n";
s += "#define FONT_BWIDTH " + (params.wbytes*params.np) + "\n";
s += "#define FONT_HEIGHT " + params.height + "\n";
s += "const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT*FONT_BWIDTH] = {\n";
} else {
s += "LOCHAR\t\t= " + params.lochar + "\n";
s += "HICHAR\t\t= " + params.hichar + "\n";
s += "FONT_HEIGHT\t= " + params.height + "\n";
s += "FontData:\n";
}
errors = [];
for (var chord=params.lochar; chord<=params.hichar; chord++) {
var glyph = font.chars[chord];
var bytes = new Uint8Array(params.wbytes*params.height);
var bytes = new Uint8Array(params.wbytes*params.height*params.np);
if (glyph) {
encodeGlyph(glyph, bytes);
s += "{ ";
if (params.output=='c_nested') s += "{ ";
else if (params.output=='dasm') s += "\thex\t";
for (var i=0; i<bytes.length; i++) {
s += "0x" + bytes[i].toString(16) + ",";
if (params.output.startsWith('c_'))
s += "0x" + hex(bytes[i]) + ",";
else if (params.output == 'dasm')
s += hex(bytes[i]);
}
s += " },";
s += "\n";
if (params.output=='c_nested') s += " },";
if (!params.output.startsWith('c_') || params.newline) s += "\n";
}
}
s += "};\n";
@ -208,22 +305,22 @@ for (var line of FONTLIST.split("\n")) {
var ltoks = line.split("|");
var ftoks = ltoks[1].split("-");
var rec = {
recid: ++li,
path: ltoks[0],
foundry: ftoks[1],
family: ftoks[2],
weight: ftoks[3].toLowerCase(),
slant: ftoks[4].toUpperCase(),
setwidth: ftoks[5],
addstyle: ftoks[6],
recid: ++li,
path: ltoks[0],
foundry: ftoks[1],
family: ftoks[2],
weight: ftoks[3].toLowerCase(),
slant: ftoks[4].toUpperCase(),
setwidth: ftoks[5],
addstyle: ftoks[6],
pixelsize: parseInt(ftoks[7]),
pointsize: parseInt(ftoks[8]),
resx: parseInt(ftoks[9]),
resy: parseInt(ftoks[10]),
spacing: ftoks[11].toUpperCase(),
avgwidth: ftoks[12]/10,
registry: ftoks[13],
encoding: ftoks[14],
resx: parseInt(ftoks[9]),
resy: parseInt(ftoks[10]),
spacing: ftoks[11].toUpperCase(),
avgwidth: parseFloat(ftoks[12])/10,
registry: ftoks[13],
encoding: ftoks[14],
};
FONTRECS.push(rec);
}
@ -232,7 +329,7 @@ function toolbarHTMLItem(id, title, maxchars) {
return function(item) {
var html = '<div style="padding: 3px 5px;">' + title + '&nbsp;' +
'<input size=' + maxchars + ' maxlength=' + maxchars +
' onchange="var el = w2ui.toolbar.set(\'' + id + '\', { value: this.value });" '+
' onchange="updateToolbarValue(event, \'' + id + '\');" '+
' value="'+ (item.value || '') + '"/></div>';
return html;
};
@ -240,39 +337,48 @@ function toolbarHTMLItem(id, title, maxchars) {
$().w2toolbar({
name: 'toolbar',
onClick: function(event) {
// TODO?
setTimeout(function() { refreshToolbar(event); }, 1);
},
tooltip: 'bottom',
items: [
{ type: 'menu-radio', id: 'preset', caption: 'Presets', img: 'icon-folder',
text: function(item) { refreshPreset(item); return item.caption; },
tooltip: 'Preset encoding options for specific platforms',
//text: function(item) { refreshPreset(item); return item.caption; },
items: [
{ text: 'Generic 8x8', id: '8x8' },
{ text: 'Atari 2600', id: 'vcs' },
{ text: 'Midway 8080', id: 'mw8080bw' },
{ text: 'NES', id: 'nes' }
]},
{ type: 'check', id: 'rotate', caption: 'Rotate' },
{ type: 'check', id: 'yflip', caption: 'Flip' },
{ type: 'menu-radio', id: 'bpp', caption: 'BPP', img: 'fas fa-star', items: [
{ text: '1' },
{ text: '2' },
{ text: '4' },
{ text: '8' }
]},
{ text: 'Generic C 8x8', id: '_8x8' },
{ text: 'Atari 2600', id: 'vcs' },
{ text: 'Midway 8080', id: 'mw8080bw' },
{ text: 'NES', id: 'nes' },
{ text: 'Apple ][', id: 'apple2' },
]},
{ type: 'check', id: 'rotate', caption: 'Rotate', img: 'fas fa-sync', tooltip: 'Rotate 90 degrees (swap X/Y)' },
{ type: 'check', id: 'xflip', caption: 'Mirror', img: 'fas fa-arrows-alt-h', tooltip: 'Flip X axis' },
{ type: 'check', id: 'yflip', caption: 'Flip', img: 'fas fa-arrows-alt-v', tooltip: 'Flip Y axis' },
{ type: 'check', id: 'msbfirst', caption: 'MSB First', img: 'fas fa-arrow-alt-circle-right', tooltip: 'If selected, MSB (left) to LSB (right)' },
{ type: 'menu-radio', id: 'bpp', caption: 'BPP', img: 'fas fa-dice-one', tooltip: 'Bits per pixel',
items: [
{ text: '1' },
{ text: '2' },
{ text: '4' },
{ text: '8' }
]},
{ type: 'html', id: 'width', html: toolbarHTMLItem('width','Width:',2) },
{ type: 'html', id: 'height', html: toolbarHTMLItem('height','Height:',2) },
{ type: 'break', id: 'break1' },
{ type: 'menu-radio', id: 'charsel', caption: 'Characters', img: 'icon-folder', items: [
//{ text: 'ISO (256 chars)', value:'0-255' },
{ text: 'ASCII (upper+lower)', id:'32-95' },
{ text: 'ASCII (upper only)', id:'32-127' }
]},
{ type: 'menu-radio', id: 'charsel', caption: 'Characters', img: 'icon-folder',
tooltip: 'Range of characters to encode, from first to last',
//text: function(item) { refreshCharSel(item); return item.caption; },
items: [
//{ text: 'ISO (256 chars)', value:'0-255' },
{ text: 'ASCII (upper only)', id:'32-95' },
{ text: 'ASCII (upper+lower)', id:'32-127' }
]},
{ type: 'html', id: 'lochar', html: toolbarHTMLItem('lochar','First:',3) },
{ type: 'html', id: 'hichar', html: toolbarHTMLItem('hichar','Last:',3) },
/*
/*
{ type: 'spacer' },
{ type: 'check', id: 'item1', caption: 'Check', img: 'icon-page', checked: true },
{ type: 'break', id: 'break0' },
{ type: 'radio', id: 'item3', group: '1', caption: 'Radio 1', icon: 'fa-star', checked: true },
{ type: 'radio', id: 'item4', group: '1', caption: 'Radio 2', icon: 'fa-star-empty' },
{ type: 'button', id: 'item5', caption: 'Item 5', icon: 'fa-home' }
*/
]
@ -312,10 +418,10 @@ $('#layout').w2layout({
name: 'layout',
panels: [
{ type: 'top', size: 50, resizable: false, style: pstyle, content: 'top' },
{ type: 'left', size: 200, resizable: true, style: pstyle, content: paramsForm },
// { type: 'left', size: 200, resizable: true, style: pstyle, content: paramsForm },
{ type: 'main', style: pstyle, content: codeTextarea },
{ type: 'preview', size: '50%', resizable: true, style: pstyle, content: previewCanvas },
{ type: 'right', size: 200, resizable: true, style: pstyle, content: 'right' },
{ type: 'left', size: '25%', resizable: true, style: pstyle, content: $("#instructions") },
{ type: 'bottom', size: 200, resizable: true, style: pstyle, content: 'bottom' }
]
});
@ -323,10 +429,4 @@ $('#layout').w2layout({
w2ui['layout'].content('top', w2ui['toolbar']);
w2ui['layout'].content('bottom', w2ui['fontGrid']);
w2ui.toolbar.set('preset', {selected:'8x8'});
w2ui.toolbar.set('bpp', {value:'1'});
w2ui.toolbar.set('width', {value:'8'});
w2ui.toolbar.set('height', {value:'8'});
w2ui.toolbar.set('lochar', {value:'32'});
w2ui.toolbar.set('hichar', {value:'95'});
loadPreset('_8x8');

View File

@ -22,8 +22,21 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
</div>
<div style="display:none">
<canvas id="previewCanvas" width=640 height=256></canvas>
<textarea id="codeTextarea" cols=80 rows=8>/* output appears here */</textarea>
<div id="instructions">
<p><a href="http://8bitworkshop.com/">8bitworkshop</a> Bitmap Font Encoder</p>
<ol>
<li>Select a font below (check out the search and filter options.)</li>
<li>Choose a preset platform, or your own encoding options.</li>
<li>Select a range of characters.</li>
<li>Check out the preview bitmap to make sure none of your characters are visibly cut off, or increase your height/width (if your platform supports it.)</li>
<li>Copy the output to the clipboard, paste it into your code.</li>
</ol>
</div>
</div>
<script src="../../jquery/jquery-2.2.3.min.js"></script>
@ -33,9 +46,24 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<!--
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
-->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/solid.css" integrity="sha384-VGP9aw4WtGH/uPAOseYxZ+Vz/vaTb1ehm1bwx92Fm8dTrE+3boLfF1SpAtB1z7HW" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/fontawesome.css" integrity="sha384-1rquJLNOM3ijoueaaeS5m+McXPJCGdr5HcA03/VHXxcp2kX2sUrQDmFc3jR5i/C7" crossorigin="anonymous">
<script>
var exports = {};
function require(modname) {
if (modname == 'jquery') return $;
else if (modname.startsWith('.')) return exports;
else { console.log("Unknown require()", modname); return exports; }
}
</script>
<link rel="stylesheet" href="../../bootstrap/css/bootstrap.min.css">
<script src="../../bootstrap/js/bootstrap.min.js"></script>
<script src="./fontlist.js"></script>
<script src="./uifont.js"></script>
<script src="../../gen/util.js"></script>
<script src="../../gen/tools/uifont.js"></script>
</body>
</html>