[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/asobj/flash/display/Bitm...
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] gnash ChangeLog server/asobj/flash/display/Bitm... |
Date: |
Fri, 20 Jun 2008 11:21:09 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Benjamin Wolsey <bwy> 08/06/20 11:21:09
Modified files:
. : ChangeLog
server/asobj/flash/display: BitmapData_as.cpp
testsuite/actionscript.all: BitmapData.as
Log message:
* testsuite/actionscript.all/BitmapData.as: more tests.
* server/asobj/flash/display/BitmapData_as.cpp: implement
constructor, getPixel, getPixel32, height, width,
transparency,
fillRect.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6995&r2=1.6996
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/flash/display/BitmapData_as.cpp?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/BitmapData.as?cvsroot=gnash&r1=1.1&r2=1.2
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6995
retrieving revision 1.6996
diff -u -b -r1.6995 -r1.6996
--- ChangeLog 20 Jun 2008 08:18:01 -0000 1.6995
+++ ChangeLog 20 Jun 2008 11:21:07 -0000 1.6996
@@ -1,5 +1,12 @@
2008-06-20 Benjamin Wolsey <address@hidden>
+ * testsuite/actionscript.all/BitmapData.as: more tests.
+ * server/asobj/flash/display/BitmapData_as.cpp: implement
+ constructor, getPixel, getPixel32, height, width, transparency,
+ fillRect.
+
+2008-06-20 Benjamin Wolsey <address@hidden>
+
* server/asobj/SoundFfmpeg.h: AudioDecoder.h expects _leftOverData to
be uint32_t, which isn't always the same as size_t.
* libmedia/AudioDecoder.h: use legal header guards.
Index: server/asobj/flash/display/BitmapData_as.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/flash/display/BitmapData_as.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- server/asobj/flash/display/BitmapData_as.cpp 5 May 2008 18:53:31
-0000 1.5
+++ server/asobj/flash/display/BitmapData_as.cpp 20 Jun 2008 11:21:08
-0000 1.6
@@ -31,7 +31,10 @@
#include "Object.h" // for AS inheritance
#include "VM.h" // for addStatics
+#include <memory>
+#include <vector>
#include <sstream>
+#include <algorithm>
namespace gnash {
@@ -97,6 +100,7 @@
o.init_property("rectangle", BitmapData_rectangle_getset,
BitmapData_rectangle_getset);
o.init_property("transparent", BitmapData_transparent_getset,
BitmapData_transparent_getset);
o.init_property("width", BitmapData_width_getset, BitmapData_width_getset);
+
}
static void
@@ -128,21 +132,145 @@
class BitmapData_as: public as_object
{
+ typedef std::vector<boost::uint32_t> BitmapArray;
+
public:
- BitmapData_as()
+ // The constructor sets the fill colour and the
+ // immutable size of the bitmap, as well as whether
+ // it can handle transparency or not.
+ BitmapData_as(size_t width, size_t height,
+ bool transparent, boost::uint32_t fillColor)
:
- as_object(getBitmapDataInterface())
+ as_object(getBitmapDataInterface()),
+ _width(width),
+ _height(height),
+ _transparent(transparent),
+ _bitmapData(new BitmapArray(width * height, fillColor + (0xff
<< 24)))
{}
- // override from as_object ?
- //std::string get_text_value() const { return "BitmapData"; }
+ size_t getWidth() const { return _width; }
+ size_t getHeight() const { return _height; }
+ bool isTransparent() const { return _transparent; }
+
+ // Returns an unsigned int representation of the pixel
+ // at (x, y) either with or without transparency.
+ boost::int32_t getPixel(int x, int y, bool transparency) const;
+
+ // Fill the bitmap with a colour starting at x, y
+ void fillRect(int x, int y, int w, int h, boost::uint32_t color);
+
+private:
+
+ // The width of the image, max 2880. This is immutable.
+ const size_t _width;
+
+ // The height of the image, max 2880. This is immutable.
+ const size_t _height;
+
+ // Whether the image is transparent. This is immutable.
+ const bool _transparent;
+
+ // A static array of 32-bit values holding the actual bitmap data.
+ // The maximum size is 2880 x 2880 * 4 bytes = 33177600 bytes, so
+ // this must be heap allocated.
+ std::auto_ptr<BitmapArray> _bitmapData;
- // override from as_object ?
- //double get_numeric_value() const { return 0; }
};
+//
+boost::int32_t
+BitmapData_as::getPixel(int x, int y, bool transparency) const
+{
+
+ // A value of 0, 0 is inside the bitmap.
+ if (x < 0 || y < 0) return 0;
+
+ // A value of _width, _height is outside the bitmap.
+ if (static_cast<size_t>(x) >= _width || static_cast<size_t>(y) >= _height)
return 0;
+
+ const size_t pixelIndex = y * _width + x;
+
+ assert ( pixelIndex < _bitmapData->size());
+
+ const boost::uint32_t pixel = (*_bitmapData)[pixelIndex];
+
+ if (transparency)
+ {
+ return static_cast<boost::int32_t>(pixel);
+ }
+
+ // Without transparency
+ return static_cast<boost::int32_t>(pixel & 0x00ffffff);
+
+}
+
+void
+BitmapData_as::fillRect(int x, int y, int w, int h, boost::uint32_t color)
+{
+ if (w < 0 || h < 0) return;
+
+ // Nothing to do if x or y are outside the image (negative height
+ // or width are not allowed). The cast to int is fine as neither
+ // dimension can be more than 2880 pixels.
+ if (x >= static_cast<int>(_width) || y >= static_cast<int>(_height))
return;
+
+ // If x or y is less than 0, make a rectangle of the
+ // intersection with the bitmap.
+ if (x < 0)
+ {
+ w += x;
+ x = 0;
+ }
+
+ if (y < 0)
+ {
+ h += y;
+ y = 0;
+ }
+
+ // Make sure that the rectangle has some area in the
+ // bitmap and that its bottom corner is within the
+ // the bitmap.
+ if (w <= 0 || h <= 0) return;
+ w = std::min<size_t>(_width - x, w);
+ h = std::min<size_t>(_height - y, h);
+
+ BitmapArray::iterator it = _bitmapData->begin() + y * _width;
+
+ // This cannot be past .end() because h + y is no larger than the
+ // height of the image.
+ const BitmapArray::iterator e = it + _width * h;
+
+ // Make colour non-transparent if the image doesn't support it.
+ if (!_transparent) color |= 0xff000000;
+
+ while (it != e)
+ {
+
+ // Fill from x for the width of the rectangle.
+ std::fill_n(it + x, w, color);
+
+ // Move to the next line
+ std::advance(it, _width);
+
+ }
+
+}
+
+as_function* getFlashDisplayBitmapDataConstructor()
+{
+ static builtin_function* cl = NULL;
+ if ( ! cl )
+ {
+ cl=new builtin_function(&BitmapData_ctor, getBitmapDataInterface());
+ VM::get().addStatic(cl);
+ attachBitmapDataStaticProperties(*cl);
+ }
+ return cl;
+}
+
static as_value
BitmapData_applyFilter(const fn_call& fn)
{
@@ -191,6 +319,9 @@
static as_value
BitmapData_dispose(const fn_call& fn)
{
+
+ // Should free the memory storing the bitmap.
+ // What is the size afterwards? Can it be reused?
boost::intrusive_ptr<BitmapData_as> ptr =
ensureType<BitmapData_as>(fn.this_ptr);
UNUSED(ptr);
LOG_ONCE( log_unimpl (__FUNCTION__) );
@@ -210,11 +341,42 @@
BitmapData_fillRect(const fn_call& fn)
{
boost::intrusive_ptr<BitmapData_as> ptr =
ensureType<BitmapData_as>(fn.this_ptr);
- UNUSED(ptr);
- LOG_ONCE( log_unimpl (__FUNCTION__) );
+
+ if (fn.nargs < 2) return as_value();
+
+ const as_value& arg = fn.arg(0);
+
+ if ( ! arg.is_object() )
+ {
+ /// Isn't an object...
+ IF_VERBOSE_ASCODING_ERRORS(
+ std::ostringstream ss;
+ fn.dump_args(ss);
+ log_aserror("Matrix.deltaTransformPoint(%s): needs an object",
ss.str());
+ );
+ return as_value();
+ }
+
+ // This can be any object with the right properties.
+ as_object* obj = arg.to_object().get();
+ assert(obj);
+
+ as_value x, y, w, h;
+
+ obj->get_member(NSV::PROP_X, &x);
+ obj->get_member(NSV::PROP_Y, &y);
+ obj->get_member(NSV::PROP_WIDTH, &w);
+ obj->get_member(NSV::PROP_HEIGHT, &h);
+
+ boost::uint32_t color = fn.arg(1).to_int();
+
+ ptr->fillRect(x.to_int(), y.to_int(), w.to_int(), h.to_int(), color);
+
return as_value();
}
+
+// Fills the bitmap with a colour starting at point x, y.
static as_value
BitmapData_floodFill(const fn_call& fn)
{
@@ -246,18 +408,35 @@
BitmapData_getPixel(const fn_call& fn)
{
boost::intrusive_ptr<BitmapData_as> ptr =
ensureType<BitmapData_as>(fn.this_ptr);
- UNUSED(ptr);
- LOG_ONCE( log_unimpl (__FUNCTION__) );
+
+ if (fn.nargs < 2)
+ {
return as_value();
+ }
+
+ // TODO: what happens when the pixel is outside the image?
+
+ int x = fn.arg(0).to_int();
+ int y = fn.arg(1).to_int();
+
+ return ptr->getPixel(x, y, false);
}
static as_value
BitmapData_getPixel32(const fn_call& fn)
{
boost::intrusive_ptr<BitmapData_as> ptr =
ensureType<BitmapData_as>(fn.this_ptr);
- UNUSED(ptr);
- LOG_ONCE( log_unimpl (__FUNCTION__) );
+ if (fn.nargs < 2)
+ {
return as_value();
+ }
+
+ // TODO: what happens when the pixel is outside the image?
+
+ int x = fn.arg(0).to_int();
+ int y = fn.arg(1).to_int();
+
+ return ptr->getPixel(x, y, true);
}
static as_value
@@ -354,9 +533,12 @@
BitmapData_height_getset(const fn_call& fn)
{
boost::intrusive_ptr<BitmapData_as> ptr =
ensureType<BitmapData_as>(fn.this_ptr);
- UNUSED(ptr);
- LOG_ONCE( log_unimpl (__FUNCTION__) );
- return as_value();
+
+ // Read-only
+ if (fn.nargs) return as_value();
+
+ // Returns the immutable height of the bitmap.
+ return as_value(ptr->getHeight());
}
static as_value
@@ -372,18 +554,24 @@
BitmapData_transparent_getset(const fn_call& fn)
{
boost::intrusive_ptr<BitmapData_as> ptr =
ensureType<BitmapData_as>(fn.this_ptr);
- UNUSED(ptr);
- LOG_ONCE( log_unimpl (__FUNCTION__) );
- return as_value();
+
+ // Read-only
+ if (fn.nargs) return as_value();
+
+ // Returns the immutable height of the bitmap.
+ return as_value(ptr->isTransparent());
}
static as_value
BitmapData_width_getset(const fn_call& fn)
{
boost::intrusive_ptr<BitmapData_as> ptr =
ensureType<BitmapData_as>(fn.this_ptr);
- UNUSED(ptr);
- LOG_ONCE( log_unimpl (__FUNCTION__) );
- return as_value();
+
+ // Read-only
+ if (fn.nargs) return as_value();
+
+ // Returns the immutable height of the bitmap.
+ return as_value(ptr->getWidth());
}
@@ -397,32 +585,61 @@
}
+static as_value
+get_flash_display_bitmap_data_constructor(const fn_call& /*fn*/)
+{
+ log_debug("Loading flash.display.BitmapData class");
+ return getFlashDisplayBitmapDataConstructor();
+}
+
as_value
BitmapData_ctor(const fn_call& fn)
{
- boost::intrusive_ptr<as_object> obj = new BitmapData_as;
- if ( fn.nargs )
+ if ( fn.nargs < 2)
{
- std::stringstream ss;
- fn.dump_args(ss);
- LOG_ONCE( log_unimpl("BitmapData(%s): %s", ss.str(),
_("arguments discarded")) );
+ // TODO: should fail if not enough arguments are passed.
+ boost::intrusive_ptr<as_object> obj = new as_object;
+ return as_value(obj.get());
}
+ size_t width, height;
+ bool transparent = true;
+ boost::uint32_t fillColor = 0xffffff;
+
+ switch (fn.nargs)
+ {
+ default:
+ // log AS coding error
+ case 4:
+ fillColor = fn.arg(3).to_int();
+ case 3:
+ transparent = fn.arg(2).to_bool();
+ case 2:
+ // Is to_int correct?
+ height = fn.arg(1).to_int();
+ width = fn.arg(0).to_int();
+ break;
+ }
+
+ // Should fail to construct the object.
+ if (width > 2880) width = 2880;
+ if (height > 2880) height = 2880;
+
+ boost::intrusive_ptr<BitmapData_as> obj =
+ new BitmapData_as(width, height, transparent, fillColor);
+
return as_value(obj.get()); // will keep alive
}
// extern
void BitmapData_class_init(as_object& where)
{
- // This is going to be the BitmapData "class"/"function"
- // in the 'where' package
- boost::intrusive_ptr<builtin_function> cl;
- cl=new builtin_function(&BitmapData_ctor, getBitmapDataInterface());
- attachBitmapDataStaticProperties(*cl);
+ string_table& st = where.getVM().getStringTable();
// Register _global.BitmapData
- where.init_member("BitmapData", cl.get());
+ where.init_destructive_property(st.find("BitmapData"),
+ get_flash_display_bitmap_data_constructor);
}
} // end of gnash namespace
Index: testsuite/actionscript.all/BitmapData.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/BitmapData.as,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- testsuite/actionscript.all/BitmapData.as 19 Jun 2008 17:40:15 -0000
1.1
+++ testsuite/actionscript.all/BitmapData.as 20 Jun 2008 11:21:09 -0000
1.2
@@ -20,7 +20,7 @@
// compile this test case with Ming makeswf, and then
// execute it like this gnash -1 -r 0 -v out.swf
-rcsid="$Id: BitmapData.as,v 1.1 2008/06/19 17:40:15 bwy Exp $";
+rcsid="$Id: BitmapData.as,v 1.2 2008/06/20 11:21:09 bwy Exp $";
#include "check.as"
@@ -80,26 +80,113 @@
check(!bmp.hasOwnProperty("width"));
check(!bmp.hasOwnProperty("rectangle"));
check(!bmp.hasOwnProperty("transparent"));
-xcheck_equals(bmp.height, 10);
-xcheck_equals(bmp.width, 10);
-xcheck_equals(bmp.transparent, true);
+check_equals(bmp.height, 10);
+check_equals(bmp.width, 10);
+check_equals(bmp.transparent, true);
xcheck_equals(bmp.rectangle.toString(), "(x=0, y=0, w=10, h=10)");
-xcheck_equals(bmp.getPixel(1, 1), 16777215);
-xcheck_equals(bmp.getPixel(9, 9), 16777215);
-xcheck_equals(bmp.getPixel32(1, 1), -1);
+check_equals(bmp.getPixel(1, 1), 16777215);
+check_equals(bmp.getPixel(9, 9), 16777215);
+check_equals(bmp.getPixel32(1, 1), -1);
+
+bmp = new Bitmap(10, 10, true);
+check_equals(bmp.getPixel32(1, 1), -1);
+bmp = new Bitmap(10, 10, false);
+check_equals(bmp.getPixel32(1, 1), -1);
+
bmp = new Bitmap(20, 30, false, 0xeeddee);
-xcheck_equals(bmp.height, 30);
-xcheck_equals(bmp.width, 20);
-xcheck_equals(bmp.transparent, false);
+check_equals(bmp.height, 30);
+check_equals(bmp.width, 20);
+check_equals(bmp.transparent, false);
xcheck_equals(bmp.rectangle.toString(), "(x=0, y=0, w=20, h=30)");
-xcheck_equals(bmp.getPixel(1, 1), 0xeeddee);
-xcheck_equals(bmp.getPixel32(1, 1), -1122834);
+check_equals(bmp.getPixel(1, 1), 0xeeddee);
+check_equals(bmp.getPixel32(1, 1), -1122834);
+
+// limits
+
+check_equals(bmp.getPixel(50, 1), 0);
+check_equals(bmp.getPixel(0, 0), 15654382);
+check_equals(bmp.getPixel(-2, -5), 0);
+
+// 0,0 is inside, 20, 30 outside a 20x30 bitmap.
+check_equals(bmp.getPixel(20, 30), 0);
+
+bmp = new Bitmap(10000, 0);
+xcheck_equals(bmp, undefined);
+bmp = new Bitmap(0, 10000);
+xcheck_equals(bmp, undefined);
+
+bmp = new Bitmap(2881, 0);
+xcheck_equals(bmp, undefined);
+bmp = new Bitmap(0, 2881);
+xcheck_equals(bmp, undefined);
+
+
+// floodFill
+bmp = new Bitmap(20, 20, false);
+bmp.floodFill(10, 10, 0x0000ff00);
+
+xcheck_equals(bmp.getPixel(10, 10), 0x0000ff00);
+bmp.floodFill(5, 5, 0x000000ff);
+xcheck_equals(bmp.getPixel(10, 0), 0x000000ff);
+
+mc = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
+mc.attachBitmap(bmp, this.getNextHighestDepth());
+
+Rectangle = flash.geom.Rectangle;
+
+bmp = new Bitmap(20, 20, false);
+r = new Rectangle(2, 2, 5, 5);
+bmp.fillRect(r, 0xff1100);
+check_equals(bmp.getPixel(1, 1), 0xffffff);
+check_equals(bmp.getPixel(2, 2), 0xff1100);
+check_equals(bmp.getPixel(2, 5), 0xff1100);
+check_equals(bmp.getPixel(5, 2), 0xff1100);
+check_equals(bmp.getPixel(2, 6), 0xff1100);
+check_equals(bmp.getPixel(6, 6), 0xff1100);
+check_equals(bmp.getPixel(6, 7), 0xffffff);
+check_equals(bmp.getPixel(7, 6), 0xffffff);
+
+r = new Rectangle(-2, -2, 8, 8);
+bmp.fillRect(r, 0x00ff00);
+check_equals(bmp.getPixel(1, 1), 0x00ff00);
+
+// Fails.
+r = new Rectangle(18, 18, -4, -4);
+bmp.fillRect(r, 0x0000ff);
+check_equals(bmp.getPixel(7, 6), 0xffffff);
+
+r = new Rectangle(18, 18, 200, 200);
+bmp.fillRect(r, 0x0000ff);
+check_equals(bmp.getPixel(19,19), 0x0000ff);
+
+// Doesn't have to be a rectangle
+g = {x: 15, y: 15, width: 2, height: 2};
+bmp.fillRect(g, 0xff00ff);
+check_equals(bmp.getPixel(16, 16), 0xff00ff);
+
+// Transparency (this bitmap is not transparent).
+g = {x: 18, y: 2, width: 7, height: 7};
+bmp.fillRect(g, 0xddff00ff);
+check_equals(bmp.getPixel32(18, 2), -65281);
+
+mc.attachBitmap(bmp, this.getNextHighestDepth());
+
+// Transparency (transparent bitmap). Fill just obliterates
+// what was there, even if it's transparent.
+bmp = new Bitmap(20, 20, true);
+r = new Rectangle(1, 1, 10, 10);
+bmp.fillRect(r, 0xff00ff00);
+r = new Rectangle(2, 2, 9, 9);
+bmp.fillRect(r, 0x99ff1100);
+check_equals(bmp.getPixel32(3, 3), -1711337216);
+
+mc.attachBitmap(bmp, this.getNextHighestDepth());
//-------------------------------------------------------------
// END OF TEST
//-------------------------------------------------------------
-totals(51);
+totals(77);
#endif // OUTPUT_VERSION >= 8
- [Gnash-commit] gnash ChangeLog server/asobj/flash/display/Bitm...,
Benjamin Wolsey <=