createTextTheme method

TextTheme createTextTheme(
  1. Typography typography,
  2. TextScaler textScaler,
  3. double scale,
  4. 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;
}