def draw()

in ebcli/bundled/asciimatics/screen.py [0:0]


    def draw(self, x, y, char=None, colour=7, bg=0, thin=False):
        """
        Draw a line from drawing cursor to the specified position.

        This uses a modified Bressenham algorithm, interpolating twice as many points to
        render down to anti-aliased characters when no character is specified,
        or uses standard algorithm plotting with the specified character.

        :param x: The column (x coord) for the location to check.
        :param y: The line (y coord) for the location to check.
        :param char: Optional character to use to draw the line.
        :param colour: Optional colour for plotting the line.
        :param bg: Optional background colour for plotting the line.
        :param thin: Optional width of anti-aliased line.
        """
        # Decide what type of line drawing to use.
        line_chars = (self._uni_line_chars if self._unicode_aware else
                      self._line_chars)

        # Define line end points.
        x0 = self._x
        y0 = self._y
        x1 = int(round(x * 2, 0))
        y1 = int(round(y * 2, 0))

        # Remember last point for next line.
        self._x = x1
        self._y = y1

        # Don't bother drawing anything if we're guaranteed to be off-screen
        if ((x0 < 0 and x1 < 0) or (x0 >= self.width * 2 and x1 >= self.width * 2) or
                (y0 < 0 and y1 < 0) or (y0 >= self.height * 2 and y1 >= self.height * 2)):
            return

        dx = abs(x1 - x0)
        dy = abs(y1 - y0)

        sx = -1 if x0 > x1 else 1
        sy = -1 if y0 > y1 else 1

        def _get_start_char(cx, cy):
            needle = self.get_from(cx, cy)
            if needle is not None:
                letter, cfg, _, cbg = needle
                if colour == cfg and bg == cbg and chr(letter) in line_chars:
                    return line_chars.find(chr(letter))
            return 0

        def _fast_fill(start_x, end_x, iy):
            next_char = -1
            for ix in range(start_x, end_x):
                if ix % 2 == 0 or next_char == -1:
                    next_char = _get_start_char(ix // 2, iy // 2)
                next_char |= 2 ** abs(ix % 2) * 4 ** (iy % 2)
                if ix % 2 == 1:
                    self.print_at(line_chars[next_char], ix // 2, iy // 2, colour, bg=bg)
            if end_x % 2 == 1:
                self.print_at(line_chars[next_char], end_x // 2, iy // 2, colour, bg=bg)

        def _draw_on_x(ix, iy):
            err = dx
            px = ix - 2
            py = iy - 2
            next_char = 0
            while ix != x1:
                if ix < px or ix - px >= 2 or iy < py or iy - py >= 2:
                    px = ix & ~1
                    py = iy & ~1
                    next_char = _get_start_char(px // 2, py // 2)
                next_char |= 2 ** abs(ix % 2) * 4 ** (iy % 2)
                err -= 2 * dy
                if err < 0:
                    iy += sy
                    err += 2 * dx
                ix += sx

                if char is None:
                    self.print_at(line_chars[next_char],
                                  px // 2, py // 2, colour, bg=bg)
                else:
                    self.print_at(char, px // 2, py // 2, colour, bg=bg)

        def _draw_on_y(ix, iy):
            err = dy
            px = ix - 2
            py = iy - 2
            next_char = 0
            while iy != y1:
                if ix < px or ix - px >= 2 or iy < py or iy - py >= 2:
                    px = ix & ~1
                    py = iy & ~1
                    next_char = _get_start_char(px // 2, py // 2)
                next_char |= 2 ** abs(ix % 2) * 4 ** (iy % 2)
                err -= 2 * dx
                if err < 0:
                    ix += sx
                    err += 2 * dy
                iy += sy

                if char is None:
                    self.print_at(line_chars[next_char],
                                  px // 2, py // 2, colour, bg=bg)
                else:
                    self.print_at(char, px // 2, py // 2, colour, bg=bg)

        if dy == 0 and thin and char is None:
            # Fast-path for polygon filling
            _fast_fill(min(x0, x1), max(x0, x1), y0)
        elif dx > dy:
            _draw_on_x(x0, y0)
            if not thin:
                _draw_on_x(x0, y0 + 1)
        else:
            _draw_on_y(x0, y0)
            if not thin:
                _draw_on_y(x0 + 1, y0)