collectStyle method

NotusStyle collectStyle(
  1. int offset,
  2. int length
)

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).

Implementation

NotusStyle collectStyle(int offset, int length) {
  final local = math.min(this.length - offset, length);

  var result = NotusStyle();
  final excluded = <NotusAttribute>{};

  void _handle(NotusStyle style) {
    if (result.isEmpty) {
      excluded.addAll(style.values);
    } else {
      for (var attr in result.values) {
        if (!style.contains(attr)) {
          excluded.add(attr);
        }
      }
    }
    final remaining = style.removeAll(excluded);
    result = result.removeAll(excluded);
    result = result.mergeAll(remaining);
  }

  final data = lookup(offset, inclusive: true);
  LeafNode? node = data.node as LeafNode?;
  if (node != null) {
    result = result.mergeAll(node.style);
    var pos = node.length - data.offset;
    while (!node!.isLast && pos < local) {
      node = node.next as LeafNode?;
      _handle(node!.style);
      pos += node.length;
    }
  }

  result = result.mergeAll(style);
  if (parent is BlockNode) {
    BlockNode block = parent as BlockNode;
    result = result.mergeAll(block.style);
  }

  final remaining = length - local;
  if (remaining > 0) {
    final rest = nextLine!.collectStyle(0, remaining);
    _handle(rest);
  }

  return result;
}