build static method

Future<UPdfShadingPaint?> build(
  1. UPdfDocument document,
  2. UPdfDict shading, {
  3. UPdfDict? resources,
})

Implementation

static Future<UPdfShadingPaint?> build(UPdfDocument document, UPdfDict shading, {UPdfDict? resources}) async {
  try {
    final int type = ((await document.resolve(shading["ShadingType"])) as num?)?.toInt() ?? 0;
    final UPdfColorSpace space = await UPdfColorSpace.load(document, shading["ColorSpace"], resources: resources);
    final UPdfFunction? function = await UPdfFunction.load(document, shading["Function"]);
    final List<double> coords = <double>[];
    final Object? coordsObject = await document.resolve(shading["Coords"]);
    if (coordsObject is List<Object?>) {
      for (final Object? entry in coordsObject) {
        final Object? value = await document.resolve(entry);
        if (value is num) coords.add(value.toDouble());
      }
    }
    final List<double> domain = <double>[0, 1];
    final Object? domainObject = await document.resolve(shading["Domain"]);
    if (domainObject is List<Object?> && domainObject.length >= 2) {
      for (int i = 0; i < 2; i++) {
        final Object? value = await document.resolve(domainObject[i]);
        if (value is num) domain[i] = value.toDouble();
      }
    }
    final List<bool> extend = <bool>[false, false];
    final Object? extendObject = await document.resolve(shading["Extend"]);
    if (extendObject is List<Object?> && extendObject.length >= 2) {
      extend[0] = extendObject[0] as bool? ?? false;
      extend[1] = extendObject[1] as bool? ?? false;
    }
    const int steps = 64;
    final List<Color> colors = <Color>[];
    final List<double> stops = <double>[];
    for (int i = 0; i < steps; i++) {
      final double t = i / (steps - 1);
      final double value = domain[0] + t * (domain[1] - domain[0]);
      final List<double> components = function?.evaluate(<double>[value]) ?? <double>[value];
      colors.add(space.color(components));
      stops.add(t);
    }
    if (type == 2 && coords.length >= 4) {
      return UPdfShadingPaint(
        shader: ui.Gradient.linear(
          Offset(coords[0], coords[1]),
          Offset(coords[2], coords[3]),
          colors,
          stops,
          extend[0] || extend[1] ? TileMode.clamp : TileMode.decal,
        ),
      );
    }
    if (type == 3 && coords.length >= 6) {
      final double r0 = coords[2];
      final double r1 = coords[5];
      final Offset center = Offset(coords[3], coords[4]);
      final Offset focal = Offset(coords[0], coords[1]);
      final double radius = r1 > r0 ? r1 : r0;
      if (radius <= 0) return UPdfShadingPaint(fallback: colors.isEmpty ? null : colors.last);
      return UPdfShadingPaint(
        shader: ui.Gradient.radial(
          center,
          radius,
          r1 >= r0 ? colors : colors.reversed.toList(),
          stops,
          extend[0] || extend[1] ? TileMode.clamp : TileMode.decal,
          null,
          focal,
          r0 < r1 ? r0 / radius : r1 / radius,
        ),
      );
    }
    final Color average = _average(colors);
    return UPdfShadingPaint(fallback: average);
  } on Object {
    return null;
  }
}