private _forEachCell()

in src/renderer/TextRenderLayer.ts [53:168]


  private _forEachCell(
    terminal: ITerminal,
    firstRow: number,
    lastRow: number,
    joinerRegistry: ICharacterJoinerRegistry | null,
    callback: (
      code: number,
      chars: string,
      width: number,
      x: number,
      y: number,
      fg: number,
      bg: number,
      flags: number
    ) => void
  ): void {
    for (let y = firstRow; y <= lastRow; y++) {
      const row = y + terminal.buffer.ydisp;
      const line = terminal.buffer.lines.get(row);
      const joinedRanges = joinerRegistry ? joinerRegistry.getJoinedCharacters(row) : [];
      for (let x = 0; x < terminal.cols; x++) {
        const charData = line.get(x);
        let code: number = <number>charData[CHAR_DATA_CODE_INDEX];

        // Can either represent character(s) for a single cell or multiple cells
        // if indicated by a character joiner.
        let chars: string = charData[CHAR_DATA_CHAR_INDEX];
        const attr: number = charData[CHAR_DATA_ATTR_INDEX];
        let width: number = charData[CHAR_DATA_WIDTH_INDEX];

        // If true, indicates that the current character(s) to draw were joined.
        let isJoined = false;
        let lastCharX = x;

        // The character to the left is a wide character, drawing is owned by
        // the char at x-1
        if (width === 0) {
          continue;
        }

        // Process any joined character ranges as needed. Because of how the
        // ranges are produced, we know that they are valid for the characters
        // and attributes of our input.
        if (joinedRanges.length > 0 && x === joinedRanges[0][0]) {
          isJoined = true;
          const range = joinedRanges.shift();

          // We already know the exact start and end column of the joined range,
          // so we get the string and width representing it directly
          chars = terminal.buffer.translateBufferLineToString(
            row,
            true,
            range[0],
            range[1]
          );
          width = range[1] - range[0];
          code = Infinity;

          // Skip over the cells occupied by this range in the loop
          lastCharX = range[1] - 1;
        }

        // If the character is an overlapping char and the character to the
        // right is a space, take ownership of the cell to the right. We skip
        // this check for joined characters because their rendering likely won't
        // yield the same result as rendering the last character individually.
        if (!isJoined && this._isOverlapping(charData)) {
          // If the character is overlapping, we want to force a re-render on every
          // frame. This is specifically to work around the case where two
          // overlaping chars `a` and `b` are adjacent, the cursor is moved to b and a
          // space is added. Without this, the first half of `b` would never
          // get removed, and `a` would not re-render because it thinks it's
          // already in the correct state.
          // this._state.cache[x][y] = OVERLAP_OWNED_CHAR_DATA;
          if (lastCharX < line.length - 1 && line.get(lastCharX + 1)[CHAR_DATA_CODE_INDEX] === NULL_CELL_CODE) {
            width = 2;
            // this._clearChar(x + 1, y);
            // The overlapping char's char data will force a clear and render when the
            // overlapping char is no longer to the left of the character and also when
            // the space changes to another character.
            // this._state.cache[x + 1][y] = OVERLAP_OWNED_CHAR_DATA;
          }
        }

        const flags = attr >> 18;
        let bg = attr & 0x1ff;
        let fg = (attr >> 9) & 0x1ff;

        // If inverse flag is on, the foreground should become the background.
        if (flags & FLAGS.INVERSE) {
          const temp = bg;
          bg = fg;
          fg = temp;
          if (fg === 256) {
            fg = INVERTED_DEFAULT_COLOR;
          }
          if (bg === 257) {
            bg = INVERTED_DEFAULT_COLOR;
          }
        }

        callback(
          code,
          chars,
          width,
          x,
          y,
          fg,
          bg,
          flags
        );

        x = lastCharX;
      }
    }
  }