def polygon(self, surface, color, pointlist, width=0): """ Draw polygon shape, and returns bounding Rect. Argument include surface to draw, color, and pointlist. Optional width argument of outline, which defaults to 0 for filled shape. """ surface.beginPath() surface.moveTo(*pointlist[0]) for point in pointlist[1:]: surface.lineTo(*point) surface.closePath() if width: surface.setLineWidth(width) if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.stroke() else: if hasattr(color, 'a'): surface.setFillStyle(color) else: surface.setFillStyle(Color(color)) surface.fill() xpts = [pt[0] for pt in pointlist] ypts = [pt[1] for pt in pointlist] xmin, xmax = min(xpts), max(xpts) ymin, ymax = min(ypts), max(ypts) if surface._display: return surface._display._surface_rect.clip( Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)) else: return surface.get_rect().clip( Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1))
def render(self, text, antialias=True, color=(0, 0, 0), background=None, surface=None): #optional surface for text rendering """ Render text onto surface. Arguments are text to render, and optional antialias, RGB color of text, RGB color of background, and surface for text rendering. """ if not surface: w, h = self.size(text) surf = Surface((w, h)) else: surf = surface w, h = surface.width, surface.height if background: surf.setFillStyle(Color(background)) surf.fillRect(0, 0, w, h) surf.setFont('%s %dpx %s' % (self.fontstyle, self.fontsize, self.fontname)) # if antialias: pass surf.setFillStyle(Color(color)) surf.setTextAlign('center') surf.setTextBaseline('middle') surf.fillText(text, w / 2, h / 2) if self.underline: surf.setLineWidth(self.fontsize / 20) surf.setStrokeStyle(Color(color)) surf.beginPath() surf.moveTo(0, h * 0.85) surf.lineTo(w, h * 0.85) surf.stroke() return surf
def arc(self, surface, color, rect, start_angle, stop_angle, width=1): """ Draw arc shape, and returns bounding Rect. Argument include surface to draw, color, rect, start_angle, stop_angle. Optional width argument of outline. """ if hasattr(rect, 'width'): _rect = rect else: _rect = Rect(rect) if _rect.width == _rect.height: surface.beginPath() surface.arc(_rect.x + int(_rect.width / 2), _rect.y + int(_rect.height / 2), int(_rect.width / 2), -start_angle, -stop_angle, True) if width: surface.setLineWidth(width) if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.stroke() else: surface.closePath() if hasattr(color, 'a'): surface.setFillStyle(color) else: surface.setFillStyle(Color(color)) surface.fill() else: surface.saveContext() surface.translate(_rect.x + int(_rect.width / 2), _rect.y + int(_rect.height / 2)) if _rect.width >= _rect.height: surface.scale(_rect.width / (_rect.height * 1.0), 1) radius = _rect.height / 2 else: surface.scale(1, _rect.height / (_rect.width * 1.0)) radius = _rect.width / 2 surface.beginPath() surface.arc(0, 0, radius, -start_angle, -stop_angle, True) if width: surface.setLineWidth(width) if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.stroke() else: surface.closePath() if hasattr(color, 'a'): surface.setFillStyle(color) else: surface.setFillStyle(Color(color)) surface.fill() surface.restoreContext() if surface._display: return surface._display._surface_rect.clip(_rect) else: return surface.get_rect().clip(_rect)
def circle(self, surface, color, position, radius, width=0): """ Draw circular shape, and returns bounding Rect. Argument include surface to draw, color, position and radius. Optional width argument of outline, which defaults to 0 for filled shape. """ surface.beginPath() surface.arc(position[0], position[1], radius, 0, 2 * _pi, False) if width: surface.setLineWidth(width) if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.stroke() else: if hasattr(color, 'a'): surface.setFillStyle(color) else: surface.setFillStyle(Color(color)) surface.fill() if surface._display: return surface._display._surface_rect.clip( Rect(position[0] - radius, position[1] - radius, 2 * radius, 2 * radius)) else: return surface.get_rect().clip( Rect(position[0] - radius, position[1] - radius, 2 * radius, 2 * radius))
def create_cursor(size, data, mask): """ Create cursor image from binary data. Arguments cursor size and its binary data and mask. Return surface, can be used with mouse.set_cursor. """ surface = Surface(size, Const.SRCALPHA) black = Color(0, 0, 0, 255) white = Color(255, 255, 255, 255) x = y = 0 rang = range(8) for i in range(len(data)): if data[i] or mask[i]: for j in rang: if data[i] & 0x01 << 7 - j: surface.setFillStyle(black) surface.fillRect(x + j, y, 1, 1) elif mask[i] & 0x01 << 7 - j: surface.setFillStyle(white) surface.fillRect(x + j, y, 1, 1) x += 8 if x >= size[0]: x = 0 y += 1 return surface
def rect(self, surface, color, rect, width=0): """ Draw rectangle shape, and returns bounding Rect. Argument include surface to draw, color, Rect. Optional width argument of outline, which defaults to 0 for filled shape. """ if hasattr(rect, 'width'): _rect = rect else: _rect = Rect(rect) if width: surface.setLineWidth(width) if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.strokeRect(_rect.x, _rect.y, _rect.width, _rect.height) else: if hasattr(color, 'a'): surface.setFillStyle(color) else: surface.setFillStyle(Color(color)) surface.fillRect(_rect.x, _rect.y, _rect.width, _rect.height) if surface._display: return surface._display._surface_rect.clip(_rect) else: return surface.get_rect().clip(_rect)
def from_threshold(surface, color, threshold=(0, 0, 0, 255)): """ **pyjsdl.mask.from_threshold** Return Mask from surface using a given color. Optional threshold argument to set color range and alpha threshold. """ mask = Mask((surface.width, surface.height)) if not mask.bit: return None imagedata = surface.getImageData(0, 0, surface.width, surface.height) data = imagedata.data if threshold == (0, 0, 0, 255): color = Color(color) width, height = surface.width * 4, surface.height for y in range(0, height): xpix = 0 i = y * width bitset = mask.bit[y] bit = bitset._bit _data = bitset._data._data for x in range(0, width, 4): ix = i + x if (data[ix] == color.r and data[ix + 1] == color.g and data[ix + 2] == color.b and data[ix + 3] >= threshold[3]): index = ~(~(xpix / bit)) _data[index] = _data[index] | bitset._bitmask[xpix % bit] xpix += 1 else: color = Color(color) col = {} col['r1'] = color.r - threshold[0] - 1 col['r2'] = color.r + threshold[0] + 1 col['g1'] = color.g - threshold[1] - 1 col['g2'] = color.g + threshold[1] + 1 col['b1'] = color.b - threshold[2] - 1 col['b2'] = color.b + threshold[2] + 1 col['a'] = threshold[3] - 1 width, height = surface.width * 4, surface.height for y in range(0, height): xpix = 0 i = y * width bitset = mask.bit[y] bit = bitset._bit _data = bitset._data._data for x in range(0, width, 4): ix = i + x if ((col['r1'] < data[ix] < col['r2']) and (col['g1'] < data[ix + 1] < col['g2']) and (col['b1'] < data[ix + 2] < col['b2']) and (data[ix + 3] > col['a'])): index = ~(~(xpix / bit)) _data[index] = _data[index] | bitset._bitmask[xpix % bit] xpix += 1 return mask
def from_threshold(surface, color, threshold=(0, 0, 0, 255)): """ **pyjsdl.mask.from_threshold** Return Mask from surface using a given color. Optional threshold argument to set color range and alpha threshold. """ mask = Mask(surface.width, surface.height) if not mask.bit: return None pixels = surface.impl.getImageData(0, 0, surface.width, surface.height) if threshold == (0, 0, 0, 255): color = Color(color) color = (color.r, color.g, color.b) width, height = surface.width * 4, surface.height for y in xrange(0, height): xpix = 0 i = y * width for x in xrange(0, width, 4): ix = i + x if surface._getPixel( pixels, ix) == color[0] and surface._getPixel( pixels, ix + 1) == color[1] and surface._getPixel( pixels, ix + 2) == color[2] and surface._getPixel( pixels, ix + 3) >= threshold[3]: mask.set_at((xpix, y)) xpix += 1 else: color = Color(color) col = {} for i, c in enumerate(('r', 'g', 'b')): if threshold[i]: col[c + '1'] = color[i] - threshold[i] - 1 col[c + '2'] = color[i] + threshold[i] + 1 else: col[c + '1'] = color[i] - 1 col[c + '2'] = color[i] + 1 col['a'] = threshold[3] - 1 width, height = surface.width * 4, surface.height for y in xrange(0, height): xpix = 0 i = y * width for x in xrange(0, width, 4): ix = i + x if (col['r1'] < surface._getPixel(pixels, ix) < col['r2']) and (col['g1'] < surface._getPixel( pixels, ix + 1) < col['g2']) and ( col['b1'] < surface._getPixel(pixels, ix + 2) < col['b2']) and (surface._getPixel( pixels, ix + 3) > col['a']): mask.set_at((xpix, y)) xpix += 1 return mask
def lines(self, surface, color, closed, pointlist, width=1): """ Draw interconnected lines, and returns Rect bound. Argument include surface to draw, color, closed, and pointlist. Optional width argument of line. """ surface.beginPath() surface.moveTo(*pointlist[0]) for point in pointlist[1:]: surface.lineTo(*point) if closed: surface.closePath() surface.setLineWidth(width) if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.stroke() xpts = [pt[0] for pt in pointlist] ypts = [pt[1] for pt in pointlist] xmin, xmax = min(xpts), max(xpts) ymin, ymax = min(ypts), max(ypts) if surface._display: return surface._display._surface_rect.clip( Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)) else: return surface.get_rect().clip( Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1))
def line(self, surface, color, point1, point2, width=1): """ Draw line, and returns bounding Rect. Argument include surface to draw, color, point1, point2. Optional width argument of line. """ surface.beginPath() surface.moveTo(*point1) surface.lineTo(*point2) surface.setLineWidth(width) if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.stroke() xpts = [pt[0] for pt in (point1, point2)] ypts = [pt[1] for pt in (point1, point2)] xmin, xmax = min(xpts), max(xpts) ymin, ymax = min(ypts), max(ypts) if surface._display: return surface._display._surface_rect.clip( Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)) else: return surface.get_rect().clip( Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1))
def clear(self): """ Clear display surface. """ self.surface.beginPath() self.surface.setFillStyle(Color(0, 0, 0)) self.surface.fillRect(0, 0, self.surface.width, self.surface.height)
def fill(self, color=None, rect=None): """ Fill surface with color. """ if color is None: HTML5Canvas.fill(self) return if color: if self._fill_style != color: self._fill_style = color if hasattr(color, 'a'): self.setFillStyle(color) else: self.setFillStyle(Color(color)) if not rect: _rect = Rect(0, 0, self.width, self.height) else: if self._display: surface_rect = self._display._surface_rect else: surface_rect = self.get_rect() if hasattr(rect, 'width'): _rect = surface_rect.clip( rect ) else: _rect = surface_rect.clip( Rect(rect) ) if not _rect.width or not _rect.height: return _rect self.fillRect(_rect.x, _rect.y, _rect.width, _rect.height) else: _rect = Rect(0, 0, self.width, self.height) self.clear() return _rect
def get_at(self, pos): """ Get color of a surface pixel. The pos argument represents x,y position of pixel. Return color (r,g,b,a) of a surface pixel. """ pixel = self.impl.getImageData(pos[0], pos[1], 1, 1) return Color([self._getPixel(pixel, i) for i in (0, 1, 2, 3)])
def get_at(self, pos): """ Get color of a surface pixel. The pos argument represents x,y position of pixel. Return color (r,g,b,a) of a surface pixel. """ pixel = self.getImageData(pos[0], pos[1], 1, 1) r, g, b, a = pixel.data return Color(r, g, b, a)
def ellipse(surface, color, rect, width=0): """ Draw ellipse shape, and returns bounding Rect. Arguments include surface to draw, color, and rect. Optional width argument of outline, which defaults to 0 for filled shape. """ if hasattr(rect, 'width'): _rect = rect else: _rect = Rect(rect) surface.saveContext() surface.translate(_rect.x + int(_rect.width / 2), _rect.y + int(_rect.height / 2)) if _rect.width >= _rect.height: surface.scale(_rect.width / (_rect.height * 1.0), 1) radius = int(_rect.height / 2) else: surface.scale(1, _rect.height / (_rect.width * 1.0)) radius = int(_rect.width / 2) surface.beginPath() surface.arc(0, 0, radius, 0, 2 * _pi, False) if width: surface.setLineWidth(width) if surface._stroke_style != color: surface._stroke_style = color if hasattr(color, 'a'): surface.setStrokeStyle(color) else: surface.setStrokeStyle(Color(color)) surface.stroke() else: if surface._fill_style != color: surface._fill_style = color if hasattr(color, 'a'): surface.setFillStyle(color) else: surface.setFillStyle(Color(color)) surface.fill() surface.restoreContext() if not _return_rect: return None if surface._display: return surface._display._surface_rect.clip(_rect) else: return surface.get_rect().clip(_rect)
def set_colorkey(self, color, flags=None): """ Set surface colorkey. """ if self._colorkey: self.replace_color((0, 0, 0, 0), self._colorkey) self._colorkey = None if color: self._colorkey = Color(color) self.replace_color(self._colorkey) return None
def set_at(self, pos, color): """ Set color of a surface pixel. The arguments represent position x,y and color of pixel. """ if hasattr(color, 'a'): _color = color else: _color = Color(color) self.setFillStyle(_color) self.fillRect(pos[0], pos[1], 1, 1) return None
def replace_color(self, color, new_color=None): """ Replace color with with new_color or with alpha. """ pixels = self.impl.getImageData(0, 0, self.width, self.height) if hasattr(color, 'a'): color1 = color else: color1 = Color(color) if new_color is None: alpha_zero = True else: if hasattr(new_color, 'a'): color2 = new_color else: color2 = Color(new_color) alpha_zero = False if alpha_zero: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a a2 = 0 for i in range(0, len(pixels.data), 4): if (self._getPixel(pixels, i) == r1 and self._getPixel(pixels, i + 1) == g1 and self._getPixel(pixels, i + 2) == b1 and self._getPixel(pixels, i + 3) == a1): self._setPixel(pixels, i + 3, a2) else: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a r2, g2, b2, a2 = color2.r, color2.g, color2.b, color2.a for i in range(0, len(pixels.data), 4): if (self._getPixel(pixels, i) == r1 and self._getPixel(pixels, i + 1) == g1 and self._getPixel(pixels, i + 2) == b1 and self._getPixel(pixels, i + 3) == a1): self._setPixel(pixels, i, r2) self._setPixel(pixels, i + 1, g2) self._setPixel(pixels, i + 2, b2) self._setPixel(pixels, i + 3, a2) self.impl.putImageData(pixels, 0, 0, 0, 0, self.width, self.height) return None
def replace_color(self, color, new_color=None): """ Replace color with with new_color or with alpha. """ pixels = self.getImageData(0, 0, self.width, self.height) if hasattr(color, 'a'): color1 = color else: color1 = Color(color) if new_color is None: alpha_zero = True else: if hasattr(new_color, 'a'): color2 = new_color else: color2 = Color(new_color) alpha_zero = False if alpha_zero: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a a2 = 0 data = pixels.data for i in range(0, len(data), 4): if (data[i] == r1 and data[i + 1] == g1 and data[i + 2] == b1 and data[i + 3] == a1): data[i + 3] = a2 else: r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a r2, g2, b2, a2 = color2.r, color2.g, color2.b, color2.a data = pixels.data for i in range(0, len(data), 4): if (data[i] == r1 and data[i + 1] == g1 and data[i + 2] == b1 and data[i + 3] == a1): data[i] = r2 data[i + 1] = g2 data[i + 2] = b2 data[i + 3] = a2 self.putImageData(pixels, 0, 0, 0, 0, self.width, self.height) return None
def replace_color(self, color, new_color=None): """ Replace color with with new_color or with alpha. """ pixels = self.impl.getImageData(0, 0, self.width, self.height) if hasattr(color, 'a'): color1 = color else: color1 = Color(color) if new_color: if hasattr(new_color, 'a'): color2 = new_color else: color2 = Color(new_color) else: color2 = Color(color1.r,color1.g,color1.b,0) col1 = (color1.r, color1.g, color1.b, color1.a) col2 = (color2.r, color2.g, color2.b, color2.a) for i in xrange(0,len(pixels.data),4): if (self._getPixel(pixels, i), self._getPixel(pixels, i+1), self._getPixel(pixels, i+2), self._getPixel(pixels, i+3)) == col1: for j in range(4): self._setPixel(pixels, i+j, col2[j]) self.impl.putImageData(pixels, 0, 0, 0, 0, self.width, self.height) return None
def set_colorkey(self, color, flags=None): """ Set surface colorkey. """ if self._colorkey: r = self._colorkey.r g = self._colorkey.g b = self._colorkey.b self._colorkey = None if color: try: color = Color(color) self._colorkey = color self.replace_color((color.r,color.g,color.b)) except: pass return None
def fill(self, color=None, rect=None): """ Fill surface with color. """ if color is None: HTML5Canvas.fill(self) return None if self._fill_style != color: self._fill_style = color if hasattr(color, 'a'): self.setFillStyle(color) else: self.setFillStyle(Color(color)) if not _return_rect: if rect is None: self.fillRect(0, 0, self.width, self.height) else: self.fillRect(rect[0], rect[1], rect[2], rect[3]) return None if rect is None: _rect = Rect(0, 0, self.width, self.height) self.fillRect(_rect.x, _rect.y, _rect.width, _rect.height) else: if self._display: if hasattr(rect, 'width'): _rect = self._display._surface_rect.clip(rect) else: _rect_ = rectPool.get(rect[0], rect[1], rect[2], rect[3]) _rect = self._display._surface_rect.clip(_rect_) rectPool.append(_rect_) else: surface_rect = rectPool.get(0, 0, self.width, self.height) if hasattr(rect, 'width'): _rect = surface_rect.clip(rect) else: _rect_ = rectPool.get(rect[0], rect[1], rect[2], rect[3]) _rect = surface_rect.clip(_rect_) rectPool.append(_rect_) rectPool.append(surface_rect) if _rect.width and _rect.height: self.fillRect(_rect.x, _rect.y, _rect.width, _rect.height) return _rect