@@ -186,14 +186,16 @@ FontGlyph.prototype.appendBits = function(bits, info) {
186
186
} ;
187
187
188
188
FontGlyph . prototype . debug = function ( ) {
189
- var map = ".#" ; //" ░█";
189
+ var map = "░█" ;
190
190
if ( this . font . bpp == 2 ) map = "░▒▓█" ;
191
191
var debugText = [ ] ;
192
- for ( var y = 0 ; y < this . font . fmHeight ; y ++ ) debugText . push ( "" ) ;
193
- for ( var x = this . xStart ; x <= this . xEnd ; x ++ ) {
194
- for ( var y = 0 ; y < this . font . fmHeight ; y ++ ) {
195
- var col = this . getPixel ( x , y ) ;
196
- debugText [ y ] += ( y >= this . yStart && y <= this . yEnd ) ? map [ col ] : "." ;
192
+ for ( var y = 0 ; y < this . font . fmHeight ; y ++ ) {
193
+ debugText [ y ] = "" ;
194
+ for ( var x = 0 ; x < this . advance ; x ++ ) {
195
+ var px = "." ;
196
+ if ( x >= this . xStart && x <= this . xEnd && y >= this . yStart && y <= this . yEnd )
197
+ px = map [ this . getPixel ( x , y ) ] ;
198
+ debugText [ y ] += px ;
197
199
}
198
200
}
199
201
console . log ( "charcode " , this . ch ) ;
@@ -229,13 +231,14 @@ FontGlyph.prototype.appendBits = function(bits, info) {
229
231
if ( ch != 32 ) return undefined ; // if it's empty and not a space, ignore it!
230
232
xStart = 0 ;
231
233
xEnd = this . fmWidth >> 1 ; // treat spaces as half-width
232
- } else if ( xEnd < this . fmWidth - 1 )
233
- xEnd += this . glyphPadX ; // if not full width, add a space after
234
+ }
234
235
}
235
236
glyph . width = xEnd + 1 - xStart ;
236
237
glyph . xStart = xStart ;
237
238
glyph . xEnd = xEnd ;
238
239
glyph . advance = glyph . width ;
240
+ if ( xEnd < this . fmWidth - 1 )
241
+ glyph . advance += this . glyphPadX ; // if not full width, add a space after
239
242
if ( ! this . glyphPadX ) glyph . advance ++ ; // hack - add once space of padding
240
243
241
244
if ( this . fullHeight ) {
@@ -351,17 +354,14 @@ function loadBDF(fontInfo) {
351
354
var fontCharCode = 0 ;
352
355
var fontBitmap = undefined ;
353
356
var fontBoundingBox = [ 0 , 0 , 0 , 0 ] ;
354
- var fontChars = [ ] ;
357
+ var charBoundingBox = [ 0 , 0 , 0 , 0 ] ;
358
+ var charAdvance = 0 ;
355
359
var COMMENTS = "" , FONTNAME = "" ;
356
360
var glyphs = [ ] ;
361
+ // https://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format
357
362
358
363
require ( "fs" ) . readFileSync ( fontInfo . fn ) . toString ( ) . split ( "\n" ) . forEach ( ( line , lineNo ) => {
359
- //console.log(lineNo);
360
- if ( line . startsWith ( "ENCODING" ) ) {
361
- fontCharCode = parseInt ( line . substr ( "ENCODING" . length ) . trim ( ) ) ;
362
- //console.log("CODE "+fontCharCode);
363
- fontBoundingBox = [ 0 , 0 , 0 , 0 ] ;
364
- }
364
+ // Font stuff
365
365
if ( line . startsWith ( "CHARSET_REGISTRY" ) )
366
366
fontCharSet = JSON . parse ( line . split ( " " ) [ 1 ] . trim ( ) ) ;
367
367
if ( line . startsWith ( "COPYRIGHT" ) )
@@ -371,29 +371,53 @@ function loadBDF(fontInfo) {
371
371
if ( line . startsWith ( "FONT" ) )
372
372
FONTNAME += "// " + line . substr ( 4 ) . trim ( ) ;
373
373
if ( line . startsWith ( "FONTBOUNDINGBOX" ) ) {
374
- let box = line . split ( / \s + / ) ;
375
- fontInfo . fmWidth = parseInt ( box [ 1 ] ) ;
376
- fontInfo . height = fontInfo . fmHeight = parseInt ( box [ 2 ] ) ;
374
+ fontBoundingBox = line . split ( " " ) . slice ( 1 ) . map ( x => parseInt ( x ) ) ;
375
+ fontInfo . fmWidth = fontBoundingBox [ 0 ] ;
376
+ fontInfo . height = fontInfo . fmHeight = fontBoundingBox [ 1 ] - fontBoundingBox [ 3 ] ;
377
+ }
378
+ // Character stuff
379
+ if ( line . startsWith ( "STARTCHAR" ) ) {
380
+ fontCharCode = undefined ;
381
+ charBoundingBox = [ 0 , 0 , 0 , 0 ] ;
382
+ charAdvance = 0 ;
383
+ fontBitmap = undefined ;
384
+ }
385
+ if ( line . startsWith ( "ENCODING" ) ) {
386
+ fontCharCode = parseInt ( line . substr ( "ENCODING" . length ) . trim ( ) ) ;
387
+ }
388
+ if ( line . startsWith ( "BBX " ) ) { // per character bounding box
389
+ charBoundingBox = line . split ( " " ) . slice ( 1 ) . map ( x => parseInt ( x ) ) ;
390
+ }
391
+ if ( line . startsWith ( "DWIDTH " ) ) { // per character bounding box
392
+ charAdvance = parseInt ( line . split ( " " ) [ 1 ] ) ;
377
393
}
378
394
if ( line == "ENDCHAR" && fontBitmap ) {
379
- var fontChar = String . fromCharCode ( fontCharCode ) ;
380
395
if ( fontBitmap && fontInfo . isChInRange ( fontCharCode ) ) {
396
+ // first we need to pad this out
397
+ var blankLine = " " . repeat ( fontInfo . fmWidth ) ;
398
+ var linesBefore = fontBoundingBox [ 1 ] - ( charBoundingBox [ 3 ] + charBoundingBox [ 1 ] ) ;
399
+ for ( var i = 0 ; i < linesBefore ; i ++ )
400
+ fontBitmap . unshift ( blankLine ) ;
401
+ while ( fontBitmap . length < fontInfo . fmHeight )
402
+ fontBitmap . push ( blankLine ) ;
403
+
381
404
let bmp = fontBitmap ; // separate copy for this getGlyph fn
382
405
let glyph = fontInfo . getGlyph ( fontCharCode , ( x , y ) => {
383
406
if ( y < 0 || y >= bmp . length ) return 0 ;
384
407
return bmp [ y ] [ x ] == "1" ? 1 : 0 ;
385
408
} ) ;
386
- if ( glyph )
387
- glyphs . push ( glyph ) ;
409
+ if ( glyph ) {
410
+ // glyph.advance = charAdvance; // overwrite calculated advance value with one from file
411
+ glyphs . push ( glyph ) ;
412
+ }
388
413
}
389
414
fontCharCode = - 1 ;
390
415
fontBitmap = undefined ;
391
416
}
392
- if ( line . startsWith ( "BBX " ) ) { // per character bounding box
393
- fontBoundingBox = line . split ( " " ) . slice ( 1 ) . map ( x => parseInt ( x ) ) ;
394
- }
395
417
if ( fontBitmap !== undefined ) {
396
418
var l = "" ;
419
+ for ( var i = 0 ; i < charBoundingBox [ 2 ] ; i ++ )
420
+ l += " " ; // padding
397
421
for ( var i = 0 ; i < line . length ; i ++ ) {
398
422
var c = parseInt ( line [ i ] , 16 ) ;
399
423
l += ( ( c + 16 ) . toString ( 2 ) ) . substr ( - 4 ) . replace ( / 0 / g, " " ) ;
@@ -424,8 +448,7 @@ function load(fontInfo) {
424
448
Font . prototype . debugPixelsUsed = function ( ) {
425
449
var pixelsUsedInRow = new Array ( this . height ) ;
426
450
pixelsUsedInRow . fill ( 0 ) ;
427
- Object . keys ( this . glyphs ) . forEach ( ch => {
428
- var glyph = this . glyphs [ ch ] ;
451
+ this . glyphs . forEach ( glyph => {
429
452
for ( var x = glyph . xStart ; x <= glyph . xEnd ; x ++ ) {
430
453
for ( var y = 0 ; y < this . height ; y ++ ) {
431
454
var col = glyph . getPixel ( x , y ) ;
@@ -437,8 +460,8 @@ Font.prototype.debugPixelsUsed = function() {
437
460
} ;
438
461
439
462
Font . prototype . debugChars = function ( ) {
440
- Object . keys ( this . glyphs ) . forEach ( ch => {
441
- this . glyphs [ ch ] . debug ( ) ;
463
+ this . glyphs . forEach ( glyph => {
464
+ glyph . debug ( ) ;
442
465
console . log ( ) ;
443
466
} ) ;
444
467
} ;
@@ -447,8 +470,7 @@ Font.prototype.debugChars = function() {
447
470
big filled blocks with the 4 digit char code. This detects these
448
471
and removes them */
449
472
Font . prototype . removeUnifontPlaceholders = function ( ) {
450
- Object . keys ( this . glyphs ) . forEach ( ch => {
451
- let glyph = this . glyphs [ ch ] ;
473
+ this . glyphs . forEach ( glyph => {
452
474
if ( glyph . xStart == 1 && glyph . yStart == 1 && glyph . xEnd == 15 && glyph . yEnd == 14 ) {
453
475
let borderEmpty = true ;
454
476
let edgesFilled = true ;
@@ -473,7 +495,7 @@ Font.prototype.removeUnifontPlaceholders = function() {
473
495
if ( borderEmpty && edgesFilled ) {
474
496
// it's a placeholder!
475
497
// glyph.debug();
476
- delete this . glyphs [ ch ] ; // remove it
498
+ delete this . glyphs [ glyph . ch ] ; // remove it
477
499
}
478
500
}
479
501
} ) ;
@@ -484,35 +506,34 @@ Font.prototype.getJS = function(options) {
484
506
// options.compressed
485
507
options = options || { } ;
486
508
this . glyphPadX = 1 ;
487
- var charCodes = this . glyphs . map ( g => g . ch ) . sort ( ( a , b ) => a - b ) ;
509
+ var charCodes = this . glyphs . map ( g => g . ch ) . filter ( c => c !== undefined ) . sort ( ( a , b ) => a - b ) ;
488
510
var charMin = charCodes [ 0 ] ;
511
+ var charMax = charCodes [ charCodes . length - 1 ] ;
512
+ console . log ( `Outputting char range ${ charMin } ..${ charMax } ` ) ;
489
513
// stats
490
514
var minY = this . height ;
491
515
var maxY = 0 ;
492
516
// get an array of bits
493
517
var bits = [ ] ;
494
518
var charGlyphs = [ ] ;
495
- Object . keys ( this . glyphs ) . forEach ( ch => {
496
- var glyph = this . glyphs [ ch ] ;
519
+ var fontWidths = new Array ( charMax + 1 ) ;
520
+ fontWidths . fill ( 0 ) ;
521
+ this . glyphs . forEach ( glyph => {
497
522
if ( glyph . yEnd > maxY ) maxY = glyph . yEnd ;
498
523
if ( glyph . yStart < minY ) minY = glyph . yStart ;
499
- } ) ;
500
- Object . keys ( this . glyphs ) . forEach ( ch => {
501
- var glyph = this . glyphs [ ch ] ;
502
- glyph . xStart = 0 ; // all glyphs have to start at 0 now
524
+ // all glyphs have go 0...advance-1 now as we have no way to offset
525
+ glyph . xStart = 0 ;
503
526
glyph . yStart = 0 ;
504
- glyph . xEnd = glyph . width - 1 ;
527
+ glyph . xEnd = glyph . advance - 1 ;
505
528
glyph . yEnd = this . height - 1 ;
529
+ glyph . width = glyph . xEnd + 1 - glyph . xStart ;
506
530
glyph . height = this . height ;
507
531
glyph . appendBits ( bits , { glyphVertical :true } ) ;
532
+ // create width array - widthBytes
533
+ fontWidths [ glyph . ch ] = glyph . width ;
508
534
} ) ;
509
535
// compact array
510
536
var fontData = bitsToBytes ( bits , this . bpp ) ;
511
- // convert width array - widthBytes
512
- var fontWidths = [ ] ;
513
- Object . keys ( this . glyphs ) . forEach ( ch => {
514
- fontWidths [ ch ] = this . glyphs [ ch ] . width ;
515
- } ) ;
516
537
fontWidths = fontWidths . slice ( charMin ) ; // don't include chars before we're outputting
517
538
var fixedWidth = fontWidths . every ( w => w == fontWidths [ 0 ] ) ;
518
539
0 commit comments