diff options
-rw-r--r-- | webkit/port/bindings/v8/v8_custom.cpp | 87 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_custom.h | 3 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 16 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.h | 4 | ||||
-rw-r--r-- | webkit/port/platform/graphics/ImageBufferSkia.cpp | 105 | ||||
-rw-r--r-- | webkit/port/platform/graphics/SkiaUtils.cpp | 3 | ||||
-rw-r--r-- | webkit/port/platform/graphics/SkiaUtils.h | 3 | ||||
-rw-r--r-- | webkit/tools/layout_tests/test_lists/tests_fixable.txt | 8 |
8 files changed, 199 insertions, 30 deletions
diff --git a/webkit/port/bindings/v8/v8_custom.cpp b/webkit/port/bindings/v8/v8_custom.cpp index 032e30e..b6ff5f3 100644 --- a/webkit/port/bindings/v8/v8_custom.cpp +++ b/webkit/port/bindings/v8/v8_custom.cpp @@ -50,6 +50,7 @@ #include "Base64.h" #include "CanvasGradient.h" #include "CanvasPattern.h" +#include "CanvasPixelArray.h" #include "CanvasRenderingContext2D.h" #include "CanvasStyle.h" #include "Clipboard.h" @@ -635,6 +636,33 @@ NAMED_PROPERTY_GETTER(HTMLCollection) { return HTMLCollectionGetNamedItems(imp, key); } +INDEXED_PROPERTY_GETTER(CanvasPixelArray) { + INC_STATS(L"DOM.CanvasPixelArray.IndexedPropertyGetter"); + CanvasPixelArray* pixelArray = + V8Proxy::ToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, + info.Holder()); + + // TODO(eroman): This performance will not be good when looping through + // many pixels. See: http://code.google.com/p/chromium/issues/detail?id=3473 + + unsigned char result; + if (!pixelArray->get(index, result)) + return v8::Undefined(); + return v8::Number::New(result); +} + +INDEXED_PROPERTY_SETTER(CanvasPixelArray) { + INC_STATS(L"DOM.CanvasPixelArray.IndexedPropertySetter"); + CanvasPixelArray* pixelArray = + V8Proxy::ToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, + info.Holder()); + + double pixelValue = value->NumberValue(); + pixelArray->set(index, pixelValue); + + // TODO(eroman): what to return? + return v8::Undefined(); +} CALLBACK_FUNC_DECL(HTMLCollectionItem) { INC_STATS(L"DOM.HTMLCollection.item()"); @@ -2072,9 +2100,6 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImageFromRect) { return v8::Undefined(); } -// Remove the macro since we don't need it anymore. -#undef TO_FLOAT - CALLBACK_FUNC_DECL(CanvasRenderingContext2DCreatePattern) { INC_STATS(L"DOM.CanvasRenderingContext2D.createPattern()"); CanvasRenderingContext2D* context = @@ -2131,11 +2156,11 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DFillText) { } String text = ToWebCoreString(args[0]); - float x = static_cast<float>(args[1]->NumberValue()); - float y = static_cast<float>(args[2]->NumberValue()); + float x = TO_FLOAT(args[1]); + float y = TO_FLOAT(args[2]); if (args.Length() == 4) { - float maxWidth = static_cast<float>(args[3]->NumberValue()); + float maxWidth = TO_FLOAT(args[3]); context->fillText(text, x, y, maxWidth); } else { context->fillText(text, x, y); @@ -2160,11 +2185,11 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeText) { } String text = ToWebCoreString(args[0]); - float x = static_cast<float>(args[1]->NumberValue()); - float y = static_cast<float>(args[2]->NumberValue()); + float x = TO_FLOAT(args[1]); + float y = TO_FLOAT(args[2]); if (args.Length() == 4) { - float maxWidth = static_cast<float>(args[3]->NumberValue()); + float maxWidth = TO_FLOAT(args[3]); context->strokeText(text, x, y, maxWidth); } else { context->strokeText(text, x, y); @@ -2175,7 +2200,45 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeText) { CALLBACK_FUNC_DECL(CanvasRenderingContext2DPutImageData) { INC_STATS(L"DOM.CanvasRenderingContext2D.putImageData()"); - V8Proxy::SetDOMException(NOT_SUPPORTED_ERR); + + // Two froms: + // * putImageData(ImageData, x, y) + // * putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) + if (args.Length() != 3 && args.Length() != 7) { + V8Proxy::SetDOMException(SYNTAX_ERR); + return v8::Handle<v8::Value>(); + } + + CanvasRenderingContext2D* context = + V8Proxy::ToNativeObject<CanvasRenderingContext2D>( + V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + ImageData* imageData = 0; + + // Need to check that the argument is of the correct type, since + // ToNativeObject() expects it to be correct. If the argument was incorrect + // we leave it null, and putImageData() will throw the correct exception + // (TYPE_MISMATCH_ERR). + if (V8Proxy::IsWrapperOfType(args[0], V8ClassIndex::IMAGEDATA)) { + imageData = V8Proxy::ToNativeObject<ImageData>( + V8ClassIndex::IMAGEDATA, args[0]); + } + + ExceptionCode ec = 0; + + if (args.Length() == 7) { + context->putImageData(imageData, + TO_FLOAT(args[1]), TO_FLOAT(args[2]), TO_FLOAT(args[3]), + TO_FLOAT(args[4]), TO_FLOAT(args[5]), TO_FLOAT(args[6]), ec); + } else { + context->putImageData(imageData, TO_FLOAT(args[1]), TO_FLOAT(args[2]), ec); + } + + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return v8::Handle<v8::Value>(); + } + return v8::Undefined(); } @@ -3433,8 +3496,8 @@ CALLBACK_FUNC_DECL(SVGMatrixRotateFromVector) { *V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<AffineTransform> >( V8ClassIndex::SVGMATRIX, args.Holder()); ExceptionCode ec = 0; - float x = static_cast<float>(args[0]->NumberValue()); - float y = static_cast<float>(args[1]->NumberValue()); + float x = TO_FLOAT(args[0]); + float y = TO_FLOAT(args[1]); AffineTransform result = imp; result.rotateFromVector(x, y); if (x == 0.0 || y == 0.0) { diff --git a/webkit/port/bindings/v8/v8_custom.h b/webkit/port/bindings/v8/v8_custom.h index a73ec55..101a1a5 100644 --- a/webkit/port/bindings/v8/v8_custom.h +++ b/webkit/port/bindings/v8/v8_custom.h @@ -351,6 +351,9 @@ DECLARE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection) DECLARE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection) DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection) +DECLARE_INDEXED_PROPERTY_GETTER(CanvasPixelArray) +DECLARE_INDEXED_PROPERTY_SETTER(CanvasPixelArray) + // NSResolver DECLARE_CALLBACK(NSResolverLookupNamespaceURI) diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index df82d3b..bc8f183 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -1230,6 +1230,11 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate( NodeCollectionIndexedPropertyEnumerator<HTMLFormElement>, v8::External::New(reinterpret_cast<void*>(V8ClassIndex::NODE))); break; + case V8ClassIndex::CANVASPIXELARRAY: + desc->InstanceTemplate()->SetIndexedPropertyHandler( + USE_INDEXED_PROPERTY_GETTER(CanvasPixelArray), + USE_INDEXED_PROPERTY_SETTER(CanvasPixelArray)); + break; case V8ClassIndex::STYLESHEET: // fall through case V8ClassIndex::CSSSTYLESHEET: { // We add an extra internal field to hold a reference to @@ -2066,6 +2071,13 @@ bool V8Proxy::MaybeDOMWrapper(v8::Handle<v8::Value> value) { bool V8Proxy::IsDOMEventWrapper(v8::Handle<v8::Value> value) { + // All kinds of events use EVENT as dom type in JS wrappers. + // See EventToV8Object + return IsWrapperOfType(value, V8ClassIndex::EVENT); +} + +bool V8Proxy::IsWrapperOfType(v8::Handle<v8::Value> value, + V8ClassIndex::V8WrapperType classType) { if (value.IsEmpty() || !value->IsObject()) return false; v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(value); @@ -2084,9 +2096,7 @@ bool V8Proxy::IsDOMEventWrapper(v8::Handle<v8::Value> value) { ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && type->Int32Value() < V8ClassIndex::CLASSINDEX_END); - // All kinds of events use EVENT as dom type in JS wrappers. - // See EventToV8Object - return V8ClassIndex::FromInt(type->Int32Value()) == V8ClassIndex::EVENT; + return V8ClassIndex::FromInt(type->Int32Value()) == classType; } diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h index da1bc7c..0923570 100644 --- a/webkit/port/bindings/v8/v8_proxy.h +++ b/webkit/port/bindings/v8/v8_proxy.h @@ -413,6 +413,10 @@ class V8Proxy { v8::Persistent<v8::Value> handle); #endif + // Check whether a V8 value is a wrapper of type |classType|. + static bool IsWrapperOfType(v8::Handle<v8::Value> obj, + V8ClassIndex::V8WrapperType classType); + private: void initContextIfNeeded(); void DisconnectEventListeners(); diff --git a/webkit/port/platform/graphics/ImageBufferSkia.cpp b/webkit/port/platform/graphics/ImageBufferSkia.cpp index a9f77d0..94dac7b 100644 --- a/webkit/port/platform/graphics/ImageBufferSkia.cpp +++ b/webkit/port/platform/graphics/ImageBufferSkia.cpp @@ -64,15 +64,110 @@ Image* ImageBuffer::image() const return m_image.get(); } -PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const +PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const { - notImplemented(); - return 0; + ASSERT(context()); + + RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); + unsigned char* data = result->data()->data().data(); + + if (rect.x() < 0 || rect.y() < 0 || + (rect.x() + rect.width()) > m_size.width() || + (rect.y() + rect.height()) > m_size.height()) + memset(data, 0, result->data()->length()); + + int originx = rect.x(); + int destx = 0; + if (originx < 0) { + destx = -originx; + originx = 0; + } + int endx = rect.x() + rect.width(); + if (endx > m_size.width()) + endx = m_size.width(); + int numColumns = endx - originx; + + int originy = rect.y(); + int desty = 0; + if (originy < 0) { + desty = -originy; + originy = 0; + } + int endy = rect.y() + rect.height(); + if (endy > m_size.height()) + endy = m_size.height(); + int numRows = endy - originy; + + const SkBitmap& bitmap = *context()->platformContext()->bitmap(); + ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); + SkAutoLockPixels bitmapLock(bitmap); + + unsigned destBytesPerRow = 4 * rect.width(); + unsigned char* destRow = data + desty * destBytesPerRow + destx * 4; + + for (int y = 0; y < numRows; ++y) { + uint32_t* srcRow = bitmap.getAddr32(originx, originy + y); + for (int x = 0; x < numColumns; ++x) { + SkColor color = SkPMColorToColor(srcRow[x]); + unsigned char* destPixel = &destRow[x * 4]; + destPixel[0] = SkColorGetR(color); + destPixel[1] = SkColorGetG(color); + destPixel[2] = SkColorGetB(color); + destPixel[3] = SkColorGetA(color); + } + destRow += destBytesPerRow; + } + + return result; } -void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&) +void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, + const IntPoint& destPoint) { - notImplemented(); + ASSERT(sourceRect.width() > 0); + ASSERT(sourceRect.height() > 0); + + int originx = sourceRect.x(); + int destx = destPoint.x() + sourceRect.x(); + ASSERT(destx >= 0); + ASSERT(destx < m_size.width()); + ASSERT(originx >= 0); + ASSERT(originx < sourceRect.right()); + + int endx = destPoint.x() + sourceRect.right(); + ASSERT(endx <= m_size.width()); + + int numColumns = endx - destx; + + int originy = sourceRect.y(); + int desty = destPoint.y() + sourceRect.y(); + ASSERT(desty >= 0); + ASSERT(desty < m_size.height()); + ASSERT(originy >= 0); + ASSERT(originy < sourceRect.bottom()); + + int endy = destPoint.y() + sourceRect.bottom(); + ASSERT(endy <= m_size.height()); + int numRows = endy - desty; + + const SkBitmap& bitmap = *context()->platformContext()->bitmap(); + ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); + SkAutoLockPixels bitmapLock(bitmap); + + unsigned srcBytesPerRow = 4 * source->width(); + + const unsigned char* srcRow = source->data()->data().data() + + originy * srcBytesPerRow + originx * 4; + + for (int y = 0; y < numRows; ++y) { + uint32_t* destRow = bitmap.getAddr32(destx, desty + y); + for (int x = 0; x < numColumns; ++x) { + const unsigned char* srcPixel = &srcRow[x * 4]; + destRow[x] = SkPreMultiplyARGB(srcPixel[3], srcPixel[0], + srcPixel[1], srcPixel[2]); + } + srcRow += srcBytesPerRow; + } } String ImageBuffer::toDataURL(const String&) const diff --git a/webkit/port/platform/graphics/SkiaUtils.cpp b/webkit/port/platform/graphics/SkiaUtils.cpp index b8570c5..1600e30 100644 --- a/webkit/port/platform/graphics/SkiaUtils.cpp +++ b/webkit/port/platform/graphics/SkiaUtils.cpp @@ -119,8 +119,7 @@ static U8CPU InvScaleByte(U8CPU component, uint32_t scale) return (component * scale + 0x8000) >> 16; } -// move this guy into SkColor.h -static SkColor SkPMColorToColor(SkPMColor pm) +SkColor SkPMColorToColor(SkPMColor pm) { if (0 == pm) return 0; diff --git a/webkit/port/platform/graphics/SkiaUtils.h b/webkit/port/platform/graphics/SkiaUtils.h index 2d2af31..0302c1c 100644 --- a/webkit/port/platform/graphics/SkiaUtils.h +++ b/webkit/port/platform/graphics/SkiaUtils.h @@ -20,6 +20,9 @@ class SkRegion; // corresponding Skia type. SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(WebCore::CompositeOperator); +// move this guy into SkColor.h +SkColor SkPMColorToColor(SkPMColor pm); + // Converts Android colors to WebKit ones. WebCore::Color SkPMColorToWebCoreColor(SkPMColor pm); diff --git a/webkit/tools/layout_tests/test_lists/tests_fixable.txt b/webkit/tools/layout_tests/test_lists/tests_fixable.txt index 6cf6b0b..6c1a978 100644 --- a/webkit/tools/layout_tests/test_lists/tests_fixable.txt +++ b/webkit/tools/layout_tests/test_lists/tests_fixable.txt @@ -795,20 +795,12 @@ V8 | KJS # LayoutTests/fast/css/shadow-multiple.html = FAIL # There appears to be some parsing error. These tests give "successfullyParsed # should be true (of type boolean). Was undefined (of type undefined)." # http://code.google.com/p/chromium/issues/detail?id=2976 -V8 | KJS # LayoutTests/fast/canvas/canvas-invalid-fillstyle.html = FAIL -V8 | KJS # LayoutTests/fast/canvas/canvas-invalid-strokestyle.html = FAIL -V8 | KJS # LayoutTests/fast/canvas/canvas-ImageData-behaviour.html = FAIL -V8 | KJS # LayoutTests/fast/canvas/canvas-alphaImageData-behavior.html = FAIL -V8 | KJS # LayoutTests/fast/canvas/canvas-putImageData.html = FAIL V8 | KJS # LayoutTests/fast/canvas/drawImage-with-negative-source-destination.html = FAIL # getImageData isn't supported on canvas. # http://code.google.com/p/chromium/issues/detail?id=2974 V8 | KJS # LayoutTests/fast/canvas/canvas-pattern-behaviour.html = FAIL V8 | KJS # LayoutTests/fast/canvas/canvas-getImageData.html = FAIL -V8 | KJS # LayoutTests/fast/canvas/canvas-longlived-context.html = FAIL -V8 | KJS # LayoutTests/fast/canvas/canvas-path-with-inf-nan-dimensions.html = FAIL -V8 | KJS # LayoutTests/fast/canvas/canvas-save-restore-with-path.html = FAIL # We don't implement toDataURL. # http://code.google.com/p/chromium/issues/detail?id=2972 |