TextPaintPlan constructor
TextPaintPlan({})
Plans the painting of letters drawn at at in a box of box, whose ink lies within ink.
Implementation
TextPaintPlan({
required ui.Size box,
required this.at,
required ui.Rect ink,
required List<Fill> fill,
required Stroke? stroke,
required List<TextEffect> effects,
}) {
final ui.Rect rect = ui.Offset.zero & box;
_box = rect;
_fills = <(Object, ui.Paint)>[for (final Fill layer in fill.reversed) fillPaint(layer, box)];
final bool fillOpaque = fill.any(isOpaque);
final List<TextInnerShadow> inner = effects.isEmpty
? const <TextInnerShadow>[]
: <TextInnerShadow>[
for (final TextEffect e in effects.reversed)
if (e is TextInnerShadow) e,
];
_innerShadows = inner;
double extent = 0;
if (stroke == null || stroke.weight == 0 || stroke.fill.isEmpty) {
_mode = .none;
} else {
final double w = stroke.weight;
// Outside and inside strokes are drawn twice as wide, then cut to one side of the outline.
final double width = stroke.align == .center ? w : 2 * w;
_mode = switch (stroke.align) {
.center => .center,
// An opaque fill hides the stroke's inner half, so drawn beneath it no cut is needed.
.outside when fillOpaque && inner.isEmpty => .under,
.outside => .outside,
.inside => .inside,
};
_strokes = <(Object, ui.Paint)>[
for (final Fill layer in stroke.fill.reversed)
((#stroke, layer, width, _placed(layer, box)), _stroking(paintFor(layer, rect), width)),
];
extent = stroke.outset;
if (extent > 0) _silhouetteStroke = 2 * extent;
// The shadows see the stroke's outer edge; an opaque one covers them.
_covered = fillOpaque && (extent == 0 || stroke.fill.any(isOpaque));
}
if (_mode == .none) _covered = fillOpaque;
_dropShadows = effects.isEmpty
? const <TextDropShadow>[]
: <TextDropShadow>[
for (final TextEffect e in effects.reversed)
if (e is TextDropShadow) e,
];
_blurs = layerBlursOf(effects);
_bounds = ink.inflate(extent + effectsReach(effects) + 1);
_placesPaints = !fill.every(_isSolid) || !(stroke?.fill.every(_isSolid) ?? true);
}