Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/three-moose-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'smp-noto-glyphs': patch
---

Gzip noto glyph fallbacks at rest
1 change: 1 addition & 0 deletions packages/glyphs/fixtures/glyphs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!*.gz
Binary file removed packages/glyphs/fixtures/glyphs/0-255.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/0-255.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/1024-1279.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/1024-1279.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/11264-11519.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/11520-11775.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/1280-1535.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/1280-1535.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/1536-1791.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/1536-1791.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/1792-2047.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/1792-2047.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/2048-2303.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/2048-2303.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/2304-2559.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/2304-2559.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/256-511.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/256-511.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/2560-2815.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/2560-2815.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/2816-3071.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/2816-3071.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/3072-3327.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/3072-3327.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/3328-3583.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/3328-3583.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/3584-3839.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/3584-3839.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/3840-4095.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/3840-4095.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/4096-4351.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/4096-4351.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/41984-42239.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/42240-42495.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/42496-42751.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/42752-43007.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/43008-43263.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/43264-43519.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/4352-4607.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/4352-4607.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/43520-43775.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/43776-44031.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/4608-4863.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/4864-5119.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/4864-5119.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/512-767.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/512-767.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/5888-6143.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/5888-6143.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/6144-6399.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/6144-6399.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/6400-6655.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/6400-6655.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/64256-64511.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/65024-65279.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/6656-6911.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/6656-6911.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/6912-7167.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/6912-7167.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/7168-7423.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/7168-7423.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/7424-7679.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/7424-7679.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/768-1023.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/7680-7935.pbf
Binary file not shown.
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/7936-8191.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/7936-8191.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/8192-8447.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/8192-8447.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/8448-8703.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/8448-8703.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/8704-8959.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/8704-8959.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/9216-9471.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/9216-9471.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/9472-9727.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/9472-9727.pbf.gz
Binary file not shown.
Binary file removed packages/glyphs/fixtures/glyphs/9728-9983.pbf
Binary file not shown.
Binary file added packages/glyphs/fixtures/glyphs/9728-9983.pbf.gz
Binary file not shown.
24 changes: 8 additions & 16 deletions packages/glyphs/lib/noto.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ const GLYPHS_DIR = fileURLToPath(new URL('../fixtures/glyphs', import.meta.url))
const cache = new Map()

/**
* Read a PBF glyph range file, returning the cached buffer or null if not found.
* Read a gzipped PBF glyph range file, returning the cached buffer or null if not found.
* @param {string} range
* @returns {Uint8Array | null}
*/
function getGlyphPbf(range) {
if (cache.has(range))
return /** @type {Uint8Array | null} */ (cache.get(range))
const filePath = path.join(GLYPHS_DIR, `${range}.pbf`)
const filePath = path.join(GLYPHS_DIR, `${range}.pbf.gz`)
try {
const data = fs.readFileSync(filePath)
cache.set(range, data)
Expand All @@ -42,6 +42,9 @@ function getGlyphPbf(range) {
* glyph ranges for common scripts, and empty PBFs for uncommon/CJK ranges
* (which MapLibre renders client-side via `localIdeographFontFamily`).
*
* All responses are gzip-encoded — both pre-built ranges (stored as .pbf.gz)
* and empty fallbacks. Fixtures are stored compressed to reduce package size.
*
* Covers 80+ scripts including Latin, Cyrillic, Greek, Arabic, Hebrew,
* Devanagari, Thai, and more. See https://github.com/satbyy/go-noto-universal
*
Expand All @@ -52,24 +55,13 @@ function getGlyphPbf(range) {
* @returns {Response}
*/
export function notoGlyphFallback(_fontstack, range) {
const pbf = getGlyphPbf(range)
if (pbf) {
return new Response(/** @type {any} */ (pbf), {
status: 200,
headers: {
'Content-Type': 'application/x-protobuf',
'Content-Length': String(pbf.byteLength),
'Cache-Control': 'public, max-age=604800',
},
})
}
// No pre-built PBF for this range — serve empty gzipped PBF
return new Response(/** @type {any} */ (EMPTY_GZ), {
const gz = getGlyphPbf(range) ?? EMPTY_GZ
return new Response(gz, {
status: 200,
headers: {
'Content-Type': 'application/x-protobuf',
'Content-Encoding': 'gzip',
'Content-Length': String(EMPTY_GZ.byteLength),
'Content-Length': String(gz.byteLength),
'Cache-Control': 'public, max-age=604800',
},
})
Expand Down
17 changes: 12 additions & 5 deletions packages/glyphs/test/noto.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,30 @@ import fs from 'node:fs'
import { notoGlyphFallback } from '../lib/noto.js'

describe('notoGlyphFallback', () => {
test('returns PBF with correct headers for a known range', () => {
test('returns gzipped PBF with correct headers for a known range', () => {
const response = notoGlyphFallback('Any Font', '0-255')
expect(response.status).toBe(200)
expect(response.headers.get('Content-Type')).toBe('application/x-protobuf')
expect(Number(response.headers.get('Content-Length'))).toBeGreaterThan(50)
// Known ranges should NOT have Content-Encoding (raw PBF, not gzipped)
expect(response.headers.get('Content-Encoding')).toBeNull()
expect(response.headers.get('Content-Encoding')).toBe('gzip')
expect(Number(response.headers.get('Content-Length'))).toBeGreaterThan(20)
expect(response.headers.get('Cache-Control')).toBe('public, max-age=604800')
})

test('returns non-empty body for known range', async () => {
const response = notoGlyphFallback('Any Font', '0-255')
const body = await response.arrayBuffer()
expect(body.byteLength).toBeGreaterThan(50)
expect(body.byteLength).toBeGreaterThan(20)
expect(body.byteLength).toBe(Number(response.headers.get('Content-Length')))
})

test('known range body is larger than empty fallback', async () => {
const known = notoGlyphFallback('Any Font', '0-255')
const unknown = notoGlyphFallback('Any Font', '60000-60255')
const knownBody = await known.arrayBuffer()
const unknownBody = await unknown.arrayBuffer()
expect(knownBody.byteLength).toBeGreaterThan(unknownBody.byteLength)
})

test('returns empty gzipped PBF for unknown range', () => {
const response = notoGlyphFallback('Any Font', '60000-60255')
expect(response.status).toBe(200)
Expand Down
12 changes: 8 additions & 4 deletions scripts/generate-glyphs.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import https from 'node:https'
import os from 'node:os'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { gzipSync } from 'node:zlib'

import { LOCAL_GLYPH_RANGES } from '../packages/api/lib/utils/style.js'

Expand Down Expand Up @@ -142,7 +143,7 @@ async function main() {

// Clean existing PBF files
for (const f of fs.readdirSync(OUTPUT_DIR)) {
if (f.endsWith('.pbf')) {
if (f.endsWith('.pbf') || f.endsWith('.pbf.gz')) {
fs.unlinkSync(path.join(OUTPUT_DIR, f))
}
}
Expand Down Expand Up @@ -170,10 +171,13 @@ async function main() {
if (excluded || data.length <= MIN_GLYPH_SIZE) {
skippedCount++
} else {
fs.copyFileSync(src, path.join(OUTPUT_DIR, filename))
totalSize += data.length
const gz = gzipSync(data)
fs.writeFileSync(path.join(OUTPUT_DIR, `${filename}.gz`), gz)
totalSize += gz.length
copiedCount++
console.log(` ${filename} (${(data.length / 1024).toFixed(1)} KB)`)
console.log(
` ${filename}.gz (${(gz.length / 1024).toFixed(1)} KB, ${((1 - gz.length / data.length) * 100).toFixed(0)}% smaller)`,
)
}
}

Expand Down