Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x_colorsc.sobin608335 -> 623290 bytes
-rwxr-xr-xcolors.py126
-rw-r--r--colorsc.py2
-rw-r--r--src/canvas.h457
-rw-r--r--src/colorsc_wrap.cxx186
5 files changed, 556 insertions, 215 deletions
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},