1
+ const _ = require ( "underscore" ) ;
2
+ const Async = require ( "async" ) ;
3
+ const Fs = require ( "fs" ) ;
4
+ const Path = require ( "path" ) ;
5
+ const { DOMParser } = require ( "xmldom" ) ;
6
+
7
+ if ( module === require . main ) {
8
+ let fonstDir = Path . resolve ( __dirname , "../resources/assets/fonts" ) ;
9
+ xmlsToJsons ( fonstDir , err => { if ( err ) throw err } ) ;
10
+ }
11
+
12
+ // Gets a dir path containing font xmls and converts them all to jsons
13
+ function xmlsToJsons ( path , callback = _ . noop ) {
14
+ Fs . readdir ( path , ( err , files ) => {
15
+ if ( err ) return callback ( err ) ;
16
+
17
+ // Remove all extensions
18
+ fileNames = _ . uniq ( files . map ( file => file . split ( "." ) [ 0 ] ) ) ;
19
+
20
+ // Convert each xml individually
21
+ Async . each ( fileNames , ( fileName , next ) => {
22
+ xmlToJson ( `${ path } /${ fileName } ` , next ) ;
23
+ } ,
24
+ ( err ) => {
25
+ if ( ! err ) console . log (
26
+ 'All fonts have been successfully parsed!'
27
+ ) ;
28
+
29
+ callback ( err ) ;
30
+ } ) ;
31
+ } ) ;
32
+ }
33
+
34
+ // Gets a font xml and converts it to json
35
+ function xmlToJson ( path , callback = _ . noop ) {
36
+ Async . waterfall ( [
37
+ ( next ) => {
38
+ Fs . readFile ( `${ path } .xml` , function ( err , xmlBuffer ) {
39
+ if ( err ) return next ( err ) ;
40
+
41
+ let json = {
42
+ chars : { }
43
+ } ;
44
+
45
+ let xml = xmlBuffer . toString ( ) ;
46
+ let doc = new DOMParser ( ) . parseFromString ( xml ) ;
47
+ let fontDoc = doc . getElementsByTagName ( "Font" ) [ 0 ] ;
48
+ let charsDoc = fontDoc . getElementsByTagName ( "Char" ) ;
49
+
50
+ // Compose meta-data about font like size and family
51
+ _ . each ( fontDoc . attributes , ( attr ) => {
52
+ json [ attr . name ] = parseInt ( attr . value ) || attr . value ;
53
+ } ) ;
54
+
55
+ // Compose data about each character in font
56
+ _ . each ( charsDoc , ( charDoc ) => {
57
+ let charCode = charDoc . getAttribute ( "code" ) ;
58
+
59
+ let char = json . chars [ charCode ] = {
60
+ rect : rect = { } ,
61
+ offset : offset = { } ,
62
+ width : parseInt ( charDoc . getAttribute ( "width" ) )
63
+ } ;
64
+
65
+ [
66
+ rect . x ,
67
+ rect . y ,
68
+ rect . width ,
69
+ rect . height
70
+ ] = extractIntegers ( charDoc . getAttribute ( "rect" ) ) ;
71
+
72
+ [ offset . x , offset . y ] = extractIntegers ( charDoc . getAttribute ( "offset" ) ) ;
73
+ } ) ;
74
+
75
+ next ( null , JSON . stringify ( json , null , 2 ) ) ;
76
+ } ) ;
77
+ } ,
78
+ ( json , next ) => {
79
+ // Once finished, write json into file
80
+ Fs . writeFile ( path + ".json" , json , ( err ) => {
81
+ next ( err ) ;
82
+ } ) ;
83
+ }
84
+ ] , ( err ) => {
85
+ if ( ! err ) console . log (
86
+ `Font ${ path } has been successfully parsed...`
87
+ ) ;
88
+
89
+ callback ( err ) ;
90
+ } ) ;
91
+ } ;
92
+
93
+ // Converts an string of numbers to array of numbers
94
+ // e.g. extractIntegers("1 2 3") -> [1, 2, 3]
95
+ function extractIntegers ( srcstr ) {
96
+ return srcstr . split ( " " ) . map ( ( substr ) => parseInt ( substr ) ) ;
97
+ }
98
+
99
+ module . exports = {
100
+ xmlToJson,
101
+ xmlsToJsons
102
+ } ;
0 commit comments