Skip to content
quarry Artifact [63a6a53bb5]
Login

Artifact [63a6a53bb5]

Artifact 63a6a53bb5b1e434764b5c4fb2463789c1e0959b51a9090b4670d0b8e4183367:


package web

import (
	"crypto/sha256"
	"embed"
	"encoding/hex"
	"fmt"
	"net/http"
	"strings"
)

// The typeface every page is set in, served from this origin like
// everything else (the privacy page promises no other host is asked
// for anything). IBM Plex, OFL-1.1, Latin-1 subsets: about 120 KB for
// all six files, each cached for a year under a content-hashed name.
//
//go:embed assets/fonts/*.woff2
var fontFiles embed.FS

type webFont struct {
	file   string // under assets/fonts
	family string
	weight int
	url    string
	body   []byte
}

// webFonts is every face quarry serves. The stylesheet uses only these
// weights; a weight between them (a 550, say) is drawn by the browser
// from the nearest real face, so TestWeightsHaveAFace keeps the
// stylesheet to these.
var webFonts = loadFonts([]webFont{
	{file: "IBMPlexSans-Regular.woff2", family: "IBM Plex Sans", weight: 400},
	{file: "IBMPlexSans-Medium.woff2", family: "IBM Plex Sans", weight: 500},
	{file: "IBMPlexSans-SemiBold.woff2", family: "IBM Plex Sans", weight: 600},
	{file: "IBMPlexSans-Bold.woff2", family: "IBM Plex Sans", weight: 700},
	{file: "IBMPlexMono-Regular.woff2", family: "IBM Plex Mono", weight: 400},
	{file: "IBMPlexMono-Medium.woff2", family: "IBM Plex Mono", weight: 500},
})

func loadFonts(fs []webFont) []webFont {
	for i := range fs {
		b, err := fontFiles.ReadFile("assets/fonts/" + fs[i].file)
		if err != nil {
			panic("fonts: " + err.Error())
		}
		sum := sha256.Sum256(b)
		name := strings.TrimSuffix(fs[i].file, ".woff2")
		fs[i].body = b
		fs[i].url = "/assets/fonts/" + name + "." + hex.EncodeToString(sum[:8]) + ".woff2"
	}
	return fs
}

// fontFaceCSS declares the faces. font-display: swap draws the text in
// the fallback at once and swaps the face in when it arrives, so a slow
// font never holds a page blank.
func fontFaceCSS() string {
	var b strings.Builder
	for _, f := range webFonts {
		fmt.Fprintf(&b, "@font-face{font-family:%q;font-style:normal;font-weight:%d;font-display:swap;src:url(%s) format(\"woff2\")}\n",
			f.family, f.weight, f.url)
	}
	return b.String()
}

// serveFonts mounts each face at its hashed URL.
func serveFonts(mux *http.ServeMux) {
	for _, f := range webFonts {
		body := f.body
		mux.HandleFunc("GET "+f.url, func(w http.ResponseWriter, _ *http.Request) {
			w.Header().Set("Content-Type", "font/woff2")
			w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
			w.Write(body)
		})
	}
}