parseColor static method

Color? parseColor(
  1. String color, {
  2. RenderStyle? renderStyle,
  3. String? propertyName,
})

Implementation

static Color? parseColor(String color, {RenderStyle? renderStyle, String? propertyName}) {
  String originalColor = color.trim();
  color = originalColor.toLowerCase();

  final String? prop = propertyName;
  final bool trace = prop != null && DebugFlags.shouldLogTransitionForProp(prop);

  if (trace) {
    cssLogger.info('[color][parse] property=$prop input="$originalColor" key="$color"');
  }

  if (color == TRANSPARENT) {
    if (trace) {
      cssLogger.info('[color][parse] property=$prop -> transparent');
    }
    return CSSColor.transparent;
  } else if (_cachedParsedColor.containsKey(color)) {
    if (trace) {
      cssLogger.info('[color][cache-hit] property=$prop key="$color"');
    }
    return _cachedParsedColor[color];
  }

  Color? parsed;
  if (color.startsWith('#')) {
    final String hex = color.substring(1);
    if (hex.length >= 3 && hex.length <= 8 && _isHexString(hex)) {
      final String up = hex.toUpperCase();
      switch (up.length) {
        case 3:
          parsed = Color(int.parse('0xFF${_x2(up)}'));
          break;
        case 4:
          final alpha = up[3];
          final rgb = up.substring(0, 3);
          parsed = Color(int.parse('0x${_x2(alpha)}${_x2(rgb)}'));
          break;
        case 6:
          parsed = Color(int.parse('0xFF$up'));
          break;
        case 8:
          final alpha = up.substring(6, 8);
          final rgb = up.substring(0, 6);
          parsed = Color(int.parse('0x$alpha$rgb'));
          break;
      }
    }
  } else if (color.startsWith(RGB)) {
    bool isRgba = color.startsWith(RGBA);
    String colorBody = originalColor.substring(isRgba ? 5 : 4, color.length - 1);

    final ({String r, String g, String b, String? a})? rgbArgs;
    if (renderStyle != null && colorBody.contains('var')) {
      final result = tryParserCSSColorWithVariable(originalColor, colorBody, renderStyle, propertyName ?? '');
      if (trace) {
        cssLogger
            .info('[color][parse] property=$prop rgb-body="$colorBody" resolved="$result"');
      }
      rgbArgs = _parseRgbArgs(result);
    } else {
      rgbArgs = _parseRgbArgs(colorBody);
    }

    if (rgbArgs != null) {
      final double? rgbR = _parseColorPart(rgbArgs.r, 0, 255, renderStyle);
      final double? rgbG = _parseColorPart(rgbArgs.g, 0, 255, renderStyle);
      final double? rgbB = _parseColorPart(rgbArgs.b, 0, 255, renderStyle);
      final double? rgbO = rgbArgs.a != null ? _parseColorPart(rgbArgs.a!, 0, 1, renderStyle) : 1;
      if (rgbR != null && rgbG != null && rgbB != null && rgbO != null) {
        parsed = Color.fromRGBO(rgbR.round(), rgbG.round(), rgbB.round(), rgbO);
      }
    } else if (trace) {
      cssLogger.info('[color][parse-failed] property=$prop rgb-body="$colorBody"');
    }
  } else if (color.startsWith(HSL)) {
    bool isHsla = color.startsWith(HSLA);
    String colorBody = originalColor.substring(isHsla ? 5 : 4, color.length - 1);

    final ({String hue, String? unit, String s, String l, String? a})? hslArgs;
    if (renderStyle != null && colorBody.contains('var')) {
      final result = tryParserCSSColorWithVariable(originalColor, colorBody, renderStyle, propertyName ?? '');
      if (trace) {
        cssLogger
            .info('[color][parse] property=$prop hsl-body="$colorBody" resolved="$result"');
      }
      hslArgs = _parseHslArgs(result);
    } else {
      hslArgs = _parseHslArgs(colorBody);
    }

    if (hslArgs != null) {
      final double? hslH = _parseColorHue(hslArgs.hue, hslArgs.unit);
      final double? hslS = _parseColorPart(hslArgs.s, 0, 1, renderStyle);
      final double? hslL = _parseColorPart(hslArgs.l, 0, 1, renderStyle);
      final double? hslA = hslArgs.a != null ? _parseColorPart(hslArgs.a!, 0, 1, renderStyle) : 1;
      if (hslH != null && hslS != null && hslL != null && hslA != null) {
        parsed = HSLColor.fromAHSL(hslA, hslH, hslS, hslL).toColor();
      }
    } else if (trace) {
      cssLogger.info('[color][parse-failed] property=$prop hsl-body="$colorBody"');
    }
  } else if (_namedColors.containsKey(color)) {
    parsed = Color(_namedColors[color]!);
  }

  if (parsed != null) {
    if (trace) {
      cssLogger.info(
          '[color][parsed] property=$prop rgba=${_colorByte(parsed.r)},${_colorByte(parsed.g)},${_colorByte(parsed.b)},a=${parsed.a.cssText()}');
    }
    _cachedParsedColor[color] = parsed;
  } else if (trace) {
    cssLogger.info('[color][parse-failed] property=$prop input="$originalColor" key="$color"');
  }

  return parsed;
}