Skip to content
Browse files

[BitmapData] Implement copyChannel

  • Loading branch information...
1 parent c425e99 commit ef2aab988100d6ab53d50723ed63375d628a4442 @aajanki aajanki committed Mar 3, 2013
View
1 src/allclasses.h
@@ -62,6 +62,7 @@ REGISTER_CLASS_NAME(NativeApplication,"flash.desktop")
REGISTER_CLASS_NAME(AVM1Movie,"flash.display")
REGISTER_CLASS_NAME(Bitmap,"flash.display")
REGISTER_CLASS_NAME(BitmapData,"flash.display")
+REGISTER_CLASS_NAME(BitmapDataChannel,"flash.display")
REGISTER_CLASS_NAME(BlendMode,"flash.display")
REGISTER_CLASS_NAME(DisplayObject,"flash.display")
REGISTER_CLASS_NAME(DisplayObjectContainer,"flash.display")
View
1 src/scripting/abc.cpp
@@ -267,6 +267,7 @@ void ABCVm::registerClasses()
builtin->registerBuiltin("Scene","flash.display",Class<Scene>::getRef());
builtin->registerBuiltin("AVM1Movie","flash.display",Class<AVM1Movie>::getRef());
builtin->registerBuiltin("Shader","flash.display",Class<Shader>::getRef());
+ builtin->registerBuiltin("BitmapDataChannel","flash.display",Class<BitmapDataChannel>::getRef());
builtin->registerBuiltin("BitmapFilter","flash.filters",Class<BitmapFilter>::getRef());
builtin->registerBuiltin("DropShadowFilter","flash.filters",Class<DropShadowFilter>::getRef());
View
92 src/scripting/flash/display/BitmapData.cpp
@@ -68,6 +68,7 @@ void BitmapData::sinit(Class_base* c)
c->setDeclaredMethodByQName("hitTest","",Class<IFunction>::getFunction(hitTest),NORMAL_METHOD,true);
c->setDeclaredMethodByQName("scroll","",Class<IFunction>::getFunction(scroll),NORMAL_METHOD,true);
c->setDeclaredMethodByQName("clone","",Class<IFunction>::getFunction(clone),NORMAL_METHOD,true);
+ c->setDeclaredMethodByQName("copyChannel","",Class<IFunction>::getFunction(copyChannel),NORMAL_METHOD,true);
// properties
c->setDeclaredMethodByQName("height","",Class<IFunction>::getFunction(_getHeight),GETTER_METHOD,true);
@@ -404,3 +405,94 @@ ASFUNCTIONBODY(BitmapData,clone)
return Class<BitmapData>::getInstanceS(*th);
}
+
+void BitmapData::clipRect(_R<BitmapData> source, _R<Rectangle> sourceRect,
+ _R<Point> destPoint, RECT& outputSourceRect,
+ Vector2& outputDestPoint)
+{
+ int sLeft = imax(sourceRect->x, 0);
+ int sTop = imax(sourceRect->y, 0);
+ int sRight = imin(sourceRect->x+sourceRect->width, source->getWidth());
+ int sBottom = imin(sourceRect->y+sourceRect->height, source->getHeight());
+
+ int dLeft = destPoint->getX();
+ int dTop = destPoint->getY();
+ if (dLeft < 0)
+ {
+ sLeft += -dLeft;
+ dLeft = 0;
+ }
+ if (dTop < 0)
+ {
+ sTop += -dTop;
+ dTop = 0;
+ }
+
+ int clippedWidth = imin(sRight - sLeft, getWidth() - dLeft);
+ int clippedHeight = imin(sBottom - sTop, getHeight() - dTop);
+
+ outputSourceRect.Xmin = sLeft;
+ outputSourceRect.Xmax = sLeft + clippedWidth;
+ outputSourceRect.Ymin = sTop;
+ outputSourceRect.Ymax = sTop + clippedHeight;
+
+ outputDestPoint.x = dLeft;
+ outputDestPoint.y = dTop;
+}
+
+ASFUNCTIONBODY(BitmapData,copyChannel)
+{
+ BitmapData* th = obj->as<BitmapData>();
+ if(th->pixels.isNull())
+ throw Class<ArgumentError>::getInstanceS("Disposed BitmapData", 2015);
+
+ _NR<BitmapData> source;
+ _NR<Rectangle> sourceRect;
+ _NR<Point> destPoint;
+ uint32_t sourceChannel;
+ uint32_t destChannel;
+ ARG_UNPACK (source) (sourceRect) (destPoint) (sourceChannel) (destChannel);
+
+ if (source.isNull())
+ throwError<TypeError>(kNullPointerError, "source");
+ if (sourceRect.isNull())
+ throwError<TypeError>(kNullPointerError, "sourceRect");
+ if (destPoint.isNull())
+ throwError<TypeError>(kNullPointerError, "destPoint");
+
+ unsigned int sourceShift = BitmapDataChannel::channelShift(sourceChannel);
+ unsigned int destShift = BitmapDataChannel::channelShift(destChannel);
+
+ RECT clippedSourceRect;
+ Vector2 clippedDestPoint;
+ th->clipRect(source, sourceRect, destPoint, clippedSourceRect, clippedDestPoint);
+ int regionWidth = clippedSourceRect.Xmax - clippedSourceRect.Xmin;
+ int regionHeight = clippedSourceRect.Ymax - clippedSourceRect.Ymin;
+
+ if (regionWidth < 0 || regionHeight < 0)
+ return NULL;
+
+ uint32_t constantChannelsMask = ~(0xFF << destShift);
+ for (int32_t y=0; y<regionHeight; y++)
+ {
+ for (int32_t x=0; x<regionWidth; x++)
+ {
+ int32_t sx = clippedSourceRect.Xmin+x;
+ int32_t sy = clippedSourceRect.Ymin+y;
+ uint32_t sourcePixel = source->pixels->getPixel(sx, sy);
+ uint32_t channel = (sourcePixel >> sourceShift) & 0xFF;
+ uint32_t destChannelValue = channel << destShift;
+
+ int32_t dx = clippedDestPoint.x + x;
+ int32_t dy = clippedDestPoint.y + y;
+ uint32_t oldPixel = th->pixels->getPixel(dx, dy);
+ uint32_t newColor = (oldPixel & constantChannelsMask) | destChannelValue;
+ th->pixels->setPixel(dx, dy, newColor, true);
+ }
+ }
+
+ th->notifyUsers();
+
+ return NULL;
+}
+
View
8 src/scripting/flash/display/BitmapData.h
@@ -29,6 +29,8 @@ namespace lightspark
class Bitmap;
class DisplayObject;
+class Point;
+class Rectangle;
class BitmapData: public ASObject, public IBitmapDrawable
{
@@ -38,6 +40,11 @@ class BitmapData: public ASObject, public IBitmapDrawable
//Bitmap will take care of removing itself when needed
std::set<Bitmap*> users;
void notifyUsers() const;
+ // Clip a rectangle to fit both source and destination
+ // bitmaps.
+ void clipRect(_R<BitmapData> source, _R<Rectangle> sourceRect,
+ _R<Point> destPoint, RECT& outputSourceRect,
+ Vector2& outputDestPoint);
public:
BitmapData(Class_base* c);
BitmapData(Class_base* c, _R<BitmapContainer> b);
@@ -74,6 +81,7 @@ class BitmapData: public ASObject, public IBitmapDrawable
ASFUNCTION(_getHeight);
ASFUNCTION(scroll);
ASFUNCTION(clone);
+ ASFUNCTION(copyChannel);
};
};
View
33 src/scripting/flash/display/flashdisplay.cpp
@@ -3479,3 +3479,36 @@ ASFUNCTIONBODY(Shader,_constructor)
LOG(LOG_NOT_IMPLEMENTED, _("Shader class is unimplemented."));
return NULL;
}
+
+void BitmapDataChannel::sinit(Class_base* c)
+{
+ c->setConstructor(NULL);
+ c->setSuper(Class<ASObject>::getRef());
+ c->setVariableByQName("ALPHA","",abstract_ui(8),DECLARED_TRAIT);
+ c->setVariableByQName("BLUE","",abstract_ui(4),DECLARED_TRAIT);
+ c->setVariableByQName("GREEN","",abstract_ui(2),DECLARED_TRAIT);
+ c->setVariableByQName("RED","",abstract_ui(1),DECLARED_TRAIT);
+}
+
+unsigned int BitmapDataChannel::channelShift(uint32_t channelConstant)
+{
+ unsigned int shift;
+ switch (channelConstant)
+ {
+ case BitmapDataChannel::ALPHA:
+ shift = 24;
+ break;
+ case BitmapDataChannel::RED:
+ shift = 16;
+ break;
+ case BitmapDataChannel::GREEN:
+ shift = 8;
+ break;
+ case BitmapDataChannel::BLUE:
+ default: // check
+ shift = 0;
+ break;
+ }
+
+ return shift;
+}
View
10 src/scripting/flash/display/flashdisplay.h
@@ -697,6 +697,16 @@ class Shader : public ASObject
ASFUNCTION(_constructor);
};
+class BitmapDataChannel : public ASObject
+{
+public:
+ enum {RED=1, GREEN=2, BLUE=4, ALPHA=8};
+ BitmapDataChannel(Class_base* c):ASObject(c){}
+ static void sinit(Class_base* c);
+ ASFUNCTION(_constructor);
+ static unsigned int channelShift(uint32_t channelConstant);
+};
+
};
#endif /* SCRIPTING_FLASH_DISPLAY_FLASHDISPLAY_H */

0 comments on commit ef2aab9

Please sign in to comment.
Something went wrong with that request. Please try again.