pub fn system_declared_weight(
family: &FontFamily,
weight: FontWeight,
) -> FontWeightExpand description
The weight a platform’s own matcher resolves weight to for a generic
family alias — never a value that family’s font config does not declare.
Android’s sans-serif is one variable Roboto-Regular.ttf described by
/system/etc/fonts.xml as nine <font weight="…"> entries, one per hundred,
each pinning wght to that hundred. The wght axis is therefore reachable
to the font config, not to a caller: an app asking sans-serif for 450
gets whichever declared entry Minikin’s matcher picks, and Minikin has no
way to express a weight between two entries. Instancing the axis at 450
anyway draws a face the platform cannot draw — text that measures and lays
out perfectly and is simply heavier than every other app on the device.
The rule is computeMatch in frameworks/minikin/libs/minikin/FontFamily.cpp:
int score = abs(style1.weight() / 100 - style2.weight() / 100);
if (style1.slant() != style2.slant()) score += 2;picked by getClosestMatch, which keeps a candidate only on match < bestMatch. Two consequences carry the behaviour, and both are load-bearing:
- The division is integer, so the request is truncated to its hundred before anything is compared. Against a full hundreds grid the nearest declared entry is therefore always the hundred below — 450 resolves to 400 and 550 to 500, not by a tie-break but outright, and 599 resolves to 500 too.
- Where a request does tie between two declared entries — 500 against a
serifdeclaring only 400 and 700 scores 1 and 2, but 600 scores 2 and 1, and a family declaring 300 and 500 ties at 400 — the strict<keeps the entry declared first. Android declares ascending, so a tie goes to the lighter face.
A slant mismatch costs 2, i.e. 200 weight units, which is why style never
competes with weight here: this resolves within one slant, as
SoftwareTextFontRegistry::register_system_face registers one.
Families this crate knows no system files for resolve to weight unchanged;
there is no declared set to honour, and nothing will register for them.
This applies to the system-font path alone. A face an app supplies is its own font, not an entry in the platform’s config, and stays instanceable at any axis value — that is what a variable font is for.