@@ -8,6 +8,7 @@ import Font from './font.mjs';
8
8
import Glyph from './glyph.mjs' ;
9
9
import { CmapEncoding , GlyphNames , addGlyphNames } from './encoding.mjs' ;
10
10
import parse from './parse.mjs' ;
11
+ import { encode } from './types.mjs' ;
11
12
import BoundingBox from './bbox.mjs' ;
12
13
import Path from './path.mjs' ;
13
14
import cpal from './tables/cpal.mjs' ;
@@ -38,7 +39,6 @@ import meta from './tables/meta.mjs';
38
39
import gasp from './tables/gasp.mjs' ;
39
40
import svg from './tables/svg.mjs' ;
40
41
import { PaletteManager } from './palettes.mjs' ;
41
- import { woff_to_otf } from './woff-to-otf.mjs' ;
42
42
/**
43
43
* The opentype library.
44
44
* @namespace opentype
@@ -467,6 +467,87 @@ function loadSync() {
467
467
console . error ( 'DEPRECATED! migrate to: opentype.parse(require("fs").readFileSync(url), opt)' ) ;
468
468
}
469
469
470
+ /**
471
+ * Convert/Uncompress a buffer of a woff font to otf/ttf without parsing
472
+ * table contents.
473
+ * @param {ArrayBuffer }
474
+ * @return {ArrayBuffer }
475
+ */
476
+ function woff_to_otf ( buffer ) {
477
+ if ( buffer . constructor !== ArrayBuffer )
478
+ buffer = new Uint8Array ( buffer ) . buffer ;
479
+ const data = new DataView ( buffer , 0 )
480
+ , out = [ ]
481
+ , signature = parse . getTag ( data , 0 )
482
+ ;
483
+
484
+ if ( signature !== 'wOFF' )
485
+ throw new Error ( `TYPE ERROR signature must be wOFF but is: "${ signature } "` ) ;
486
+
487
+ const flavor = parse . getTag ( data , 4 )
488
+ , numTables = parse . getUShort ( data , 12 )
489
+ , tableEntries = parseWOFFTableEntries ( data , numTables )
490
+ , max = [ ]
491
+ ;
492
+ for ( let n = 0 ; n < 64 ; n ++ ) {
493
+ if ( Math . pow ( 2 , n ) > numTables )
494
+ break ;
495
+ max . splice ( 0 , Infinity , n , 2 ** n ) ;
496
+ }
497
+ const searchRange = max [ 1 ] * 16
498
+ , entrySelector = max [ 0 ]
499
+ , rangeShift = numTables * 16 - searchRange
500
+ ;
501
+
502
+ out . push (
503
+ ...encode . TAG ( flavor )
504
+ , ...encode . USHORT ( numTables )
505
+ , ...encode . USHORT ( searchRange )
506
+ , ...encode . USHORT ( entrySelector )
507
+ , ...encode . USHORT ( rangeShift )
508
+ ) ;
509
+ let offset = out . length + numTables * 16 ;
510
+
511
+ for ( let i = 0 ; i < numTables ; i ++ ) {
512
+ const tableEntry = tableEntries [ i ] ;
513
+ out . push (
514
+ ...encode . TAG ( tableEntry . tag )
515
+ , ...encode . ULONG ( tableEntry . checksum )
516
+ , ...encode . ULONG ( offset )
517
+ , ...encode . ULONG ( tableEntry . length )
518
+ ) ;
519
+ tableEntry . outOffset = offset ;
520
+ offset += tableEntry . length ;
521
+ if ( ( offset % 4 ) !== 0 )
522
+ offset += 4 - ( offset % 4 ) ;
523
+ }
524
+ const initialData = new Uint8Array ( out . length )
525
+ , buffers = [ initialData ]
526
+ ;
527
+ for ( let i = 0 , l = out . length ; i < l ; i ++ )
528
+ initialData [ i ] = out [ i ] ;
529
+
530
+ for ( let i = 0 ; i < numTables ; i ++ ) {
531
+ const tableEntry = tableEntries [ i ]
532
+ , table = uncompressTable ( data , tableEntry ) // => {data: view, offset: 0};
533
+ , offset = tableEntry . outOffset + tableEntry . length
534
+ , padding = ( offset % 4 ) !== 0
535
+ ? 4 - ( offset % 4 )
536
+ : 0
537
+ ;
538
+ buffers . push (
539
+ new Uint8Array ( table . data . buffer , table . offset , tableEntry . length )
540
+ , new Uint8Array ( padding )
541
+ ) ;
542
+ }
543
+ const result = new Uint8Array ( buffers . reduce ( ( accum , buffer ) => accum + buffer . byteLength , 0 ) ) ;
544
+ buffers . reduce ( ( offset , buffer ) => {
545
+ result . set ( buffer , offset ) ;
546
+ return offset + buffer . byteLength ;
547
+ } , 0 ) ;
548
+ return result . buffer ;
549
+ }
550
+
470
551
export {
471
552
Font ,
472
553
Glyph ,
@@ -476,7 +557,5 @@ export {
476
557
parseBuffer as parse ,
477
558
load ,
478
559
loadSync ,
479
- parseWOFFTableEntries ,
480
- uncompressTable ,
481
560
woff_to_otf
482
561
} ;
0 commit comments