collectStyle method

Style collectStyle(
  1. int offset,
  2. int len
)

Returns style for specified text range.

Only attributes applied to all characters within this range are included in the result. Inline and line level attributes are handled separately, e.g.:

  • line attribute X is included in the result only if it exists for every line within this range (partially included lines are counted).
  • inline attribute X is included in the result only if it exists for every character within this range (line-break characters excluded).

In essence, it is INTERSECTION of each individual segment's styles

Implementation

Style collectStyle(int offset, int len) {
  final local = math.min(length - offset, len);
  var result = const Style();
  final excluded = <Attribute>{};

  void handle(Style style) {
    for (final attr in result.values) {
      if (!style.containsKey(attr.key) ||
          (style.attributes[attr.key]?.value != attr.value)) {
        excluded.add(attr);
      }
    }
    result = result.removeAll(excluded);
  }

  final data = queryChild(offset, true);
  var node = data.node as Leaf?;
  if (node != null) {
    result = node.style;
    var pos = node.length - data.offset;
    while (!node!.isLast && pos < local) {
      node = node.next as Leaf;
      handle(node.style);
      pos += node.length;
    }
  }

  /// Blank lines do not have style and must get the active style from prior line
  if (isEmpty) {
    var prevLine = previous;
    while (prevLine is Block && prevLine.isNotEmpty) {
      prevLine = prevLine.children.last;
    }
    if (prevLine is Line) {
      result = result.mergeAll(prevLine.collectStyle(prevLine.length - 1, 1));
    }
  } else {
    result = result.mergeAll(style);
  }
  if (parent is Block) {
    final block = parent as Block;
    result = result.mergeAll(block.style);
  }

  var remaining = len - local;
  var nxt = nextLine;

  /// Skip over empty lines that have no attributes
  while (remaining > 0 && nxt != null && nxt.isEmpty) {
    remaining--;
    nxt = nxt.nextLine;
  }
  if (remaining > 0 && nxt != null) {
    final rest = nxt.collectStyle(0, remaining);
    handle(rest);
  }

  return result;
}