def _copy_body(self, cli, ui_content, new_screen, write_position, move_x,
                   width, vertical_scroll=0, horizontal_scroll=0,
                   has_focus=False, wrap_lines=False, highlight_lines=False,
                   vertical_scroll_2=0, always_hide_cursor=False):
        """
        Copy the UIContent into the output screen.
        """
        xpos = write_position.xpos + move_x
        ypos = write_position.ypos
        line_count = ui_content.line_count
        new_buffer = new_screen.data_buffer
        empty_char = _CHAR_CACHE['', Token]
        ZeroWidthEscape = Token.ZeroWidthEscape

        # Map visible line number to (row, col) of input.
        # 'col' will always be zero if line wrapping is off.
        visible_line_to_row_col = {}
        rowcol_to_yx = {}  # Maps (row, col) from the input to (y, x) screen coordinates.

        # Fill background with default_char first.
        default_char = ui_content.default_char

        if default_char:
            for y in range(ypos, ypos + write_position.height):
                new_buffer_row = new_buffer[y]
                for x in range(xpos, xpos + width):
                    new_buffer_row[x] = default_char

        # Copy content.
        def copy():
            y = - vertical_scroll_2
            lineno = vertical_scroll

            while y < write_position.height and lineno < line_count:
                # Take the next line and copy it in the real screen.
                line = ui_content.get_line(lineno)

                col = 0
                x = -horizontal_scroll

                visible_line_to_row_col[y] = (lineno, horizontal_scroll)
                new_buffer_row = new_buffer[y + ypos]

                for token, text in line:
                    # Remember raw VT escape sequences. (E.g. FinalTerm's
                    # escape sequences.)
                    if token == ZeroWidthEscape:
                        new_screen.zero_width_escapes[y + ypos][x + xpos] += text
                        continue

                    for c in text:
                        char = _CHAR_CACHE[c, token]
                        char_width = char.width

                        # Wrap when the line width is exceeded.
                        if wrap_lines and x + char_width > width:
                            visible_line_to_row_col[y + 1] = (
                                lineno, visible_line_to_row_col[y][1] + x)
                            y += 1
                            x = -horizontal_scroll  # This would be equal to zero.
                                                    # (horizontal_scroll=0 when wrap_lines.)
                            new_buffer_row = new_buffer[y + ypos]

                            if y >= write_position.height:
                                return y  # Break out of all for loops.

                        # Set character in screen and shift 'x'.
                        if x >= 0 and y >= 0 and x < write_position.width:
                            new_buffer_row[x + xpos] = char

                            # When we print a multi width character, make sure
                            # to erase the neighbous positions in the screen.
                            # (The empty string if different from everything,
                            # so next redraw this cell will repaint anyway.)
                            if char_width > 1:
                                for i in range(1, char_width):
                                    new_buffer_row[x + xpos + i] = empty_char

                            # If this is a zero width characters, then it's
                            # probably part of a decomposed unicode character.
                            # See: https://en.wikipedia.org/wiki/Unicode_equivalence
                            # Merge it in the previous cell.
                            elif char_width == 0 and x - 1 >= 0:
                                prev_char = new_buffer_row[x + xpos - 1]
                                char2 = _CHAR_CACHE[prev_char.char + c, prev_char.token]
                                new_buffer_row[x + xpos - 1] = char2

                            # Keep track of write position for each character.
                            rowcol_to_yx[lineno, col] = (y + ypos, x + xpos)

                        col += 1
                        x += char_width

                lineno += 1
                y += 1
            return y

        y = copy()

        def cursor_pos_to_screen_pos(row, col):
            " Translate row/col from UIContent to real Screen coordinates. "
            try:
                y, x = rowcol_to_yx[row, col]
            except KeyError:
                # Normally this should never happen. (It is a bug, if it happens.)
                # But to be sure, return (0, 0)
                return Point(y=0, x=0)

                # raise ValueError(
                #     'Invalid position. row=%r col=%r, vertical_scroll=%r, '
                #     'horizontal_scroll=%r, height=%r' %
                #     (row, col, vertical_scroll, horizontal_scroll, write_position.height))
            else:
                return Point(y=y, x=x)

        # Set cursor and menu positions.
        if ui_content.cursor_position:
            screen_cursor_position = cursor_pos_to_screen_pos(
                    ui_content.cursor_position.y, ui_content.cursor_position.x)

            if has_focus:
                new_screen.cursor_position = screen_cursor_position

                if always_hide_cursor:
                    new_screen.show_cursor = False
                else:
                    new_screen.show_cursor = ui_content.show_cursor

                self._highlight_digraph(cli, new_screen)

            if highlight_lines:
                self._highlight_cursorlines(
                    cli, new_screen, screen_cursor_position, xpos, ypos, width,
                    write_position.height)

        # Draw input characters from the input processor queue.
        if has_focus and ui_content.cursor_position:
            self._show_input_processor_key_buffer(cli, new_screen)

        # Set menu position.
        if not new_screen.menu_position and ui_content.menu_position:
            new_screen.menu_position = cursor_pos_to_screen_pos(
                    ui_content.menu_position.y, ui_content.menu_position.x)

        # Update output screne height.
        new_screen.height = max(new_screen.height, ypos + write_position.height)

        return visible_line_to_row_col, rowcol_to_yx
def _copy_body ( self , cli , ui_content , new_screen , write_position , move_x , width , vertical_scroll = 0 , horizontal_scroll = 0 , has_focus = False , wrap_lines = False , highlight_lines = False , vertical_scroll_2 = 0 , always_hide_cursor = False ) : xpos = write_position . xpos + move_x ypos = write_position . ypos line_count = ui_content . line_count new_buffer = new_screen . data_buffer empty_char = _CHAR_CACHE [ '' , Token ] ZeroWidthEscape = Token . ZeroWidthEscape visible_line_to_row_col = { } rowcol_to_yx = { } default_char = ui_content . default_char if default_char : for y in range ( ypos , ypos + write_position . height ) : new_buffer_row = new_buffer [ y ] for x in range ( xpos , xpos + width ) : new_buffer_row [ x ] = default_char def copy ( ) : y = - vertical_scroll_2 lineno = vertical_scroll while y < write_position . height and lineno < line_count : line = ui_content . get_line ( lineno ) col = 0 x = - horizontal_scroll visible_line_to_row_col [ y ] = ( lineno , horizontal_scroll ) new_buffer_row = new_buffer [ y + ypos ] for token , text in line : if token == ZeroWidthEscape : new_screen . zero_width_escapes [ y + ypos ] [ x + xpos ] += text continue for c in text : char = _CHAR_CACHE [ c , token ] char_width = char . width if wrap_lines and x + char_width > width : visible_line_to_row_col [ y + 1 ] = ( lineno , visible_line_to_row_col [ y ] [ 1 ] + x ) y += 1 x = - horizontal_scroll new_buffer_row = new_buffer [ y + ypos ] if y >= write_position . height : return y if x >= 0 and y >= 0 and x < write_position . width : new_buffer_row [ x + xpos ] = char if char_width > 1 : for i in range ( 1 , char_width ) : new_buffer_row [ x + xpos + i ] = empty_char elif char_width == 0 and x - 1 >= 0 : prev_char = new_buffer_row [ x + xpos - 1 ] char2 = _CHAR_CACHE [ prev_char . char + c , prev_char . token ] new_buffer_row [ x + xpos - 1 ] = char2 rowcol_to_yx [ lineno , col ] = ( y + ypos , x + xpos ) col += 1 x += char_width lineno += 1 y += 1 return y y = copy ( ) def cursor_pos_to_screen_pos ( row , col ) : try : y , x = rowcol_to_yx [ row , col ] except KeyError : return Point ( y = 0 , x = 0 ) else : return Point ( y = y , x = x ) if ui_content . cursor_position : screen_cursor_position = cursor_pos_to_screen_pos ( ui_content . cursor_position . y , ui_content . cursor_position . x ) if has_focus : new_screen . cursor_position = screen_cursor_position if always_hide_cursor : new_screen . show_cursor = False else : new_screen . show_cursor = ui_content . show_cursor self . _highlight_digraph ( cli , new_screen ) if highlight_lines : self . _highlight_cursorlines ( cli , new_screen , screen_cursor_position , xpos , ypos , width , write_position . height ) if has_focus and ui_content . cursor_position : self . _show_input_processor_key_buffer ( cli , new_screen ) if not new_screen . menu_position and ui_content . menu_position : new_screen . menu_position = cursor_pos_to_screen_pos ( ui_content . menu_position . y , ui_content . menu_position . x ) new_screen . height = max ( new_screen . height , ypos + write_position . height ) return visible_line_to_row_col , rowcol_to_yx
Copy the UIContent into the output screen.