Beispiel #1
0
    def bake(self, shape, target=None, offset=(0, 0)):
        """Apply the transformation stack for each pixel in the given shape

        Args:
          - shape: Source shape object to be processed
          - target [Optional]: optional target where final pixels are blitted into.
                If target is not given, 'shape' is modified inplace. Defaults to None.
          - offset: pixel-offset to blit the data to. Most useful with the target
          option.

        Returns:
          the affected Shape object
        """
        from terminedia.image import FullShape

        if target:
            source = shape
        else:
            # Creates a copy of all data channels, sans sprites neither transformers:
            source = FullShape.promote(shape)
            target = shape

        # if target is shape, bad things will happen for some transformers - specially Kernel based transforms

        offset = V2(offset)
        for pos, pixel in source:
            target[pos + offset] = self.process(source, pos, pixel)
        return target
Beispiel #2
0
    def _check_and_promote(self):
        """called at initialization to try to promote any object that is not a Shape
        to a Shape.

        """
        from terminedia.image import shape, Shape, FullShape
        for index, item in enumerate(self.shapes):
            if not isinstance(item, Shape):
                item = shape(item)
            if not isinstance(item, FullShape):
                item = FullShape.promote(item)
                self.shapes[index] = shape(item)
Beispiel #3
0
    def __init__(self, size=(), clear_screen=True):
        if not size:
            #: Set in runtime to a method to retrieve the screen width, height.
            #: The class is **not** aware of terminal resizings while running, though.
            self.get_size = lambda: V2(os.get_terminal_size())
            try:
                size = self.get_size()
            except OSError as error:
                if error.errno == 25:
                    logger.error(
                        "This terminal type does not allow guessing screen size."
                        "Pass an explicit (cols, rows) size when instantiating {self.__class__}"
                    )
                raise
        else:
            self.get_size = lambda: V2(size)

        #: Namespace to configure drawing and printing color and other parameters.
        #: Currently, the attributes that are used from here are
        #: ``color``, ``background``, ``direction``, ``effects`` and ``char``.
        self.context = Context()

        #: Namespace for drawing methods, containing an instance of the :any:`Drawing` class
        self.draw = Drawing(self.set_at, self.reset_at, self.get_size,
                            self.context)
        self.width, self.height = self.size = size

        #: Namespace to allow high-resolution drawing using a :any:`HighRes` instance
        #: One should either use the public methods in HighRes or the methods on the
        #: :any:`Drawing` instance at ``Screen.high.draw`` to do 1/4 block pixel
        #: manipulation.
        self.high = HighRes(self)
        self.braille = HighRes(self,
                               block_class=BrailleChars,
                               block_width=2,
                               block_height=4)

        self.text = terminedia.text.Text(self)

        #: Namespace for low-level Terminal commands, an instance of :any:`JournalingScreenCommands`.
        #: This attribute can be used as a context manager to group
        #: various screen operations in a single block that is rendered at once.
        self.commands = JournalingScreenCommands()
        self.clear_screen = clear_screen
        self.data = FullShape.new((self.width, self.height))
        # Synchronize context for data and screen painting.
        self.data.context = self.context
Beispiel #4
0
    def _check_and_promote(self, shape_specs):
        """called at initialization to try to promote any object that is not a Shape
        to a Shape.

        """
        from terminedia.image import shape, Shape, FullShape
        if isinstance(
                shape_specs,
            (str, Path, Shape, V2)) or (isinstance(shape_specs, Sequence)
                                        and len(shape_specs) == 2
                                        and isinstance(shape_specs[0], Real)):
            shape_specs = [shape_specs]
        shapes = []
        for index, item in enumerate(shape_specs):
            if not isinstance(item, Shape):
                item = shape(item)
            if not isinstance(item, FullShape):
                item = FullShape.promote(item)
            shapes.append(item)
        return shapes
Beispiel #5
0
    def __init__(self,
                 size=(),
                 clear_screen=True,
                 backend="ansi",
                 interactive=True):
        from terminedia import context as root_context

        self.interactive = interactive

        if not size:
            self.get_size = lambda: V2(os.get_terminal_size())
            try:
                size = self.get_size()
            except OSError as error:
                if error.errno == 25:
                    logger.error(
                        "This terminal type does not allow guessing screen size."
                        "Pass an explicit (cols, rows) size when instantiating {self.__class__}"
                    )
                raise
            self.dynamic_size = True
        else:
            self.get_size = lambda: V2(size)
            self.dynamic_size = False

        #: Namespace to configure drawing and printing color and other parameters.
        #: Currently, the attributes that are used from here are
        #: ``color``, ``background``, ``direction``, ``effects`` and ``char``.
        self.context = Context()

        width, height = size

        # Main data structure with image information:
        self.shape = self.data = FullShape.new(size)
        # Synchronize context for data and screen painting.
        self.data.context = self.context

        #: Namespace to allow high-resolution drawing using a :any:`HighRes` instance
        #: One should either use the public methods in HighRes or the methods on the
        #: :any:`Drawing` instance at ``Screen.high.draw`` to do 1/2, 1/4, 1/6 and 1/8 block pixel
        #: manipulation.
        self.high = HighRes(self)
        self.braille = HighRes(self,
                               block_class=BrailleChars,
                               block_width=2,
                               block_height=4)
        self.square = HighRes(self,
                              block_class=HalfChars,
                              block_width=1,
                              block_height=2)
        self.sextant = HighRes(self,
                               block_class=SextantChars,
                               block_width=2,
                               block_height=3)
        self.full = self

        self.text = terminedia.text.TextPlane(self)

        self.backend = backend = backend.upper()
        if backend == "ANSI":
            from terminedia.terminal import JournalingScreenCommands as CommandsClass
        elif backend == "HTML":
            from terminedia.html import JournalingHTMLCommands as CommandsClass
        else:
            raise ValueError(f"Unrecognized backend: {backend!r}.")

        #: Namespace for low-level rendering commands, an instance of :any:`JournalingCommandsMixin`.
        #: This attribute can be used as a context manager to group
        #: various output operations in a single block that is rendered at once.
        self.commands = CommandsClass()
        self.clear_screen = clear_screen

        self.shape.isroot = True

        #: Namespace for drawing methods, containing an instance of the :any:`Drawing` class
        self.draw = Drawing(self.set_at, self.reset_at, self.get_at,
                            self.get_size, self.context)

        self.sprites = self.data.sprites
        self.root_context = root_context
        self._last_setitem = 0
        self._init_event_system()