public final void render(TerminalEmulator mEmulator,Canvas canvas,int topRow,int selectionY1,int selectionY2,int selectionX1,int selectionX2){
  final boolean reverseVideo=mEmulator.isReverseVideo();
  final int endRow=topRow + mEmulator.mRows;
  final int columns=mEmulator.mColumns;
  final int cursorCol=mEmulator.getCursorCol();
  final int cursorRow=mEmulator.getCursorRow();
  final boolean cursorVisible=mEmulator.isShowingCursor();
  final TerminalBuffer screen=mEmulator.getScreen();
  final int[] palette=mEmulator.mColors.mCurrentColors;
  if (reverseVideo)   canvas.drawColor(palette[TextStyle.COLOR_INDEX_FOREGROUND],PorterDuff.Mode.SRC);
  float heightOffset=mFontLineSpacingAndAscent;
  for (int row=topRow; row < endRow; row++) {
    heightOffset+=mFontLineSpacing;
    final int cursorX=(row == cursorRow && cursorVisible) ? cursorCol : -1;
    int selx1=-1, selx2=-1;
    if (row >= selectionY1 && row <= selectionY2) {
      if (row == selectionY1)       selx1=selectionX1;
      selx2=(row == selectionY2) ? selectionX2 : mEmulator.mColumns;
    }
    TerminalRow lineObject=screen.allocateFullLineIfNecessary(screen.externalToInternalRow(row));
    final char[] line=lineObject.mText;
    final int charsUsedInLine=lineObject.getSpaceUsed();
    long lastRunStyle=0;
    boolean lastRunInsideCursor=false;
    int lastRunStartColumn=-1;
    int lastRunStartIndex=0;
    boolean lastRunFontWidthMismatch=false;
    int currentCharIndex=0;
    float measuredWidthForRun=0.f;
    for (int column=0; column < columns; ) {
      final char charAtIndex=line[currentCharIndex];
      final boolean charIsHighsurrogate=Character.isHighSurrogate(charAtIndex);
      final int charsForCodePoint=charIsHighsurrogate ? 2 : 1;
      final int codePoint=charIsHighsurrogate ? Character.toCodePoint(charAtIndex,line[currentCharIndex + 1]) : charAtIndex;
      final int codePointWcWidth=WcWidth.width(codePoint);
      final boolean insideCursor=(column >= selx1 && column <= selx2) || (cursorX == column || (codePointWcWidth == 2 && cursorX == column + 1));
      final long style=lineObject.getStyle(column);
      final float measuredCodePointWidth=(codePoint < asciiMeasures.length) ? asciiMeasures[codePoint] : mTextPaint.measureText(line,currentCharIndex,charsForCodePoint);
      final boolean fontWidthMismatch=Math.abs(measuredCodePointWidth / mFontWidth - codePointWcWidth) > 0.01;
      if (style != lastRunStyle || insideCursor != lastRunInsideCursor || fontWidthMismatch || lastRunFontWidthMismatch) {
        if (column == 0) {
        }
 else {
          final int columnWidthSinceLastRun=column - lastRunStartColumn;
          final int charsSinceLastRun=currentCharIndex - lastRunStartIndex;
          drawTextRun(canvas,line,palette,heightOffset,lastRunStartColumn,columnWidthSinceLastRun,lastRunStartIndex,charsSinceLastRun,measuredWidthForRun,lastRunInsideCursor,lastRunStyle,reverseVideo);
        }
        measuredWidthForRun=0.f;
        lastRunStyle=style;
        lastRunInsideCursor=insideCursor;
        lastRunStartColumn=column;
        lastRunStartIndex=currentCharIndex;
        lastRunFontWidthMismatch=fontWidthMismatch;
      }
      measuredWidthForRun+=measuredCodePointWidth;
      column+=codePointWcWidth;
      currentCharIndex+=charsForCodePoint;
      while (currentCharIndex < charsUsedInLine && WcWidth.width(line,currentCharIndex) <= 0) {
        currentCharIndex+=Character.isHighSurrogate(line[currentCharIndex]) ? 2 : 1;
      }
    }
    final int columnWidthSinceLastRun=columns - lastRunStartColumn;
    final int charsSinceLastRun=currentCharIndex - lastRunStartIndex;
    drawTextRun(canvas,line,palette,heightOffset,lastRunStartColumn,columnWidthSinceLastRun,lastRunStartIndex,charsSinceLastRun,measuredWidthForRun,lastRunInsideCursor,lastRunStyle,reverseVideo);
  }
}

public final void render ( TerminalEmulator mEmulator , Canvas canvas , int topRow , int selectionY1 , int selectionY2 , int selectionX1 , int selectionX2 ) { final boolean reverseVideo = mEmulator . isReverseVideo ( ) ; final int endRow = topRow + mEmulator . mRows ; final int columns = mEmulator . mColumns ; final int cursorCol = mEmulator . getCursorCol ( ) ; final int cursorRow = mEmulator . getCursorRow ( ) ; final boolean cursorVisible = mEmulator . isShowingCursor ( ) ; final TerminalBuffer screen = mEmulator . getScreen ( ) ; final int [ ] palette = mEmulator . mColors . mCurrentColors ; if ( reverseVideo ) canvas . drawColor ( palette [ TextStyle . COLOR_INDEX_FOREGROUND ] , PorterDuff . Mode . SRC ) ; float heightOffset = mFontLineSpacingAndAscent ; for ( int row = topRow ; row < endRow ; row ++ ) { heightOffset += mFontLineSpacing ; final int cursorX = ( row == cursorRow && cursorVisible ) ? cursorCol : - 1 ; int selx1 = - 1 , selx2 = - 1 ; if ( row >= selectionY1 && row <= selectionY2 ) { if ( row == selectionY1 ) selx1 = selectionX1 ; selx2 = ( row == selectionY2 ) ? selectionX2 : mEmulator . mColumns ; } TerminalRow lineObject = screen . allocateFullLineIfNecessary ( screen . externalToInternalRow ( row ) ) ; final char [ ] line = lineObject . mText ; final int charsUsedInLine = lineObject . getSpaceUsed ( ) ; long lastRunStyle = 0 ; boolean lastRunInsideCursor = false ; int lastRunStartColumn = - 1 ; int lastRunStartIndex = 0 ; boolean lastRunFontWidthMismatch = false ; int currentCharIndex = 0 ; float measuredWidthForRun = 0.f ; for ( int column = 0 ; column < columns ; ) { final char charAtIndex = line [ currentCharIndex ] ; final boolean charIsHighsurrogate = Character . isHighSurrogate ( charAtIndex ) ; final int charsForCodePoint = charIsHighsurrogate ? 2 : 1 ; final int codePoint = charIsHighsurrogate ? Character . toCodePoint ( charAtIndex , line [ currentCharIndex + 1 ] ) : charAtIndex ; final int codePointWcWidth = WcWidth . width ( codePoint ) ; final boolean insideCursor = ( column >= selx1 && column <= selx2 ) || ( cursorX == column || ( codePointWcWidth == 2 && cursorX == column + 1 ) ) ; final long style = lineObject . getStyle ( column ) ; final float measuredCodePointWidth = ( codePoint < asciiMeasures . length ) ? asciiMeasures [ codePoint ] : mTextPaint . measureText ( line , currentCharIndex , charsForCodePoint ) ; final boolean fontWidthMismatch = Math . abs ( measuredCodePointWidth / mFontWidth - codePointWcWidth ) > 0.01 ; if ( style != lastRunStyle || insideCursor != lastRunInsideCursor || fontWidthMismatch || lastRunFontWidthMismatch ) { if ( column == 0 ) { } else { final int columnWidthSinceLastRun = column - lastRunStartColumn ; final int charsSinceLastRun = currentCharIndex - lastRunStartIndex ; drawTextRun ( canvas , line , palette , heightOffset , lastRunStartColumn , columnWidthSinceLastRun , lastRunStartIndex , charsSinceLastRun , measuredWidthForRun , lastRunInsideCursor , lastRunStyle , reverseVideo ) ; } measuredWidthForRun = 0.f ; lastRunStyle = style ; lastRunInsideCursor = insideCursor ; lastRunStartColumn = column ; lastRunStartIndex = currentCharIndex ; lastRunFontWidthMismatch = fontWidthMismatch ; } measuredWidthForRun += measuredCodePointWidth ; column += codePointWcWidth ; currentCharIndex += charsForCodePoint ; while ( currentCharIndex < charsUsedInLine && WcWidth . width ( line , currentCharIndex ) <= 0 ) { currentCharIndex += Character . isHighSurrogate ( line [ currentCharIndex ] ) ? 2 : 1 ; } } final int columnWidthSinceLastRun = columns - lastRunStartColumn ; final int charsSinceLastRun = currentCharIndex - lastRunStartIndex ; drawTextRun ( canvas , line , palette , heightOffset , lastRunStartColumn , columnWidthSinceLastRun , lastRunStartIndex , charsSinceLastRun , measuredWidthForRun , lastRunInsideCursor , lastRunStyle , reverseVideo ) ; } }
render the terminal to a canvas with at a specified row scroll , and an optional rectangular selection .
