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