@@ -9,6 +9,7 @@ import Font from './font.js';
9
9
import Glyph from './glyph.js' ;
10
10
import { CmapEncoding , GlyphNames , addGlyphNames } from './encoding.js' ;
11
11
import parse from './parse.js' ;
12
+ import { encode } from './types.js' ;
12
13
import BoundingBox from './bbox.js' ;
13
14
import Path from './path.js' ;
14
15
import cpal from './tables/cpal.js' ;
@@ -35,7 +36,6 @@ import os2 from './tables/os2.js';
35
36
import post from './tables/post.js' ;
36
37
import meta from './tables/meta.js' ;
37
38
import gasp from './tables/gasp.js' ;
38
- import { woff_to_otf } from './woff-to-otf.js' ;
39
39
/**
40
40
* The opentype library.
41
41
* @namespace opentype
@@ -534,6 +534,87 @@ function loadSync(url, opt) {
534
534
return parseBuffer ( require ( 'fs' ) . readFileSync ( url ) , opt ) ;
535
535
}
536
536
537
+ /**
538
+ * Convert/Uncompress a buffer of a woff font to otf/ttf without parsing
539
+ * table contents.
540
+ * @param {ArrayBuffer }
541
+ * @return {ArrayBuffer }
542
+ */
543
+ function woff_to_otf ( buffer ) {
544
+ if ( buffer . constructor !== ArrayBuffer )
545
+ buffer = new Uint8Array ( buffer ) . buffer ;
546
+ const data = new DataView ( buffer , 0 )
547
+ , out = [ ]
548
+ , signature = parse . getTag ( data , 0 )
549
+ ;
550
+
551
+ if ( signature !== 'wOFF' )
552
+ throw new Error ( `TYPE ERROR signature must be wOFF but is: "${ signature } "` ) ;
553
+
554
+ const flavor = parse . getTag ( data , 4 )
555
+ , numTables = parse . getUShort ( data , 12 )
556
+ , tableEntries = parseWOFFTableEntries ( data , numTables )
557
+ , max = [ ]
558
+ ;
559
+ for ( let n = 0 ; n < 64 ; n ++ ) {
560
+ if ( Math . pow ( 2 , n ) > numTables )
561
+ break ;
562
+ max . splice ( 0 , Infinity , n , 2 ** n ) ;
563
+ }
564
+ const searchRange = max [ 1 ] * 16
565
+ , entrySelector = max [ 0 ]
566
+ , rangeShift = numTables * 16 - searchRange
567
+ ;
568
+
569
+ out . push (
570
+ ...encode . TAG ( flavor )
571
+ , ...encode . USHORT ( numTables )
572
+ , ...encode . USHORT ( searchRange )
573
+ , ...encode . USHORT ( entrySelector )
574
+ , ...encode . USHORT ( rangeShift )
575
+ ) ;
576
+ let offset = out . length + numTables * 16 ;
577
+
578
+ for ( let i = 0 ; i < numTables ; i ++ ) {
579
+ const tableEntry = tableEntries [ i ] ;
580
+ out . push (
581
+ ...encode . TAG ( tableEntry . tag )
582
+ , ...encode . ULONG ( tableEntry . checksum )
583
+ , ...encode . ULONG ( offset )
584
+ , ...encode . ULONG ( tableEntry . length )
585
+ )
586
+ tableEntry . outOffset = offset ;
587
+ offset += tableEntry . length ;
588
+ if ( ( offset % 4 ) !== 0 )
589
+ offset += 4 - ( offset % 4 ) ;
590
+ }
591
+ const initialData = new Uint8Array ( out . length )
592
+ , buffers = [ initialData ]
593
+ ;
594
+ for ( let i = 0 , l = out . length ; i < l ; i ++ )
595
+ initialData [ i ] = out [ i ] ;
596
+
597
+ for ( let i = 0 ; i < numTables ; i ++ ) {
598
+ const tableEntry = tableEntries [ i ]
599
+ , table = uncompressTable ( data , tableEntry ) // => {data: view, offset: 0};
600
+ , offset = tableEntry . outOffset + tableEntry . length
601
+ , padding = ( offset % 4 ) !== 0
602
+ ? 4 - ( offset % 4 )
603
+ : 0
604
+ ;
605
+ buffers . push (
606
+ new Uint8Array ( table . data . buffer , table . offset , tableEntry . length )
607
+ , new Uint8Array ( padding )
608
+ ) ;
609
+ }
610
+ const result = new Uint8Array ( buffers . reduce ( ( accum , buffer ) => accum + buffer . byteLength , 0 ) ) ;
611
+ buffers . reduce ( ( offset , buffer ) => {
612
+ result . set ( buffer , offset )
613
+ return offset + buffer . byteLength
614
+ } , 0 )
615
+ return result . buffer ;
616
+ }
617
+
537
618
export {
538
619
Font ,
539
620
Glyph ,
@@ -543,7 +624,5 @@ export {
543
624
parseBuffer as parse ,
544
625
load ,
545
626
loadSync ,
546
- parseWOFFTableEntries ,
547
- uncompressTable ,
548
627
woff_to_otf
549
628
} ;
0 commit comments