Commits

Brendan Howell  committed 6ed83db

basics of cairo image compositing now works

  • Participants
  • Parent commits 0c7b0d4

Comments (0)

Files changed (2)

 import pygame
 import os
 import io
+import cairo
+import math
 
 SCREEN = None
 PROJECT_DIR = None
+CTX = None
+
+#TODO: write a generic transform stack to manage arbitrary sequences of 
+#      transformations:
+#       ctx.save()
+#       
+
+class Image2:
+    """All-purpose class for cairo-based pixel images in pycessing"""
+    def __init__(self, file_name):
+        self.file_name = file_name
+        self.loaded = False
+        self.transformed = False
+        self.matrix = cairo.Matrix()
+        self.rotation = 0
+        self.scalex = 1
+        self.scaley = 1
+        
+        
+    def _loadSurface_(self):
+        """load image from file or file_obj"""
+        try:
+            path = os.path.join(PROJECT_DIR, self.file_name)
+            surface = pygame.image.load(path).convert_alpha()
+        except:
+            path = self.file_name
+            buf = io.BytesIO(path.read())
+            surface = pygame.image.load(buf).convert_alpha()
+        
+        self.width = surface.get_width()
+        self.height = surface.get_height()    
+        ar = pygame.surfarray.array2d(surface)
+        stride = surface.get_width() * 4
+        self.surface = cairo.ImageSurface.create_for_data(ar,
+                           cairo.FORMAT_ARGB32, surface.get_width(), 
+                           surface.get_height(), stride)
+        self.loaded = True
+
+    def draw(self, x, y, sx=None, sy=None):
+        #draws to the cairo context
+        if(not(self.loaded)):
+            self._loadSurface_()
+        if(sx and sy):
+            if(width and height):
+                area = (sx, sy, width, height)
+            else:
+                area = (sx, sy, self.surface.get_width(), 
+						self.surface.get_height())
+        else:
+            area = None
+            
+        CTX.save()
+
+        self.matrix.translate(x/self.width, y/self.height)
+        CTX.set_matrix(self.matrix)
+        CTX.set_source_surface(self.surface, 0, 0)
+        CTX.paint()
+        CTX.restore()
+        
+    def rotate(self, angle):
+        if(not(self.loaded)):
+            self._loadSurface_()
+        radians = math.pi * angle / 180.0
+        self.matrix.rotate(-1 * self.rotation)
+        self.rotation = radians
+        self.matrix.rotate(radians)
+        
+    def scale(self, pixelsx, pixelsy):
+        if(not(self.loaded)):
+            self._loadSurface_()
+        oldx = float(self.width) / self.scalex
+        oldy = float(self.height) / self.scaley
+        self.matrix.scale(oldx, oldy)
+        sx = float(pixelsx) / self.width
+        sy = float(pixelsy) / self.height
+        self.matrix.scale(sx, sy)
+        
+    def get_width(self):
+        if(not(self.loaded)):
+            self._loadSurface_()
+        dx, dy = self.matrix.transform_distance(self.width, 0)
+        return dx
+    
+    def get_height(self):
+        if(not(self.loaded)):
+            self._loadSurface_()
+        dx, dy = self.matrix.transform_distance(0, self.height)
+        return dy
 
 class Image:
     """All-purpose class for pixel images in pycessing"""
             self.surface.set_at((x, y), (r, g, b, a))
         else:
             self.surface.set_at((x, y), (r, g, b))
-        
-        
-    def setCompositing(self, operation):
-        pass
+        
 drawing.setSurface(pycessing.screen)
 drawing.setBackground(127, 127, 127)
 images.SCREEN = pycessing.screen
+images.CTX = drawing.ctx
 typo.SCREEN = pycessing.screen
 
 while 1: