itemBounds function

EmRect itemBounds(
  1. DisplayItem item
)

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));
  }
}