From 718936110b9511631fa1f4396be992752bf8b719 Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Thu, 22 Aug 2013 22:45:26 -0400 Subject: include renpy --- unrpyc/renpy/display/imagelike.py | 382 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 unrpyc/renpy/display/imagelike.py (limited to 'unrpyc/renpy/display/imagelike.py') diff --git a/unrpyc/renpy/display/imagelike.py b/unrpyc/renpy/display/imagelike.py new file mode 100644 index 0000000..aea1d15 --- /dev/null +++ b/unrpyc/renpy/display/imagelike.py @@ -0,0 +1,382 @@ +# Copyright 2004-2013 Tom Rothamel +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import renpy.display +from renpy.display.render import render, Render, Matrix2D + +# This file contains displayables that are image-like, because they take +# up a rectangular area of the screen, and do not respond to input. + +class Solid(renpy.display.core.Displayable): + """ + :doc: disp_imagelike + + A displayable that fills the area its assigned with `color`. + + :: + + image white = Solid("#fff") + + """ + + def __init__(self, color, **properties): + + super(Solid, self).__init__(**properties) + + if color is not None: + self.color = renpy.easy.color(color) + else: + self.color = None + + def visit(self): + return [ ] + + def render(self, width, height, st, at): + + color = self.color or self.style.color + + rv = Render(width, height) + + if color is None or width <= 0 or height <= 0: + return rv + + SIZE = 10 + + if width < SIZE or height < SIZE: + tex = renpy.display.draw.solid_texture(width, height, color) + else: + tex = renpy.display.draw.solid_texture(SIZE, SIZE, color) + rv.forward = Matrix2D(1.0 * SIZE / width, 0, 0, 1.0 * SIZE / height) + rv.reverse = Matrix2D(1.0 * width / SIZE, 0, 0, 1.0 * height / SIZE) + + rv.blit(tex, (0, 0)) + + return rv + +class Frame(renpy.display.core.Displayable): + """ + :doc: disp_imagelike + :args: (image, xborder, yborder, tile=False, **properties) + + A displayable that resizes an image to fill the available area, + while preserving the width and height of its borders. is often + used as the background of a window or button. + + .. figure:: frame_example.png + + Using a frame to resize an image to double its size. + + `image` + An image manipulator that will be resized by this frame. + + `left` + The size of the border on the left side. + + `top` + The size of the border on the top. + + `right` + The size of the border on the right side. If None, defaults + to `left`. + + `bottom` + The side of the border on the bottom. If None, defaults to `top`. + + `tile` + If true, tiling is used to resize sections of the image, + rather than scaling. + + :: + + # Resize the background of the text window if it's too small. + init python: + style.window.background = Frame("frame.png", 10, 10) + """ + + __version__ = 1 + + def after_upgrade(self, version): + if version < 2: + self.left = self.xborder + self.right = self.xborder + self.top = self.yborder + self.bottom = self.yborder + + def __init__(self, image, left, top, right=None, bottom=None, bilinear=True, tile=False, **properties): + super(Frame, self).__init__(**properties) + + self.image = renpy.easy.displayable(image) + self.tile = tile + + if right is None: + right = left + if bottom is None: + bottom = top + + self.left = left + self.top = top + self.right = right + self.bottom = bottom + + def render(self, width, height, st, at): + + crend = render(self.image, width, height, st, at) + + sw, sh = crend.get_size() + sw = int(sw) + sh = int(sh) + + dw = int(width) + dh = int(height) + + bw = self.left + self.right + bh = self.top + self.bottom + + xborder = min(bw, sw - 2, dw) + if xborder: + left = self.left * xborder / bw + right = self.right * xborder / bw + else: + left = 0 + right = 0 + + yborder = min(bh, sh - 2, dh) + if yborder: + top = self.top * yborder / bh + bottom = self.bottom * yborder / bh + else: + top = 0 + bottom = 0 + + if renpy.display.draw.info["renderer"] == "sw": + return self.sw_render(crend, dw, dh, left, top, right, bottom) + + def draw(x0, x1, y0, y1): + + # Compute the coordinates of the left, right, top, and + # bottom sides of the region, for both the source and + # destination surfaces. + + # left side. + if x0 >= 0: + dx0 = x0 + sx0 = x0 + else: + dx0 = dw + x0 + sx0 = sw + x0 + + # right side. + if x1 > 0: + dx1 = x1 + sx1 = x1 + else: + dx1 = dw + x1 + sx1 = sw + x1 + + # top side. + if y0 >= 0: + dy0 = y0 + sy0 = y0 + else: + dy0 = dh + y0 + sy0 = sh + y0 + + # bottom side + if y1 > 0: + dy1 = y1 + sy1 = y1 + else: + dy1 = dh + y1 + sy1 = sh + y1 + + # Quick exit. + if sx0 == sx1 or sy0 == sy1: + return + + # Compute sizes. + csw = sx1 - sx0 + csh = sy1 - sy0 + cdw = dx1 - dx0 + cdh = dy1 - dy0 + + if csw <= 0 or csh <= 0 or cdh <= 0 or cdw <= 0: + return + + # Get a subsurface. + cr = crend.subsurface((sx0, sy0, csw, csh)) + + # Scale or tile if we have to. + if csw != cdw or csh != cdh: + + if self.tile: + newcr = Render(cdw, cdh) + newcr.clipping = True + + for x in range(0, cdw, csw): + for y in range(0, cdh, csh): + newcr.blit(cr, (x, y)) + + cr = newcr + + else: + + newcr = Render(cdw, cdh) + newcr.forward = Matrix2D(1.0 * csw / cdw, 0, 0, 1.0 * csh / cdh) + newcr.reverse = Matrix2D(1.0 * cdw / csw, 0, 0, 1.0 * cdh / csh) + newcr.blit(cr, (0, 0)) + + cr = newcr + + # Blit. + rv.blit(cr, (dx0, dy0)) + return + + rv = Render(dw, dh) + + self.draw_pattern(draw, left, top, right, bottom) + + return rv + + def draw_pattern(self, draw, left, top, right, bottom): + # Top row. + if top: + + if left: + draw(0, left, 0, top) + + draw(left, -right, 0, top) + + if right: + draw(-right, 0, 0, top) + + # Middle row. + if left: + draw(0, left, top, -bottom) + + draw(left, -right, top, -bottom) + + if right: + draw(-right, 0, top, -bottom) + + # Bottom row. + if bottom: + if left: + draw(0, left, -bottom, 0) + + draw(left, -right, -bottom, 0) + + if right: + draw(-right, 0, -bottom, 0) + + + + def sw_render(self, crend, dw, dh, left, top, right, bottom): + + source = crend.render_to_texture(True) + sw, sh = source.get_size() + + dest = renpy.display.swdraw.surface(dw, dh, True) + rv = dest + + def draw(x0, x1, y0, y1): + + # Compute the coordinates of the left, right, top, and + # bottom sides of the region, for both the source and + # destination surfaces. + + # left side. + if x0 >= 0: + dx0 = x0 + sx0 = x0 + else: + dx0 = dw + x0 + sx0 = sw + x0 + + # right side. + if x1 > 0: + dx1 = x1 + sx1 = x1 + else: + dx1 = dw + x1 + sx1 = sw + x1 + + # top side. + if y0 >= 0: + dy0 = y0 + sy0 = y0 + else: + dy0 = dh + y0 + sy0 = sh + y0 + + # bottom side + if y1 > 0: + dy1 = y1 + sy1 = y1 + else: + dy1 = dh + y1 + + sy1 = sh + y1 + + # Quick exit. + if sx0 == sx1 or sy0 == sy1 or dx1 <= dx0 or dy1 <= dy0: + return + + # Compute sizes. + srcsize = (sx1 - sx0, sy1 - sy0) + dstsize = (int(dx1 - dx0), int(dy1 - dy0)) + + # Get a subsurface. + surf = source.subsurface((sx0, sy0, srcsize[0], srcsize[1])) + + # Scale or tile if we have to. + if dstsize != srcsize: + if self.tile: + tilew, tileh = srcsize + dstw, dsth = dstsize + + surf2 = renpy.display.pgrender.surface_unscaled(dstsize, surf) + + for y in range(0, dsth, tileh): + for x in range(0, dstw, tilew): + surf2.blit(surf, (x, y)) + + surf = surf2 + + else: + surf2 = renpy.display.scale.real_transform_scale(surf, dstsize) + surf = surf2 + + # Blit. + dest.blit(surf, (dx0, dy0)) + + self.draw_pattern(draw, left, top, right, bottom) + + rrv = renpy.display.render.Render(dw, dh) + rrv.blit(rv, (0, 0)) + rrv.depends_on(crend) + + # And, finish up. + return rrv + + def visit(self): + return [ self.image ] + + -- cgit v1.2.3-54-g00ecf