diff --git a/crates/vibescrobble-query/src/card.rs b/crates/vibescrobble-query/src/card.rs index 4199da03..1e3255ea 100644 --- a/crates/vibescrobble-query/src/card.rs +++ b/crates/vibescrobble-query/src/card.rs @@ -6,7 +6,10 @@ //! milliseconds rather than a Chrome. The faces are the page's own //! (`web/fonts/`), compiled in, so a card is set in what the board is set //! in. Emoji are drawn from the colour font `--emoji-font` names, Noto Color -//! Emoji in the image; without one, a card is drawn without its emoji. +//! Emoji in the image; without one, a card is drawn without its emoji. A +//! name or a line in Cyrillic or Greek is set in Inter's own, compiled in +//! too, and one in Chinese, Japanese or Korean in Noto Sans CJK from +//! [`CJK_FONTS`] where the machine has it. //! //! The look is the zine's (`web/plate.css`, `web/zine.css`): lavender riso //! stock under a dot screen, a paper bar with the wordmark over a ska @@ -43,6 +46,13 @@ pub const HEIGHT: u32 = 630; /// copies to the same place. pub const DEFAULT_EMOJI_FONT: &str = "/usr/share/fonts/truetype/noto/NotoColorEmoji.ttf"; +/// Where Debian's `fonts-noto-cjk` puts Noto Sans CJK, regular and bold, +/// which the image copies to the same place. +pub const CJK_FONTS: [&str; 2] = [ + "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", + "/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc", +]; + /// How many drawn cards are kept. A card is a few hundred kilobytes, so this /// is a few tens of megabytes at most. pub const CACHED: usize = 64; @@ -53,6 +63,14 @@ pub const DRAWING: usize = 2; const INTER: &[u8] = include_bytes!("../../../web/fonts/inter-latin-400.woff2"); const INTER_BOLD: &[u8] = include_bytes!("../../../web/fonts/inter-latin-700.woff2"); +/// Inter's Cyrillic and Greek, regular and bold, which set what the Latin +/// faces have no glyph for. +const INTER_MORE: [&[u8]; 4] = [ + include_bytes!("../../../web/fonts/inter-cyrillic-400.woff2"), + include_bytes!("../../../web/fonts/inter-cyrillic-700.woff2"), + include_bytes!("../../../web/fonts/inter-greek-400.woff2"), + include_bytes!("../../../web/fonts/inter-greek-700.woff2"), +]; const BAGEL: &[u8] = include_bytes!("../../../web/fonts/bagel-fat-one-latin-400.woff2"); const RIGHTEOUS: &[u8] = include_bytes!("../../../web/fonts/righteous-latin-400.woff2"); // The zine's other hands, for the swarm cards: the poster's display face, @@ -400,6 +418,10 @@ impl Faces { ] { db.load_font_data(face.clone()); } + // After the Latin faces, so a query for Inter finds those first. + for face in inter_more() { + db.load_font_data(face.clone()); + } db.set_sans_serif_family("Inter"); let emoji = match emoji_font { Some(path) => match db.load_font_file(path) { @@ -414,7 +436,19 @@ impl Faces { false } }; - info!(faces = db.len(), emoji, "loaded the faces cards are set in"); + // Mapped rather than read, so a face costs memory only for the + // glyphs a card draws from it. + let mut cjk = true; + for path in CJK_FONTS { + if let Err(err) = db.load_font_file(path) { + warn!(path, %err, "no CJK face; cards set Chinese, Japanese and Korean as missing glyphs"); + cjk = false; + } + } + info!( + faces = db.len(), + emoji, cjk, "loaded the faces cards are set in" + ); Self { db: Arc::new(db), inter, @@ -442,12 +476,8 @@ pub(crate) fn render_at( width: u32, height: u32, ) -> Result, String> { - let options = usvg::Options { - fontdb: faces.db.clone(), - font_family: "Inter".to_owned(), - ..usvg::Options::default() - }; - let tree = usvg::Tree::from_str(svg, &options).map_err(|err| format!("card SVG: {err}"))?; + let tree = + usvg::Tree::from_str(svg, &options(faces)).map_err(|err| format!("card SVG: {err}"))?; let mut pixmap = resvg::tiny_skia::Pixmap::new(width, height).ok_or("no canvas for a card")?; resvg::render( &tree, @@ -459,31 +489,120 @@ pub(crate) fn render_at( .map_err(|err| format!("card PNG: {err}")) } +/// How a card's SVG is read: in its faces, Inter where none is named. +fn options(faces: &Faces) -> usvg::Options<'static> { + usvg::Options { + fontdb: faces.db.clone(), + font_family: "Inter".to_owned(), + font_resolver: usvg::FontResolver { + select_fallback: Box::new(fallback), + ..usvg::FontResolver::default() + }, + ..usvg::Options::default() + } +} + +/// The face to set `ch` in when the face asked for has no glyph for it: the +/// first family that has one, in the weight asked for where that family +/// has it, so a bold name in Cyrillic is set in Inter's bold Cyrillic and +/// a bold one in Chinese in Noto Sans CJK's bold. +fn fallback(ch: char, used: &[fontdb::ID], db: &mut Arc) -> Option { + let weight = used + .first() + .and_then(|id| db.face(*id)) + .map(|face| face.weight); + let has = |face: &&fontdb::FaceInfo| { + !used.contains(&face.id) + && db.with_face_data(face.id, |data, index| { + skrifa::FontRef::from_index(data, index) + .is_ok_and(|font| font.charmap().map(ch).is_some()) + }) == Some(true) + }; + let first = db.faces().find(has)?; + let family = &first.families.first()?.0; + let weighted = db.faces().filter(has).find(|face| { + Some(face.weight) == weight && face.families.first().is_some_and(|f| &f.0 == family) + }); + Some(weighted.unwrap_or(first).id) +} + /// How wide `text` is set in `font` at `px`, near enough to wrap by. /// /// Advances only: no kerning and no shaping. A grapheme the face has no -/// glyph for — an emoji, a script outside its subset — is counted as a -/// square and a bit, which errs wide, so a line wrapped by this fits. +/// glyph for is measured in the face a card sets it in: Inter's Cyrillic +/// or Greek of the same weight, or Noto Sans CJK, which sets Han and kana +/// on one em and Hangul on a little less. Anything else, an emoji most +/// likely, is counted as a square and a bit. Both err wide, so a line +/// wrapped by this fits. pub(crate) fn width(font: &[u8], text: &str, px: f32) -> f32 { let Ok(face) = skrifa::FontRef::new(font) else { return text.graphemes(true).count() as f32 * px * 0.6; }; - let charmap = face.charmap(); - let metrics = face.glyph_metrics(Size::new(px), LocationRef::default()); + let bold = face.attributes().weight.value() >= 600.0; + let faces = std::iter::once(face).chain( + inter_more() + .iter() + .skip(usize::from(bold)) + .step_by(2) + .filter_map(|more| skrifa::FontRef::new(more).ok()), + ); + let measures: Vec<_> = faces + .map(|face| { + ( + face.charmap(), + face.glyph_metrics(Size::new(px), LocationRef::default()), + ) + }) + .collect(); text.graphemes(true) .map(|grapheme| { let mut chars = grapheme.chars(); match (chars.next(), chars.next()) { - (Some(ch), None) => charmap - .map(ch) - .and_then(|glyph| metrics.advance_width(glyph)) - .unwrap_or(px * 1.2), + (Some(ch), None) => measures + .iter() + .find_map(|(charmap, metrics)| { + charmap + .map(ch) + .and_then(|glyph| metrics.advance_width(glyph)) + }) + .unwrap_or(if wide(ch) { px } else { px * 1.2 }), _ => px * 1.2, } }) .sum() } +/// Whether `ch` is Han, kana, Hangul or a full-width form: what Noto Sans +/// CJK sets on one em at most. +fn wide(ch: char) -> bool { + matches!( + u32::from(ch), + 0x1100..=0x115F + | 0x2E80..=0x303E + | 0x3041..=0x33FF + | 0x3400..=0x4DBF + | 0x4E00..=0x9FFF + | 0xA960..=0xA97F + | 0xAC00..=0xD7A3 + | 0xF900..=0xFAFF + | 0xFE30..=0xFE4F + | 0xFF01..=0xFF60 + | 0xFFE0..=0xFFE6 + | 0x20000..=0x3FFFD + ) +} + +/// Inter's Cyrillic and Greek, regular then bold of each, decoded once. +fn inter_more() -> &'static [Vec] { + static MORE: OnceLock>> = OnceLock::new(); + MORE.get_or_init(|| { + INTER_MORE + .iter() + .map(|woff2| wuff::decompress_woff2(woff2).unwrap_or_default()) + .collect() + }) +} + /// Inter, regular and bold, decoded once without the rest of a card's /// faces. fn inter_faces() -> &'static (Vec, Vec) { @@ -969,6 +1088,137 @@ mod tests { ); } + /// Every glyph `svg` sets, with the family and weight of the face it + /// was set in. + fn set_in(svg: &str, faces: &Faces) -> Vec<(String, u16, String, String)> { + fn walk( + group: &usvg::Group, + db: &fontdb::Database, + out: &mut Vec<(String, u16, String, String)>, + ) { + for node in group.children() { + match node { + usvg::Node::Group(group) => walk(group, db, out), + usvg::Node::Text(text) => { + for glyph in text + .layouted() + .iter() + .flat_map(|span| &span.positioned_glyphs) + { + let face = db.face(glyph.font).expect("a face"); + let missing = if glyph.id.0 == 0 { "missing" } else { "" }; + out.push(( + face.families[0].0.clone(), + face.weight.0, + glyph.text.clone(), + missing.to_owned(), + )); + } + } + _ => {} + } + } + } + let tree = usvg::Tree::from_str(svg, &options(faces)).expect("it parses"); + let mut out = Vec::new(); + walk(tree.root(), tree.fontdb(), &mut out); + out + } + + /// A name in Cyrillic and Greek is set in Inter's own, bold as the + /// name is, and so is a line; a line with Chinese in it is set in Noto + /// Sans CJK where the machine has it, whole, since resvg sets a run in + /// one fallback face where that face has all of it. No glyph is the + /// missing one. + #[test] + fn a_card_sets_cyrillic_greek_and_chinese() { + let faces = Faces::load(None); + let card = Card { + did: "did:plc:zhizn6mbfqhzpldiwtoeyrxs".to_owned(), + name: "Жизнь Ωμέγα".to_owned(), + handle: Some("zhizn.example".to_owned()), + picture: None, + said: Some(Said { + emoji: "🪴".to_owned(), + text: "и всё ещё".to_owned(), + at: "2026-10-17T10:03:00Z".to_owned(), + by: None, + }), + }; + let drawn = svg(&card, None, &faces); + if let Some(dir) = std::env::var_os("CARD_OUT") { + let png = render(&drawn, &faces).expect("it draws"); + std::fs::write(PathBuf::from(dir).join("scripts.png"), &png).expect("written"); + } + let set = set_in(&drawn, &faces); + for letter in ["Ж", "з", "Ω", "έ"] { + let glyph = set + .iter() + .find(|(.., text, _)| text == letter) + .expect(letter); + assert_eq!( + (glyph.0.as_str(), glyph.1, glyph.3.as_str()), + ("Inter", 700, ""), + "{letter}" + ); + } + let glyph = set.iter().find(|(.., text, _)| text == "в").expect("в"); + assert_eq!( + (glyph.0.as_str(), glyph.1, glyph.3.as_str()), + ("Inter", 400, "") + ); + let chinese = Card { + said: Some(Said { + text: "测试中文 и всё: 正在检查卡片上的中文字体".to_owned(), + ..card.said.clone().expect("said") + }), + ..card + }; + let drawn = svg(&chinese, None, &faces); + if let Some(dir) = std::env::var_os("CARD_OUT") { + let png = render(&drawn, &faces).expect("it draws"); + std::fs::write(PathBuf::from(dir).join("scripts-cjk.png"), &png).expect("written"); + } + let set = set_in(&drawn, &faces); + if CJK_FONTS + .iter() + .all(|path| std::path::Path::new(path).is_file()) + { + for letter in ["测", "文"] { + let glyph = set + .iter() + .find(|(.., text, _)| text == letter) + .expect(letter); + assert!(glyph.0.starts_with("Noto Sans CJK"), "{glyph:?}"); + assert_eq!((glyph.1, glyph.3.as_str()), (400, ""), "{letter}"); + } + } + // Measured in the face that sets it, so a wrapped line fits. + let more = inter_more(); + assert_eq!( + width(&faces.inter_bold, "Жизнь", 54.0), + width(&more[1], "Жизнь", 54.0) + ); + assert_eq!( + width(&faces.inter, "Ωμέγα", 38.0), + width(&more[2], "Ωμέγα", 38.0) + ); + // Noto Sans CJK sets a Han or kana grapheme on one em, and Hangul + // on a little less, so counting it as one errs wide. + assert_eq!(width(&faces.inter, "测试한ア", 38.0), 4.0 * 38.0); + if let Ok(cjk) = std::fs::read(CJK_FONTS[0]) { + for (letter, em) in [('测', 1.0), ('ア', 1.0), ('、', 1.0), ('한', 0.92)] { + let face = skrifa::FontRef::from_index(&cjk, 0).expect("a face"); + let glyph = face.charmap().map(letter).expect("a glyph"); + let advance = face + .glyph_metrics(Size::new(38.0), LocationRef::default()) + .advance_width(glyph) + .expect("an advance"); + assert!((advance - 38.0 * em).abs() < 0.01, "{letter}: {advance}"); + } + } + } + #[test] fn a_long_line_wraps_and_is_cut_at_its_last() { let faces = Faces::load(None); diff --git a/docs/running-locally.md b/docs/running-locally.md index 5279779c..955d1d7d 100644 --- a/docs/running-locally.md +++ b/docs/running-locally.md @@ -404,9 +404,12 @@ cards are sent with `Cache-Control: public, max-age=300`, and a 404 with `no-cache`. Cards are SVG rasterised in-process by resvg, in the page's own faces from -`web/fonts/`, which the binary carries. Emoji come from the colour font -`--emoji-font` names (Debian's `fonts-noto-color-emoji` by default, which the -image installs); without one a card is drawn without its emoji. Two are drawn +`web/fonts/`, which the binary carries, Inter's Cyrillic and Greek among +them. Emoji come from the colour font `--emoji-font` names (Debian's +`fonts-noto-color-emoji` by default, which the image installs); without one a +card is drawn without its emoji. Chinese, Japanese and Korean are set in Noto +Sans CJK from Debian's `fonts-noto-cjk` paths, which the image carries the +sans faces of; without them those glyphs are drawn missing. Two are drawn at a time and the last 64 are held. `--public-url` sets the origin the tags' absolute URLs are written against; without it, the request's `Host` is used. The pages' styles are `web/share.css`, which Caddy serves beside the canvas. diff --git a/infra/files/vibescrobble.Dockerfile b/infra/files/vibescrobble.Dockerfile index ea6b0bfd..4c906e5f 100644 --- a/infra/files/vibescrobble.Dockerfile +++ b/infra/files/vibescrobble.Dockerfile @@ -89,12 +89,12 @@ RUN base="https://huggingface.co/${MODEL_REPO}/resolve/${MODEL_REVISION}" && \ done # What the runtime stage needs from a package manager and a shell: the CA -# bundle, an account for the user the services run as, and the colour emoji -# font a share card's emoji are drawn from. None holds anything -# per-architecture, so they are made natively, from the same base, and -# copied across. +# bundle, an account for the user the services run as, the colour emoji +# font a share card's emoji are drawn from, and the CJK faces its Chinese, +# Japanese and Korean are set in. None holds anything per-architecture, so +# they are made natively, from the same base, and copied across. FROM --platform=$BUILDPLATFORM debian:bookworm-slim@sha256:3783cc01769c7b2b1b83a5c5ad96c815348e28ed7da68e2e3687004faa906251 AS system -RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates fonts-noto-color-emoji && \ +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates fonts-noto-color-emoji fonts-noto-cjk && \ rm -rf /var/lib/apt/lists/* && \ useradd --system --uid 65532 vibescrobble && mkdir -p /data @@ -106,6 +106,9 @@ COPY --from=system /etc/ssl/certs /etc/ssl/certs COPY --from=system /usr/share/ca-certificates /usr/share/ca-certificates # Where vibescrobble-query's `--emoji-font` looks unless told otherwise. COPY --from=system /usr/share/fonts/truetype/noto/NotoColorEmoji.ttf /usr/share/fonts/truetype/noto/NotoColorEmoji.ttf +# Where it looks for Noto Sans CJK, regular and bold: the sans only, since +# the package's serif faces are half its weight and nothing sets them. +COPY --from=system /usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc /usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc /usr/share/fonts/opentype/noto/ COPY --from=build /out/vibescrobble-index /out/vibescrobble-query /usr/local/bin/ # `--model` takes a directory as readily as a Hugging Face id, and a directory # is what this is: no network, no cache layout, no revision to resolve. diff --git a/web/fonts/README.md b/web/fonts/README.md index 6ef89627..36cfdaa2 100644 --- a/web/fonts/README.md +++ b/web/fonts/README.md @@ -11,6 +11,10 @@ same faces. | `inter-latin-400.woff2` | Inter | 400 | SIL OFL 1.1, `OFL-Inter.txt` | Fontsource `@fontsource/inter`, latin subset | | `inter-latin-600.woff2` | Inter | 600 | SIL OFL 1.1, `OFL-Inter.txt` | Fontsource `@fontsource/inter`, latin subset | | `inter-latin-700.woff2` | Inter | 700 | SIL OFL 1.1, `OFL-Inter.txt` | Fontsource `@fontsource/inter`, latin subset | +| `inter-cyrillic-400.woff2` | Inter | 400 | SIL OFL 1.1, `OFL-Inter.txt` | Fontsource `@fontsource/inter` 5.3.0, cyrillic subset | +| `inter-cyrillic-700.woff2` | Inter | 700 | SIL OFL 1.1, `OFL-Inter.txt` | Fontsource `@fontsource/inter` 5.3.0, cyrillic subset | +| `inter-greek-400.woff2` | Inter | 400 | SIL OFL 1.1, `OFL-Inter.txt` | Fontsource `@fontsource/inter` 5.3.0, greek subset | +| `inter-greek-700.woff2` | Inter | 700 | SIL OFL 1.1, `OFL-Inter.txt` | Fontsource `@fontsource/inter` 5.3.0, greek subset | | `bagel-fat-one-latin-400.woff2` | Bagel Fat One | 400 | SIL OFL 1.1, `OFL-BagelFatOne.txt` | Fontsource `@fontsource/bagel-fat-one`, latin subset | | `righteous-latin-400.woff2` | Righteous | 400 | SIL OFL 1.1, `OFL-Righteous.txt` | Fontsource `@fontsource/righteous`, latin subset | | `caveat-brush-latin-400.woff2` | Caveat Brush | 400 | SIL OFL 1.1, `OFL-CaveatBrush.txt` | Fontsource `@fontsource/caveat-brush`, latin subset | @@ -18,7 +22,9 @@ same faces. | `bowlby-one-sc-latin-400.woff2` | Bowlby One SC | 400 | SIL OFL 1.1, `OFL-BowlbyOneSC.txt` | Fontsource `@fontsource/bowlby-one-sc`, latin subset | | `reenie-beanie-latin-400.woff2` | Reenie Beanie | 400 | SIL OFL 1.1, `OFL-ReenieBeanie.txt` | Fontsource `@fontsource/reenie-beanie`, latin subset | -Inter is for anything that is read. Bagel Fat One is for headings, and +Inter is for anything that is read. Its Cyrillic and Greek subsets are for +the share cards only, which have no system faces to fall back to; no page +declares them. Bagel Fat One is for headings, and `web/wordmark.svg` is drawn from it by `web/dev/wordmark.mjs`. Righteous sets the caption boxes and the readings' names; Caveat Brush the scrawled marker; and with Courier Prime and Bowlby One SC they are the scraps `web/zine.js` diff --git a/web/fonts/inter-cyrillic-400.woff2 b/web/fonts/inter-cyrillic-400.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e7583fca2f891e8f3ad0b714b2225be51ff1abf4 GIT binary patch literal 7712 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 literal 0 HcmV?d00001 diff --git a/web/fonts/inter-greek-400.woff2 b/web/fonts/inter-greek-400.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e7103fb5d82ee7b79263e028974a0fbb5c1f1e4c GIT binary patch literal 7776 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 M`~Cewv-ubp04?^+K>z>% literal 0 HcmV?d00001 diff --git a/web/fonts/inter-greek-700.woff2 b/web/fonts/inter-greek-700.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3a9fc0b9ba4ec20c1599ce319c590fd8408e76b5 GIT binary patch literal 7920 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 PUh{MR{nABY3=9kaNPj2a literal 0 HcmV?d00001