// d2fonts holds fonts for renderings
// This file contains the common code shared between WASM and non-WASM builds.
// d2fonts_embed.go contains the embedded fonts for non-WASM builds.
// d2fonts_embed_wasm.go contains compressed fonts for WASM builds that are decompressed at runtime.
// We do this to reduce the size of WASM builds for JS packages to be smaller

// TODO write a script to do this as part of CI // Currently using an online converter: https://dopiaza.org/tools/datauri/index.php
package d2fonts import ( fontlib ) type FontFamily string type FontStyle string type Font struct { Family FontFamily Style FontStyle Size int } func ( FontFamily) ( int, FontStyle) Font { return Font{ Family: , Style: , Size: , } } func ( Font) ( string) string { var string := make(map[rune]bool) for , := range { if , := []; ! { [] = true = + string() } } FontFamiliesMu.Lock() defer FontFamiliesMu.Unlock() := FontFaces.Get() := make([]byte, len()) copy(, ) = font.UTF8CutFont(, ) , := fontlib.Sfnt2Woff() if != nil { // If subset fails, return full encoding return FontEncodings.Get() } return fmt.Sprintf("data:application/font-woff;base64,%v", base64.StdEncoding.EncodeToString()) } const ( FONT_SIZE_XS = 13 FONT_SIZE_S = 14 FONT_SIZE_M = 16 FONT_SIZE_L = 20 FONT_SIZE_XL = 24 FONT_SIZE_XXL = 28 FONT_SIZE_XXXL = 32 FONT_STYLE_REGULAR FontStyle = "regular" FONT_STYLE_BOLD FontStyle = "bold" FONT_STYLE_SEMIBOLD FontStyle = "semibold" FONT_STYLE_ITALIC FontStyle = "italic" SourceSansPro FontFamily = "SourceSansPro" SourceCodePro FontFamily = "SourceCodePro" HandDrawn FontFamily = "HandDrawn" ) var FontSizes = []int{ FONT_SIZE_XS, FONT_SIZE_S, FONT_SIZE_M, FONT_SIZE_L, FONT_SIZE_XL, FONT_SIZE_XXL, FONT_SIZE_XXXL, } var FontStyles = []FontStyle{ FONT_STYLE_REGULAR, FONT_STYLE_BOLD, FONT_STYLE_SEMIBOLD, FONT_STYLE_ITALIC, } var FontFamilies = []FontFamily{ SourceSansPro, SourceCodePro, HandDrawn, } var FontFamiliesMu sync.Mutex var FontEncodings syncmap.SyncMap[Font, string] var FontFaces syncmap.SyncMap[Font, []byte] var D2_FONT_TO_FAMILY = map[string]FontFamily{ "default": SourceSansPro, "mono": SourceCodePro, } func ( Font, FontStyle, []byte) error { FontFaces.Set(, ) , := fontlib.Sfnt2Woff() if != nil { return fmt.Errorf("failed to encode ttf to woff: %v", ) } := fmt.Sprintf("data:application/font-woff;base64,%v", base64.StdEncoding.EncodeToString()) FontEncodings.Set(, ) return nil } func ( string, , , , []byte) (*FontFamily, error) { FontFamiliesMu.Lock() defer FontFamiliesMu.Unlock() := FontFamily() := Font{ Family: , Style: FONT_STYLE_REGULAR, } if != nil { := AddFontStyle(, FONT_STYLE_REGULAR, ) if != nil { return nil, } } else { := Font{ Family: SourceSansPro, Style: FONT_STYLE_REGULAR, } FontFaces.Set(, FontFaces.Get()) FontEncodings.Set(, FontEncodings.Get()) } := Font{ Family: , Style: FONT_STYLE_ITALIC, } if != nil { := AddFontStyle(, FONT_STYLE_ITALIC, ) if != nil { return nil, } } else { := Font{ Family: SourceSansPro, Style: FONT_STYLE_ITALIC, } FontFaces.Set(, FontFaces.Get()) FontEncodings.Set(, FontEncodings.Get()) } := Font{ Family: , Style: FONT_STYLE_BOLD, } if != nil { := AddFontStyle(, FONT_STYLE_BOLD, ) if != nil { return nil, } } else { := Font{ Family: SourceSansPro, Style: FONT_STYLE_BOLD, } FontFaces.Set(, FontFaces.Get()) FontEncodings.Set(, FontEncodings.Get()) } := Font{ Family: , Style: FONT_STYLE_SEMIBOLD, } if != nil { := AddFontStyle(, FONT_STYLE_SEMIBOLD, ) if != nil { return nil, } } else { := Font{ Family: SourceSansPro, Style: FONT_STYLE_SEMIBOLD, } FontFaces.Set(, FontFaces.Get()) FontEncodings.Set(, FontEncodings.Get()) } FontFamilies = append(FontFamilies, ) return &, nil }