measure method

  1. @override
NodeLayout measure({
  1. required LatexNode node,
  2. required RenderContext context,
  3. required NodeLayout measureNode(
    1. LatexNode,
    2. RenderContext
    ),
  4. required NodeLayout measureGroup(
    1. List<LatexNode>,
    2. RenderContext
    ),
})
override

Measures a node and returns its layout.

Implementation

@override
NodeLayout measure({
  required LatexNode node,
  required RenderContext context,
  required NodeLayout Function(LatexNode, RenderContext) measureNode,
  required NodeLayout Function(List<LatexNode>, RenderContext) measureGroup,
}) {
  final substackNode = node as SubstackNode;
  if (substackNode.rows.isEmpty) {
    return NodeLayout.empty;
  }

  final substackContext = context.shrink(MathConstants.scriptScale);
  final fontSizePx = substackContext.fontSize;
  final rowSpacing = fontSizePx * 0.15;

  final rowLayouts = substackNode.rows
      .map((row) => measureGroup(row, substackContext))
      .toList();

  double maxWidth = 0.0;
  for (final layout in rowLayouts) {
    if (layout.width > maxWidth) maxWidth = layout.width;
  }

  double totalHeight = 0.0;
  final positions = <double>[];

  for (final layout in rowLayouts) {
    positions.add(totalHeight);
    totalHeight += layout.height + rowSpacing;
  }

  if (positions.isNotEmpty) totalHeight -= rowSpacing;

  final baseline = totalHeight / 2.0;

  return NodeLayout(
    width: maxWidth,
    height: totalHeight,
    baseline: baseline,
    draw: (canvas, x, y) {
      for (int i = 0; i < rowLayouts.length; i++) {
        final layout = rowLayouts[i];
        final rowX = x + (maxWidth - layout.width) / 2.0;
        layout.draw(canvas, rowX, y + positions[i]);
      }
    },
  );
}