diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e69de29 diff --git a/assets/fonts/dejavu_sans.png b/assets/fonts/dejavu_sans.png new file mode 100644 index 0000000..67b77bc Binary files /dev/null and b/assets/fonts/dejavu_sans.png differ diff --git a/assets/fonts/dejavu_sans_book_8.json b/assets/fonts/dejavu_sans_book_8.json new file mode 100644 index 0000000..a306b3c --- /dev/null +++ b/assets/fonts/dejavu_sans_book_8.json @@ -0,0 +1,730 @@ +{ + "config": { + "base": 10, + "bold": 0, + "charHeight": 12, + "charSpacing": 0, + "face": "DejaVu Sans", + "italic": 0, + "lineSpacing": 0, + "size": 8, + "smooth": 1, + "textureFile": "dejavu_sans_book_8.PNG", + "textureHeight": 64, + "textureWidth": 128 + }, + "kerning": [ + { + "amount": -1, + "first": 76, + "second": 84 + }, + { + "amount": -1, + "first": 76, + "second": 86 + }, + { + "amount": -1, + "first": 76, + "second": 89 + }, + { + "amount": -1, + "first": 84, + "second": 97 + }, + { + "amount": -1, + "first": 84, + "second": 99 + }, + { + "amount": -1, + "first": 84, + "second": 101 + }, + { + "amount": -1, + "first": 84, + "second": 111 + }, + { + "amount": -1, + "first": 84, + "second": 114 + }, + { + "amount": -1, + "first": 84, + "second": 115 + }, + { + "amount": -1, + "first": 84, + "second": 117 + }, + { + "amount": -1, + "first": 84, + "second": 119 + }, + { + "amount": -1, + "first": 84, + "second": 121 + }, + { + "amount": -1, + "first": 89, + "second": 97 + }, + { + "amount": -1, + "first": 89, + "second": 101 + }, + { + "amount": -1, + "first": 89, + "second": 111 + }, + { + "amount": -1, + "first": 89, + "second": 117 + } + ], + "symbols": [ + { + "height": 1, + "id": 32, + "width": 1, + "x": 1, + "xadvance": 4, + "xoffset": 0, + "y": 10, + "yoffset": 10 + }, + { + "height": 10, + "id": 108, + "width": 3, + "x": 3, + "xadvance": 3, + "xoffset": 1, + "y": 1, + "yoffset": 1 + }, + { + "height": 9, + "id": 73, + "width": 3, + "x": 7, + "xadvance": 3, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 9, + "id": 105, + "width": 3, + "x": 11, + "xadvance": 3, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 7, + "id": 114, + "width": 5, + "x": 15, + "xadvance": 5, + "xoffset": 1, + "y": 4, + "yoffset": 4 + }, + { + "height": 10, + "id": 102, + "width": 6, + "x": 21, + "xadvance": 4, + "xoffset": 0, + "y": 1, + "yoffset": 1 + }, + { + "height": 9, + "id": 49, + "width": 6, + "x": 28, + "xadvance": 7, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 9, + "id": 70, + "width": 6, + "x": 35, + "xadvance": 6, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 9, + "id": 116, + "width": 6, + "x": 42, + "xadvance": 4, + "xoffset": 0, + "y": 2, + "yoffset": 2 + }, + { + "height": 10, + "id": 98, + "width": 7, + "x": 49, + "xadvance": 7, + "xoffset": 1, + "y": 1, + "yoffset": 1 + }, + { + "height": 10, + "id": 100, + "width": 7, + "x": 57, + "xadvance": 7, + "xoffset": 0, + "y": 1, + "yoffset": 1 + }, + { + "height": 10, + "id": 104, + "width": 7, + "x": 65, + "xadvance": 7, + "xoffset": 1, + "y": 1, + "yoffset": 1 + }, + { + "height": 10, + "id": 107, + "width": 7, + "x": 73, + "xadvance": 6, + "xoffset": 1, + "y": 1, + "yoffset": 1 + }, + { + "height": 9, + "id": 50, + "width": 7, + "x": 81, + "xadvance": 7, + "xoffset": 0, + "y": 2, + "yoffset": 2 + }, + { + "height": 9, + "id": 66, + "width": 7, + "x": 89, + "xadvance": 8, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 9, + "id": 69, + "width": 7, + "x": 97, + "xadvance": 7, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 9, + "id": 76, + "width": 7, + "x": 105, + "xadvance": 6, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 9, + "id": 80, + "width": 7, + "x": 113, + "xadvance": 7, + "xoffset": 1, + "y": 2, + "yoffset": 2 + }, + { + "height": 7, + "id": 97, + "width": 7, + "x": 1, + "xadvance": 7, + "xoffset": 0, + "y": 14, + "yoffset": 4 + }, + { + "height": 7, + "id": 99, + "width": 7, + "x": 9, + "xadvance": 6, + "xoffset": 0, + "y": 14, + "yoffset": 4 + }, + { + "height": 7, + "id": 110, + "width": 7, + "x": 17, + "xadvance": 7, + "xoffset": 1, + "y": 14, + "yoffset": 4 + }, + { + "height": 7, + "id": 115, + "width": 7, + "x": 25, + "xadvance": 6, + "xoffset": 0, + "y": 14, + "yoffset": 4 + }, + { + "height": 7, + "id": 117, + "width": 7, + "x": 33, + "xadvance": 7, + "xoffset": 0, + "y": 14, + "yoffset": 4 + }, + { + "height": 7, + "id": 122, + "width": 7, + "x": 41, + "xadvance": 6, + "xoffset": 0, + "y": 14, + "yoffset": 4 + }, + { + "height": 9, + "id": 48, + "width": 8, + "x": 49, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 51, + "width": 8, + "x": 58, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 52, + "width": 8, + "x": 67, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 53, + "width": 8, + "x": 76, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 54, + "width": 8, + "x": 85, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 55, + "width": 8, + "x": 94, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 56, + "width": 8, + "x": 103, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 57, + "width": 8, + "x": 112, + "xadvance": 7, + "xoffset": 0, + "y": 12, + "yoffset": 2 + }, + { + "height": 9, + "id": 68, + "width": 8, + "x": 1, + "xadvance": 8, + "xoffset": 1, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 72, + "width": 8, + "x": 10, + "xadvance": 8, + "xoffset": 1, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 75, + "width": 8, + "x": 19, + "xadvance": 7, + "xoffset": 1, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 78, + "width": 8, + "x": 28, + "xadvance": 8, + "xoffset": 1, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 82, + "width": 8, + "x": 37, + "xadvance": 8, + "xoffset": 1, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 83, + "width": 8, + "x": 46, + "xadvance": 7, + "xoffset": 0, + "y": 22, + "yoffset": 2 + }, + { + "height": 7, + "id": 101, + "width": 8, + "x": 55, + "xadvance": 7, + "xoffset": 0, + "y": 24, + "yoffset": 4 + }, + { + "height": 7, + "id": 111, + "width": 8, + "x": 64, + "xadvance": 7, + "xoffset": 0, + "y": 24, + "yoffset": 4 + }, + { + "height": 7, + "id": 118, + "width": 8, + "x": 73, + "xadvance": 7, + "xoffset": 0, + "y": 24, + "yoffset": 4 + }, + { + "height": 7, + "id": 120, + "width": 8, + "x": 82, + "xadvance": 7, + "xoffset": 0, + "y": 24, + "yoffset": 4 + }, + { + "height": 9, + "id": 65, + "width": 9, + "x": 91, + "xadvance": 8, + "xoffset": 0, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 67, + "width": 9, + "x": 101, + "xadvance": 8, + "xoffset": 0, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 71, + "width": 9, + "x": 111, + "xadvance": 9, + "xoffset": 0, + "y": 22, + "yoffset": 2 + }, + { + "height": 9, + "id": 77, + "width": 9, + "x": 1, + "xadvance": 9, + "xoffset": 1, + "y": 32, + "yoffset": 2 + }, + { + "height": 9, + "id": 84, + "width": 9, + "x": 11, + "xadvance": 7, + "xoffset": -1, + "y": 32, + "yoffset": 2 + }, + { + "height": 9, + "id": 85, + "width": 9, + "x": 21, + "xadvance": 8, + "xoffset": 0, + "y": 32, + "yoffset": 2 + }, + { + "height": 9, + "id": 86, + "width": 9, + "x": 31, + "xadvance": 8, + "xoffset": 0, + "y": 32, + "yoffset": 2 + }, + { + "height": 9, + "id": 88, + "width": 9, + "x": 41, + "xadvance": 8, + "xoffset": 0, + "y": 32, + "yoffset": 2 + }, + { + "height": 9, + "id": 89, + "width": 9, + "x": 51, + "xadvance": 7, + "xoffset": -1, + "y": 32, + "yoffset": 2 + }, + { + "height": 9, + "id": 90, + "width": 9, + "x": 61, + "xadvance": 8, + "xoffset": 0, + "y": 32, + "yoffset": 2 + }, + { + "height": 9, + "id": 79, + "width": 10, + "x": 71, + "xadvance": 9, + "xoffset": 0, + "y": 32, + "yoffset": 2 + }, + { + "height": 7, + "id": 109, + "width": 10, + "x": 82, + "xadvance": 11, + "xoffset": 1, + "y": 34, + "yoffset": 4 + }, + { + "height": 7, + "id": 119, + "width": 10, + "x": 93, + "xadvance": 9, + "xoffset": 0, + "y": 34, + "yoffset": 4 + }, + { + "height": 9, + "id": 87, + "width": 12, + "x": 104, + "xadvance": 11, + "xoffset": 0, + "y": 32, + "yoffset": 2 + }, + { + "height": 10, + "id": 81, + "width": 10, + "x": 1, + "xadvance": 9, + "xoffset": 0, + "y": 42, + "yoffset": 2 + }, + { + "height": 11, + "id": 74, + "width": 5, + "x": 12, + "xadvance": 3, + "xoffset": -1, + "y": 42, + "yoffset": 2 + }, + { + "height": 11, + "id": 106, + "width": 5, + "x": 18, + "xadvance": 3, + "xoffset": -1, + "y": 42, + "yoffset": 2 + }, + { + "height": 9, + "id": 103, + "width": 7, + "x": 24, + "xadvance": 7, + "xoffset": 0, + "y": 44, + "yoffset": 4 + }, + { + "height": 9, + "id": 112, + "width": 7, + "x": 32, + "xadvance": 7, + "xoffset": 1, + "y": 44, + "yoffset": 4 + }, + { + "height": 9, + "id": 113, + "width": 7, + "x": 40, + "xadvance": 7, + "xoffset": 0, + "y": 44, + "yoffset": 4 + }, + { + "height": 9, + "id": 121, + "width": 8, + "x": 48, + "xadvance": 7, + "xoffset": 0, + "y": 44, + "yoffset": 4 + } + ] +} diff --git a/src/font/dejavusans.c b/src/font/dejavusans.c new file mode 100644 index 0000000..78e3638 --- /dev/null +++ b/src/font/dejavusans.c @@ -0,0 +1,792 @@ + + +#include "font.h" + +struct FontKerning gDejaVuSansKerning[] = { + {.amount = -1, .first = 76, .second = 84}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 76, .second = 86}, + {.amount = -1, .first = 84, .second = 111}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 76, .second = 89}, + {.amount = -1, .first = 84, .second = 114}, + {.amount = -1, .first = 84, .second = 115}, + {.amount = -1, .first = 89, .second = 111}, + {.amount = -1, .first = 84, .second = 117}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 84, .second = 119}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 84, .second = 121}, + {.amount = -1, .first = 89, .second = 117}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 84, .second = 97}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 84, .second = 99}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 84, .second = 101}, + {.amount = -1, .first = 89, .second = 97}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = 0, .first = 0, .second = 0}, + {.amount = -1, .first = 89, .second = 101}, + {.amount = 0, .first = 0, .second = 0}, +}; + + +struct FontSymbol gDejaVuSansSymbols[] = { + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 1, .y = 10, + .width = 1, .height = 1, + .xoffset = 0, .yoffset = 10, + .xadvance = 4, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 49, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 28, .y = 2, + .width = 6, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 81, .y = 2, + .width = 7, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 58, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 67, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 76, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 85, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 94, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 103, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 112, .y = 12, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 91, .y = 22, + .width = 9, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 89, .y = 2, + .width = 7, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 101, .y = 22, + .width = 9, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 1, .y = 22, + .width = 8, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 97, .y = 2, + .width = 7, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 35, .y = 2, + .width = 6, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 6, + }, + { + .x = 111, .y = 22, + .width = 9, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 9, + }, + { + .x = 10, .y = 22, + .width = 8, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 7, .y = 2, + .width = 3, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 3, + }, + { + .x = 12, .y = 42, + .width = 5, .height = 11, + .xoffset = -1, .yoffset = 2, + .xadvance = 3, + }, + { + .x = 19, .y = 22, + .width = 8, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 105, .y = 2, + .width = 7, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 6, + }, + { + .x = 1, .y = 32, + .width = 9, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 9, + }, + { + .x = 28, .y = 22, + .width = 8, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 71, .y = 32, + .width = 10, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 9, + }, + { + .x = 113, .y = 2, + .width = 7, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 1, .y = 42, + .width = 10, .height = 10, + .xoffset = 0, .yoffset = 2, + .xadvance = 9, + }, + { + .x = 37, .y = 22, + .width = 8, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 46, .y = 22, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 11, .y = 32, + .width = 9, .height = 9, + .xoffset = -1, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 21, .y = 32, + .width = 9, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 31, .y = 32, + .width = 9, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 104, .y = 32, + .width = 12, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 11, + }, + { + .x = 41, .y = 32, + .width = 9, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 51, .y = 32, + .width = 9, .height = 9, + .xoffset = -1, .yoffset = 2, + .xadvance = 7, + }, + { + .x = 61, .y = 32, + .width = 9, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 8, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 0, .y = 0, + .width = 0, .height = 0, + .xoffset = 0, .yoffset = 0, + .xadvance = 0, + }, + { + .x = 1, .y = 14, + .width = 7, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 49, .y = 1, + .width = 7, .height = 10, + .xoffset = 1, .yoffset = 1, + .xadvance = 7, + }, + { + .x = 9, .y = 14, + .width = 7, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 6, + }, + { + .x = 57, .y = 1, + .width = 7, .height = 10, + .xoffset = 0, .yoffset = 1, + .xadvance = 7, + }, + { + .x = 55, .y = 24, + .width = 8, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 21, .y = 1, + .width = 6, .height = 10, + .xoffset = 0, .yoffset = 1, + .xadvance = 4, + }, + { + .x = 24, .y = 44, + .width = 7, .height = 9, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 65, .y = 1, + .width = 7, .height = 10, + .xoffset = 1, .yoffset = 1, + .xadvance = 7, + }, + { + .x = 11, .y = 2, + .width = 3, .height = 9, + .xoffset = 1, .yoffset = 2, + .xadvance = 3, + }, + { + .x = 18, .y = 42, + .width = 5, .height = 11, + .xoffset = -1, .yoffset = 2, + .xadvance = 3, + }, + { + .x = 73, .y = 1, + .width = 7, .height = 10, + .xoffset = 1, .yoffset = 1, + .xadvance = 6, + }, + { + .x = 3, .y = 1, + .width = 3, .height = 10, + .xoffset = 1, .yoffset = 1, + .xadvance = 3, + }, + { + .x = 82, .y = 34, + .width = 10, .height = 7, + .xoffset = 1, .yoffset = 4, + .xadvance = 11, + }, + { + .x = 17, .y = 14, + .width = 7, .height = 7, + .xoffset = 1, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 64, .y = 24, + .width = 8, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 32, .y = 44, + .width = 7, .height = 9, + .xoffset = 1, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 40, .y = 44, + .width = 7, .height = 9, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 15, .y = 4, + .width = 5, .height = 7, + .xoffset = 1, .yoffset = 4, + .xadvance = 5, + }, + { + .x = 25, .y = 14, + .width = 7, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 6, + }, + { + .x = 42, .y = 2, + .width = 6, .height = 9, + .xoffset = 0, .yoffset = 2, + .xadvance = 4, + }, + { + .x = 33, .y = 14, + .width = 7, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 73, .y = 24, + .width = 8, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 93, .y = 34, + .width = 10, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 9, + }, + { + .x = 82, .y = 24, + .width = 8, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 48, .y = 44, + .width = 8, .height = 9, + .xoffset = 0, .yoffset = 4, + .xadvance = 7, + }, + { + .x = 41, .y = 14, + .width = 7, .height = 7, + .xoffset = 0, .yoffset = 4, + .xadvance = 6, + }, +}; + +struct Font gDejaVuSansFont = { + .kerning = &gDejaVuSansKerning[0], + .symbols = &gDejaVuSansSymbols[0], + .base = 10, + .charHeight = 12, + .symbolCount = 123, + .kerningMultiplier = 1, + .kerningMask = 0x1f, + .maxCollisions = 0, +}; + diff --git a/src/font/font.c b/src/font/font.c new file mode 100644 index 0000000..371cc4e --- /dev/null +++ b/src/font/font.c @@ -0,0 +1,23 @@ +#include "font.h" + +int fontDetermineKerning(struct Font* font, char first, char second) { + unsigned index = ((unsigned)first * (unsigned)font->kerningMultiplier + (unsigned)second) & (unsigned)font->kerningMask; + int maxIterations = font->maxCollisions; + + do { + struct FontKerning* kerning = &font->kerning[index]; + + if (kerning->amount == 0) { + return 0; + } + + if (kerning->first == first && kerning->second == second) { + return kerning->amount; + } + + ++index; + --maxIterations; + } while (maxIterations >= 0); + + return 0; +} \ No newline at end of file diff --git a/src/font/font.h b/src/font/font.h new file mode 100644 index 0000000..408d156 --- /dev/null +++ b/src/font/font.h @@ -0,0 +1,29 @@ +#ifndef __FONT_FONT_H__ +#define __FONT_FONT_H__ + +struct FontKerning { + char amount; + char first; + char second; +}; + +struct FontSymbol { + char x, y; + char width, height; + char xoffset, yoffset; + char xadvance; +}; + +struct Font { + struct FontKerning* kerning; + struct FontSymbol* symbols; + + char base; + char charHeight; + unsigned short symbolCount; + unsigned short kerningMultiplier; + unsigned short kerningMask; + unsigned short maxCollisions; +}; + +#endif \ No newline at end of file diff --git a/tools/font_converter.js b/tools/font_converter.js new file mode 100644 index 0000000..d671091 --- /dev/null +++ b/tools/font_converter.js @@ -0,0 +1,144 @@ +// this tool takes a the json output from https://github.com/andryblack/fontbuilder and create a font usabe in portal64 + +const fs = require('fs'); + +const name = process.argv[2]; +const input = JSON.parse(fs.readFileSync(process.argv[3])); + +function hashFunction(first, second, multiplier, arraySize) { + return ((first * multiplier) + second) % arraySize; +} + +function checkForCollisions(kerningList, multiplier, arraySize) { + const sparseArray = []; + sparseArray.length = arraySize; + + if (arraySize < kerningList.length) { + return null; + } + + let totalCollisions = 0; + let maxCollisions = 0; + + for (const kerning of kerningList) { + let index = hashFunction(kerning.first, kerning.second, multiplier, arraySize); + + let currentCollisions = 0; + + while (sparseArray[index]) { + index = (index + 1) % arraySize; + totalCollisions = totalCollisions + 1; + currentCollisions = currentCollisions + 1; + } + + maxCollisions = Math.max(maxCollisions, currentCollisions); + + sparseArray[index] = kerning; + } + + for (let i = 0; i < arraySize; ++i) { + if (!sparseArray[i]) { + sparseArray[i] = {amount: 0, first: 0, second: 0}; + } + } + + return {sparseArray, totalCollisions, maxCollisions}; +} + +function searchForBestKerning(kerningList) { + let result; + let multiplier; + + let arraySize = 1; + let mask = 2; + + while (arraySize < kerningList.length) { + arraySize *= 2; + mask <<= 1; + } + + arraySize *= 2; + + for (let i = 1; i < 0x10000; ++i) { + const check = checkForCollisions(kerningList, i, arraySize); + + if (!result || check.totalCollisions < result.totalCollisions) { + result = check + multiplier = i; + } + } + + console.log(`totalCollisions = ${result.totalCollisions}`); + + mask -= 1; + + return {result: result.sparseArray, multiplier: multiplier, mask: mask, totalCollisions: result.totalCollisions, maxCollisions: result.maxCollisions}; +} + +function buildKerning(kerningList) { + return `struct FontKerning g${name}Kerning[] = { +${kerningList.map(kerning => ` {.amount = ${kerning.amount}, .first = ${kerning.first}, .second = ${kerning.second}},`).join('\n')} +}; +` +} + +function buildFont(multiplier, mask, symbolCount, maxCollisions) { + return `struct Font g${name}Font = { + .kerning = &g${name}Kerning[0], + .symbols = &g${name}Symbols[0], + .base = ${input.config.base}, + .charHeight = ${input.config.charHeight}, + .symbolCount = ${symbolCount}, + .kerningMultiplier = ${multiplier}, + .kerningMask = 0x${mask.toString(16)}, + .maxCollisions = ${maxCollisions}, +}; +` +} + +function sparseSymbols(symbols) { + const result = []; + + for (let i = 0; i < symbols.length; ++i) { + result[symbols[i].id] = symbols[i]; + } + + for (let i = 0; i < result.length; ++i) { + if (!result[i]) { + result[i] = { + x: 0, y: 0, + width: 0, height: 0, + xoffset: 0, yoffset: 0, + xadvance: 0, + }; + } + } + + return result; +} + +function buildSymbol(symbol) { + return ` { + .x = ${symbol.x}, .y = ${symbol.y}, + .width = ${symbol.width}, .height = ${symbol.height}, + .xoffset = ${symbol.xoffset}, .yoffset = ${symbol.yoffset}, + .xadvance = ${symbol.xadvance}, + },` +} + +const kerningResult = searchForBestKerning(input.kerning); + +const symbols = sparseSymbols(input.symbols); + +fs.writeFileSync(process.argv[4], ` + +#include "font.h" + +${buildKerning(kerningResult.result)} + +struct FontSymbol g${name}Symbols[] = { +${symbols.map(buildSymbol).join('\n')} +}; + +${buildFont(kerningResult.multiplier, kerningResult.mask, symbols.length, kerningResult.maxCollisions)} +`); \ No newline at end of file