def __init__(self, width=80, height=25, font=None, fgcolor=DEFAULTFGCOLOR, bgcolor=DEFAULTBGCOLOR, windowsurface=None, inputcursorblinking=True, inputcursorblinkspeed=1000):
        """
        Creates a new PygcurseSurface object.

        - width and height are the number of characters the the object can display.
        - font is a pygame.Font object used to display the characters. PygcurseSurface can only display one font of one size at a time. The size of the underlying pygame.Surface object is calculated from the font size and width/height accordingly. If None, then a default generic font is used.
        - fgcolor is the foreground color  (ie the color of the text). It is set to either a pygame.Color object, an RGB tuple, an RGBA tuple, or a string that is a key in the colornames dict.
        - bgcolor is the background color of the text.
        - windowSurface is optional. If None, than the user is responsible for calling the update() method on this object and blitting it's surface to the screen, and calling pygame.display.update(). If a pygame.Surface object is specified, then PygcurseSurface object handles updating automatically (unless disabled). (See the update() method for more details.)
        - inputcursorblinking is a boolean variable that tracks if the input cursor should be blinking or stay solid.
        - blinkspeed is how many milliseconds should go by before the cursor changes state (if it is blinking).
        """
        pygame.init()
        self._cursorx = 0
        self._cursory = 0
        self._cursorstack = []
        self._width = width
        self._height = height

        # The self._screen* members are 2D lists that store data for each cell of the PygcurseSurface object. _screenchar[x][y] holds the character at cell x, y. _screenfgcolor and _screenbgcolor  stores the foreground/background color of the cell, etc.
        self._screenchar = [[None] * height for i in range(width)]

        # intialize the foreground and background colors of each cell
        self._fgcolor = fgcolor
        self._bgcolor = bgcolor
        # make sure the values in _screenfgcolor and _screenbgcolor are always pygame.Color objects, and not RGB/RGBA tuples or color strings like 'blue'. Use getpygamecolor().
        self._screenfgcolor = [[None] * height for i in range(width)]
        self._screenbgcolor = [[None] * height for i in range(width)]
        for x in range(width):
            for y in range(height):
                self._screenfgcolor[x][y] = fgcolor
                self._screenbgcolor[x][y] = bgcolor

        # intialize the dirty flag for each cell to True. If the cell's dirty flag is True, then update() needs to update this cell on the self._surfaceobj pygame.Surface object.
        self._screendirty = [[True] * height for i in range(width)]

        # initalize the tinting of each cell to 0. (255 is max, -255 is minimum)
        self._rdelta = 0
        self._gdelta = 0
        self._bdelta = 0
        self._screenRdelta = [[0] * height for i in range(width)]
        self._screenGdelta = [[0] * height for i in range(width)]
        self._screenBdelta = [[0] * height for i in range(width)]

        # The "input cursor" is a separate cursor used by the input() method (and PygcurseInput objects). It tracks where the typed characters should appear. This is separate from the regular cursor which tracks where print() and putchar() should output characters. The mode can be:
        # - None, meaning there is no visible cursor
        # - 'underline', meaning a generic underscore-looking cursor
        # - 'insert', meaning a small box cursor (used when the Insert key has been pressed.)
        # - 'box', which is a box that covers the entire cell, and inverts the foreground and background colors.
        # inputcursorblinking is a boolean variable that tracks if the input cursor should be blinking or stay solid.
        self._inputcursormode = None # either None, 'underline', 'insert' or 'box'
        self.inputcursorblinking = inputcursorblinking
        self.inputcursorblinkspeed = inputcursorblinkspeed
        self._inputcursorx = 0
        self._inputcursory = 0

        self._scrollcount = 0 # the number of times writing text to the bottom row has scrolled the screen up a line.

        if font is None:
            self._font = pygame.font.Font(None, 18)
        else:
            self._font = font

        # the width and height in pixels of each cell depends on the font used.
        self._cellwidth, self._cellheight = calcfontsize(self._font) # width and height of each cell in pixels

        self._autoupdate = True
        if windowsurface == _NEW_WINDOW:
            self._windowsurface = pygame.display.set_mode((self._cellwidth * width, self._cellheight * height))
            self._managesdisplay = True
        elif windowsurface == FULLSCREEN:
            self._windowsurface = pygame.display.set_mode((self._cellwidth * width, self._cellheight * height), pygame.FULLSCREEN)
            self._managesdisplay = True
        else:
            self._windowsurface = windowsurface
            self._managesdisplay = False
        self._autodisplayupdate = self._windowsurface is not None
        self._autoblit = self._windowsurface is not None

        self._tabsize = 8 # how many spaces a tab inserts.

        # width and height of the entire surface, in pixels.
        self._pixelwidth = self._width * self._cellwidth
        self._pixelheight = self._height * self._cellheight

        self._surfaceobj = pygame.Surface((self._pixelwidth, self._pixelheight))
        self._surfaceobj = self._surfaceobj.convert_alpha() # TODO - This is needed for erasing, but does this have a performance hit?

        self.input_history = []
dataset/ETHPy150Open asweigart/pygcurse/pygcurse/__init__.py/PygcurseSurface.__init__/original