createTextTheme method
TextTheme
createTextTheme(
- Typography typography,
- TextScaler textScaler,
- double scale,
- double devicePixelRatio,
Implementation
TextTheme createTextTheme(
Typography typography,
TextScaler textScaler,
double scale,
double devicePixelRatio,
) {
final tt = switch (brightness) {
(Brightness.dark) => typography.white,
(Brightness.light) => typography.black,
};
scale = scale.sizeScale;
final txtC = primary.backgroundText;
const h = null; // Respect font's settings, unless compactLineHeights.
// Each style gets a line height that fits the ink of its font, or the
// font's own line box without compactLineHeights. One place for every
// widget that takes its style from the theme. The letters are centred
// only in fonts that patchFontLineMetrics changed.
TextStyle lineHeight(TextStyle style) {
final height = compactLineHeights
? lineHeightForFontFamily(
style.fontFamily,
clearance: lineHeightClearance,
)
: naturalLineHeightForFontFamily(style.fontFamily);
if (height == null) return style;
return style.copyWith(
height: height,
leadingDistribution: TextLeadingDistribution.even,
);
}
// Normalize apparent text size across fonts. The table is generated
// offline by rasterizing a small body/UI phrase corpus for each Google
// Font, then using a composite of rendered phrase height, x-height, and a
// weak average-advance term as the visual-height metric. Theme construction
// stays synchronous and does not depend on TextPainter line boxes or runtime
// pixel readback.
final displayScale = visualHeightScaleForFontFamily(
tt.displayMedium!.fontFamily,
);
final headlineScale = visualHeightScaleForFontFamily(
tt.headlineMedium!.fontFamily,
);
final titleScale = headlineScale;
final bodyScale = visualHeightScaleForFontFamily(tt.bodyMedium!.fontFamily);
final labelScale = visualHeightScaleForFontFamily(
tt.labelMedium!.fontFamily,
);
// Sizes are logical pixels for a Roboto-equivalent visual height. The
// per-family scales above convert them for the selected fonts.
//
// bodyMedium is the reading size. 17 lp gives a Roboto x-height of about
// 15 arcminutes on phones and tablets at typical viewing distances: three
// times the 20/20 acuity limit, the size needed for fluent reading. The
// body steps use a ratio of about 1.125. Labels are short strings at a
// heavier weight, so labelMedium is one step below bodyMedium. labelLarge
// matches bodyMedium, as button text does on iOS and in Material 3.
// labelSmall stays at 14 until its uses are reviewed.
final textTheme = tt.copyWith(
displayLarge: lineHeight(
tt.displayLarge!.copyWith(
fontSize: 32 * scale * displayScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.displayLarge),
height: h,
),
),
displayMedium: lineHeight(
tt.displayMedium!.copyWith(
fontSize: 29 * scale * displayScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.displayMedium),
height: h,
),
),
displaySmall: lineHeight(
tt.displaySmall!.copyWith(
fontSize: 27 * scale * displayScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.displaySmall),
height: h,
),
),
titleLarge: lineHeight(
tt.headlineLarge!.copyWith(
fontSize: 29 * scale * titleScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.headlineLarge),
height: h,
),
),
titleMedium: lineHeight(
tt.headlineMedium!.copyWith(
fontSize: 27 * scale * titleScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.headlineMedium),
height: h,
),
),
titleSmall: lineHeight(
tt.headlineSmall!.copyWith(
fontSize: 24 * scale * titleScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.headlineSmall),
height: h,
),
),
headlineLarge: lineHeight(
tt.headlineLarge!.copyWith(
fontSize: 29 * scale * headlineScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.headlineLarge),
height: h,
),
),
headlineMedium: lineHeight(
tt.headlineMedium!.copyWith(
fontSize: 27 * scale * headlineScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.headlineMedium),
height: h,
),
),
headlineSmall: lineHeight(
tt.headlineSmall!.copyWith(
fontSize: 24 * scale * headlineScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.headlineSmall),
height: h,
),
),
bodyLarge: lineHeight(
tt.bodyLarge!.copyWith(
fontSize: 19 * scale * bodyScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.bodyLarge),
height: h,
),
),
bodyMedium: lineHeight(
tt.bodyMedium!.copyWith(
fontSize: 17 * scale * bodyScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.bodyMedium),
height: h,
),
),
bodySmall: lineHeight(
tt.bodySmall!.copyWith(
fontSize: 15 * scale * bodyScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.bodySmall),
height: h,
),
),
labelLarge: lineHeight(
tt.labelLarge!.copyWith(
fontSize: 17 * scale * labelScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.labelLarge),
height: h,
),
),
labelMedium: lineHeight(
tt.labelMedium!.copyWith(
fontSize: 15 * scale * labelScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.labelMedium),
height: h,
),
),
labelSmall: lineHeight(
tt.labelSmall!.copyWith(
fontSize: 14 * scale * labelScale,
color: txtC,
fontFamilyFallback: _mergedFontFamilyFallback(tt.labelSmall),
height: h,
),
),
);
return textTheme;
}