summaryrefslogtreecommitdiff
path: root/unrpyc/renpy/display/imagelike.py
diff options
context:
space:
mode:
Diffstat (limited to 'unrpyc/renpy/display/imagelike.py')
-rw-r--r--unrpyc/renpy/display/imagelike.py382
1 files changed, 382 insertions, 0 deletions
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 <pytom@bishoujo.us>
+#
+# 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 ]
+
+