@@ -26,17 +26,25 @@ export function renderFontFace(properties: Record<string, string | undefined>) {
2626 return `@font-face {\n\t${ toCSS ( properties ) } \n}\n` ;
2727}
2828
29- export function generateFontFace ( family : string , font : unifont . FontFaceData ) {
30- return renderFontFace ( {
31- 'font-family' : family ,
32- src : renderFontSrc ( font . src ) ,
29+ export function unifontFontFaceDataToProperties (
30+ font : Partial < unifont . FontFaceData > ,
31+ ) : Record < string , string | undefined > {
32+ return {
33+ src : font . src ? renderFontSrc ( font . src ) : undefined ,
3334 'font-display' : font . display ?? 'swap' ,
3435 'unicode-range' : font . unicodeRange ?. join ( ',' ) ,
3536 'font-weight' : Array . isArray ( font . weight ) ? font . weight . join ( ' ' ) : font . weight ?. toString ( ) ,
3637 'font-style' : font . style ,
3738 'font-stretch' : font . stretch ,
3839 'font-feature-settings' : font . featureSettings ,
3940 'font-variation-settings' : font . variationSettings ,
41+ } ;
42+ }
43+
44+ export function generateFontFace ( family : string , font : unifont . FontFaceData ) {
45+ return renderFontFace ( {
46+ 'font-family' : family ,
47+ ...unifontFontFaceDataToProperties ( font ) ,
4048 } ) ;
4149}
4250
@@ -145,6 +153,7 @@ export function isGenericFontFamily(str: string): str is keyof typeof DEFAULT_FA
145153export type GetMetricsForFamilyFont = {
146154 hash : string ;
147155 url : string ;
156+ data : Partial < unifont . FontFaceData > ;
148157} ;
149158
150159export type GetMetricsForFamily = (
@@ -169,42 +178,44 @@ export async function generateFallbacksCSS({
169178 family : Pick < ResolvedFontFamily , 'name' | 'nameWithHash' > ;
170179 /** The family fallbacks */
171180 fallbacks : Array < string > ;
172- font : GetMetricsForFamilyFont | null ;
181+ font : Array < GetMetricsForFamilyFont > ;
173182 metrics : {
174183 getMetricsForFamily : GetMetricsForFamily ;
175184 generateFontFace : typeof generateFallbackFontFace ;
176185 } | null ;
177- } ) : Promise < null | { css : string ; fallbacks : Array < string > } > {
186+ } ) : Promise < null | { css ? : string ; fallbacks : Array < string > } > {
178187 // We avoid mutating the original array
179188 let fallbacks = [ ..._fallbacks ] ;
180189 if ( fallbacks . length === 0 ) {
181190 return null ;
182191 }
183192
184- let css = '' ;
185-
186- if ( ! fontData || ! metrics ) {
187- return { css, fallbacks } ;
193+ if ( fontData . length === 0 || ! metrics ) {
194+ return { fallbacks } ;
188195 }
189196
190197 // The last element of the fallbacks is usually a generic family name (eg. serif)
191198 const lastFallback = fallbacks [ fallbacks . length - 1 ] ;
192199 // If it's not a generic family name, we can't infer local fonts to be used as fallbacks
193200 if ( ! isGenericFontFamily ( lastFallback ) ) {
194- return { css , fallbacks } ;
201+ return { fallbacks } ;
195202 }
196203
197204 // If it's a generic family name, we get the associated local fonts (eg. Arial)
198205 const localFonts = DEFAULT_FALLBACKS [ lastFallback ] ;
199206 // Some generic families do not have associated local fonts so we abort early
200207 if ( localFonts . length === 0 ) {
201- return { css , fallbacks } ;
208+ return { fallbacks } ;
202209 }
203210
204- const foundMetrics = await metrics . getMetricsForFamily ( family . name , fontData ) ;
205- if ( ! foundMetrics ) {
206- // If there are no metrics, we can't generate useful fallbacks
207- return { css, fallbacks } ;
211+ // If the family is already a system font, no need to generate fallbacks
212+ if (
213+ localFonts . includes (
214+ // @ts -expect-error TS is not smart enough
215+ family . name ,
216+ )
217+ ) {
218+ return { fallbacks } ;
208219 }
209220
210221 const localFontsMappings = localFonts . map ( ( font ) => ( {
@@ -214,15 +225,18 @@ export async function generateFallbacksCSS({
214225
215226 // We prepend the fallbacks with the local fonts and we dedupe in case a local font is already provided
216227 fallbacks = [ ...new Set ( [ ...localFontsMappings . map ( ( m ) => m . name ) , ...fallbacks ] ) ] ;
228+ let css = '' ;
217229
218230 for ( const { font, name } of localFontsMappings ) {
219- css += metrics . generateFontFace ( {
220- metrics : foundMetrics ,
221- fallbackMetrics : SYSTEM_METRICS [ font ] ,
222- font,
223- name,
224- // TODO: forward some properties once we generate one fallback per font face data
225- } ) ;
231+ for ( const { hash, url, data } of fontData ) {
232+ css += metrics . generateFontFace ( {
233+ metrics : await metrics . getMetricsForFamily ( family . name , { hash, url, data } ) ,
234+ fallbackMetrics : SYSTEM_METRICS [ font ] ,
235+ font,
236+ name,
237+ properties : unifontFontFaceDataToProperties ( data ) ,
238+ } ) ;
239+ }
226240 }
227241
228242 return { css, fallbacks } ;
0 commit comments