itemBounds function
The painted extent of item, in em.
Implementation
EmRect itemBounds(DisplayItem item) {
switch (item) {
case GlyphItem():
final m = item.font.metrics(item.glyph);
final s = item.size;
final left = item.flipped ? item.advance - m.right * s : m.left * s;
final right = item.flipped ? item.advance - m.left * s : m.right * s;
return EmRect(
item.x + math.min(0, left),
item.y - m.height * s,
item.x + math.max(item.advance, right),
item.y + m.depth * s,
);
case RectItem():
return EmRect(item.x, item.y, item.x + item.width, item.y + item.height);
case LineItem():
final t = item.thickness / 2;
return EmRect(
math.min(item.x1, item.x2) - t,
math.min(item.y1, item.y2) - t,
math.max(item.x1, item.x2) + t,
math.max(item.y1, item.y2) + t,
);
case PathItem():
return _pathBounds(item.commands);
case FillItem():
return _pathBounds(item.commands);
case TextItem():
return EmRect(
item.x,
item.y - 0.75 * item.size,
item.x + item.width,
item.y + 0.25 * item.size,
);
case ImageItem():
return EmRect(item.x, item.y, item.x + item.width, item.y + item.height);
case CompositeItem():
return [
...item.backdrop,
...item.source,
].map(itemBounds).fold(_pathBounds(const []), (a, b) => a.union(b));
}
}