From 411f9d06686573063a02d1f2953c58090996cb45 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Wed, 13 Sep 2017 16:41:36 -0700 Subject: [PATCH] Improvements to fix for copyPixels using alpha image (resolve #1707) --- lime/graphics/utils/ImageDataUtil.hx | 73 ++++++++++++------ .../include/graphics/utils/ImageDataUtil.h | 5 +- project/src/graphics/utils/ImageDataUtil.cpp | 74 +++++++++++++------ 3 files changed, 108 insertions(+), 44 deletions(-) diff --git a/lime/graphics/utils/ImageDataUtil.hx b/lime/graphics/utils/ImageDataUtil.hx index 0c11a2ffd..c001d534f 100644 --- a/lime/graphics/utils/ImageDataUtil.hx +++ b/lime/graphics/utils/ImageDataUtil.hx @@ -284,20 +284,20 @@ class ImageDataUtil { var alphaData = alphaImage.buffer.data; var alphaFormat = alphaImage.buffer.format; + var alphaPosition, alphaPixel:RGBA; var alphaView = new ImageDataView (alphaImage, new Rectangle (alphaPoint.x, alphaPoint.y, alphaImage.width, alphaImage.height)); - var alphaPosition, alphaPixel:RGBA; - var alphaOffsetY = alphaView.y + sourceView.y; + alphaView.offset (sourceView.x, sourceView.y); + + destView.clip (Std.int (destPoint.x), Std.int (destPoint.y), alphaView.width, alphaView.height); if (blend) { for (y in 0...destView.height) { - if (!alphaView.hasRow (y + alphaOffsetY)) continue; - sourcePosition = sourceView.row (y); destPosition = destView.row (y); - alphaPosition = alphaView.row (y + alphaOffsetY); + alphaPosition = alphaView.row (y); for (x in 0...destView.width) { @@ -334,11 +334,9 @@ class ImageDataUtil { for (y in 0...destView.height) { - if (!alphaView.hasRow (y + alphaOffsetY)) continue; - sourcePosition = sourceView.row (y); destPosition = destView.row (y); - alphaPosition = alphaView.row (y + alphaOffsetY); + alphaPosition = alphaView.row (y); for (x in 0...destView.width) { @@ -1540,8 +1538,8 @@ private class ImageDataView { public var height (default, null):Int; public var width (default, null):Int; + private var byteOffset:Int; private var image:Image; - private var offset:Int; private var rect:Rectangle; private var stride:Int; @@ -1568,11 +1566,7 @@ private class ImageDataView { stride = image.buffer.stride; - x = Math.ceil (this.rect.x); - y = Math.ceil (this.rect.y); - width = Math.floor (this.rect.width); - height = Math.floor (this.rect.height); - offset = (stride * (this.y + image.offsetY)) + ((this.x + image.offsetX) * 4); + __update (); } @@ -1580,12 +1574,7 @@ private class ImageDataView { public function clip (x:Int, y:Int, width:Int, height:Int):Void { rect.__contract (x, y, width, height); - - this.x = Math.ceil (rect.x); - this.y = Math.ceil (rect.y); - this.width = Math.floor (rect.width); - this.height = Math.floor (rect.height); - offset = (stride * (this.y + image.offsetY)) + ((this.x + image.offsetX) * 4); + __update (); } @@ -1597,9 +1586,51 @@ private class ImageDataView { } + public function offset (x:Int, y:Int):Void { + + if (x < 0) { + + rect.x += x; + if (rect.x < 0) rect.x = 0; + + } else { + + rect.x += x; + rect.width -= x; + + } + + if (y < 0) { + + rect.y += y; + if (rect.y < 0) rect.y = 0; + + } else { + + rect.y += y; + rect.height -= y; + + } + + __update (); + + } + + public inline function row (y:Int):Int { - return offset + stride * y; + return byteOffset + stride * y; + + } + + + private function __update ():Void { + + this.x = Math.ceil (rect.x); + this.y = Math.ceil (rect.y); + this.width = Math.floor (rect.width); + this.height = Math.floor (rect.height); + byteOffset = (stride * (this.y + image.offsetY)) + ((this.x + image.offsetX) * 4); } diff --git a/project/include/graphics/utils/ImageDataUtil.h b/project/include/graphics/utils/ImageDataUtil.h index e013013be..2385ee660 100644 --- a/project/include/graphics/utils/ImageDataUtil.h +++ b/project/include/graphics/utils/ImageDataUtil.h @@ -49,6 +49,7 @@ namespace lime { void Clip (int x, int y, int width, int height); bool HasRow (int y); + void Offset (int x, int y); int Row (int y); int x; @@ -58,8 +59,10 @@ namespace lime { private: + void __Update (); + + int byteOffset; Image* image; - int offset; Rectangle* rect; int stride; diff --git a/project/src/graphics/utils/ImageDataUtil.cpp b/project/src/graphics/utils/ImageDataUtil.cpp index 3bbcf483f..b8d96bedd 100644 --- a/project/src/graphics/utils/ImageDataUtil.cpp +++ b/project/src/graphics/utils/ImageDataUtil.cpp @@ -210,22 +210,22 @@ namespace lime { uint8_t* alphaData = (uint8_t*)alphaImage->buffer->data->Data (); PixelFormat alphaFormat = alphaImage->buffer->format; bool alphaPremultiplied = alphaImage->buffer->premultiplied; + int alphaPosition; + RGBA alphaPixel; Rectangle alphaRect = Rectangle (alphaPoint->x, alphaPoint->y, alphaImage->width, alphaImage->height); ImageDataView alphaView = ImageDataView (alphaImage, &alphaRect); - int alphaPosition; - RGBA alphaPixel; - int alphaOffsetY = alphaView.y + sourceView.y; + alphaView.Offset (sourceView.x, sourceView.y); + + destView.Clip (destPoint->x, destPoint->y, alphaView.width, alphaView.height); if (blend) { for (int y = 0; y < destView.height; y++) { - if (!alphaView.HasRow (y + alphaOffsetY)) continue; - sourcePosition = sourceView.Row (y); destPosition = destView.Row (y); - alphaPosition = alphaView.Row (y + alphaOffsetY); + alphaPosition = alphaView.Row (y); for (int x = 0; x < destView.width; x++) { @@ -262,11 +262,9 @@ namespace lime { for (int y = 0; y < destView.height; y++) { - if (!alphaView.HasRow (y + alphaOffsetY)) continue; - sourcePosition = sourceView.Row (y); destPosition = destView.Row (y); - alphaPosition = alphaView.Row (y + alphaOffsetY); + alphaPosition = alphaView.Row (y); for (int x = 0; x < destView.width; x++) { @@ -826,11 +824,7 @@ namespace lime { stride = image->buffer->Stride (); - x = (int) ceil (this->rect->x); - y = (int) ceil (this->rect->y); - width = (int) floor (this->rect->width); - height = (int) floor (this->rect->height); - offset = (stride * (this->y + image->offsetY)) + ((this->x + image->offsetX) * 4); + __Update (); } @@ -839,13 +833,7 @@ namespace lime { void ImageDataView::Clip (int x, int y, int width, int height) { rect->Contract (x, y, width, height); - - this->x = (int) ceil (rect->x); - this->y = (int) ceil (rect->y); - this->width = (int) floor (rect->width); - this->height = (int) floor (rect->height); - offset = (stride * (this->y + image->offsetY)) + ((this->x + image->offsetX) * 4); - + __Update (); } @@ -857,9 +845,51 @@ namespace lime { } + void ImageDataView::Offset (int x, int y) { + + if (x < 0) { + + rect->x += x; + if (rect->x < 0) rect->x = 0; + + } else { + + rect->x += x; + rect->width -= x; + + } + + if (y < 0) { + + rect->y += y; + if (rect->y < 0) rect->y = 0; + + } else { + + rect->y += y; + rect->height -= y; + + } + + __Update (); + + } + + inline int ImageDataView::Row (int y) { - return offset + stride * y; + return byteOffset + stride * y; + + } + + + inline void ImageDataView::__Update () { + + this->x = (int) ceil (rect->x); + this->y = (int) ceil (rect->y); + this->width = (int) floor (rect->width); + this->height = (int) floor (rect->height); + byteOffset = (stride * (this->y + image->offsetY)) + ((this->x + image->offsetX) * 4); }