Skip to content

Instantly share code, notes, and snippets.

@nuta
Created September 13, 2019 14:32
Show Gist options
  • Select an option

  • Save nuta/77f4da068cd0dd197662c3a08db260f7 to your computer and use it in GitHub Desktop.

Select an option

Save nuta/77f4da068cd0dd197662c3a08db260f7 to your computer and use it in GitHub Desktop.
Resea Font Editor

Bitmap Font Editor

  1. Install dependencies.
$ yarn
  1. Install Chrome Canary and enable Native File System API.

  2. Launch the editor.

$ yarn run open
<template html>
<main>
<div class="menu">
<h1 class="item">Bitmap Font Editor</h1>
<div class="item">
<button class="ui labeled icon button"
:class="{ 'blue': !erase }" @click="erase = false">
<i class="left pencil alternate icon"></i>
Fill
</button>
</div>
<div class="item">
<button class="ui labeled icon button item"
:class="{ 'red': erase }" @click="erase = true">
<i class="left eraser icon"></i>
Erase
</button>
</div>
<i class="ellipsis horizontal icon"></i>
<div class="item">
<button class="ui labeled icon button item" @click="loadFile">
<i class="left folder open icon"></i>
Load
</button>
</div>
<div class="item">
<button class="ui labeled icon button item" @click="saveFile">
<i class="left save icon"></i>
Save
</button>
</div>
</div>
<div class="ui centered cards">
<div class="card" v-for="(glyph, char) in glyphs" :key="char">
<div class="content">
<div class="editor">
<div class="row" v-for="y in height" :key="y">
<div v-for="x in width" v-bind:key="x"
:class="[glyph[y - 1][x - 1] ? 'fill' : '', 'cell']"
@click="edit(char, y - 1, x - 1)"></div>
</div>
</div>
<h2 class="ascii"><pre>{{ char }}</pre></h2>
<div class="meta">U+{{ char.codePointAt(0).toString(16) }}</div>
</div>
</div>
</div>
</main>
</template>
<script lang="ts">
import Vue from "vue";
import yaml from "js-yaml";
export default Vue.extend({
data() {
let glyphs = {};
for (let i = 0x20; i < 0x7f; i++) {
let bitmap = [];
for (let i = 0; i < 16; i++) {
bitmap.push([]);
for (let j = 0; j < 8; j++)
bitmap[i][j] = false;
}
glyphs[String.fromCodePoint(i)] = bitmap;
}
return {
writeFileHandle: null,
glyphs,
width: 8,
height: 16,
erase: false,
};
},
methods: {
edit(char, y, x) {
this.glyphs[char][y][x] = !this.erase;
this.$forceUpdate();
},
async loadFile() {
let handle, file, font;
try {
handle = await window.chooseFileSystemEntries({
type: "openFile",
accepts: [
{
extensions: ["yaml", "yml"],
mimeTypes: [
"application/x-yaml",
"text/yaml",
"text/plain",
]
}
]
});
file = await handle.getFile();
font = yaml.safeLoad(await file.text());
} catch(err) {
console.error(err);
alert("Failed to load the file.");
}
const glyphs = this.glyphs;
for (const glyph of font.glyphs) {
const bitmap = [];
for (const row of glyph.glyph.replace(/[ \n]/g, "").match(/.{8}/g)) {
const bitmap_row = [];
for (const cell of row) {
bitmap_row.push(!(cell == '.'));
}
bitmap.push(bitmap_row);
}
glyphs[String.fromCodePoint(glyph.codepoint)] = bitmap;
}
this.glyphs = glyphs;
this.$forceUpdate();
},
async openFileToSave() {
try {
this.writeFileHandle = await window.chooseFileSystemEntries({
type: "saveFile",
accepts: [
{
extensions: ["yaml", "yml"],
}
]
});
} catch(err) {
console.error(err);
alert("Failed to open the file.");
}
},
async saveFile() {
if (!this.writeFileHandle) {
await this.openFileToSave();
}
let font = "glyphs:\n";
for (const [char, bitmap] of Object.entries(this.glyphs)) {
font += ` # '${char}'\n`;
font += ` - codepoint: 0x${char.codePointAt(0).toString(16)}\n`;
font += " glyph: >\n";
for (const row of bitmap) {
font += " ";
for (const cell of row) {
font += cell ? "@" : ".";
}
font += "\n";
}
font += "\n";
}
const writer = await this.writeFileHandle.createWriter();
await writer.truncate(0);
await writer.write(0, font);
await writer.close();
const file = await this.writeFileHandle.getFile();
new Noty({
type: "success",
text: `Saved to ${file.name}`,
timeout: 3
}).show();
}
},
mounted() {
// Draw/erase by drawgging.
let drawing = false;
let modifiedCells = [];
for (const editor of Array.from(document.querySelectorAll(".editor"))) {
editor.addEventListener("mousedown", ev => drawing = true);
editor.addEventListener("mouseup", ev => {
drawing = false
modifiedCells = [];
});
editor.addEventListener("mousemove", ev => {
if (!drawing || modifiedCells.includes(ev.target))
return;
ev.target.dispatchEvent(new MouseEvent("click"));
modifiedCells.push(ev.target);
});
}
document.addEventListener("keydown", ev => {
// Cmd/Ctrl+S.
if ((ev.metaKey || ev.ctrlKey) && ev.keyCode == 83) {
this.saveFile();
ev.preventDefault();
return;
}
if (ev.key === "f") {
this.erase = false;
ev.preventDefault();
return;
}
if (ev.key === "e") {
this.erase = true;
ev.preventDefault();
return;
}
});
}
});
</script>
<style lang="scss" scoped>
main {
width: 100vw;
margin-top: 100px;
}
.menu {
position: fixed;
top: 0;
z-index: 1000;
background: #fafafa;
border-bottom: 1px solid #f7f7f7;
width: 100vw;
padding: 10px 0;
h1 {
vertical-align: middle;
margin: 0 30px;
}
& > * {
display: inline-block;
}
}
.editor {
cursor: cell;
border-collapse: collapse;
margin: 0 auto 0;
width: fit-content;
.row {
display: table-row;
}
.cell {
display: table-cell;
width: 20px;
height: 20px;
border: 2px solid #a9a9a9;
&.fill {
background: #3a3a3a;
}
.ascii {
user-select: none;
}
}
}
</style>
glyphs:
# '0'
- codepoint: 0x30
glyph: >
........
........
.@@@@@@.
@@....@@
@@....@@
@@....@@
@@@...@@
@@@@..@@
@@.@@.@@
@@..@@@@
@@...@@@
@@....@@
@@....@@
.@@@@@@.
........
........
# '1'
- codepoint: 0x31
glyph: >
........
........
...@@...
..@@@...
.@@@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
@@@@@@@@
........
........
# '2'
- codepoint: 0x32
glyph: >
........
........
..@@@@..
.@@..@@.
@@....@@
......@@
......@@
.....@@.
....@@..
...@@...
..@@....
.@@.....
@@....@@
@@@@@@@@
........
........
# '3'
- codepoint: 0x33
glyph: >
........
........
.@@@@@@.
@@....@@
......@@
......@@
......@@
..@@@@@.
......@@
......@@
......@@
......@@
@@....@@
.@@@@@@.
........
........
# '4'
- codepoint: 0x34
glyph: >
........
........
....@@..
...@@@..
..@@@@..
.@@.@@..
@@..@@..
@@..@@..
@@..@@..
@@@@@@@@
....@@..
....@@..
....@@..
...@@@@.
........
........
# '5'
- codepoint: 0x35
glyph: >
........
........
@@@@@@@.
@@......
@@......
@@......
@@......
@@@@@@@.
......@@
......@@
......@@
......@@
@@....@@
.@@@@@@.
........
........
# '6'
- codepoint: 0x36
glyph: >
........
........
..@@@@..
.@@..@@.
@@......
@@......
@@......
@@......
@@@@@@@.
@@....@@
@@....@@
@@....@@
@@....@@
.@@@@@@.
........
........
# '7'
- codepoint: 0x37
glyph: >
........
........
@@@@@@@@
@@....@@
@@....@@
......@@
.....@@.
....@@..
...@@...
..@@....
..@@....
..@@....
..@@....
..@@....
........
........
# '8'
- codepoint: 0x38
glyph: >
........
........
.@@@@@@.
@@....@@
@@....@@
@@....@@
@@....@@
.@@@@@@.
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
.@@@@@@.
........
........
# '9'
- codepoint: 0x39
glyph: >
........
........
.@@@@@@.
@@....@@
@@....@@
@@....@@
@@....@@
.@@@@@@@
......@@
......@@
......@@
@@....@@
@@...@@.
.@@@@@..
........
........
# ' '
- codepoint: 0x20
glyph: >
........
........
........
........
........
........
........
........
........
........
........
........
........
........
........
........
# '!'
- codepoint: 0x21
glyph: >
........
........
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
........
...@@...
...@@...
........
........
........
# '"'
- codepoint: 0x22
glyph: >
........
........
.@@..@@.
.@@..@@.
.@@..@@.
.@@..@@.
........
........
........
........
........
........
........
........
........
........
# '#'
- codepoint: 0x23
glyph: >
........
........
........
........
.@@..@@.
.@@..@@.
@@@@@@@@
.@@..@@.
.@@..@@.
.@@..@@.
@@@@@@@@
.@@..@@.
.@@..@@.
.@@..@@.
........
........
# '$'
- codepoint: 0x24
glyph: >
...@@...
...@@...
.@@@@@@.
@@.@@.@@
@@.@@.@@
@@.@@...
@@.@@...
@@@@@@@.
...@@@@@
...@@.@@
...@@.@@
@@.@@.@@
@@.@@@@.
.@@@@@..
...@@...
...@@...
# '%'
- codepoint: 0x25
glyph: >
........
........
........
........
........
@@@....@
@.@...@@
@@@..@@.
....@@..
...@@...
..@@....
.@@..@@@
@@...@.@
@....@@@
........
........
# '&'
- codepoint: 0x26
glyph: >
........
........
..@@@@..
.@@..@@.
.@@..@@.
.@@..@@.
..@@@@..
.@@@....
@@.@@..@
@@..@.@@
@@..@@@.
@@...@@.
@@..@@@.
.@@@@.@@
........
........
# '''
- codepoint: 0x27
glyph: >
........
........
...@@...
...@@...
...@@...
...@@...
........
........
........
........
........
........
........
........
........
........
# '('
- codepoint: 0x28
glyph: >
........
....@@..
...@@...
..@@....
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
..@@....
...@@...
....@@..
........
# ')'
- codepoint: 0x29
glyph: >
........
..@@....
...@@...
....@@..
.....@@.
.....@@.
.....@@.
.....@@.
.....@@.
.....@@.
.....@@.
.....@@.
....@@..
...@@...
..@@....
........
# '*'
- codepoint: 0x2a
glyph: >
........
........
........
........
........
........
.@@..@@.
..@@@@..
@@@@@@@@
..@@@@..
.@@..@@.
........
........
........
........
........
# '+'
- codepoint: 0x2b
glyph: >
........
........
........
........
........
........
...@@...
...@@...
.@@@@@@.
...@@...
...@@...
........
........
........
........
........
# ','
- codepoint: 0x2c
glyph: >
........
........
........
........
........
........
........
........
........
........
........
........
..@@....
..@@....
.@@.....
@@......
# '-'
- codepoint: 0x2d
glyph: >
........
........
........
........
........
........
........
........
.@@@@@@.
........
........
........
........
........
........
........
# '.'
- codepoint: 0x2e
glyph: >
........
........
........
........
........
........
........
........
........
........
........
........
..@@....
..@@....
........
........
# '/'
- codepoint: 0x2f
glyph: >
........
........
........
........
........
.......@
......@@
.....@@.
....@@..
...@@...
..@@....
.@@.....
@@......
@.......
........
........
# ':'
- codepoint: 0x3a
glyph: >
........
........
........
........
...@@...
...@@...
........
........
........
........
........
...@@...
...@@...
........
........
........
# ';'
- codepoint: 0x3b
glyph: >
........
........
........
........
...@@...
...@@...
........
........
........
........
........
...@@...
...@@...
..@@....
........
........
# '<'
- codepoint: 0x3c
glyph: >
........
........
........
.....@@.
....@@..
...@@...
..@@....
.@@.....
@@......
.@@.....
..@@....
...@@...
....@@..
.....@@.
........
........
# '='
- codepoint: 0x3d
glyph: >
........
........
........
........
........
........
........
.@@@@@@.
........
........
........
.@@@@@@.
........
........
........
........
# '>'
- codepoint: 0x3e
glyph: >
........
........
........
.@@.....
..@@....
...@@...
....@@..
.....@@.
......@@
.....@@.
....@@..
...@@...
..@@....
.@@.....
........
........
# '?'
- codepoint: 0x3f
glyph: >
........
........
.@@@@@@.
@@....@@
@@....@@
@@....@@
....@@@@
...@@...
...@@...
...@@...
...@@...
........
...@@...
...@@...
........
........
# '@'
- codepoint: 0x40
glyph: >
........
........
.@@@@@..
@@...@@.
@@....@@
@@.@@@@@
@@.@@@@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@.@@@@@
@@.@@.@@
@@......
.@@@@@@@
........
........
# 'A'
- codepoint: 0x41
glyph: >
........
........
...@@...
..@@@@..
.@@@@@@.
@@@..@@@
@@....@@
@@....@@
@@@@@@@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
........
........
# 'B'
- codepoint: 0x42
glyph: >
........
........
@@@@@@@.
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@@@@@.
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
@@@@@@@.
........
........
# 'C'
- codepoint: 0x43
glyph: >
........
........
.@@@@@@.
@@@...@@
@@.....@
@@......
@@......
@@......
@@......
@@......
@@......
@@.....@
@@@...@@
.@@@@@@.
........
........
# 'D'
- codepoint: 0x44
glyph: >
........
........
@@@@@@..
.@@..@@.
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@..@@.
@@@@@@..
........
........
# 'E'
- codepoint: 0x45
glyph: >
........
........
@@@@@@@@
.@@...@@
.@@....@
.@@.....
.@@.....
.@@..@..
.@@@@@..
.@@..@..
.@@.....
.@@....@
.@@...@@
@@@@@@@@
........
........
# 'F'
- codepoint: 0x46
glyph: >
........
........
@@@@@@@@
.@@...@@
.@@....@
.@@.....
.@@.....
.@@..@..
.@@@@@..
.@@..@..
.@@.....
.@@.....
.@@.....
@@@@....
........
........
# 'G'
- codepoint: 0x47
glyph: >
........
........
..@@@@@.
.@@...@@
@@.....@
@@......
@@......
@@......
@@..@@@@
@@....@@
@@....@@
@@....@@
@@@..@@@
.@@@@@.@
........
........
# 'H'
- codepoint: 0x48
glyph: >
........
........
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@@@@@@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
........
........
# 'I'
- codepoint: 0x49
glyph: >
........
........
.@@@@@@.
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
.@@@@@@.
........
........
# 'J'
- codepoint: 0x4a
glyph: >
........
........
..@@@@@.
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
@@..@@..
@@..@@..
.@@@@...
........
........
# 'K'
- codepoint: 0x4b
glyph: >
........
........
@@@...@@
.@@...@@
.@@...@@
.@@..@@.
.@@.@@..
.@@@@...
.@@@@...
.@@.@@..
.@@..@@.
.@@...@@
.@@...@@
@@@...@@
........
........
# 'L'
- codepoint: 0x4c
glyph: >
........
........
@@@@@...
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
.@@....@
.@@...@@
@@@@@@@@
........
........
# 'M'
- codepoint: 0x4d
glyph: >
........
........
@@....@@
@@@..@@@
@@@..@@@
@@@@@@@@
@@@@@@@@
@@.@@.@@
@@.@@.@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
........
........
# 'N'
- codepoint: 0x4e
glyph: >
........
........
@@....@@
@@@...@@
@@@...@@
@@@@..@@
@@@@..@@
@@.@@.@@
@@.@@@@@
@@..@@@@
@@...@@@
@@...@@@
@@....@@
@@....@@
........
........
# 'O'
- codepoint: 0x4f
glyph: >
........
........
..@@@@..
.@@..@@.
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
.@@..@@.
..@@@@..
........
........
# 'P'
- codepoint: 0x50
glyph: >
........
........
@@@@@@@.
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@@@@@.
.@@.....
.@@.....
.@@.....
.@@.....
.@@.....
@@@@....
........
........
# 'Q'
- codepoint: 0x51
glyph: >
........
........
..@@@@..
.@@..@@.
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@.@..@@
@@.@@.@@
.@@.@@@.
..@@@@@.
.....@@@
......@@
# 'R'
- codepoint: 0x52
glyph: >
........
........
@@@@@@@.
@@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@@@@@.
.@@.@@..
.@@..@@.
.@@...@@
.@@...@@
.@@...@@
@@@...@@
........
........
# 'S'
- codepoint: 0x53
glyph: >
........
........
.@@@@@@.
@@....@@
@@....@@
@@......
@@......
@@@@@@@.
.....@@@
......@@
......@@
@@....@@
@@...@@@
.@@@@@@.
........
........
# 'T'
- codepoint: 0x54
glyph: >
........
........
@@@@@@@@
@@@@@@@@
@..@@..@
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
..@@@@..
........
........
# 'U'
- codepoint: 0x55
glyph: >
........
........
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@@..@@@
.@@@@@@.
........
........
# 'V'
- codepoint: 0x56
glyph: >
........
........
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
.@@..@@.
..@@@@..
...@@...
........
........
# 'W'
- codepoint: 0x57
glyph: >
........
........
@@....@@
@@....@@
@@....@@
@@....@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@@@@@@@
.@@..@@.
........
........
# 'X'
- codepoint: 0x58
glyph: >
........
........
@@....@@
@@....@@
.@@..@@.
.@@..@@.
..@@@@..
...@@...
...@@...
..@@@@..
.@@..@@.
.@@..@@.
@@....@@
@@....@@
........
........
# 'Y'
- codepoint: 0x59
glyph: >
........
........
@@....@@
@@....@@
@@....@@
@@....@@
.@@..@@.
..@@@@..
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
........
........
# 'Z'
- codepoint: 0x5a
glyph: >
........
........
@@@@@@@@
@@....@@
@.....@@
.....@@.
....@@..
...@@...
..@@....
.@@.....
@@......
@@.....@
@@....@@
@@@@@@@@
........
........
# '['
- codepoint: 0x5b
glyph: >
........
........
..@@@@..
..@@....
..@@....
..@@....
..@@....
..@@....
..@@....
..@@....
..@@....
..@@....
..@@....
..@@@@..
........
........
# '\'
- codepoint: 0x5c
glyph: >
........
........
........
........
........
@.......
@@......
.@@.....
..@@....
...@@...
....@@..
.....@@.
......@@
.......@
........
........
# ']'
- codepoint: 0x5d
glyph: >
........
........
..@@@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
..@@@@..
........
........
# '^'
- codepoint: 0x5e
glyph: >
...@....
..@@@...
.@@.@@..
@@...@@.
........
........
........
........
........
........
........
........
........
........
........
........
# '_'
- codepoint: 0x5f
glyph: >
........
........
........
........
........
........
........
........
........
........
........
........
........
@@@@@@@@
........
........
# '`'
- codepoint: 0x60
glyph: >
........
........
...@@...
....@@..
.....@@.
........
........
........
........
........
........
........
........
........
........
........
# 'a'
- codepoint: 0x61
glyph: >
........
........
........
........
........
........
.@@@@@..
.....@@.
.....@@.
.@@@@@@.
@@...@@.
@@...@@.
@@..@@@.
.@@@@.@@
........
........
# 'b'
- codepoint: 0x62
glyph: >
........
........
@@@.....
.@@.....
.@@.....
.@@.....
.@@@@...
.@@..@@.
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@..@@@
@@.@@@@.
........
........
# 'c'
- codepoint: 0x63
glyph: >
........
........
........
........
........
........
.@@@@@@.
@@@...@@
@@......
@@......
@@......
@@......
@@@...@@
.@@@@@@.
........
........
# 'd'
- codepoint: 0x64
glyph: >
........
........
.....@@@
.....@@.
.....@@.
.....@@.
...@@@@.
.@@..@@.
@@...@@.
@@...@@.
@@...@@.
@@...@@.
@@@..@@.
.@@@@.@@
........
........
# 'e'
- codepoint: 0x65
glyph: >
........
........
........
........
........
........
.@@@@@@.
@@@...@@
@@....@@
@@@@@@@@
@@......
@@......
@@@...@@
.@@@@@@.
........
........
# 'f'
- codepoint: 0x66
glyph: >
........
........
...@@@@.
..@@..@@
..@@...@
..@@....
@@@@@@..
..@@....
..@@....
..@@....
..@@....
..@@....
..@@....
.@@@@...
........
........
# 'g'
- codepoint: 0x67
glyph: >
........
........
........
........
........
........
.@@@@.@@
@@..@@@.
@@...@@.
@@...@@.
@@..@@@.
.@@@@@@.
.....@@.
.....@@.
@@...@@.
.@@@@@..
# 'h'
- codepoint: 0x68
glyph: >
........
........
@@@.....
.@@.....
.@@.....
.@@.....
.@@.@@@.
.@@@@.@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
@@@...@@
........
........
# 'i'
- codepoint: 0x69
glyph: >
........
........
........
...@@...
...@@...
........
..@@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
..@@@@..
........
........
# 'j'
- codepoint: 0x6a
glyph: >
........
........
........
....@@..
....@@..
........
...@@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
....@@..
@@.@@@..
.@@@@...
# 'k'
- codepoint: 0x6b
glyph: >
........
........
@@@.....
.@@.....
.@@.....
.@@...@@
.@@..@@@
.@@.@@..
.@@@@...
.@@@@...
.@@.@@..
.@@..@@.
.@@...@@
@@@...@@
........
........
# 'l'
- codepoint: 0x6c
glyph: >
........
........
..@@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
..@@@@..
........
........
# 'm'
- codepoint: 0x6d
glyph: >
........
........
........
........
........
........
.@@..@@.
@@@@@@@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@....@@
........
........
# 'n'
- codepoint: 0x6e
glyph: >
........
........
........
........
........
........
@@.@@@..
.@@@@@@.
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
.@@...@@
........
........
# 'o'
- codepoint: 0x6f
glyph: >
........
........
........
........
........
........
..@@@@..
.@@..@@.
@@....@@
@@....@@
@@....@@
@@....@@
.@@..@@.
..@@@@..
........
........
# 'p'
- codepoint: 0x70
glyph: >
........
........
........
........
........
........
@@.@@@@.
.@@@..@@
.@@...@@
.@@...@@
.@@...@@
.@@@..@@
.@@@@@@.
.@@.....
.@@.....
@@@@....
# 'q'
- codepoint: 0x71
glyph: >
........
........
........
........
........
........
.@@@@.@@
@@..@@@.
@@...@@.
@@...@@.
@@...@@.
@@..@@@.
.@@@@@@.
.....@@.
.....@@.
....@@@@
# 'r'
- codepoint: 0x72
glyph: >
........
........
........
........
........
........
@@.@@@@.
.@@@@.@@
.@@...@@
.@@.....
.@@.....
.@@.....
.@@.....
@@@@....
........
........
# 's'
- codepoint: 0x73
glyph: >
........
........
........
........
........
........
.@@@@@..
@@...@@.
.@@.....
..@@@...
...@@@@.
.....@@.
@@...@@.
.@@@@@..
........
........
# 't'
- codepoint: 0x74
glyph: >
........
........
........
........
..@@....
..@@....
@@@@@@..
..@@....
..@@....
..@@....
..@@....
..@@....
..@@..@@
...@@@@.
........
........
# 'u'
- codepoint: 0x75
glyph: >
........
........
........
........
........
........
@@...@@.
@@...@@.
@@...@@.
@@...@@.
@@...@@.
@@...@@.
@@..@@@.
.@@@@.@@
........
........
# 'v'
- codepoint: 0x76
glyph: >
........
........
........
........
........
........
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
.@@..@@.
..@@@@..
........
........
# 'w'
- codepoint: 0x77
glyph: >
........
........
........
........
........
........
@@....@@
@@....@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@.@@.@@
@@@@@@@@
.@@..@@.
........
........
# 'x'
- codepoint: 0x78
glyph: >
........
........
........
........
........
........
@@....@@
.@@..@@.
..@@@@..
...@@...
...@@...
..@@@@..
.@@..@@.
@@....@@
........
........
# 'y'
- codepoint: 0x79
glyph: >
........
........
........
........
........
........
@@....@@
@@....@@
@@....@@
@@....@@
@@....@@
.@@@@@@@
......@@
.....@@.
....@@@.
@@@@@@..
# 'z'
- codepoint: 0x7a
glyph: >
........
........
........
........
........
........
@@@@@@@@
@@...@@.
....@@..
...@@...
..@@....
.@@.....
@@....@@
@@@@@@@@
........
........
# '{'
- codepoint: 0x7b
glyph: >
........
....@@@.
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
.@@@....
...@@...
...@@...
...@@...
...@@...
...@@...
....@@@.
........
# '|'
- codepoint: 0x7c
glyph: >
........
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
........
# '}'
- codepoint: 0x7d
glyph: >
........
.@@@....
...@@...
...@@...
...@@...
...@@...
...@@...
...@@...
....@@@.
...@@...
...@@...
...@@...
...@@...
...@@...
.@@@....
........
# '~'
- codepoint: 0x7e
glyph: >
........
........
........
........
........
........
........
.@@@.@@.
@@.@@@..
........
........
........
........
........
........
........
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bitmap Font Editor</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.4/noty.min.css" integrity="sha256-soW/iAENd5uEBh0+aUIS1m2dK4K6qTcB9MLuOnWEQhw=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.4/noty.min.js" integrity="sha256-ITwLtH5uF4UlWjZ0mdHOhPwDpLoqxzfFCZXn1wE56Ps=" crossorigin="anonymous"></script>
</head>
<body>
<div id="app"></div>
<script src="./index.js"></script>
</body>
</html>
import Vue from 'vue';
import App from './app.vue';
const app = new Vue({ render: f => f(App) }).$mount("#app");
#!/usr/bin/env python3
import argparse
import struct
import re
import yaml
def mkfont(font):
chars = [None] * 0x80
for glyph in font["glyphs"]:
chars[glyph["codepoint"]] = glyph["glyph"]
print("//")
print("// Automatically generated by mkfont.py.")
print("//")
print("#include <types.h>")
print("")
print("const uint8_t font[] = {")
for (asc, glyph) in enumerate(chars):
print(f" // '{chr(asc)}' 0x{asc:0>2x}")
if glyph is None:
for i in range(0, 16):
print(" 0x00, // ........")
else:
glyph = glyph.replace(" ", "").replace("\n", "")
assert len(glyph) == 8 * 16
for row in re.findall(".{8}", glyph):
byte = 0
for i, bit in enumerate(reversed(row)):
if bit != ".":
byte |= 1 << i
print(f" 0x{byte:0>2x}, // {row.replace('@', '#')}")
print("")
print("};")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("input")
args = parser.parse_args()
font = mkfont(yaml.safe_load(open(args.input)))
if __name__ == "__main__":
main()
{
"private": true,
"main": "index.js",
"scripts": {
"open": "parcel dev index.html --open"
},
"devDependencies": {
"@vue/component-compiler-utils": "^3.0.0",
"parcel-bundler": "^1.12.3",
"sass": "^1.23.0-module.beta.1",
"typescript": "^3.6.3",
"vue-template-compiler": "^2.6.10"
},
"dependencies": {
"js-yaml": "^3.13.1",
"vue": "^2.6.10",
"vue-hot-reload-api": "^2.3.3"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment