@dryanovski/gamefoo 0.2.1 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/core/animate.js +147 -0
  2. package/dist/core/asset.js +74 -0
  3. package/dist/core/behaviour.js +88 -0
  4. package/dist/core/behaviours/collidable.js +186 -0
  5. package/dist/core/behaviours/control.js +75 -0
  6. package/dist/core/behaviours/healtkit.js +153 -0
  7. package/dist/core/behaviours/sprite_render.js +193 -0
  8. package/dist/core/camera.js +134 -0
  9. package/dist/core/engine.d.ts +1 -1
  10. package/dist/core/engine.d.ts.map +1 -1
  11. package/dist/core/engine.js +527 -0
  12. package/dist/core/fonts/font_bitmap.js +205 -0
  13. package/dist/core/fonts/font_bitmap_prebuild.js +137 -0
  14. package/dist/core/fonts/internal/font_3x5.js +169 -0
  15. package/dist/core/fonts/internal/font_4x6.js +171 -0
  16. package/dist/core/fonts/internal/font_5x5.js +129 -0
  17. package/dist/core/fonts/internal/font_6x8.js +171 -0
  18. package/dist/core/fonts/internal/font_8x13.js +171 -0
  19. package/dist/core/fonts/internal/font_8x8.js +171 -0
  20. package/dist/core/game_object_register.js +134 -0
  21. package/dist/core/input.js +170 -0
  22. package/dist/core/sprite.js +222 -0
  23. package/dist/core/utils/perlin_noise.js +183 -0
  24. package/dist/core/world.js +304 -0
  25. package/dist/debug/monitor.js +47 -0
  26. package/dist/decorators/index.js +1 -0
  27. package/dist/decorators/log.js +42 -0
  28. package/dist/entities/dynamic_entity.js +99 -0
  29. package/dist/entities/entity.js +283 -0
  30. package/dist/entities/player.js +93 -0
  31. package/dist/entities/text.js +62 -0
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +47 -29
  35. package/dist/subsystems/camera_system.d.ts +2 -2
  36. package/dist/subsystems/camera_system.d.ts.map +1 -1
  37. package/dist/subsystems/camera_system.js +41 -0
  38. package/dist/subsystems/collision_system.js +17 -0
  39. package/dist/subsystems/monitor_system.js +20 -0
  40. package/dist/subsystems/object_system.d.ts +1 -1
  41. package/dist/subsystems/object_system.d.ts.map +1 -1
  42. package/dist/subsystems/object_system.js +29 -0
  43. package/dist/subsystems/types.d.ts +1 -1
  44. package/dist/subsystems/types.d.ts.map +1 -1
  45. package/dist/subsystems/types.js +0 -0
  46. package/dist/types.js +10 -0
  47. package/package.json +17 -6
  48. package/src/core/animate.ts +159 -0
  49. package/src/core/asset.ts +76 -0
  50. package/src/core/behaviour.ts +145 -0
  51. package/src/core/behaviours/collidable.ts +296 -0
  52. package/src/core/behaviours/control.ts +80 -0
  53. package/src/core/behaviours/healtkit.ts +166 -0
  54. package/src/core/behaviours/sprite_render.ts +216 -0
  55. package/src/core/camera.ts +145 -0
  56. package/src/core/engine.ts +607 -0
  57. package/src/core/fonts/font_bitmap.ts +232 -0
  58. package/src/core/fonts/font_bitmap_prebuild.ts +141 -0
  59. package/src/core/fonts/internal/font_3x5.ts +178 -0
  60. package/src/core/fonts/internal/font_4x6.ts +180 -0
  61. package/src/core/fonts/internal/font_5x5.ts +137 -0
  62. package/src/core/fonts/internal/font_6x8.ts +180 -0
  63. package/src/core/fonts/internal/font_8x13.ts +180 -0
  64. package/src/core/fonts/internal/font_8x8.ts +180 -0
  65. package/src/core/game_object_register.ts +146 -0
  66. package/src/core/input.ts +182 -0
  67. package/src/core/sprite.ts +339 -0
  68. package/src/core/utils/perlin_noise.ts +196 -0
  69. package/src/core/world.ts +331 -0
  70. package/src/debug/monitor.ts +60 -0
  71. package/src/decorators/index.ts +1 -0
  72. package/src/decorators/log.ts +45 -0
  73. package/src/entities/dynamic_entity.ts +106 -0
  74. package/src/entities/entity.ts +322 -0
  75. package/src/entities/player.ts +99 -0
  76. package/src/entities/text.ts +72 -0
  77. package/src/index.ts +51 -0
  78. package/src/subsystems/camera_system.ts +52 -0
  79. package/src/subsystems/collision_system.ts +21 -0
  80. package/src/subsystems/monitor_system.ts +26 -0
  81. package/src/subsystems/object_system.ts +37 -0
  82. package/src/subsystems/types.ts +46 -0
  83. package/src/types.ts +178 -0
  84. package/dist/index.js.map +0 -9
@@ -0,0 +1,205 @@
1
+ import { metadata as FONT_3x5_METADATA } from "./internal/font_3x5";
2
+ import { metadata as FONT_4x6_METADATA } from "./internal/font_4x6";
3
+ import { metadata as FONT_5x5_METADATA } from "./internal/font_5x5";
4
+ import { metadata as FONT_6x8_METADATA } from "./internal/font_6x8";
5
+ import { metadata as FONT_8x8_METADATA } from "./internal/font_8x8";
6
+ import { metadata as FONT_8x13_METADATA } from "./internal/font_8x13";
7
+ /**
8
+ * Internal catalogue of registered bitmap font definitions.
9
+ *
10
+ * Fonts are added at module load time. Currently ships with the
11
+ * built-in {@link FONT_5x5 | 5x5} pixel font.
12
+ *
13
+ * @internal
14
+ */
15
+ const Catalog = new Map();
16
+ Catalog.set(FONT_3x5_METADATA.name, FONT_3x5_METADATA);
17
+ Catalog.set(FONT_4x6_METADATA.name, FONT_4x6_METADATA);
18
+ Catalog.set(FONT_5x5_METADATA.name, FONT_5x5_METADATA);
19
+ Catalog.set(FONT_6x8_METADATA.name, FONT_6x8_METADATA);
20
+ Catalog.set(FONT_8x13_METADATA.name, FONT_8x13_METADATA);
21
+ Catalog.set(FONT_8x8_METADATA.name, FONT_8x8_METADATA);
22
+ /**
23
+ * Pixel-perfect bitmap font renderer.
24
+ *
25
+ * `FontBitmap` looks up a named font from the built-in catalogue,
26
+ * then renders individual characters or whole strings onto a
27
+ * `CanvasRenderingContext2D` one pixel at a time using `fillRect`.
28
+ *
29
+ * Each character is stored as an array of row bitmasks where each bit
30
+ * represents a single pixel.
31
+ *
32
+ * @category Fonts
33
+ * @since 0.1.0
34
+ *
35
+ * @example Rendering text with the built-in 5x5 font
36
+ * ```ts
37
+ * import { FontBitmap } from "gamefoo";
38
+ *
39
+ * const font = new FontBitmap("5x5");
40
+ *
41
+ * ctx.fillStyle = "#ffffff";
42
+ * font.renderText("HELLO WORLD", 10, 10, ctx);
43
+ * ```
44
+ *
45
+ * @example Measuring text width
46
+ * ```ts
47
+ * const font = new FontBitmap("5x5");
48
+ * const width = font.getTextWidth("SCORE 999");
49
+ * // width === 9 * 6 = 54 (each char is 5px + 1px spacing)
50
+ * ```
51
+ *
52
+ * @see {@link FONT_5x5} — the built-in 5x5 pixel font data
53
+ */
54
+ export default class FontBitmap {
55
+ /** The catalogue name of the loaded font (e.g. `"5x5"`). */
56
+ name;
57
+ /**
58
+ * Character bitmask data keyed by character string.
59
+ *
60
+ * Each value is an array of integers where each integer represents
61
+ * one row of pixels (MSB = leftmost pixel).
62
+ */
63
+ data;
64
+ /**
65
+ * Character cell width in pixels (including spacing).
66
+ *
67
+ * @defaultValue `0` (populated from catalogue on construction)
68
+ */
69
+ width = 0;
70
+ /**
71
+ * Character cell height in pixels.
72
+ *
73
+ * @defaultValue `0` (populated from catalogue on construction)
74
+ */
75
+ height = 0;
76
+ /**
77
+ * Horizontal spacing between the drawable area and the full cell
78
+ * width, in pixels.
79
+ *
80
+ * @defaultValue `0`
81
+ */
82
+ spacing = 0;
83
+ /**
84
+ * Creates a font renderer for the named catalogue entry.
85
+ *
86
+ * If the name does not match any registered font the instance will
87
+ * have empty data and zero dimensions — calls to `renderChar` /
88
+ * `renderText` will be no-ops.
89
+ *
90
+ * @param name - The catalogue key (e.g. `"5x5"`).
91
+ *
92
+ * @throws Error if the name is not found in the catalogue.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * const font = new FontBitmap("5x5");
97
+ * ```
98
+ */
99
+ constructor(name) {
100
+ this.name = name;
101
+ this.data = {};
102
+ if (Catalog.has(name)) {
103
+ this.data = Catalog.get(name).data;
104
+ }
105
+ else {
106
+ throw new Error(`FontBitmap: No font found for name "${name}".`);
107
+ }
108
+ this.width = this.metadata?.width || 0;
109
+ this.height = this.metadata?.height || 0;
110
+ this.spacing = this.metadata?.spacing || 0;
111
+ }
112
+ /**
113
+ * Returns the raw catalogue entry for this font, or `null` if the
114
+ * font name was not found.
115
+ *
116
+ * @returns Font metadata object or `null`.
117
+ */
118
+ get metadata() {
119
+ return Catalog.get(this.name) || null;
120
+ }
121
+ /**
122
+ * Retrieves the bitmask rows for a single character.
123
+ *
124
+ * @param char - A single character string (e.g. `"A"`).
125
+ * @returns An array of row bitmasks, or `null` if the character is
126
+ * not defined in this font.
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * const rows = font.getChar("A");
131
+ * // rows → [14, 17, 31, 17, 17] for the 5x5 font
132
+ * ```
133
+ */
134
+ getChar(char) {
135
+ return this.data[char] || null;
136
+ }
137
+ /**
138
+ * Computes the pixel width required to render the given text string.
139
+ *
140
+ * @param text - The string to measure.
141
+ * @returns Width in pixels (`text.length * cellWidth`).
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * const w = font.getTextWidth("HI"); // 12 for the 5x5 font
146
+ * ```
147
+ */
148
+ getTextWidth(text) {
149
+ return text.length * this.width;
150
+ }
151
+ /**
152
+ * Renders a single character at the given pixel position.
153
+ *
154
+ * Each set bit in the character's row bitmask produces a 1x1
155
+ * `fillRect` call using the context's current `fillStyle`.
156
+ *
157
+ * @param char - The character to draw.
158
+ * @param x - Left edge X coordinate in canvas pixels.
159
+ * @param y - Top edge Y coordinate in canvas pixels.
160
+ * @param ctx - The 2-D rendering context to draw into.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * ctx.fillStyle = "#00ff00";
165
+ * font.renderChar("G", 20, 40, ctx);
166
+ * ```
167
+ */
168
+ renderChar(char, x, y, ctx) {
169
+ const charData = this.getChar(char);
170
+ if (charData === null) {
171
+ return;
172
+ }
173
+ for (let row = 0; row < charData.length; row++) {
174
+ const bits = charData[row];
175
+ for (let col = 0; col < this.width - this.spacing; col++) {
176
+ if ((bits & (1 << (this.width - this.spacing - 1 - col))) !== 0) {
177
+ ctx.fillRect(x + col, y + row, 1, 1);
178
+ }
179
+ }
180
+ }
181
+ }
182
+ /**
183
+ * Renders a full text string by drawing each character sequentially.
184
+ *
185
+ * Characters are spaced according to the font's cell width.
186
+ *
187
+ * @param text - The string to render.
188
+ * @param x - Left edge X coordinate of the first character.
189
+ * @param y - Top edge Y coordinate.
190
+ * @param ctx - The 2-D rendering context.
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * ctx.fillStyle = "#ffffff";
195
+ * font.renderText("GAME OVER", 100, 50, ctx);
196
+ * ```
197
+ */
198
+ renderText(text, x, y, ctx) {
199
+ let offsetX = 0;
200
+ for (const char of text) {
201
+ this.renderChar(char, x + offsetX, y, ctx);
202
+ offsetX += this.width;
203
+ }
204
+ }
205
+ }
@@ -0,0 +1,137 @@
1
+ import FontBitmap from "./font_bitmap";
2
+ /**
3
+ * Bitmap font renderer that pre-builds character paths for faster rendering and
4
+ * reduced CPU usage at the cost of increased memory usage.
5
+ *
6
+ * GC pressure is reduced by pre-building `Path2D` objects for each character,
7
+ * which are then reused on subsequent renders. This can significantly improve
8
+ * performance when rendering the same characters multiple times, such as in a
9
+ * game UI or repeated text elements.
10
+ *
11
+ * Build on top of {@link FontBitmap}, `FontBitmapPrebuild` overrides the character rendering
12
+ *
13
+ * @category Fonts
14
+ * @since 0.2.0
15
+ *
16
+ * @example Pre-building glyphs for a menu
17
+ *
18
+ * ```ts
19
+ * import { FontBitmapPrebuild } from "gamefoo";
20
+ *
21
+ * const font = new FontBitmapPrebuild("5x5");
22
+ * font.prebuildGlyphs("PLAY SETTINGS EXIT".split(""));
23
+ *
24
+ * // Later in the render loop
25
+ * ctx.fillStyle = "#ffffff";
26
+ * font.renderText("PLAY", 10, 10, ctx);
27
+ * font.renderText("SETTINGS", 10, 20, ctx);
28
+ * font.renderText("EXIT", 10, 30, ctx);
29
+ * ```
30
+ *
31
+ * @example Performance comparison
32
+ *
33
+ * ```ts
34
+ * import { FontBitmap, FontBitmapPrebuild } from "gamefoo";
35
+ *
36
+ * const fontStandard = new FontBitmap("5x5");
37
+ * const fontPrebuild = new FontBitmapPrebuild("5x5");
38
+ * fontPrebuild.prebuildGlyphs("ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""));
39
+ *
40
+ * // In the render loop, measure time taken to render a string multiple times
41
+ * console.time("Standard Bitmap");
42
+ * for (let i = 0; i < 1000; i++) {
43
+ * fontStandard.renderText("HELLO WORLD", 10, 10, ctx);
44
+ * }
45
+ * console.timeEnd("Standard Bitmap");
46
+ *
47
+ * console.time("Prebuilt Bitmap");
48
+ * for (let i = 0; i < 1000; i++) {
49
+ * fontPrebuild.renderText("HELLO WORLD", 10, 10, ctx);
50
+ * }
51
+ * console.timeEnd("Prebuilt Bitmap");
52
+ * ```
53
+ *
54
+ * @remarks
55
+ *
56
+ * Pre-building glyphs can significantly improve rendering performance when
57
+ * the same characters are rendered multiple times, as it avoids the overhead
58
+ * of constructing `Path2D` objects on each render. However, it does increase
59
+ * memory usage, especially if a large number of unique characters are pre-built.
60
+ * Use this class when you have a known set of characters that will be rendered
61
+ * frequently, such as in a game UI or static text elements.
62
+ *
63
+ * @see FontBitmap for a more memory-efficient alternative that builds paths on demand.
64
+ *
65
+ */
66
+ export default class FontBitmapPrebuild extends FontBitmap {
67
+ /**
68
+ * Map of pre-built `Path2D` objects for each character. Keys are characters,
69
+ * values are their corresponding paths.
70
+ * This cache is used to store pre-built paths for characters that have been
71
+ * rendered at least once, allowing for faster rendering on subsequent calls.
72
+ */
73
+ glyphPaths = new Map();
74
+ /**
75
+ * Builds a `Path2D` object for the specified character based on its bitmap data.
76
+ * This method reads the character's bitmap data and constructs a path that
77
+ * represents the filled pixels of the character.
78
+ *
79
+ * @param char The character to build a path for.
80
+ *
81
+ * @returns A `Path2D` object representing the character's shape, or `null` if the character is not found in the font data.
82
+ *
83
+ * @remarks
84
+ * This method is called internally when a character is rendered for the first time
85
+ * or when pre-building glyphs. It converts the bitmap representation of the character
86
+ * into a vector path that can be efficiently rendered using `CanvasRenderingContext2D`.
87
+ * The resulting `Path2D` object is cached in the `glyphPaths` map for future use, reducing the overhead of path construction on subsequent renders.
88
+ */
89
+ buildGlyphPath(char) {
90
+ const charData = this.getChar(char);
91
+ if (!charData)
92
+ return null;
93
+ const path = new Path2D();
94
+ const w = this.width - this.spacing;
95
+ for (let row = 0; row < charData.length; row++) {
96
+ const bits = charData[row];
97
+ for (let col = 0; col < w; col++) {
98
+ if ((bits & (1 << (w - 1 - col))) !== 0) {
99
+ path.rect(col, row, 1, 1);
100
+ }
101
+ }
102
+ }
103
+ return path;
104
+ }
105
+ /**
106
+ * Pre-builds `Path2D` objects for a set of characters, storing them in the `glyphPaths`
107
+ * cache. This method can be called with a list of characters that are expected to
108
+ * be rendered frequently,
109
+ */
110
+ prebuildGlyphs(chars = []) {
111
+ for (const char of chars) {
112
+ if (!this.glyphPaths.has(char)) {
113
+ const built = this.buildGlyphPath(char);
114
+ if (built) {
115
+ this.glyphPaths.set(char, built);
116
+ }
117
+ }
118
+ }
119
+ }
120
+ /**
121
+ * Renders a single character at the given pixel position using a pre-built `Path2D` object.
122
+ * If the character's path has not been pre-built, it will be built on demand and cached for future use.
123
+ */
124
+ renderChar(char, x, y, ctx) {
125
+ let path = this.glyphPaths.get(char);
126
+ if (path === undefined) {
127
+ const built = this.buildGlyphPath(char);
128
+ if (!built)
129
+ return;
130
+ path = built;
131
+ this.glyphPaths.set(char, path);
132
+ }
133
+ ctx.translate(x, y);
134
+ ctx.fill(path);
135
+ ctx.translate(-x, -y);
136
+ }
137
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Built-in 3x5 pixel bitmap font.
3
+ *
4
+ * Each character is a 3-pixel-wide, 5-pixel-tall glyph stored as an
5
+ * array of 5 integers. Each integer is a bitmask where bit 2
6
+ * (MSB) corresponds to the leftmost pixel and bit 0 to the rightmost.
7
+ *
8
+ * Ultra-compact, great for HUDs and tiny labels.
9
+ *
10
+ * Supported characters: uppercase A–Z, lowercase a–z, digits 0–9,
11
+ * and common punctuation / special characters.
12
+ *
13
+ * @category Fonts
14
+ * @since 0.2.0
15
+ * @internal
16
+ *
17
+ * @example Reading a glyph
18
+ * ```ts
19
+ * import FONT_3x5 from "./font_3x5";
20
+ *
21
+ * const letterA = FONT_3x5["A"];
22
+ * // 2, 5, 7, 5, 5
23
+ * ```
24
+ */
25
+ /** Catalogue name used by {@link FontBitmap} to look up this font. */
26
+ export const FONT_3x5_NAME = "3x5";
27
+ /**
28
+ * Glyph width in pixels (excluding spacing).
29
+ * @defaultValue `3`
30
+ */
31
+ export const FONT_3x5_WIDTH = 3;
32
+ /**
33
+ * Glyph height in pixels.
34
+ * @defaultValue `5`
35
+ */
36
+ export const FONT_3x5_HEIGHT = 5;
37
+ /**
38
+ * Horizontal spacing between glyphs in pixels.
39
+ * @defaultValue `1`
40
+ */
41
+ export const FONT_3x5_SPACING = 1;
42
+ /**
43
+ * Complete set of supported characters as a single string.
44
+ */
45
+ export const FONT_3x5_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz !?.,:;-+*/\\()[]<>=#%&@^_'\"`~|$";
46
+ /**
47
+ * Glyph data keyed by character.
48
+ *
49
+ * Each value is a 5-element `number[]` where each entry is a 3-bit
50
+ * row bitmask (bit 2 = leftmost pixel, bit 0 = rightmost pixel).
51
+ *
52
+ * @see {@link FontBitmap} — consumes this data for rendering
53
+ */
54
+ export const FONT_3x5 = {
55
+ "0": [2, 5, 5, 5, 2],
56
+ "1": [2, 6, 2, 2, 7],
57
+ "2": [6, 1, 2, 4, 7],
58
+ "3": [6, 1, 2, 1, 6],
59
+ "4": [5, 5, 7, 1, 1],
60
+ "5": [7, 4, 6, 1, 6],
61
+ "6": [3, 4, 6, 5, 2],
62
+ "7": [7, 1, 2, 2, 2],
63
+ "8": [2, 5, 2, 5, 2],
64
+ "9": [2, 5, 3, 1, 6],
65
+ A: [2, 5, 7, 5, 5],
66
+ B: [6, 5, 6, 5, 6],
67
+ C: [3, 4, 4, 4, 3],
68
+ D: [6, 5, 5, 5, 6],
69
+ E: [7, 4, 6, 4, 7],
70
+ F: [7, 4, 6, 4, 4],
71
+ G: [3, 4, 5, 5, 3],
72
+ H: [5, 5, 7, 5, 5],
73
+ I: [7, 2, 2, 2, 7],
74
+ J: [7, 1, 1, 5, 2],
75
+ K: [5, 5, 6, 5, 5],
76
+ L: [4, 4, 4, 4, 7],
77
+ M: [5, 7, 7, 5, 5],
78
+ N: [5, 7, 7, 5, 5],
79
+ O: [2, 5, 5, 5, 2],
80
+ P: [6, 5, 6, 4, 4],
81
+ Q: [2, 5, 5, 3, 1],
82
+ R: [6, 5, 6, 5, 5],
83
+ S: [3, 4, 2, 1, 6],
84
+ T: [7, 2, 2, 2, 2],
85
+ U: [5, 5, 5, 5, 7],
86
+ V: [5, 5, 5, 5, 2],
87
+ W: [5, 5, 5, 7, 5],
88
+ X: [5, 5, 2, 5, 5],
89
+ Y: [5, 5, 2, 2, 2],
90
+ Z: [7, 1, 2, 4, 7],
91
+ a: [0, 3, 5, 7, 5],
92
+ b: [4, 6, 5, 5, 6],
93
+ c: [0, 3, 4, 4, 3],
94
+ d: [1, 3, 5, 5, 3],
95
+ e: [0, 2, 5, 6, 3],
96
+ f: [3, 4, 6, 4, 4],
97
+ g: [0, 3, 5, 3, 6],
98
+ h: [4, 6, 5, 5, 5],
99
+ i: [0, 2, 0, 2, 3],
100
+ j: [0, 1, 0, 1, 6],
101
+ k: [4, 5, 6, 5, 5],
102
+ l: [2, 2, 2, 2, 3],
103
+ m: [0, 7, 7, 5, 5],
104
+ n: [0, 6, 5, 5, 5],
105
+ o: [0, 2, 5, 5, 2],
106
+ p: [0, 6, 5, 6, 4],
107
+ q: [0, 3, 5, 3, 1],
108
+ r: [0, 3, 4, 4, 4],
109
+ s: [0, 3, 2, 1, 6],
110
+ t: [2, 7, 2, 2, 3],
111
+ u: [0, 5, 5, 5, 3],
112
+ v: [0, 5, 5, 5, 2],
113
+ w: [0, 5, 5, 7, 5],
114
+ x: [0, 5, 2, 2, 5],
115
+ y: [0, 5, 3, 1, 6],
116
+ z: [0, 7, 2, 4, 7],
117
+ " ": [0, 0, 0, 0, 0],
118
+ "!": [2, 2, 2, 0, 2],
119
+ "?": [6, 1, 2, 0, 2],
120
+ ".": [0, 0, 0, 0, 2],
121
+ ",": [0, 0, 0, 2, 4],
122
+ ":": [0, 2, 0, 2, 0],
123
+ ";": [0, 2, 0, 2, 4],
124
+ "-": [0, 0, 7, 0, 0],
125
+ "+": [0, 2, 7, 2, 0],
126
+ "*": [0, 5, 2, 5, 0],
127
+ "/": [1, 1, 2, 4, 4],
128
+ "\\": [4, 4, 2, 1, 1],
129
+ "(": [1, 2, 2, 2, 1],
130
+ ")": [4, 2, 2, 2, 4],
131
+ "[": [3, 2, 2, 2, 3],
132
+ "]": [6, 2, 2, 2, 6],
133
+ "<": [1, 2, 4, 2, 1],
134
+ ">": [4, 2, 1, 2, 4],
135
+ "=": [0, 7, 0, 7, 0],
136
+ "#": [5, 7, 5, 7, 5],
137
+ "%": [5, 1, 2, 4, 5],
138
+ "&": [2, 5, 2, 5, 3],
139
+ "@": [2, 5, 7, 4, 3],
140
+ "^": [2, 5, 0, 0, 0],
141
+ _: [0, 0, 0, 0, 7],
142
+ "'": [2, 2, 0, 0, 0],
143
+ '"': [5, 5, 0, 0, 0],
144
+ "`": [4, 2, 0, 0, 0],
145
+ "~": [0, 2, 5, 4, 0],
146
+ "|": [2, 2, 2, 2, 2],
147
+ $: [2, 3, 6, 3, 2],
148
+ };
149
+ /**
150
+ * Complete metadata object for the 3x5 font, used by the
151
+ * {@link FontBitmap} catalogue at module load time.
152
+ *
153
+ * @internal
154
+ */
155
+ export const metadata = {
156
+ /** Catalogue name. */
157
+ name: FONT_3x5_NAME,
158
+ /** Cell width including spacing (3 + 1 = 4). */
159
+ width: FONT_3x5_WIDTH + FONT_3x5_SPACING,
160
+ /** Cell height (5). */
161
+ height: FONT_3x5_HEIGHT,
162
+ /** Inter-glyph spacing (1). */
163
+ spacing: FONT_3x5_SPACING,
164
+ /** Supported character string. */
165
+ chars: FONT_3x5_CHARS,
166
+ /** Glyph bitmask data. */
167
+ data: FONT_3x5,
168
+ };
169
+ export default FONT_3x5;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Built-in 4x6 pixel bitmap font.
3
+ *
4
+ * Each character is a 4-pixel-wide, 6-pixel-tall glyph stored as an
5
+ * array of 6 integers. Each integer is a bitmask where bit 3
6
+ * (MSB) corresponds to the leftmost pixel and bit 0 to the rightmost.
7
+ *
8
+ * Small but readable, good for status bars.
9
+ *
10
+ * Supported characters: uppercase A–Z, lowercase a–z, digits 0–9,
11
+ * and common punctuation / special characters.
12
+ *
13
+ * @category Fonts
14
+ * @since 0.2.0
15
+ * @internal
16
+ *
17
+ * @example Reading a glyph
18
+ * ```ts
19
+ * import FONT_4x6 from "./font_4x6";
20
+ *
21
+ * const letterA = FONT_4x6["A"];
22
+ * // 6, 9, 9, 15, 9, 9
23
+ * ```
24
+ */
25
+ /** Catalogue name used by {@link FontBitmap} to look up this font. */
26
+ export const FONT_4x6_NAME = "4x6";
27
+ /**
28
+ * Glyph width in pixels (excluding spacing).
29
+ * @defaultValue `4`
30
+ */
31
+ export const FONT_4x6_WIDTH = 4;
32
+ /**
33
+ * Glyph height in pixels.
34
+ * @defaultValue `6`
35
+ */
36
+ export const FONT_4x6_HEIGHT = 6;
37
+ /**
38
+ * Horizontal spacing between glyphs in pixels.
39
+ * @defaultValue `1`
40
+ */
41
+ export const FONT_4x6_SPACING = 1;
42
+ /**
43
+ * Complete set of supported characters as a single string.
44
+ */
45
+ export const FONT_4x6_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz !?.,:;-+*/\\()[]{}<>=#%&@^_'\"`~|$";
46
+ /**
47
+ * Glyph data keyed by character.
48
+ *
49
+ * Each value is a 6-element `number[]` where each entry is a 4-bit
50
+ * row bitmask (bit 3 = leftmost pixel, bit 0 = rightmost pixel).
51
+ *
52
+ * @see {@link FontBitmap} — consumes this data for rendering
53
+ */
54
+ export const FONT_4x6 = {
55
+ "0": [6, 9, 11, 13, 9, 6],
56
+ "1": [2, 6, 2, 2, 2, 7],
57
+ "2": [6, 9, 1, 6, 8, 15],
58
+ "3": [14, 1, 6, 1, 1, 14],
59
+ "4": [3, 5, 9, 15, 1, 1],
60
+ "5": [15, 8, 14, 1, 1, 14],
61
+ "6": [3, 4, 14, 9, 9, 6],
62
+ "7": [15, 1, 2, 4, 4, 4],
63
+ "8": [6, 9, 6, 9, 9, 6],
64
+ "9": [6, 9, 9, 7, 1, 12],
65
+ A: [6, 9, 9, 15, 9, 9],
66
+ B: [14, 9, 14, 9, 9, 14],
67
+ C: [7, 8, 8, 8, 8, 7],
68
+ D: [14, 9, 9, 9, 9, 14],
69
+ E: [15, 8, 14, 8, 8, 15],
70
+ F: [15, 8, 14, 8, 8, 8],
71
+ G: [7, 8, 8, 11, 9, 7],
72
+ H: [9, 9, 15, 9, 9, 9],
73
+ I: [14, 4, 4, 4, 4, 14],
74
+ J: [7, 1, 1, 1, 9, 6],
75
+ K: [9, 10, 12, 10, 9, 9],
76
+ L: [8, 8, 8, 8, 8, 15],
77
+ M: [9, 15, 15, 9, 9, 9],
78
+ N: [9, 13, 11, 9, 9, 9],
79
+ O: [6, 9, 9, 9, 9, 6],
80
+ P: [14, 9, 9, 14, 8, 8],
81
+ Q: [6, 9, 9, 9, 6, 3],
82
+ R: [14, 9, 9, 14, 9, 9],
83
+ S: [7, 8, 6, 1, 1, 14],
84
+ T: [15, 4, 4, 4, 4, 4],
85
+ U: [9, 9, 9, 9, 9, 6],
86
+ V: [9, 9, 9, 9, 6, 6],
87
+ W: [9, 9, 9, 15, 15, 9],
88
+ X: [9, 9, 6, 6, 9, 9],
89
+ Y: [9, 9, 6, 4, 4, 4],
90
+ Z: [15, 1, 2, 4, 8, 15],
91
+ a: [0, 6, 1, 7, 9, 7],
92
+ b: [8, 8, 14, 9, 9, 14],
93
+ c: [0, 7, 8, 8, 8, 7],
94
+ d: [1, 1, 7, 9, 9, 7],
95
+ e: [0, 6, 9, 15, 8, 7],
96
+ f: [3, 4, 14, 4, 4, 4],
97
+ g: [0, 7, 9, 7, 1, 14],
98
+ h: [8, 8, 14, 9, 9, 9],
99
+ i: [0, 4, 0, 4, 4, 6],
100
+ j: [0, 2, 0, 2, 2, 12],
101
+ k: [8, 9, 10, 12, 10, 9],
102
+ l: [4, 4, 4, 4, 4, 3],
103
+ m: [0, 0, 14, 15, 9, 9],
104
+ n: [0, 0, 14, 9, 9, 9],
105
+ o: [0, 0, 6, 9, 9, 6],
106
+ p: [0, 0, 14, 9, 14, 8],
107
+ q: [0, 0, 7, 9, 7, 1],
108
+ r: [0, 0, 7, 8, 8, 8],
109
+ s: [0, 0, 7, 12, 3, 14],
110
+ t: [4, 4, 14, 4, 4, 3],
111
+ u: [0, 0, 9, 9, 9, 7],
112
+ v: [0, 0, 9, 9, 6, 6],
113
+ w: [0, 0, 9, 9, 15, 9],
114
+ x: [0, 0, 9, 6, 6, 9],
115
+ y: [0, 0, 9, 7, 1, 14],
116
+ z: [0, 0, 15, 2, 4, 15],
117
+ " ": [0, 0, 0, 0, 0, 0],
118
+ "!": [2, 2, 2, 2, 0, 2],
119
+ "?": [6, 9, 1, 2, 0, 2],
120
+ ".": [0, 0, 0, 0, 0, 4],
121
+ ",": [0, 0, 0, 0, 4, 8],
122
+ ":": [0, 4, 0, 4, 0, 0],
123
+ ";": [0, 4, 0, 4, 4, 8],
124
+ "-": [0, 0, 15, 0, 0, 0],
125
+ "+": [0, 4, 14, 4, 0, 0],
126
+ "*": [0, 9, 6, 6, 9, 0],
127
+ "/": [1, 1, 2, 4, 8, 8],
128
+ "\\": [8, 8, 4, 2, 1, 1],
129
+ "(": [2, 4, 4, 4, 4, 2],
130
+ ")": [4, 2, 2, 2, 2, 4],
131
+ "[": [6, 4, 4, 4, 4, 6],
132
+ "]": [6, 2, 2, 2, 2, 6],
133
+ "{": [3, 4, 12, 4, 4, 3],
134
+ "}": [12, 2, 3, 2, 2, 12],
135
+ "<": [1, 2, 4, 4, 2, 1],
136
+ ">": [8, 4, 2, 2, 4, 8],
137
+ "=": [0, 15, 0, 15, 0, 0],
138
+ "#": [5, 15, 5, 15, 5, 0],
139
+ "%": [9, 1, 2, 4, 8, 9],
140
+ "&": [4, 10, 4, 10, 9, 7],
141
+ "@": [6, 9, 11, 11, 8, 6],
142
+ "^": [4, 10, 0, 0, 0, 0],
143
+ _: [0, 0, 0, 0, 0, 15],
144
+ "'": [6, 4, 0, 0, 0, 0],
145
+ '"': [10, 10, 0, 0, 0, 0],
146
+ "`": [8, 4, 0, 0, 0, 0],
147
+ "~": [0, 6, 9, 9, 0, 0],
148
+ "|": [4, 4, 4, 4, 4, 4],
149
+ $: [4, 7, 12, 7, 1, 14],
150
+ };
151
+ /**
152
+ * Complete metadata object for the 4x6 font, used by the
153
+ * {@link FontBitmap} catalogue at module load time.
154
+ *
155
+ * @internal
156
+ */
157
+ export const metadata = {
158
+ /** Catalogue name. */
159
+ name: FONT_4x6_NAME,
160
+ /** Cell width including spacing (4 + 1 = 5). */
161
+ width: FONT_4x6_WIDTH + FONT_4x6_SPACING,
162
+ /** Cell height (6). */
163
+ height: FONT_4x6_HEIGHT,
164
+ /** Inter-glyph spacing (1). */
165
+ spacing: FONT_4x6_SPACING,
166
+ /** Supported character string. */
167
+ chars: FONT_4x6_CHARS,
168
+ /** Glyph bitmask data. */
169
+ data: FONT_4x6,
170
+ };
171
+ export default FONT_4x6;