@@ -2,7 +2,15 @@ import parseASCII from "parse-bmfont-ascii";
22import parseXML from "parse-bmfont-xml" ;
33import readBinary from "parse-bmfont-binary" ;
44import { BmCharacter , BmKerning , BmFont , BmCommonProps } from "./types.js" ;
5+ import png from "@jimp/js-png" ;
6+ import { createJimp } from "@jimp/core" ;
7+ import path from "path" ;
8+ import { convertXML } from "simple-xml-to-json" ;
59
10+ export const isWebWorker =
11+ typeof self !== "undefined" && self . document === undefined ;
12+
13+ const CharacterJimp = createJimp ( { formats : [ png ] } ) ;
614const HEADER = Buffer . from ( [ 66 , 77 , 70 , 3 ] ) ;
715
816function isBinary ( buf : Buffer | string ) {
@@ -20,17 +28,16 @@ function isBinary(buf: Buffer | string) {
2028 ) ;
2129}
2230
23- function parseFont (
24- file : string ,
25- data : Buffer | string ,
26- ) : {
31+ export interface LoadedFont {
2732 chars : BmCharacter [ ] ;
2833 kernings : BmKerning [ ] ;
2934 common : BmCommonProps ;
3035 // eslint-disable-next-line @typescript-eslint/no-explicit-any
3136 info : Record < string , any > ;
3237 pages : string [ ] ;
33- } {
38+ }
39+
40+ function parseFont ( file : string , data : Buffer | string ) : LoadedFont {
3441 if ( isBinary ( data ) ) {
3542 if ( typeof data === "string" ) {
3643 data = Buffer . from ( data , "binary" ) ;
@@ -52,13 +59,68 @@ function parseFont(
5259 return parseASCII ( data ) ;
5360}
5461
62+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63+ function parseNumbersInObject < T extends Record < string , any > > ( obj : T ) {
64+ for ( const key in obj ) {
65+ try {
66+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67+ ( obj as any ) [ key ] = parseInt ( obj [ key ] , 10 ) ;
68+ } catch {
69+ // do nothing
70+ }
71+
72+ if ( typeof obj [ key ] === "object" ) {
73+ parseNumbersInObject ( obj [ key ] ) ;
74+ }
75+ }
76+
77+ return obj ;
78+ }
79+
5580/**
5681 *
5782 * @param bufferOrUrl A URL to a file or a buffer
5883 * @returns
5984 */
60- async function loadBitmapFontData ( bufferOrUrl : string | Buffer ) {
61- if ( typeof bufferOrUrl === "string" ) {
85+ export async function loadBitmapFontData (
86+ bufferOrUrl : string | Buffer
87+ ) : Promise < LoadedFont > {
88+ if ( isWebWorker && typeof bufferOrUrl === "string" ) {
89+ const res = await fetch ( bufferOrUrl ) ;
90+ const text = await res . text ( ) ;
91+ const json = convertXML ( text ) ;
92+
93+ const font = json . font . children . reduce (
94+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95+ ( acc : Record < string , any > , i : any ) => ( { ...acc , ...i } ) ,
96+ { }
97+ ) ;
98+ const pages : LoadedFont [ "pages" ] = [ ] ;
99+ const chars : LoadedFont [ "chars" ] = [ ] ;
100+ const kernings : LoadedFont [ "kernings" ] = [ ] ;
101+
102+ for ( let i = 0 ; i < font . pages . children . length ; i ++ ) {
103+ const p = font . pages . children [ i ] . page ;
104+ const id = parseInt ( p . id , 10 ) ;
105+ pages [ id ] = parseNumbersInObject ( p . file ) ;
106+ }
107+
108+ for ( let i = 0 ; i < font . chars . children . length ; i ++ ) {
109+ chars . push ( parseNumbersInObject ( font . chars . children [ i ] . char ) ) ;
110+ }
111+
112+ for ( let i = 0 ; i < font . kernings . children . length ; i ++ ) {
113+ kernings . push ( parseNumbersInObject ( font . kernings . children [ i ] . kerning ) ) ;
114+ }
115+
116+ return {
117+ info : font . info ,
118+ common : font . common ,
119+ pages,
120+ chars,
121+ kernings,
122+ } satisfies LoadedFont ;
123+ } else if ( typeof bufferOrUrl === "string" ) {
62124 const res = await fetch ( bufferOrUrl ) ;
63125 const text = await res . text ( ) ;
64126
@@ -69,11 +131,9 @@ async function loadBitmapFontData(bufferOrUrl: string | Buffer) {
69131}
70132
71133type RawFont = Awaited < ReturnType < typeof loadBitmapFontData > > ;
134+ export type ResolveBmFont = Omit < BmFont , "pages" > & Pick < RawFont , "pages" > ;
72135
73- export async function loadBitmapFont (
74- bufferOrUrl : string | Buffer ,
75- ) : Promise < Omit < BmFont , "pages" > & Pick < RawFont , "pages" > > {
76- const font = await loadBitmapFontData ( bufferOrUrl ) ;
136+ export async function processBitmapFont ( file : string , font : LoadedFont ) {
77137 const chars : Record < string , BmCharacter > = { } ;
78138 const kernings : Record < string , BmKerning > = { } ;
79139
@@ -94,5 +154,10 @@ export async function loadBitmapFont(
94154 ...font ,
95155 chars,
96156 kernings,
157+ pages : await Promise . all (
158+ font . pages . map ( async ( page ) =>
159+ CharacterJimp . read ( path . join ( path . dirname ( file ) , page ) )
160+ )
161+ ) ,
97162 } ;
98163}
0 commit comments