Skip to content

Commit

Permalink
[BitmapData] Implement copyChannel
Browse files Browse the repository at this point in the history
  • Loading branch information
aajanki committed Mar 3, 2013
1 parent c425e99 commit ef2aab9
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/allclasses.h
Expand Up @@ -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")
Expand Down
1 change: 1 addition & 0 deletions src/scripting/abc.cpp
Expand Up @@ -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());
Expand Down
92 changes: 92 additions & 0 deletions src/scripting/flash/display/BitmapData.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

8 changes: 8 additions & 0 deletions src/scripting/flash/display/BitmapData.h
Expand Up @@ -29,6 +29,8 @@ namespace lightspark

class Bitmap;
class DisplayObject;
class Point;
class Rectangle;

class BitmapData: public ASObject, public IBitmapDrawable
{
Expand All @@ -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);
Expand Down Expand Up @@ -74,6 +81,7 @@ class BitmapData: public ASObject, public IBitmapDrawable
ASFUNCTION(_getHeight);
ASFUNCTION(scroll);
ASFUNCTION(clone);
ASFUNCTION(copyChannel);
};

};
Expand Down
33 changes: 33 additions & 0 deletions src/scripting/flash/display/flashdisplay.cpp
Expand Up @@ -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;
}
10 changes: 10 additions & 0 deletions src/scripting/flash/display/flashdisplay.h
Expand Up @@ -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.