linebender / linebender/parley
Custom Font Collection
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 736
- Forks
- 120
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 53
Description
Motivation
I am trying to render user text in arbitrary language. The app should work in both desktop and wasm.
Most languages are covered by Noto Sans CJK(5MB) + Noto Sans non-CJK megamerge (5MB), which is fine for desktop but not in web. 10MB is too bad for page load time. In Firefox, wasm cannot access the local font, so having required fonts pre-installed doesn't help.
One solution is to split the font into many smaller chunks like Google fonts api does.
Google CDN serves Noto Sans JP in 100+ chunks:
https://unpkg.com/@fontsource/noto-sans-jp@4.5.5/unicode.json
Automatic css generation for given weights / family / styles:
https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&family=Noto+Sans+JP:wght@400;700&display=swap
@font-face {
font-family: 'Noto Sans JP';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/notosansjp/v56/-F62fjtqLzI2JPCgQBnw7HFow2oe2EcP5pp0erwTqsSWs9Jezazjcb4.114.woff2) format('woff2');
unicode-range: U+3e, U+3005, U+4e0d, U+4e88, U+4ecb, U+4ee3, U+4ef6, U+4fdd, U+4fe1, U+500b, U+50cf, U+5186, U+5316, U+53d7, U+540c, U+544a, U+54e1, U+5728, U+58f2, U+5973, U+5b89, U+5c71, U+5e02, U+5e97, U+5f15, U+5fc3, U+5fdc, U+601d, U+611b, U+611f, U+671f, U+6728, U+6765, U+683c, U+6b21, U+6ce8, U+6d3b, U+6d77, U+7530, U+7740, U+7acb, U+7d50, U+826f, U+8f09, U+8fbc, U+9001, U+9053, U+91ce, U+9762, U+98df;
}
@font-face {
font-family: 'Noto Sans JP';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/notosansjp/v56/-F62fjtqLzI2JPCgQBnw7HFow2oe2EcP5pp0erwTqsSWs9Jezazjcb4.115.woff2) format('woff2');
unicode-range: U+7c, U+3080, U+4ee5, U+5148, U+516c, U+521d, U+5225, U+529b, U+52a0, U+53ef, U+56de, U+56fd, U+5909, U+591a, U+5b66, U+5b9f, U+5bb6, U+5bfe, U+5e73, U+5e83, U+5ea6, U+5f53, U+6027, U+610f, U+6210, U+6240, U+660e, U+66f4, U+66f8, U+6709, U+6771, U+697d, U+69d8, U+6a5f, U+6c34, U+6cbb, U+73fe, U+756a, U+7684, U+771f, U+793a, U+7f8e, U+898f, U+8a2d, U+8a71, U+8fd1, U+9078, U+9577, U+96fb, U+ff5e;
}
Each chunk is 1KB~50KB which is suitable for web.
Feature Request
In parley/fontique we need
- faster font lookup mechanism than naively iterating FontStack or fallback list (There are 100+ Noto Sans family, and 700+ chunks in total)
- priority between fallback fonts
// fontique-0.8.0/src/collection/query.rs
for family in self.state.families.iter_mut()
.chain(self.state.fallback_families.iter_mut()) {
// ... probe best-match + default font, callback ...
}
The definition of best-match also can get complex. I suggest to make Collection customizable with user-provided implementation.
struct MyFontCollection {
// sorted, non-overlapping ranges for binary-search
coverage: Vec<UnicodeRange, ChunkIndex>,
chunks: Vec<Font>,
}
impl parley::SomeTrait for MyFontCollection {
..
}
impl MyFontCollection {
async fn ensure(&mut self, text: .., lang: ..) {
// 1. check local font
// 2. load fonts via network
}
}
font_context.collection = Arc::new(MyFontCollection::default());
font_context.collection.ensure("abc").await; // load some chunks of Noto Sans
font_context.collection.ensure("가나다").await; // load some chunks of Noto Sans CJK
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading fontique-0.8.0/src/collection/query.rs and tracing how Collection searches families and fallback families. Clarify the requirements for customizable collection lookup, fallback priority, and loading font chunks for desktop and wasm; done means an agreed design that addresses the proposed use cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- desktop, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100