resolveFontFeaturesForVariant static method
({List<FontFeature> features, FontVariantCapsSynthesis synth})
resolveFontFeaturesForVariant(
- CSSRenderStyle renderStyle
Implementation
static ({List<ui.FontFeature> features, FontVariantCapsSynthesis synth}) resolveFontFeaturesForVariant(
CSSRenderStyle renderStyle) {
final String v = renderStyle.fontVariant;
if (v.isEmpty || v == 'normal') {
return (features: const <ui.FontFeature>[], synth: FontVariantCapsSynthesis.none);
}
if (v == 'none') {
// Treat as disabling common/contextual/discretionary/historical ligatures.
return (
features: const <ui.FontFeature>[
ui.FontFeature('liga', 0),
ui.FontFeature('clig', 0),
ui.FontFeature('calt', 0),
ui.FontFeature('dlig', 0),
ui.FontFeature('hlig', 0),
],
synth: FontVariantCapsSynthesis.none
);
}
final tokens = v.split(RegExp(r'\s+')).where((t) => t.isNotEmpty).toList();
final List<ui.FontFeature> features = <ui.FontFeature>[];
FontVariantCapsSynthesis synth = FontVariantCapsSynthesis.none;
final bool hasAllSmallCaps = tokens.contains('all-small-caps');
final bool hasSmallCaps = tokens.contains('small-caps');
final bool hasAllPetiteCaps = tokens.contains('all-petite-caps');
final bool hasPetiteCaps = tokens.contains('petite-caps');
if (hasAllSmallCaps || hasSmallCaps) {
final bool hasSmcp = supportsFontFeature(renderStyle, 'smcp');
final bool hasC2sc = hasAllSmallCaps ? supportsFontFeature(renderStyle, 'c2sc') : true;
if (hasAllSmallCaps && hasSmcp && hasC2sc) {
features.add(const ui.FontFeature.enable('smcp'));
features.add(const ui.FontFeature.enable('c2sc'));
} else if (!hasAllSmallCaps && hasSmcp) {
features.add(const ui.FontFeature.enable('smcp'));
} else {
synth = hasAllSmallCaps ? FontVariantCapsSynthesis.allLetters : FontVariantCapsSynthesis.lowercaseOnly;
}
} else if (hasAllPetiteCaps || hasPetiteCaps) {
final bool hasPcap = supportsFontFeature(renderStyle, 'pcap');
final bool hasC2pc = hasAllPetiteCaps ? supportsFontFeature(renderStyle, 'c2pc') : true;
if (hasAllPetiteCaps && hasPcap && hasC2pc) {
features.add(const ui.FontFeature.enable('pcap'));
features.add(const ui.FontFeature.enable('c2pc'));
} else if (!hasAllPetiteCaps && hasPcap) {
features.add(const ui.FontFeature.enable('pcap'));
} else {
synth = hasAllPetiteCaps ? FontVariantCapsSynthesis.allLetters : FontVariantCapsSynthesis.lowercaseOnly;
}
} else if (tokens.contains('unicase')) {
features.add(const ui.FontFeature.enable('unic'));
} else if (tokens.contains('titling-caps')) {
features.add(const ui.FontFeature.enable('titl'));
}
for (final t in tokens) {
switch (t) {
// Ligatures
case 'common-ligatures':
features.add(const ui.FontFeature.enable('liga'));
features.add(const ui.FontFeature.enable('clig'));
break;
case 'no-common-ligatures':
features.add(const ui.FontFeature('liga', 0));
features.add(const ui.FontFeature('clig', 0));
break;
case 'discretionary-ligatures':
features.add(const ui.FontFeature.enable('dlig'));
break;
case 'no-discretionary-ligatures':
features.add(const ui.FontFeature('dlig', 0));
break;
case 'historical-ligatures':
features.add(const ui.FontFeature.enable('hlig'));
break;
case 'no-historical-ligatures':
features.add(const ui.FontFeature('hlig', 0));
break;
case 'contextual':
features.add(const ui.FontFeature.enable('calt'));
break;
case 'no-contextual':
features.add(const ui.FontFeature('calt', 0));
break;
case 'historical-forms':
features.add(const ui.FontFeature.enable('hist'));
break;
// Numeric
case 'lining-nums':
features.add(const ui.FontFeature.enable('lnum'));
break;
case 'oldstyle-nums':
features.add(const ui.FontFeature.enable('onum'));
break;
case 'proportional-nums':
features.add(const ui.FontFeature.enable('pnum'));
break;
case 'tabular-nums':
features.add(const ui.FontFeature.enable('tnum'));
break;
case 'diagonal-fractions':
features.add(const ui.FontFeature.enable('frac'));
break;
case 'stacked-fractions':
features.add(const ui.FontFeature.enable('afrc'));
break;
case 'slashed-zero':
features.add(const ui.FontFeature.enable('zero'));
break;
case 'ordinal':
features.add(const ui.FontFeature.enable('ordn'));
break;
// East Asian
case 'jis78':
features.add(const ui.FontFeature.enable('jp78'));
break;
case 'jis83':
features.add(const ui.FontFeature.enable('jp83'));
break;
case 'jis90':
features.add(const ui.FontFeature.enable('jp90'));
break;
case 'jis04':
features.add(const ui.FontFeature.enable('jp04'));
break;
case 'simplified':
features.add(const ui.FontFeature.enable('smpl'));
break;
case 'traditional':
features.add(const ui.FontFeature.enable('trad'));
break;
case 'full-width':
features.add(const ui.FontFeature.enable('fwid'));
break;
case 'proportional-width':
features.add(const ui.FontFeature.enable('pwid'));
break;
case 'ruby':
features.add(const ui.FontFeature.enable('ruby'));
break;
// Position
case 'sub':
features.add(const ui.FontFeature.enable('subs'));
break;
case 'super':
features.add(const ui.FontFeature.enable('sups'));
break;
default:
break;
}
}
return (features: features, synth: synth);
}