From 27d791f844f0a6a39fd48da39d5721d256c3787d Mon Sep 17 00:00:00 2001 From: Wade Brainerd Date: Sat, 29 Nov 2008 23:15:44 +0000 Subject: Zooming and scrolling working via keyboard. --- diff --git a/_colorsc.so b/_colorsc.so index ecff122..99a5994 100755 --- a/_colorsc.so +++ b/_colorsc.so Binary files differ diff --git a/colors.py b/colors.py index 1e0ab74..7981bb9 100755 --- a/colors.py +++ b/colors.py @@ -112,7 +112,7 @@ class BrushControlsPanel(gtk.HBox): sizebox = gtk.VBox() sizelabel = gtk.Label(_('Brush Size')) sizebox.pack_end(sizelabel, False) - self.size = gtk.Adjustment(50, 1, 260, 1, 10, 10) + self.size = gtk.Adjustment(50, 1, 130, 1, 10, 10) self.sizebar = gtk.VScale(self.size) self.sizebar.set_property("draw-value", False) self.sizebar.set_property("inverted", True) @@ -395,7 +395,7 @@ class Colors(activity.Activity, ExportedGObject): # The actual drawing canvas is at 1/2 resolution, which improves performance by 4x and still leaves a decent # painting resolution of 600x400 on the XO. - self.easel = Canvas(self.width/2, self.height/2) + self.easel = Canvas(800, 400) self.set_brush(self.easel.brush) # The Canvas internally stores the image as 32bit. When rendering, it scales up and blits into canvasimage, @@ -974,16 +974,14 @@ class Colors(activity.Activity, ExportedGObject): self.scroll = pos # Clamp scroll position to within absolute limits. - self.scroll.x = min(max(self.scroll.x, 0), self.easel.width) - self.scroll.y = min(max(self.scroll.y, 0), self.easel.height) + self.scroll.x = min(max(self.scroll.x, -100), self.easel.width*self.zoom - self.width + 100) + self.scroll.y = min(max(self.scroll.y, -100), self.easel.height*self.zoom - self.height + 100) - #log.debug("scroll: %f, %f" % (self.scroll.x, self.scroll.y)) - #----------------------------------------------------------------------------------------------------------------- # Zoom code def init_zoom (self): - self.zoom = 1.0 + self.zoom = 2.0 self.zoomref = None def zoom_to (self, zoom): @@ -991,32 +989,50 @@ class Colors(activity.Activity, ExportedGObject): self.end_draw() # Adjust scroll position to keep the same point centered on screen while the zoom changes. - # This is either the reference point (the center of the last stroke) or else the screen center. + # This is either the reference point (the center of the last stroke) or else the mouse pointer. if self.zoomref != None: scrollcenter = self.zoomref else: - scrollcenter = self.scroll + Pos(self.width*0.5/self.zoom, self.height*0.5/self.zoom) + scrollcenter = self.screen_to_easel(Pos(self.mx, self.my)) self.zoom = zoom - self.scroll_to(scrollcenter - Pos(self.width*0.5/self.zoom, self.height*0.5/self.zoom)) + self.scroll_to(self.easel_to_screen(scrollcenter) - Pos(self.mx, self.my)) self.zoomref = None #log.debug('zoom %f', self.zoom) self.flush_entire_canvas() def zoom_in (self): - #if self.zoom == 0.75: - # self.zoom_to(1.0) - # self.scroll_to(Pos(0,0)) if self.zoom == 1.0: self.zoom_to(2.0) + elif self.zoom == 2.0: + self.zoom_to(4.0) + elif self.zoom == 4.0: + self.zoom_to(8.0) def zoom_out (self): - if self.zoom == 2.0: + if self.zoom == 8.0: + self.zoom_to(4.0) + elif self.zoom == 4.0: + self.zoom_to(2.0) + elif self.zoom == 2.0: self.zoom_to(1.0) - self.scroll_to(Pos(0,0)) - #elif self.zoom == 1.0: - # self.zoom_to(0.75) + def easel_to_screen(self, pos): + r = pos + #r = r / Pos(self.easel.width, self.easel.height) + #r = r * Pos(self.width, self.height) + r = r * Pos(self.zoom, self.zoom) + r = r - self.scroll + return r + + def screen_to_easel(self, pos): + r = pos + r = r + self.scroll + r = r / Pos(self.zoom, self.zoom) + #r = r / Pos(self.width, self.height) + #r = r * Pos(self.easel.width, self.easel.height) + return r + #----------------------------------------------------------------------------------------------------------------- # Drawing commands # @@ -1026,7 +1042,7 @@ class Colors(activity.Activity, ExportedGObject): # be played back. def draw (self, pos): - relpos = pos * Pos(self.easel.width, self.easel.height) / Pos(self.zoom, self.zoom) - self.scroll + relpos = self.screen_to_easel(pos) relpos = relpos / Pos(self.easel.width, self.easel.height) self.easel.play_command(DrawCommand.create_draw(relpos, int(self.pressure)), True) @@ -1039,7 +1055,6 @@ class Colors(activity.Activity, ExportedGObject): # Record a new default zoom-in focal point. #self.zoomref = (self.easel.strokemin + self.easel.strokemax) * Pos(0.5,0.5) - self.zoomref = Pos(self.mx, self.my) def set_brush (self, brush): #log.debug("set_brush color=%d,%d,%d type=%d size=%d opacity=%d", brush.color.r, brush.color.g, brush.color.b, brush.type, brush.size, brush.opacity) @@ -1130,13 +1145,12 @@ class Colors(activity.Activity, ExportedGObject): if self.easel.dirtymin.x > self.easel.dirtymax.x: return - x = int(self.easel.dirtymin.x*2) - y = int(self.easel.dirtymin.y*2) - w = int(self.easel.dirtymax.x*2-x+1) - h = int(self.easel.dirtymax.y*2-y+1) + mn = self.easel_to_screen(self.easel.dirtymin) + mx = self.easel_to_screen(self.easel.dirtymax) + #log.debug("x=%d y=%d width=%d height=%d" % (x, y, w, h)) - self.easelarea.queue_draw_area(x, y, w, h) + self.easelarea.queue_draw_area(int(mn.x), int(mn.y), int(mx.x-mn.x+1), int(mx.y-mn.y+1)) self.easel.reset_dirty_rect() @@ -1147,15 +1161,15 @@ class Colors(activity.Activity, ExportedGObject): def flush_cursor (self): """Causes a redraw of the canvas area covered by the cursor.""" - r = int(self.easel.brush.size*2*self.pressure/256) + r = int(self.easel.brush.size*self.zoom/2*self.pressure/256) #log.debug("mx=%d my=%d r=%d lastmx=%d lastmy=%d lastr=%d" % \ # (self.mx, self.my, r, self.lastmx, self.lastmy, self.lastr)) - x0 = min(self.lastmx-self.lastr/2, self.mx-r/2) - y0 = min(self.lastmy-self.lastr/2, self.my-r/2) - x1 = max(self.lastmx+self.lastr/2, self.mx+r/2) - y1 = max(self.lastmy+self.lastr/2, self.my+r/2) + x0 = min(self.lastmx-self.lastr, self.mx-r) + y0 = min(self.lastmy-self.lastr, self.my-r) + x1 = max(self.lastmx+self.lastr, self.mx+r) + y1 = max(self.lastmy+self.lastr, self.my+r) self.easelarea.queue_draw_area(x0, y0, x1-x0+2, y1-y0+2) @@ -1282,8 +1296,7 @@ class Colors(activity.Activity, ExportedGObject): # Update drawing. if self.cur_buttons & Colors.BUTTON_TOUCH: if self.mx != self.lastmx or self.my != self.lastmy: - mpos = Pos(float(self.mx)/self.width, float(self.my)/self.height) - self.draw(mpos) + self.draw(Pos(self.mx, self.my)) self.flush_dirty_canvas() elif self.easel.stroke: self.end_draw() @@ -1347,14 +1360,11 @@ class Colors(activity.Activity, ExportedGObject): # Rebuild easelimage. self.easelimage = gtk.gdk.Image(gtk.gdk.IMAGE_FASTEST, gtk.gdk.visual_get_system(), rect[2], rect[3]) - - # Reconfigure canvas. - self.easel.resize(rect[2]/2, rect[3]/2) # Resize panels. self.brush_controls.set_size_request(rect[2], rect[3]) self.progress.set_size_request(rect[2], rect[3]) - + return True def on_canvasarea_expose (self, widget, event): @@ -1368,23 +1378,43 @@ class Colors(activity.Activity, ExportedGObject): gc = self.easelarea.get_style().fg_gc[gtk.STATE_NORMAL] # Blit dirty rectangle of canvas into the image. + src_x = int(event.area.x/self.zoom+self.scroll.x) + src_y = int(event.area.y/self.zoom+self.scroll.y) + + dest_x = int(event.area.x) + dest_y = int(event.area.y) + dest_w = int(event.area.width) + dest_h = int(event.area.height) + if self.zoom == 1.0: - self.easel.blit_2x( - self.easelimage, - int(event.area.x), int(event.area.y), int(event.area.width), int(event.area.height), - int(-self.scroll.x), int(-self.scroll.y), - self.overlay_active) + spos = self.screen_to_easel(Pos(dest_x, dest_y)) + self.easel.blit_1x(self.easelimage, int(spos.x), int(spos.y), dest_x, dest_y, dest_w, dest_h, self.overlay_active) + elif self.zoom == 2.0: + dest_x = dest_x & ~1 + dest_y = dest_y & ~1 + dest_w = (dest_w+1) & ~1 + dest_h = (dest_h+1) & ~1 + spos = self.screen_to_easel(Pos(dest_x, dest_y)) + self.easel.blit_2x(self.easelimage, int(spos.x), int(spos.y), dest_x, dest_y, dest_w, dest_h, self.overlay_active) #self.easel.blit_2x( # self.easelimage, # 0, 0, rect.width, rect.height, # int(-self.scroll.x), int(-self.scroll.y), # self.overlay_active) - elif self.zoom == 2.0: - self.easel.blit_4x( - self.easelimage, - int(event.area.x), int(event.area.y), int(event.area.width), int(event.area.height), - int(-self.scroll.x/2), int(-self.scroll.y/2), - self.overlay_active) + elif self.zoom == 4.0: + dest_x = dest_x & ~3 + dest_y = dest_y & ~3 + dest_w = (dest_w+3) & ~3 + dest_h = (dest_h+3) & ~3 + spos = self.screen_to_easel(Pos(dest_x, dest_y)) + self.easel.blit_4x(self.easelimage, int(spos.x), int(spos.y), dest_x, dest_y, dest_w, dest_h, self.overlay_active) + elif self.zoom == 8.0: + dest_x = dest_x & ~7 + dest_y = dest_y & ~7 + dest_w = (dest_w+7) & ~7 + dest_h = (dest_h+7) & ~7 + spos = self.screen_to_easel(Pos(dest_x, dest_y)) + self.easel.blit_8x(self.easelimage, int(spos.x), int(spos.y), dest_x, dest_y, dest_w, dest_h, self.overlay_active) # Then draw the image to the screen. self.easelarea.bin_window.draw_image( @@ -1405,8 +1435,8 @@ class Colors(activity.Activity, ExportedGObject): y = self.height-50-size[1]/pango.SCALE self.easelarea.bin_window.draw_layout(gc, x, y, layout) - #self.easelarea.bin_window.draw_arc(self.easelarea.get_style().black_gc, False, self.mx-r/2, self.my-r/2, r, r, 0, 360*64) - self.lastr = int(self.easel.brush.size*2*self.pressure/256) + #self.easelarea.bin_window.draw_arc(self.easelarea.get_style().black_gc, False, self.mx-r, self.my-r, r, r, 0, 360*64) + self.lastr = int(self.easel.brush.size*self.pressure/256) self.lastmx = self.mx self.lastmy = self.my diff --git a/colorsc.py b/colorsc.py index 765f598..66342c8 100644 --- a/colorsc.py +++ b/colorsc.py @@ -500,8 +500,10 @@ class Canvas(_object): def update_playback(*args): return _colorsc.Canvas_update_playback(*args) def get_num_commands(*args): return _colorsc.Canvas_get_num_commands(*args) def play_range(*args): return _colorsc.Canvas_play_range(*args) + def blit_1x(*args): return _colorsc.Canvas_blit_1x(*args) def blit_2x(*args): return _colorsc.Canvas_blit_2x(*args) def blit_4x(*args): return _colorsc.Canvas_blit_4x(*args) + def blit_8x(*args): return _colorsc.Canvas_blit_8x(*args) def downsize_video(*args): return _colorsc.Canvas_downsize_video(*args) def videopaint_motion(*args): return _colorsc.Canvas_videopaint_motion(*args) def blit_videopaint(*args): return _colorsc.Canvas_blit_videopaint(*args) diff --git a/src/canvas.h b/src/canvas.h index e06b1e8..78ff6ca 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -1020,46 +1020,139 @@ public: // Draws a region of the canvas into a GdkImage for display on the screen, with optional scaling // and darkening. - void blit_2x(GdkImage* img, int x, int y, int w, int h, int scroll_x, int scroll_y, bool overlay) + void blit_1x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay) { unsigned short* pixels = (unsigned short*)img->mem; int pitch = img->bpl/sizeof(unsigned short); - // Round to multiple of 2. - x &= ~1; - y &= ~1; - w = (w+1) & ~1; - h = (h+1) & ~1; - - // Clip rectangle. - if (x < 0) + // Clip destination rectangle. Source clipping is handled per pixel. + if (dest_x < 0) { - w += x; - x = 0; + dest_w += dest_x; + dest_x = 0; } - if (y < 0) + if (dest_y < 0) { - h += y; - y = 0; + dest_h += dest_y; + dest_y = 0; } - if (x+w > (width-1)*2) - w = (width-1)*2-x; - if (y+h > (height-1)*2) - h = (height-1)*2-y; + if (dest_x+dest_w > img->width) + dest_w = img->width - dest_x; + if (dest_y+dest_h > img->height) + dest_h = img->height - dest_y; - // Translate origin to output location. - int src_x = (x - scroll_x)/2; - int src_y = (y - scroll_y)/2; + int csy = src_y; + for (int cdy = dest_y; cdy < dest_y+dest_h; cdy++) + { + unsigned short* __restrict row = &pixels[cdy*pitch+dest_x]; + + // If out of bounds vertically, fill row with the background color. + if (csy < 0 || csy >= height) + { + for (int cdx = 0; cdx < dest_w; cdx++) + { + unsigned int rgb = 0; + *row++ = rgb; + } + } + else + { + unsigned int* __restrict src = &image[csy*width+src_x]; + + int cdx = 0; + int csx = src_x; + + // Fill any portion that is to the left of the src image with + // background color. + while (csx < 0 && cdx < dest_w) + { + unsigned int rgb = 0; + *row++ = rgb; + src++; + csx++; + cdx++; + } + + // Copy the pixels. + if (overlay) + { + while (csx < width && cdx < dest_w) + { + unsigned int p = *src; + p &= ~0x03030303; + p >>= 2; + unsigned int r = (((p>>16)&0xff)>>3)<<11; + unsigned int g = (((p>> 8)&0xff)>>2)<<5; + unsigned int b = (((p>> 0)&0xff)>>3); + unsigned int rgb = r|g|b; + *row++ = rgb; + src++; + csx++; + cdx++; + } + } + else + { + while (csx < width && cdx < dest_w) + { + unsigned int p = *src; + unsigned int r = (((p>>16)&0xff)>>3)<<11; + unsigned int g = (((p>> 8)&0xff)>>2)<<5; + unsigned int b = (((p>> 0)&0xff)>>3); + unsigned int rgb = r|g|b; + *row++ = rgb; + src++; + csx++; + cdx++; + } + } + + // Fill any portion to the right of src with background pixels. + while (cdx < dest_w) + { + unsigned int rgb = 0; + *row++ = rgb; + src++; + csx++; + cdx++; + } + } + + csy++; + } + } + + void blit_2x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay) + { + unsigned short* pixels = (unsigned short*)img->mem; + int pitch = img->bpl/sizeof(unsigned short); + + // Clip destination rectangle. Source clipping is handled per pixel. + if (dest_x < 0) + { + dest_w += dest_x; + dest_x = 0; + } + if (dest_y < 0) + { + dest_h += dest_y; + dest_y = 0; + } + if (dest_x+dest_w > img->width-2) + dest_w = (img->width-2) - dest_x; + if (dest_y+dest_h > img->height-2) + dest_h = (img->height-2) - dest_y; int csy = src_y; - for (int cy = y; cy < y+h; cy += 2) + for (int cdy = dest_y; cdy < dest_y+dest_h; cdy += 2) { - unsigned short* __restrict row0 = &pixels[cy*pitch+x]; + unsigned short* __restrict row0 = &pixels[cdy*pitch+dest_x]; unsigned short* __restrict row1 = row0 + pitch; + // If out of bounds vertically, fill row with the background color. if (csy < 0 || csy >= height) { - for (int cx = 0; cx < w; cx += 2) + for (int cdx = 0; cdx < dest_w; cdx += 2) { unsigned int rgb = 0; row0[0] = rgb; @@ -1074,10 +1167,12 @@ public: { unsigned int* __restrict src = &image[csy*width+src_x]; - int cx = 0; + int cdx = 0; int csx = src_x; - while (csx < 0 && cx < w) + // Fill any portion that is to the left of the src image with + // background color. + while (csx < 0 && cdx < dest_w) { unsigned int rgb = 0; row0[0] = rgb; @@ -1088,12 +1183,13 @@ public: row1 += 2; src++; csx++; - cx += 2; + cdx += 2; } + // Copy the pixels. if (overlay) { - while (csx < width && cx < w) + while (csx < width && cdx < dest_w) { unsigned int p = *src; p &= ~0x03030303; @@ -1110,12 +1206,12 @@ public: row1 += 2; src++; csx++; - cx += 2; + cdx += 2; } } else { - while (csx < width && cx < w) + while (csx < width && cdx < dest_w) { unsigned int p = *src; unsigned int r = (((p>>16)&0xff)>>3)<<11; @@ -1130,11 +1226,12 @@ public: row1 += 2; src++; csx++; - cx += 2; + cdx += 2; } } - while (cx < w) + // Fill any portion to the right of src with background pixels. + while (cdx < dest_w) { unsigned int rgb = 0; row0[0] = rgb; @@ -1145,7 +1242,7 @@ public: row1 += 2; src++; csx++; - cx += 2; + cdx += 2; } } @@ -1153,110 +1250,188 @@ public: } } - void blit_4x(GdkImage* img, int x, int y, int w, int h, int scroll_x, int scroll_y, bool overlay) + void blit_4x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay) { unsigned short* pixels = (unsigned short*)img->mem; int pitch = img->bpl/sizeof(unsigned short); - + // Clip rectangle. - if (x < 0) + // Clip destination rectangle. Source clipping is handled per pixel. + if (dest_x < 0) { - w += x; - x = 0; + dest_w += dest_x; + dest_x = 0; } - if (y < 0) + if (dest_y < 0) { - h += y; - y = 0; + dest_h += dest_y; + dest_y = 0; } + if (dest_x + dest_w > img->width-4) + dest_w = (img->width-4) - dest_x; + if (dest_y + dest_h > img->height-4) + dest_h = (img->height-4) - dest_y; - x &= ~3; - y &= ~3; - w = (w) & ~3; - h = (h) & ~3; - - if (x+w > (width-7)*4) - w = (width-7)*4-x; - if (y+h > (height-7)*4) - h = (height-7)*4-y; + int csy = src_y; + for (int cdy = dest_y; cdy < dest_y+dest_h; cdy += 4) + { + unsigned short* __restrict row0 = &pixels[cdy*pitch+dest_x]; + unsigned short* __restrict row1 = row0 + pitch; + unsigned short* __restrict row2 = row1 + pitch; + unsigned short* __restrict row3 = row2 + pitch; + +#define FILL_PIXEL(rgb) \ + row0[0] = rgb; row0[1] = rgb; row0[2] = rgb; row0[3] = rgb; \ + row1[0] = rgb; row1[1] = rgb; row1[2] = rgb; row1[3] = rgb; \ + row2[0] = rgb; row2[1] = rgb; row2[2] = rgb; row2[3] = rgb; \ + row3[0] = rgb; row3[1] = rgb; row3[2] = rgb; row3[3] = rgb; \ + row0 += 4; row1 += 4; row2 += 4; row3 += 4; + + if (csy < 0 || csy >= height) + { + for (int cdx = 0; cdx < dest_w; cdx += 4) + { + FILL_PIXEL(0) + } + } + else + { + unsigned int* __restrict src = &image[csy*width+src_x]; + + int cdx = 0; + int csx = src_x; + + while (csx < 0 && cdx < dest_w) + { + FILL_PIXEL(0) + + src++; + csx++; + cdx += 4; + } + + if (overlay) + { + while (csx < width && cdx < dest_w) + { + unsigned int p = *src; + p &= ~0x03030303; + p >>= 2; + unsigned int r = (((p>>16)&0xff)>>3)<<11; + unsigned int g = (((p>> 8)&0xff)>>2)<<5; + unsigned int b = (((p>> 0)&0xff)>>3); + unsigned int rgb = r|g|b; + FILL_PIXEL(rgb) + + src++; + csx++; + cdx += 4; + } + } + else + { + while (csx < width && cdx < dest_w) + { + unsigned int p = *src; + unsigned int r = (((p>>16)&0xff)>>3)<<11; + unsigned int g = (((p>> 8)&0xff)>>2)<<5; + unsigned int b = (((p>> 0)&0xff)>>3); + unsigned int rgb = r|g|b; + FILL_PIXEL(rgb) + + src++; + csx++; + cdx += 4; + } + } + + while (cdx < dest_w) + { + FILL_PIXEL(0) + + src++; + csx++; + cdx += 4; + } + } - // Translate origin to output location. - int src_x = (x - scroll_x)/4; - int src_y = (y - scroll_y)/4; +#undef FILL_PIXEL + + csy++; + } + } + + void blit_8x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay) + { + unsigned short* pixels = (unsigned short*)img->mem; + int pitch = img->bpl/sizeof(unsigned short); + + // Clip rectangle. + // Clip destination rectangle. Source clipping is handled per pixel. + if (dest_x < 0) + { + dest_w += dest_x; + dest_x = 0; + } + if (dest_y < 0) + { + dest_h += dest_y; + dest_y = 0; + } + if (dest_x + dest_w > img->width-8) + dest_w = (img->width-8) - dest_x; + if (dest_y + dest_h > img->height-8) + dest_h = (img->height-8) - dest_y; int csy = src_y; - for (int cy = y; cy < y+h; cy += 4) + for (int cdy = dest_y; cdy < dest_y+dest_h; cdy += 8) { - unsigned short* __restrict row0 = &pixels[cy*pitch+x]; + unsigned short* __restrict row0 = &pixels[cdy*pitch+dest_x]; unsigned short* __restrict row1 = row0 + pitch; unsigned short* __restrict row2 = row1 + pitch; unsigned short* __restrict row3 = row2 + pitch; + unsigned short* __restrict row4 = row3 + pitch; + unsigned short* __restrict row5 = row4 + pitch; + unsigned short* __restrict row6 = row5 + pitch; + unsigned short* __restrict row7 = row6 + pitch; + +#define FILL_PIXEL(rgb) \ + row0[0] = rgb; row0[1] = rgb; row0[2] = rgb; row0[3] = rgb; row0[4] = rgb; row0[5] = rgb; row0[6] = rgb; row0[7] = rgb; \ + row1[0] = rgb; row1[1] = rgb; row1[2] = rgb; row1[3] = rgb; row1[4] = rgb; row1[5] = rgb; row1[6] = rgb; row1[7] = rgb; \ + row2[0] = rgb; row2[1] = rgb; row2[2] = rgb; row2[3] = rgb; row2[4] = rgb; row2[5] = rgb; row2[6] = rgb; row2[7] = rgb; \ + row3[0] = rgb; row3[1] = rgb; row3[2] = rgb; row3[3] = rgb; row3[4] = rgb; row3[5] = rgb; row3[6] = rgb; row3[7] = rgb; \ + row4[0] = rgb; row4[1] = rgb; row4[2] = rgb; row4[3] = rgb; row4[4] = rgb; row4[5] = rgb; row4[6] = rgb; row4[7] = rgb; \ + row5[0] = rgb; row5[1] = rgb; row5[2] = rgb; row5[3] = rgb; row5[4] = rgb; row5[5] = rgb; row5[6] = rgb; row5[7] = rgb; \ + row6[0] = rgb; row6[1] = rgb; row6[2] = rgb; row6[3] = rgb; row6[4] = rgb; row6[5] = rgb; row6[6] = rgb; row6[7] = rgb; \ + row7[0] = rgb; row7[1] = rgb; row7[2] = rgb; row7[3] = rgb; row7[4] = rgb; row7[5] = rgb; row7[6] = rgb; row7[7] = rgb; \ + row0 += 8; row1 += 8; row2 += 8; row3 += 8; row4 += 8; row5 += 8; row6 += 8; row7 += 8; if (csy < 0 || csy >= height) { - for (int cx = 0; cx < w; cx += 4) + for (int cdx = 0; cdx < dest_w; cdx += 8) { - unsigned int rgb = 0; - row0[0] = rgb; - row0[1] = rgb; - row0[2] = rgb; - row0[3] = rgb; - row1[0] = rgb; - row1[1] = rgb; - row1[2] = rgb; - row1[3] = rgb; - row2[0] = rgb; - row2[1] = rgb; - row2[2] = rgb; - row2[3] = rgb; - row3[0] = rgb; - row3[1] = rgb; - row3[2] = rgb; - row3[3] = rgb; - row0 += 4; - row1 += 4; - row2 += 4; - row3 += 4; + FILL_PIXEL(0) } } else { unsigned int* __restrict src = &image[csy*width+src_x]; - int cx = 0; + int cdx = 0; int csx = src_x; - while (csx < 0 && cx < w) + while (csx < 0 && cdx < dest_w) { - unsigned int rgb = 0; - row0[0] = rgb; - row0[1] = rgb; - row0[2] = rgb; - row0[3] = rgb; - row1[0] = rgb; - row1[1] = rgb; - row1[2] = rgb; - row1[3] = rgb; - row2[0] = rgb; - row2[1] = rgb; - row2[2] = rgb; - row2[3] = rgb; - row3[0] = rgb; - row3[1] = rgb; - row3[2] = rgb; - row3[3] = rgb; - row0 += 4; - row1 += 4; - row2 += 4; - row3 += 4; + FILL_PIXEL(0) + src++; csx++; - cx += 4; + cdx += 8; } if (overlay) { - while (csx < width && cx < w) + while (csx < width && cdx < dest_w) { unsigned int p = *src; p &= ~0x03030303; @@ -1265,95 +1440,43 @@ public: unsigned int g = (((p>> 8)&0xff)>>2)<<5; unsigned int b = (((p>> 0)&0xff)>>3); unsigned int rgb = r|g|b; - row0[0] = rgb; - row0[1] = rgb; - row0[2] = rgb; - row0[3] = rgb; - row1[0] = rgb; - row1[1] = rgb; - row1[2] = rgb; - row1[3] = rgb; - row2[0] = rgb; - row2[1] = rgb; - row2[2] = rgb; - row2[3] = rgb; - row3[0] = rgb; - row3[1] = rgb; - row3[2] = rgb; - row3[3] = rgb; - row0 += 4; - row1 += 4; - row2 += 4; - row3 += 4; + FILL_PIXEL(rgb) + src++; csx++; - cx += 4; + cdx += 8; } } else { - while (csx < width && cx < w) + while (csx < width && cdx < dest_w) { unsigned int p = *src; unsigned int r = (((p>>16)&0xff)>>3)<<11; unsigned int g = (((p>> 8)&0xff)>>2)<<5; unsigned int b = (((p>> 0)&0xff)>>3); unsigned int rgb = r|g|b; - row0[0] = rgb; - row0[1] = rgb; - row0[2] = rgb; - row0[3] = rgb; - row1[0] = rgb; - row1[1] = rgb; - row1[2] = rgb; - row1[3] = rgb; - row2[0] = rgb; - row2[1] = rgb; - row2[2] = rgb; - row2[3] = rgb; - row3[0] = rgb; - row3[1] = rgb; - row3[2] = rgb; - row3[3] = rgb; - row0 += 4; - row1 += 4; - row2 += 4; - row3 += 4; + FILL_PIXEL(rgb) + src++; csx++; - cx += 4; + cdx += 8; } } - while (cx < w) + while (cdx < dest_w) { unsigned int rgb = 0; - row0[0] = rgb; - row0[1] = rgb; - row0[2] = rgb; - row0[3] = rgb; - row1[0] = rgb; - row1[1] = rgb; - row1[2] = rgb; - row1[3] = rgb; - row2[0] = rgb; - row2[1] = rgb; - row2[2] = rgb; - row2[3] = rgb; - row3[0] = rgb; - row3[1] = rgb; - row3[2] = rgb; - row3[3] = rgb; - row0 += 4; - row1 += 4; - row2 += 4; - row3 += 4; + FILL_PIXEL(rgb) + src++; csx++; - cx += 4; + cdx += 8; } } +#undef FILL_PIXEL + csy++; } } diff --git a/src/colorsc_wrap.cxx b/src/colorsc_wrap.cxx index 20918af..96fd8d1 100644 --- a/src/colorsc_wrap.cxx +++ b/src/colorsc_wrap.cxx @@ -9341,6 +9341,98 @@ fail: } +SWIGINTERN PyObject *_wrap_Canvas_blit_1x(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + Canvas *arg1 = (Canvas *) 0 ; + GdkImage *arg2 = (GdkImage *) 0 ; + int arg3 ; + int arg4 ; + int arg5 ; + int arg6 ; + int arg7 ; + int arg8 ; + bool arg9 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + int val5 ; + int ecode5 = 0 ; + int val6 ; + int ecode6 = 0 ; + int val7 ; + int ecode7 = 0 ; + int val8 ; + int ecode8 = 0 ; + bool val9 ; + int ecode9 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; + PyObject * obj5 = 0 ; + PyObject * obj6 = 0 ; + PyObject * obj7 = 0 ; + PyObject * obj8 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO:Canvas_blit_1x",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Canvas, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Canvas_blit_1x" "', argument " "1"" of type '" "Canvas *""'"); + } + arg1 = reinterpret_cast< Canvas * >(argp1); + { + // todo- Error checking would be nice. + PyGObject* pygo = (PyGObject*)obj1; + GdkImage* img = (GdkImage*)pygo->obj; + arg2 = img; + } + ecode3 = SWIG_AsVal_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Canvas_blit_1x" "', argument " "3"" of type '" "int""'"); + } + arg3 = static_cast< int >(val3); + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Canvas_blit_1x" "', argument " "4"" of type '" "int""'"); + } + arg4 = static_cast< int >(val4); + ecode5 = SWIG_AsVal_int(obj4, &val5); + if (!SWIG_IsOK(ecode5)) { + SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "Canvas_blit_1x" "', argument " "5"" of type '" "int""'"); + } + arg5 = static_cast< int >(val5); + ecode6 = SWIG_AsVal_int(obj5, &val6); + if (!SWIG_IsOK(ecode6)) { + SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "Canvas_blit_1x" "', argument " "6"" of type '" "int""'"); + } + arg6 = static_cast< int >(val6); + ecode7 = SWIG_AsVal_int(obj6, &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "Canvas_blit_1x" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + ecode8 = SWIG_AsVal_int(obj7, &val8); + if (!SWIG_IsOK(ecode8)) { + SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "Canvas_blit_1x" "', argument " "8"" of type '" "int""'"); + } + arg8 = static_cast< int >(val8); + ecode9 = SWIG_AsVal_bool(obj8, &val9); + if (!SWIG_IsOK(ecode9)) { + SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "Canvas_blit_1x" "', argument " "9"" of type '" "bool""'"); + } + arg9 = static_cast< bool >(val9); + (arg1)->blit_1x(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_Canvas_blit_2x(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; Canvas *arg1 = (Canvas *) 0 ; @@ -9525,6 +9617,98 @@ fail: } +SWIGINTERN PyObject *_wrap_Canvas_blit_8x(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + Canvas *arg1 = (Canvas *) 0 ; + GdkImage *arg2 = (GdkImage *) 0 ; + int arg3 ; + int arg4 ; + int arg5 ; + int arg6 ; + int arg7 ; + int arg8 ; + bool arg9 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + int val5 ; + int ecode5 = 0 ; + int val6 ; + int ecode6 = 0 ; + int val7 ; + int ecode7 = 0 ; + int val8 ; + int ecode8 = 0 ; + bool val9 ; + int ecode9 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; + PyObject * obj5 = 0 ; + PyObject * obj6 = 0 ; + PyObject * obj7 = 0 ; + PyObject * obj8 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO:Canvas_blit_8x",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Canvas, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Canvas_blit_8x" "', argument " "1"" of type '" "Canvas *""'"); + } + arg1 = reinterpret_cast< Canvas * >(argp1); + { + // todo- Error checking would be nice. + PyGObject* pygo = (PyGObject*)obj1; + GdkImage* img = (GdkImage*)pygo->obj; + arg2 = img; + } + ecode3 = SWIG_AsVal_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Canvas_blit_8x" "', argument " "3"" of type '" "int""'"); + } + arg3 = static_cast< int >(val3); + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Canvas_blit_8x" "', argument " "4"" of type '" "int""'"); + } + arg4 = static_cast< int >(val4); + ecode5 = SWIG_AsVal_int(obj4, &val5); + if (!SWIG_IsOK(ecode5)) { + SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "Canvas_blit_8x" "', argument " "5"" of type '" "int""'"); + } + arg5 = static_cast< int >(val5); + ecode6 = SWIG_AsVal_int(obj5, &val6); + if (!SWIG_IsOK(ecode6)) { + SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "Canvas_blit_8x" "', argument " "6"" of type '" "int""'"); + } + arg6 = static_cast< int >(val6); + ecode7 = SWIG_AsVal_int(obj6, &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "Canvas_blit_8x" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + ecode8 = SWIG_AsVal_int(obj7, &val8); + if (!SWIG_IsOK(ecode8)) { + SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "Canvas_blit_8x" "', argument " "8"" of type '" "int""'"); + } + arg8 = static_cast< int >(val8); + ecode9 = SWIG_AsVal_bool(obj8, &val9); + if (!SWIG_IsOK(ecode9)) { + SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "Canvas_blit_8x" "', argument " "9"" of type '" "bool""'"); + } + arg9 = static_cast< bool >(val9); + (arg1)->blit_8x(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_Canvas_downsize_video(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; Canvas *arg1 = (Canvas *) 0 ; @@ -11597,8 +11781,10 @@ static PyMethodDef SwigMethods[] = { { (char *)"Canvas_update_playback", _wrap_Canvas_update_playback, METH_VARARGS, NULL}, { (char *)"Canvas_get_num_commands", _wrap_Canvas_get_num_commands, METH_VARARGS, NULL}, { (char *)"Canvas_play_range", _wrap_Canvas_play_range, METH_VARARGS, NULL}, + { (char *)"Canvas_blit_1x", _wrap_Canvas_blit_1x, METH_VARARGS, NULL}, { (char *)"Canvas_blit_2x", _wrap_Canvas_blit_2x, METH_VARARGS, NULL}, { (char *)"Canvas_blit_4x", _wrap_Canvas_blit_4x, METH_VARARGS, NULL}, + { (char *)"Canvas_blit_8x", _wrap_Canvas_blit_8x, METH_VARARGS, NULL}, { (char *)"Canvas_downsize_video", _wrap_Canvas_downsize_video, METH_VARARGS, NULL}, { (char *)"Canvas_videopaint_motion", _wrap_Canvas_videopaint_motion, METH_VARARGS, NULL}, { (char *)"Canvas_blit_videopaint", _wrap_Canvas_blit_videopaint, METH_VARARGS, NULL}, -- cgit v0.9.1