From e36aaa5dfc2dc40259d1366fc3bb9b6c4a783d02 Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 2 May 2014 19:44:26 -0300 Subject: [PATCH] Fix issue #197 - Index 0 is made transparent, even when it is not the transparent color Now image_scale and ase_parallelogram_map_standard functions use the image mask color. --- src/app/ui/editor/moving_pixels_state.cpp | 7 +- src/app/ui/editor/pixels_movement.cpp | 14 ++-- src/raster/rotate.cpp | 98 ++++++++++++++--------- src/raster/rotsprite.cpp | 14 +++- 4 files changed, 77 insertions(+), 56 deletions(-) diff --git a/src/app/ui/editor/moving_pixels_state.cpp b/src/app/ui/editor/moving_pixels_state.cpp index 0a02435ab..d6bab0d31 100644 --- a/src/app/ui/editor/moving_pixels_state.cpp +++ b/src/app/ui/editor/moving_pixels_state.cpp @@ -392,11 +392,10 @@ void MovingPixelsState::setTransparentColor(const app::Color& color) { ASSERT(m_pixelsMovement != NULL); - Sprite* sprite = m_currentEditor->getSprite(); - ASSERT(sprite != NULL); + Layer* layer = m_currentEditor->getLayer(); + ASSERT(layer != NULL); - PixelFormat format = sprite->getPixelFormat(); - m_pixelsMovement->setMaskColor(color_utils::color_for_image(color, format)); + m_pixelsMovement->setMaskColor(color_utils::color_for_layer(color, layer)); } void MovingPixelsState::dropPixels(Editor* editor) diff --git a/src/app/ui/editor/pixels_movement.cpp b/src/app/ui/editor/pixels_movement.cpp index 3f90db158..39cc4def2 100644 --- a/src/app/ui/editor/pixels_movement.cpp +++ b/src/app/ui/editor/pixels_movement.cpp @@ -569,16 +569,14 @@ gfx::Size PixelsMovement::getInitialImageSize() const void PixelsMovement::setMaskColor(uint32_t mask_color) { - { - ContextWriter writer(m_reader); - Image* extraImage = m_document->getExtraCelImage(); + ContextWriter writer(m_reader); + Image* extraImage = m_document->getExtraCelImage(); - ASSERT(extraImage != NULL); + ASSERT(extraImage != NULL); - extraImage->setMaskColor(mask_color); - redrawExtraImage(); - update_screen_for_document(m_document); - } + extraImage->setMaskColor(mask_color); + redrawExtraImage(); + update_screen_for_document(m_document); } diff --git a/src/raster/rotate.cpp b/src/raster/rotate.cpp index 838765838..93bbfa24b 100644 --- a/src/raster/rotate.cpp +++ b/src/raster/rotate.cpp @@ -63,12 +63,19 @@ static color_t grayscale_blender(color_t back, color_t front) { return graya_blenders[BLEND_MODE_NORMAL](back, front, 255); } -static color_t if_blender(color_t back, color_t front) { - if (front != 0) - return front; - else - return back; -} +class if_blender { +public: + if_blender(color_t mask) : m_mask(mask) { + } + color_t operator()(color_t back, color_t front) { + if (front != m_mask) + return front; + else + return back; + } +private: + color_t m_mask; +}; void image_scale(Image *dst, Image *src, int x, int y, int w, int h) { @@ -86,11 +93,11 @@ void image_scale(Image *dst, Image *src, int x, int y, int w, int h) break; case IMAGE_INDEXED: - image_scale_tpl(dst, src, x, y, w, h, if_blender); + image_scale_tpl(dst, src, x, y, w, h, if_blender(src->getMaskColor())); break; case IMAGE_BITMAP: - image_scale_tpl(dst, src, x, y, w, h, if_blender); + image_scale_tpl(dst, src, x, y, w, h, if_blender(0)); break; } } @@ -138,15 +145,16 @@ void image_parallelogram (Image *bmp, Image *sprite, template static void draw_scanline(Image *bmp, Image *spr, - fixed l_bmp_x, int bmp_y_i, - fixed r_bmp_x, - fixed l_spr_x, fixed l_spr_y, - fixed spr_dx, fixed spr_dy) + fixed l_bmp_x, int bmp_y_i, + fixed r_bmp_x, + fixed l_spr_x, fixed l_spr_y, + fixed spr_dx, fixed spr_dy, + Delegate& delegate) { r_bmp_x >>= 16; l_bmp_x >>= 16; - Delegate delegate(bmp, gfx::Rect(l_bmp_x, bmp_y_i, r_bmp_x - l_bmp_x + 1, 1)); + delegate.lockBits(bmp, gfx::Rect(l_bmp_x, bmp_y_i, r_bmp_x - l_bmp_x + 1, 1)); for (int x=(int)l_bmp_x; x<=(int)r_bmp_x; ++x) { delegate.feedLine(spr, l_spr_x>>16, l_spr_y>>16); @@ -154,30 +162,34 @@ static void draw_scanline(Image *bmp, Image *spr, l_spr_x += spr_dx; l_spr_y += spr_dy; } + + delegate.unlockBits(); } template class GenericDelegate { public: - GenericDelegate(Image* bmp, const gfx::Rect& bounds) : - m_bits(bmp, Image::ReadWriteLock, bounds), - m_it(m_bits.begin()), - m_end(m_bits.end()) { + void lockBits(Image* bmp, const gfx::Rect& bounds) { + m_bits = bmp->lockBits(Image::ReadWriteLock, bounds); + m_it = m_bits.begin(); + m_end = m_bits.end(); + } + + void unlockBits() { + m_bits.unlock(); } private: - LockImageBits m_bits; + ImageBits m_bits; protected: typename LockImageBits::iterator m_it, m_end; }; class RgbDelegate : public GenericDelegate { - BLEND_COLOR m_blender; public: - RgbDelegate(Image* bmp, const gfx::Rect& bounds) : - GenericDelegate(bmp, bounds), - m_blender(rgba_blenders[BLEND_MODE_NORMAL]) { + RgbDelegate() { + m_blender = rgba_blenders[BLEND_MODE_NORMAL]; } void feedLine(Image* spr, int spr_x, int spr_y) { @@ -186,14 +198,15 @@ public: *m_it = m_blender(*m_it, spr->getPixel(spr_x, spr_y), 255); ++m_it; } + +private: + BLEND_COLOR m_blender; }; class GrayscaleDelegate : public GenericDelegate { - BLEND_COLOR m_blender; public: - GrayscaleDelegate(Image* bmp, const gfx::Rect& bounds) : - GenericDelegate(bmp, bounds), - m_blender(graya_blenders[BLEND_MODE_NORMAL]) { + GrayscaleDelegate() { + m_blender = graya_blenders[BLEND_MODE_NORMAL]; } void feedLine(Image* spr, int spr_x, int spr_y) { @@ -202,30 +215,32 @@ public: *m_it = m_blender(*m_it, spr->getPixel(spr_x, spr_y), 255); ++m_it; } + +private: + BLEND_COLOR m_blender; }; class IndexedDelegate : public GenericDelegate { public: - IndexedDelegate(Image* bmp, const gfx::Rect& bounds) : - GenericDelegate(bmp, bounds) { + IndexedDelegate(color_t mask_color) : + m_mask_color(mask_color) { } void feedLine(Image* spr, int spr_x, int spr_y) { ASSERT(m_it != m_end); register int c = spr->getPixel(spr_x, spr_y); - if (c != 0) // TODO + if (c != m_mask_color) *m_it = c; ++m_it; } + +private: + color_t m_mask_color; }; class BitmapDelegate : public GenericDelegate { public: - BitmapDelegate(Image* bmp, const gfx::Rect& bounds) : - GenericDelegate(bmp, bounds) { - } - void feedLine(Image* spr, int spr_x, int spr_y) { ASSERT(m_it != m_end); @@ -261,8 +276,9 @@ public: * anti-aliased blending. */ template -static void ase_parallelogram_map(Image *bmp, Image *spr, fixed xs[4], fixed ys[4], - int sub_pixel_accuracy) +static void ase_parallelogram_map( + Image *bmp, Image *spr, fixed xs[4], fixed ys[4], + int sub_pixel_accuracy, Delegate& delegate = Delegate()) { /* Index in xs[] and ys[] to topmost point. */ int top_index; @@ -634,9 +650,9 @@ static void ase_parallelogram_map(Image *bmp, Image *spr, fixed xs[4], fixed ys[ } } draw_scanline(bmp, spr, - l_bmp_x_rounded, bmp_y_i, r_bmp_x_rounded, - l_spr_x_rounded, l_spr_y_rounded, - spr_dx, spr_dy); + l_bmp_x_rounded, bmp_y_i, r_bmp_x_rounded, + l_spr_x_rounded, l_spr_y_rounded, + spr_dx, spr_dy, delegate); } /* I'm not going to apoligize for this label and its gotos: to get @@ -677,9 +693,11 @@ static void ase_parallelogram_map_standard(Image *bmp, Image *sprite, ase_parallelogram_map(bmp, sprite, xs, ys, false); break; - case IMAGE_INDEXED: - ase_parallelogram_map(bmp, sprite, xs, ys, false); + case IMAGE_INDEXED: { + IndexedDelegate delegate(bmp->getMaskColor()); + ase_parallelogram_map(bmp, sprite, xs, ys, false, delegate); break; + } case IMAGE_BITMAP: ase_parallelogram_map(bmp, sprite, xs, ys, false); diff --git a/src/raster/rotsprite.cpp b/src/raster/rotsprite.cpp index a34f7951e..9c4f8ce7d 100644 --- a/src/raster/rotsprite.cpp +++ b/src/raster/rotsprite.cpp @@ -168,7 +168,7 @@ void image_rotsprite(Image* bmp, Image* spr, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) { - static ImageBufferPtr buf1, buf2, buf3; + static ImageBufferPtr buf1, buf2, buf3; // TODO non-thread safe if (!buf1) buf1.reset(new ImageBuffer(1)); if (!buf2) buf2.reset(new ImageBuffer(1)); @@ -179,12 +179,18 @@ void image_rotsprite(Image* bmp, Image* spr, base::UniquePtr tmp_copy(Image::create(spr->getPixelFormat(), spr->getWidth()*scale, spr->getHeight()*scale, buf2)); base::UniquePtr spr_copy(Image::create(spr->getPixelFormat(), spr->getWidth()*scale, spr->getHeight()*scale, buf3)); - bmp_copy->clear(0); - spr_copy->clear(0); + color_t maskColor = bmp->getMaskColor(); + + bmp_copy->setMaskColor(maskColor); + tmp_copy->setMaskColor(maskColor); + spr_copy->setMaskColor(maskColor); + + bmp_copy->clear(maskColor); + spr_copy->clear(maskColor); spr_copy->copy(spr, 0, 0); for (int i=0; i<3; ++i) { - tmp_copy->clear(0); + tmp_copy->clear(maskColor); image_scale2x(tmp_copy, spr_copy, spr->getWidth()*(1<getHeight()*(1<copy(tmp_copy, 0, 0); }