parameters: (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)
return_statement: return visible_line_to_row_col, rowcol_to_yx
docstring: Copy the UIContent into the output screen.
docstring_summary: Copy the UIContent into the output screen.
docstring_tokens: Copy the UIContent into the output screen .
function: 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
function_tokens: 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 # 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