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
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)
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
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
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()