22
33import isUrl from 'is-url' ;
44import * as fontkit from 'fontkit' ;
5+ import {
6+ FontDescriptor ,
7+ FontSourceOptions ,
8+ FontStyle ,
9+ FontWeight ,
10+ } from './types' ;
511
612const FONT_WEIGHTS = {
713 thin : 100 ,
@@ -20,29 +26,44 @@ const FONT_WEIGHTS = {
2026 black : 900 ,
2127} ;
2228
23- const fetchFont = async ( src , options ) => {
29+ const fetchFont = async ( src : string , options ) => {
2430 const response = await fetch ( src , options ) ;
2531 const data = await response . arrayBuffer ( ) ;
2632
2733 return new Uint8Array ( data ) ;
2834} ;
2935
30- const isDataUrl = ( dataUrl ) => {
36+ const isDataUrl = ( dataUrl : string ) => {
3137 const header = dataUrl . split ( ',' ) [ 0 ] ;
3238 const hasDataPrefix = header . substring ( 0 , 5 ) === 'data:' ;
3339 const hasBase64Prefix = header . split ( ';' ) [ 1 ] === 'base64' ;
3440
3541 return hasDataPrefix && hasBase64Prefix ;
3642} ;
3743
38- const resolveFontWeight = ( value ) => {
44+ const resolveFontWeight = ( value : FontWeight ) => {
3945 return typeof value === 'string' ? FONT_WEIGHTS [ value ] : value ;
4046} ;
4147
42- const sortByFontWeight = ( a , b ) => a . fontWeight - b . fontWeight ;
48+ const sortByFontWeight = ( a : FontSource , b : FontSource ) =>
49+ a . fontWeight - b . fontWeight ;
4350
4451class FontSource {
45- constructor ( src , fontFamily , fontStyle , fontWeight , options ) {
52+ src : string ;
53+ fontFamily : string ;
54+ fontStyle : FontStyle ;
55+ fontWeight : number ;
56+ data : fontkit . Font | fontkit . FontCollection | null ;
57+ options : FontSourceOptions ;
58+ loadResultPromise : Promise < void > | null ;
59+
60+ constructor (
61+ src : string ,
62+ fontFamily : string ,
63+ fontStyle : FontStyle ,
64+ fontWeight : number ,
65+ options : FontSourceOptions ,
66+ ) {
4667 this . src = src ;
4768 this . fontFamily = fontFamily ;
4869 this . fontStyle = fontStyle || 'normal' ;
@@ -53,7 +74,7 @@ class FontSource {
5374 this . loadResultPromise = null ;
5475 }
5576
56- async _load ( ) {
77+ async _load ( ) : Promise < void > {
5778 const { postscriptName } = this . options ;
5879
5980 if ( isDataUrl ( this . src ) ) {
@@ -82,11 +103,14 @@ class FontSource {
82103}
83104
84105class Font {
85- static create ( family ) {
106+ family : string ;
107+ sources : FontSource [ ] ;
108+
109+ static create ( family : string ) {
86110 return new Font ( family ) ;
87111 }
88112
89- constructor ( family ) {
113+ constructor ( family : string ) {
90114 this . family = family ;
91115 this . sources = [ ] ;
92116 }
@@ -99,39 +123,46 @@ class Font {
99123 ) ;
100124 }
101125
102- resolve ( descriptor ) {
126+ resolve ( descriptor : FontDescriptor ) {
103127 const { fontWeight = 400 , fontStyle = 'normal' } = descriptor ;
104128 const styleSources = this . sources . filter ( ( s ) => s . fontStyle === fontStyle ) ;
105129
106- // Weight resolution. https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#Fallback_weights
107130 const exactFit = styleSources . find ( ( s ) => s . fontWeight === fontWeight ) ;
108131
109132 if ( exactFit ) return exactFit ;
110133
111- let res ;
134+ // Weight resolution. https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#Fallback_weights
135+
136+ let res : FontSource ;
137+
138+ const numericFontWeight = resolveFontWeight ( fontWeight ) ;
139+
140+ if ( numericFontWeight >= 400 && numericFontWeight <= 500 ) {
141+ const leftOffset = styleSources . filter (
142+ ( s ) => s . fontWeight <= numericFontWeight ,
143+ ) ;
112144
113- if ( fontWeight >= 400 && fontWeight <= 500 ) {
114- const leftOffset = styleSources . filter ( ( s ) => s . fontWeight <= fontWeight ) ;
115145 const rightOffset = styleSources . filter ( ( s ) => s . fontWeight > 500 ) ;
146+
116147 const fit = styleSources . filter (
117- ( s ) => s . fontWeight >= fontWeight && s . fontWeight < 500 ,
148+ ( s ) => s . fontWeight >= numericFontWeight && s . fontWeight < 500 ,
118149 ) ;
119150
120151 res = fit [ 0 ] || leftOffset [ leftOffset . length - 1 ] || rightOffset [ 0 ] ;
121152 }
122153
123154 const lt = styleSources
124- . filter ( ( s ) => s . fontWeight < fontWeight )
155+ . filter ( ( s ) => s . fontWeight < numericFontWeight )
125156 . sort ( sortByFontWeight ) ;
126157 const gt = styleSources
127- . filter ( ( s ) => s . fontWeight > fontWeight )
158+ . filter ( ( s ) => s . fontWeight > numericFontWeight )
128159 . sort ( sortByFontWeight ) ;
129160
130- if ( fontWeight < 400 ) {
161+ if ( numericFontWeight < 400 ) {
131162 res = lt [ lt . length - 1 ] || gt [ 0 ] ;
132163 }
133164
134- if ( fontWeight > 500 ) {
165+ if ( numericFontWeight > 500 ) {
135166 res = gt [ 0 ] || lt [ lt . length - 1 ] ;
136167 }
137168
0 commit comments