[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

hausmann at webkit.org hausmann at webkit.org
Thu Feb 4 21:22:58 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit dbb954196850211552f1ffdb15529b66c9d1e260
Author: hausmann at webkit.org <hausmann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jan 21 08:25:21 2010 +0000

    WebCore: [Qt] Adding QPixmap/QImage support for the Qt hybrid layer
           Allows accesing QPixmap and QImage based arguments from Qt signals,
           slots and properties
           This is done by an intermediate object that can be turned into
           web-based objects by calling either toHTMLImageElement() or
           toDataURL()
    https://bugs.webkit.org/show_bug.cgi?id=32461
    
    Patch by No'am Rosenthal <noam.rosenthal at nokia.com> on 2010-01-21
    Reviewed by Simon Hausmann.
    
    Tests are in WebKit/qt/tests/hybridPixmap
    
    * WebCore.pro:
    * bridge/qt/qt_pixmapruntime.cpp: Added.
    (JSC::Bindings::QtPixmapWidthField::name): "width"
    (JSC::Bindings::QtPixmapWidthField::valueFromInstance): width of
    pixmap
    (JSC::Bindings::QtPixmapWidthField::setValueToInstance): nothing
    (JSC::Bindings::QtPixmapHeightField::name): "height"
    (JSC::Bindings::QtPixmapHeightField::valueFromInstance): height of
    pixmap
    (JSC::Bindings::QtPixmapHeightField::setValueToInstance): nothing
    (JSC::Bindings::QtPixmapRuntimeMethod::numParameters): 0
    (JSC::Bindings::QtPixmapCreateElementMethod::name): toHTMLImageElement
    (JSC::Bindings::QtPixmapCreateElementMethod::invoke): creates an HTML
    element from the QPixmap
    (JSC::Bindings::QtPixmapToDataUrlMethod::name): "toDataURL"
    (JSC::Bindings::QtPixmapToDataUrlMethod::invoke): encodes the image to
    a base64 data url
    (JSC::Bindings::QtPixmapToStringMethod::name): "toString"
    (JSC::Bindings::QtPixmapToStringMethod::invoke): [Qt Native Pixmap
    w,h]
    
    (JSC::Bindings::QtPixmapRuntimeObjectImp::createStructure):
    runtime-object broilerplate
    (JSC::Bindings::QtPixmapRuntimeObjectImp::classInfo): ditto
    (JSC::Bindings::QtPixmapRuntimeObjectImp::QtPixmapRuntimeObjectImp):
    ditto
    (JSC::Bindings::): ditto
    (JSC::Bindings::QtPixmapClass::QtPixmapClass): class for the
    intermediate pixmap-holder
    (JSC::Bindings::QtPixmapInstance::getClass): ditto
    (JSC::Bindings::QtPixmapInstance::invokeMethod): ditto
    (JSC::Bindings::QtPixmapClass::methodsNamed): toHTMLImageElement,
    toDataURL
    (JSC::Bindings::QtPixmapClass::fieldNamed): width, height
    (JSC::Bindings::QtPixmapInstance::getPropertyNames):
            toHTMLImageElement, toDataURL, width, height
    (JSC::Bindings::QtPixmapInstance::defaultValue): nothing
    (JSC::Bindings::QtPixmapInstance::valueOf): toString
    (JSC::Bindings::data): holds a QVariant of type QImage/QPixmap
    (JSC::Bindings::QtPixmapInstance::width): width of the image/pixmap
    (JSC::Bindings::QtPixmapInstance::height): height of the image/pixmap
    (JSC::Bindings::QtPixmapInstance::toPixmap): converts to a QPixmap
    (JSC::Bindings::QtPixmapInstance::toImage): converts to a QImage
    (JSC::Bindings::QtPixmapInstance::variantFromObject): makes sure this
    is the right type of object, and creates a QVariant
    (JSC::Bindings::QtPixmapInstance::createRuntimeObject): creates a new
    intermediate pixmap holder from a QVariant
    (JSC::Bindings::QtPixmapInstance::canHandle): returns true if a
    QPixmap/QImage is required
    * bridge/qt/qt_pixmapruntime.h: Added.
    * bridge/qt/qt_runtime.cpp: hooks for the bridge
    (JSC::Bindings::convertValueToQVariant): handle QPixmap/QImage if the
    object is the intermediate pixmap holder or an HTMLImageElement
    (JSC::Bindings::convertQVariantToValue): creates the intermediate
    object from a QVariant of type QImage/QPixmap
    
    WebKit/qt: [Qt] Adding QPixmap/QImage support for the Qt hybrid layer
    https://bugs.webkit.org/show_bug.cgi?id=32461
    
    Patch by No'am Rosenthal <noam.rosenthal at nokia.com> on 2010-01-21
    Reviewed by Simon Hausmann.
    
    * tests/hybridPixmap: Added.
    * tests/hybridPixmap/hybridPixmap.pro: Added.
    * tests/hybridPixmap/resources.qrc: Added.
    * tests/hybridPixmap/test.html: Added.
    * tests/hybridPixmap/tst_hybridPixmap.cpp: Added.
    (tst_hybridPixmap::tst_hybridPixmap): tests most of the use cases for
    hybrid pixmap/image manipulation
    (tst_hybridPixmap::init): QTestLib initialization
    (tst_hybridPixmap::cleanup): QTestLib cleanup
    (tst_hybridPixmap::hybridPixmap): run the html file
    * tests/hybridPixmap/widget.cpp: Added.
    (Widget::Widget):
    (Widget::refreshJS):
    (Widget::start):
    (Widget::completeTest):
    (Widget::setPixmap):
    (Widget::pixmap):
    (Widget::setImage):
    (Widget::image):
    (Widget::~Widget):
    (Widget::changeEvent):
    (Widget::compare):
    (Widget::imageSlot):
    (Widget::pixmapSlot):
    (Widget::randomSlot):
    * tests/hybridPixmap/widget.h: Added.
    * tests/hybridPixmap/widget.ui: Added.
    * tests/tests.pro:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53611 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d51115c..dff61e4 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,73 @@
+2010-01-21  No'am Rosenthal  <noam.rosenthal at nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Adding QPixmap/QImage support for the Qt hybrid layer
+        Allows accesing QPixmap and QImage based arguments from Qt signals,
+        slots and properties
+        This is done by an intermediate object that can be turned into
+        web-based objects by calling either toHTMLImageElement() or
+        toDataURL()
+        https://bugs.webkit.org/show_bug.cgi?id=32461
+
+        Tests are in WebKit/qt/tests/hybridPixmap
+
+        * WebCore.pro:
+        * bridge/qt/qt_pixmapruntime.cpp: Added.
+        (JSC::Bindings::QtPixmapWidthField::name): "width"
+        (JSC::Bindings::QtPixmapWidthField::valueFromInstance): width of
+        pixmap
+        (JSC::Bindings::QtPixmapWidthField::setValueToInstance): nothing
+        (JSC::Bindings::QtPixmapHeightField::name): "height"
+        (JSC::Bindings::QtPixmapHeightField::valueFromInstance): height of
+        pixmap
+        (JSC::Bindings::QtPixmapHeightField::setValueToInstance): nothing
+        (JSC::Bindings::QtPixmapRuntimeMethod::numParameters): 0
+        (JSC::Bindings::QtPixmapCreateElementMethod::name): toHTMLImageElement
+        (JSC::Bindings::QtPixmapCreateElementMethod::invoke): creates an HTML
+        element from the QPixmap
+        (JSC::Bindings::QtPixmapToDataUrlMethod::name): "toDataURL"
+        (JSC::Bindings::QtPixmapToDataUrlMethod::invoke): encodes the image to
+        a base64 data url
+        (JSC::Bindings::QtPixmapToStringMethod::name): "toString"
+        (JSC::Bindings::QtPixmapToStringMethod::invoke): [Qt Native Pixmap
+        w,h]
+
+        (JSC::Bindings::QtPixmapRuntimeObjectImp::createStructure):
+        runtime-object broilerplate
+        (JSC::Bindings::QtPixmapRuntimeObjectImp::classInfo): ditto
+        (JSC::Bindings::QtPixmapRuntimeObjectImp::QtPixmapRuntimeObjectImp):
+        ditto
+        (JSC::Bindings::): ditto
+        (JSC::Bindings::QtPixmapClass::QtPixmapClass): class for the
+        intermediate pixmap-holder 
+        (JSC::Bindings::QtPixmapInstance::getClass): ditto
+        (JSC::Bindings::QtPixmapInstance::invokeMethod): ditto
+        (JSC::Bindings::QtPixmapClass::methodsNamed): toHTMLImageElement,
+        toDataURL
+        (JSC::Bindings::QtPixmapClass::fieldNamed): width, height
+        (JSC::Bindings::QtPixmapInstance::getPropertyNames):
+                toHTMLImageElement, toDataURL, width, height
+        (JSC::Bindings::QtPixmapInstance::defaultValue): nothing
+        (JSC::Bindings::QtPixmapInstance::valueOf): toString
+        (JSC::Bindings::data): holds a QVariant of type QImage/QPixmap
+        (JSC::Bindings::QtPixmapInstance::width): width of the image/pixmap
+        (JSC::Bindings::QtPixmapInstance::height): height of the image/pixmap
+        (JSC::Bindings::QtPixmapInstance::toPixmap): converts to a QPixmap
+        (JSC::Bindings::QtPixmapInstance::toImage): converts to a QImage
+        (JSC::Bindings::QtPixmapInstance::variantFromObject): makes sure this
+        is the right type of object, and creates a QVariant
+        (JSC::Bindings::QtPixmapInstance::createRuntimeObject): creates a new
+        intermediate pixmap holder from a QVariant
+        (JSC::Bindings::QtPixmapInstance::canHandle): returns true if a
+        QPixmap/QImage is required
+        * bridge/qt/qt_pixmapruntime.h: Added.
+        * bridge/qt/qt_runtime.cpp: hooks for the bridge
+        (JSC::Bindings::convertValueToQVariant): handle QPixmap/QImage if the
+        object is the intermediate pixmap holder or an HTMLImageElement
+        (JSC::Bindings::convertQVariantToValue): creates the intermediate
+        object from a QVariant of type QImage/QPixmap
+
 2010-01-21  Luiz Agostini  <luiz.agostini at openbossa.org>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index c1912e9..15bacde 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -1042,6 +1042,7 @@ HEADERS += \
     bridge/qt/qt_class.h \
     bridge/qt/qt_instance.h \
     bridge/qt/qt_runtime.h \
+    bridge/qt/qt_pixmapruntime.h \
     bridge/runtime_array.h \
     bridge/runtime_method.h \
     bridge/runtime_object.h \
@@ -1943,6 +1944,7 @@ SOURCES += \
     bindings/js/ScriptControllerQt.cpp \
     bridge/qt/qt_class.cpp \
     bridge/qt/qt_instance.cpp \
+    bridge/qt/qt_pixmapruntime.cpp \
     bridge/qt/qt_runtime.cpp \
     page/qt/DragControllerQt.cpp \
     page/qt/EventHandlerQt.cpp \
diff --git a/WebCore/bridge/qt/qt_pixmapruntime.cpp b/WebCore/bridge/qt/qt_pixmapruntime.cpp
new file mode 100644
index 0000000..a6298fc
--- /dev/null
+++ b/WebCore/bridge/qt/qt_pixmapruntime.cpp
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+#include "config.h"
+#include "qt_pixmapruntime.h"
+
+#include "CachedImage.h"
+#include "DOMWindow.h"
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+#include "JSDOMBinding.h"
+#include "JSDOMWindow.h"
+#include "JSGlobalObject.h"
+#include "JSHTMLImageElement.h"
+#include "JSLock.h"
+#include "ObjectPrototype.h"
+#include "StillImageQt.h"
+#include <QBuffer>
+#include <QByteArray>
+#include <QImage>
+#include <QPixmap>
+#include <QVariant>
+#include <runtime_object.h>
+#include <runtime_root.h>
+
+using namespace WebCore;
+namespace JSC {
+
+namespace Bindings {
+
+class QtPixmapClass : public Class {
+public:
+    QtPixmapClass();
+    virtual MethodList methodsNamed(const Identifier&, Instance*) const;
+    virtual Field* fieldNamed(const Identifier&, Instance*) const;
+};
+
+
+class QtPixmapWidthField : public Field {
+public:
+    static const char* name() { return "width"; }
+    virtual JSValue valueFromInstance(ExecState* exec, const Instance* pixmap) const
+    {
+        return jsNumber(exec, static_cast<const QtPixmapInstance*>(pixmap)->width());
+    }
+    virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const {}
+};
+class QtPixmapHeightField : public Field {
+public:
+    static const char* name() { return "height"; }
+    virtual JSValue valueFromInstance(ExecState* exec, const Instance* inst) const
+    {
+        return jsNumber(exec, static_cast<const QtPixmapInstance*>(inst)->height());
+    }
+    virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const {}
+};
+
+class QtPixmapRuntimeMethod : public Method {
+public:
+    virtual int numParameters() const
+    {
+        return 0;
+    }
+    virtual JSValue invoke(ExecState* exec, QVariant&, PassRefPtr<RootObject> root, QtPixmapInstance* inst) = 0;
+
+};
+
+class QtPixmapCreateElementMethod : public QtPixmapRuntimeMethod {
+public:
+    static const char* name() { return "toHTMLImageElement"; }
+    JSValue invoke(ExecState* exec, QVariant& v, PassRefPtr<RootObject> root, QtPixmapInstance*)
+    {
+        QPixmap pxm;
+        if (v.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) {
+            pxm = QPixmap::fromImage(v.value<QImage>());
+            v = QVariant::fromValue<QPixmap>(pxm);
+        } else
+            pxm = v.value<QPixmap>();
+
+        Document* document = 0;
+        JSDOMGlobalObject* global = static_cast<JSDOMGlobalObject*>(root->globalObject());
+        if (global) {
+            DOMWindow* dWindow = toDOMWindow(global);
+            if (dWindow)
+                document = dWindow->document();
+        }
+
+        if (document) {
+            PassRefPtr<StillImage> img = WebCore::StillImage::create(pxm);
+            RefPtr<HTMLImageElement> image = new HTMLImageElement(HTMLNames::imgTag, document);
+            image->setCachedImage(new CachedImage(img.get()));
+            toJS(exec, global, document);
+            return asObject(toJS(exec, global, image.release()));
+        }
+        return jsUndefined();
+    }
+
+};
+
+class QtPixmapToDataUrlMethod : public QtPixmapRuntimeMethod {
+public:
+    static const char* name() { return "toDataUrl"; }
+    JSValue invoke(ExecState* exec, QVariant& v, PassRefPtr<RootObject> root, QtPixmapInstance*)
+    {
+        QImage image;
+        // for getting the data url, we always prefer the image.
+        if (v.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) {
+            image = v.value<QPixmap>().toImage();
+            v = QVariant::fromValue<QImage>(image);
+        } else
+            image = v.value<QImage>();
+        QByteArray ba;
+        QBuffer b(&ba);
+        image.save(&b, "PNG");
+        const QString b64 = QString("data:image/png;base64,") + ba.toBase64();
+        const UString ustring((UChar*)b64.utf16(), b64.length());
+        return jsString(exec, ustring);
+    }
+
+};
+
+class QtPixmapToStringMethod : public QtPixmapRuntimeMethod {
+    public:
+    static const char* name() { return "toString"; }
+    JSValue invoke(ExecState* exec, QVariant& v, PassRefPtr<RootObject> root, QtPixmapInstance* inst)
+    {
+        return inst->valueOf(exec);
+    }
+
+};
+
+struct QtPixmapMetaData {
+    QtPixmapToDataUrlMethod toDataUrlMethod;
+    QtPixmapCreateElementMethod createElementMethod;
+    QtPixmapToStringMethod toStringMethod;
+    QtPixmapHeightField heightField;
+    QtPixmapWidthField widthField;
+    QtPixmapClass cls;
+} qt_pixmap_metaData;
+
+// Derived RuntimeObject
+class QtPixmapRuntimeObjectImp : public RuntimeObjectImp {
+public:
+    QtPixmapRuntimeObjectImp(ExecState*, PassRefPtr<Instance>);
+
+    static const ClassInfo s_info;
+
+    static PassRefPtr<Structure> createStructure(JSValue prototype)
+    {
+        return Structure::create(prototype, TypeInfo(ObjectType,  StructureFlags));
+    }
+
+protected:
+    static const unsigned StructureFlags = RuntimeObjectImp::StructureFlags | OverridesMarkChildren;
+
+private:
+    virtual const ClassInfo* classInfo() const { return &s_info; }
+};
+
+QtPixmapRuntimeObjectImp::QtPixmapRuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> instance)
+    : RuntimeObjectImp(exec, WebCore::deprecatedGetDOMStructure<QtPixmapRuntimeObjectImp>(exec), instance)
+{
+}
+
+const ClassInfo QtPixmapRuntimeObjectImp::s_info = { "QtPixmapRuntimeObject", &RuntimeObjectImp::s_info, 0, 0 };
+
+
+QtPixmapClass::QtPixmapClass()
+{
+}
+
+
+Class* QtPixmapInstance::getClass() const
+{
+    return &qt_pixmap_metaData.cls;
+}
+
+JSValue QtPixmapInstance::invokeMethod(ExecState* exec, const MethodList& methods, const ArgList& args)
+{
+    if (methods.size() == 1) {
+        QtPixmapRuntimeMethod* mtd = static_cast<QtPixmapRuntimeMethod*>(methods[0]);        
+        return mtd->invoke(exec, data, rootObject(), this);
+    }
+    return jsUndefined();
+}
+
+MethodList QtPixmapClass::methodsNamed(const Identifier& identifier, Instance*) const
+{
+    MethodList methods;
+    if (identifier == QtPixmapToDataUrlMethod::name())
+        methods.append(&qt_pixmap_metaData.toDataUrlMethod);
+    else if (identifier == QtPixmapCreateElementMethod::name())
+        methods.append(&qt_pixmap_metaData.createElementMethod);
+    else if (identifier == QtPixmapToStringMethod::name())
+        methods.append(&qt_pixmap_metaData.toStringMethod);
+    return methods;
+}
+
+Field* QtPixmapClass::fieldNamed(const Identifier& identifier, Instance*) const
+{
+    if (identifier == QtPixmapWidthField::name())
+        return &qt_pixmap_metaData.widthField;
+    if (identifier == QtPixmapHeightField::name())
+        return &qt_pixmap_metaData.heightField;
+    return 0;
+}
+
+void QtPixmapInstance::getPropertyNames(ExecState*exec, PropertyNameArray& arr)
+{
+    arr.add(Identifier(exec, UString(QtPixmapToDataUrlMethod::name())));
+    arr.add(Identifier(exec, UString(QtPixmapCreateElementMethod::name())));
+    arr.add(Identifier(exec, UString(QtPixmapToStringMethod::name())));
+    arr.add(Identifier(exec, UString(QtPixmapWidthField::name())));
+    arr.add(Identifier(exec, UString(QtPixmapHeightField::name())));
+}
+
+JSValue QtPixmapInstance::defaultValue(ExecState* exec, PreferredPrimitiveType ptype) const
+{
+    if (ptype == PreferNumber) {
+        return jsBoolean(
+                (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>()) && !(data.value<QImage>()).isNull())
+                || (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>()) && !data.value<QPixmap>().isNull()));
+    }
+    if (ptype == PreferString)
+        return valueOf(exec);
+    return jsUndefined();
+}
+
+JSValue QtPixmapInstance::valueOf(ExecState* exec) const
+{
+    const QString toStr = QString("[Qt Native Pixmap %1,%2]").arg(width()).arg(height());
+    UString ustring((UChar*)toStr.utf16(), toStr.length());
+    return jsString(exec, ustring);
+}
+
+QtPixmapInstance::QtPixmapInstance(PassRefPtr<RootObject> rootObj, const QVariant& d)
+        :Instance(rootObj), data(d)
+{
+}
+
+int QtPixmapInstance::width() const
+{
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>()))
+        return data.value<QPixmap>().width();
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>()))
+        return data.value<QImage>().width();
+    return 0;
+}
+
+int QtPixmapInstance::height() const
+{
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>()))
+        return data.value<QPixmap>().height();
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>()))
+        return data.value<QImage>().height();
+    return 0;
+}
+
+QPixmap QtPixmapInstance::toPixmap()
+{
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>()))
+        return data.value<QPixmap>();
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) {
+        const QPixmap pxm = QPixmap::fromImage(data.value<QImage>());
+        data = QVariant::fromValue<QPixmap>(pxm);
+        return pxm;
+    }
+    return QPixmap();
+
+}
+
+QImage QtPixmapInstance::toImage()
+{
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>()))
+        return data.value<QImage>();
+    if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) {
+        const QImage img = data.value<QPixmap>().toImage();
+        data = QVariant::fromValue<QImage>(img);
+        return img;
+    }
+    return QImage();
+}
+
+QVariant QtPixmapInstance::variantFromObject(JSObject* object, QMetaType::Type hint)
+{
+    if (!object) {
+        if (hint == qMetaTypeId<QPixmap>())
+            return QVariant::fromValue<QPixmap>(QPixmap());
+        if (hint == qMetaTypeId<QImage>())
+            return QVariant::fromValue<QImage>(QImage());
+    } else if (object->inherits(&JSHTMLImageElement::s_info)) {
+        JSHTMLImageElement* el = static_cast<JSHTMLImageElement*>(object);
+        HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(el->impl());
+        if (imageElement) {
+            CachedImage* cImg = imageElement->cachedImage();
+            if (cImg) {
+                Image* img = cImg->image();
+                if (img) {
+                    QPixmap* pxm = img->nativeImageForCurrentFrame();
+                    if (pxm) {
+                        return (hint == static_cast<QMetaType::Type>(qMetaTypeId<QPixmap>()))
+                              ? QVariant::fromValue<QPixmap>(*pxm)
+                              : QVariant::fromValue<QImage>(pxm->toImage());
+                    }
+                }
+            }
+        }
+    } else if (object->inherits(&QtPixmapRuntimeObjectImp::s_info)) {
+        QtPixmapRuntimeObjectImp* imp = static_cast<QtPixmapRuntimeObjectImp*>(object);
+        QtPixmapInstance* inst = static_cast<QtPixmapInstance*>(imp->getInternalInstance());
+        if (inst) {
+            if (hint == qMetaTypeId<QPixmap >())
+                return QVariant::fromValue<QPixmap>(inst->toPixmap());
+            if (hint == qMetaTypeId<QImage>())
+                return QVariant::fromValue<QImage>(inst->toImage());
+        }
+    }
+    return 0;
+}
+JSObject* QtPixmapInstance::createRuntimeObject(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& data)
+{
+    JSLock lock(SilenceAssertionsOnly);
+    return new(exec) QtPixmapRuntimeObjectImp(exec, new QtPixmapInstance(root, data));
+}
+
+bool QtPixmapInstance::canHandle(QMetaType::Type hint)
+{
+    return hint == qMetaTypeId<QImage>() || hint == qMetaTypeId<QPixmap>();
+}
+
+}
+
+}
diff --git a/WebCore/bridge/qt/qt_pixmapruntime.h b/WebCore/bridge/qt/qt_pixmapruntime.h
new file mode 100644
index 0000000..5455298
--- /dev/null
+++ b/WebCore/bridge/qt/qt_pixmapruntime.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef qt_pixmapruntime_h
+#define qt_pixmapruntime_h
+
+#include "Bridge.h"
+#include <QVariant>
+
+namespace JSC {
+
+namespace Bindings {
+
+class QtPixmapInstance : public Instance {
+    QVariant data;
+public:
+    QtPixmapInstance(PassRefPtr<RootObject> rootObj, const QVariant& newData);
+    virtual Class* getClass() const;
+    virtual JSValue invokeMethod(ExecState*, const MethodList&, const ArgList& args);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+
+    virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
+    virtual JSValue valueOf(ExecState* exec) const;
+    int width() const;
+    int height() const;
+    QPixmap toPixmap();
+    QImage toImage();
+    static JSObject* createRuntimeObject(ExecState*, PassRefPtr<RootObject>, const QVariant&);
+    static QVariant variantFromObject(JSObject*, QMetaType::Type hint);
+    static bool canHandle(QMetaType::Type hint);
+};
+
+}
+
+}
+#endif
diff --git a/WebCore/bridge/qt/qt_runtime.cpp b/WebCore/bridge/qt/qt_runtime.cpp
index c711baa..6be3387 100644
--- a/WebCore/bridge/qt/qt_runtime.cpp
+++ b/WebCore/bridge/qt/qt_runtime.cpp
@@ -43,6 +43,7 @@
 #include "qobject.h"
 #include "qstringlist.h"
 #include "qt_instance.h"
+#include "qt_pixmapruntime.h"
 #include "qvarlengtharray.h"
 #include <JSFunction.h>
 #include <limits.h>
@@ -719,6 +720,8 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
                     }
                 }
                 break;
+            } else if (QtPixmapInstance::canHandle(static_cast<QMetaType::Type>(hint))) {
+                ret = QtPixmapInstance::variantFromObject(object, static_cast<QMetaType::Type>(hint));
             } else if (hint == (QMetaType::Type) qMetaTypeId<QVariant>()) {
                 if (value.isUndefinedOrNull()) {
                     if (distance)
@@ -848,6 +851,9 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
         return QtInstance::getQtInstance(obj, root, QScriptEngine::QtOwnership)->createRuntimeObject(exec);
     }
 
+    if (QtPixmapInstance::canHandle(static_cast<QMetaType::Type>(variant.type())))
+        return QtPixmapInstance::createRuntimeObject(exec, root, variant);
+
     if (type == QMetaType::QVariantMap) {
         // create a new object, and stuff properties into it
         JSObject* ret = constructEmptyObject(exec);
diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog
index c23c018..b1e4a59 100644
--- a/WebKit/qt/ChangeLog
+++ b/WebKit/qt/ChangeLog
@@ -1,3 +1,39 @@
+2010-01-21  No'am Rosenthal  <noam.rosenthal at nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Adding QPixmap/QImage support for the Qt hybrid layer
+        https://bugs.webkit.org/show_bug.cgi?id=32461
+
+        * tests/hybridPixmap: Added.
+        * tests/hybridPixmap/hybridPixmap.pro: Added.
+        * tests/hybridPixmap/resources.qrc: Added.
+        * tests/hybridPixmap/test.html: Added.
+        * tests/hybridPixmap/tst_hybridPixmap.cpp: Added.
+        (tst_hybridPixmap::tst_hybridPixmap): tests most of the use cases for
+        hybrid pixmap/image manipulation 
+        (tst_hybridPixmap::init): QTestLib initialization
+        (tst_hybridPixmap::cleanup): QTestLib cleanup
+        (tst_hybridPixmap::hybridPixmap): run the html file
+        * tests/hybridPixmap/widget.cpp: Added.
+        (Widget::Widget):
+        (Widget::refreshJS):
+        (Widget::start):
+        (Widget::completeTest):
+        (Widget::setPixmap):
+        (Widget::pixmap):
+        (Widget::setImage):
+        (Widget::image):
+        (Widget::~Widget):
+        (Widget::changeEvent):
+        (Widget::compare):
+        (Widget::imageSlot):
+        (Widget::pixmapSlot):
+        (Widget::randomSlot):
+        * tests/hybridPixmap/widget.h: Added.
+        * tests/hybridPixmap/widget.ui: Added.
+        * tests/tests.pro:
+
 2010-01-21  Luiz Agostini  <luiz.agostini at openbossa.org>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebKit/qt/tests/hybridPixmap/hybridPixmap.pro b/WebKit/qt/tests/hybridPixmap/hybridPixmap.pro
new file mode 100644
index 0000000..0e49a70
--- /dev/null
+++ b/WebKit/qt/tests/hybridPixmap/hybridPixmap.pro
@@ -0,0 +1,10 @@
+# -------------------------------------------------
+# Project created by QtCreator 2009-12-10T11:25:02
+# -------------------------------------------------
+include(../tests.pri)
+TARGET = hybridPixmap
+SOURCES += widget.cpp
+HEADERS += widget.h
+FORMS += widget.ui
+RESOURCES += resources.qrc
+CONFIG += console
diff --git a/WebKit/qt/tests/hybridPixmap/resources.qrc b/WebKit/qt/tests/hybridPixmap/resources.qrc
new file mode 100644
index 0000000..5fd47e3
--- /dev/null
+++ b/WebKit/qt/tests/hybridPixmap/resources.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>test.html</file>
+    </qresource>
+</RCC>
diff --git a/WebKit/qt/tests/hybridPixmap/test.html b/WebKit/qt/tests/hybridPixmap/test.html
new file mode 100644
index 0000000..ddaf75c
--- /dev/null
+++ b/WebKit/qt/tests/hybridPixmap/test.html
@@ -0,0 +1,57 @@
+<html>
+    <head>
+        <style>
+            img { display: block; border-style: groove}
+        </style>
+        <script>
+            function startTest()
+            {
+                var obj = myWidget.image;
+                var pxm = myWidget.pixmap;
+
+                var img = obj.toHTMLImageElement();
+                var img1 = document.getElementById("img1");
+                var img2 = document.getElementById("img2");
+                document.body.appendChild(img);
+                document.body.appendChild(pxm.toHTMLImageElement());
+                var signalsFired = 0;
+                myWidget.compare(obj.toString(),"[Qt Native Pixmap "+obj.width+","+obj.height+"]");
+                myWidget.compare(String(pxm),"[Qt Native Pixmap "+pxm.width+","+pxm.height+"]");
+
+                // this shouldn't work but shouldn't crash
+                myWidget.randomSlot("foobar");
+
+                myWidget.pixmapSignal.connect(function(imgFromSignal) {
+                    myWidget.compare(imgFromSignal.height, img2.height);
+                    if (++signalsFired == 2)
+                        myWidget.completeTest();
+                });
+
+                myWidget.imageSignal.connect(function(imgFromSignal) {
+                    myWidget.compare(pxm.height, img2.height);
+                    if (++signalsFired == 2)
+                        myWidget.completeTest();
+                });
+
+                function continueTestAfterImagesAreLoaded()
+                {
+                    if (img1.complete && img2.complete) {
+                        myWidget.compare(pxm.height, img2.height);
+                        myWidget.pixmapSlot(img);
+                        myWidget.imageSlot(pxm);
+                    }
+                }
+                img1.onload = continueTestAfterImagesAreLoaded;
+                img2.onload = continueTestAfterImagesAreLoaded;
+                img1.src = obj.toDataUrl();
+                img2.src = myWidget.pixmap.toDataUrl();
+                myWidget.image = pxm;
+                myWidget.pixmap = img;
+            }
+        </script>
+    </head>
+    <body onload="startTest()">
+        <img id="img1" />
+        <img id="img2" />
+    </body>
+</html>
diff --git a/WebKit/qt/tests/hybridPixmap/tst_hybridPixmap.cpp b/WebKit/qt/tests/hybridPixmap/tst_hybridPixmap.cpp
new file mode 100644
index 0000000..72dbb3b
--- /dev/null
+++ b/WebKit/qt/tests/hybridPixmap/tst_hybridPixmap.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include "../util.h"
+
+#include "widget.h"
+#include <QtTest/QtTest>
+
+class tst_hybridPixmap : public QObject {
+    Q_OBJECT
+
+public:
+    tst_hybridPixmap(QObject* o = 0) : QObject(o) {}
+
+public slots:
+    void init()
+    {
+    }
+
+    void cleanup()
+    {
+    }
+
+private slots:
+    void hybridPixmap()
+    {
+        Widget widget;
+        widget.show();
+        widget.start();
+        waitForSignal(&widget, SIGNAL(testComplete()));
+    }
+};
+
+QTEST_MAIN(tst_hybridPixmap)
+
+#include <tst_hybridPixmap.moc>
diff --git a/WebKit/qt/tests/hybridPixmap/widget.cpp b/WebKit/qt/tests/hybridPixmap/widget.cpp
new file mode 100644
index 0000000..cfdb1d6
--- /dev/null
+++ b/WebKit/qt/tests/hybridPixmap/widget.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include "widget.h"
+
+#include "qwebelement.h"
+#include "qwebframe.h"
+#include "ui_widget.h"
+#include <QPainter>
+#include <QtTest/QtTest>
+
+Widget::Widget(QWidget* parent) :
+    QWidget(parent),
+    ui(new Ui::Widget)
+{
+    ui->setupUi(this);
+}
+
+void Widget::refreshJS()
+{
+    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("myWidget", this);
+}
+void Widget::start()
+{
+    ui->webView->load(QUrl("qrc:///test.html"));
+    connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(refreshJS()));
+    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("myWidget", this);
+}
+
+void Widget::completeTest()
+{
+    QCOMPARE(ui->lbl1->pixmap()->size(), ui->lbl2->size());
+    QCOMPARE(ui->lbl3->size(), ui->lbl4->pixmap()->size());
+    QCOMPARE(ui->lbl2->size().width(), ui->webView->page()->mainFrame()->findFirstElement("#img1").evaluateJavaScript("this.width").toInt());
+    QCOMPARE(ui->lbl3->size().width(), ui->webView->page()->mainFrame()->findFirstElement("#img2").evaluateJavaScript("this.width").toInt());
+    emit testComplete();
+}
+
+void Widget::setPixmap(const QPixmap& p)
+{
+    ui->lbl1->setPixmap(p);
+}
+QPixmap Widget::pixmap() const
+{
+    QPixmap px(ui->lbl3->size());
+    {
+        QPainter p(&px);
+        ui->lbl3->render(&p);
+    }
+    return px;
+}
+void Widget::setImage(const QImage& img)
+{
+    ui->lbl4->setPixmap(QPixmap::fromImage(img));
+}
+
+QImage Widget::image() const
+{
+    QImage img(ui->lbl2->size(), QImage::Format_ARGB32);
+    {
+        QPainter p(&img);
+        ui->lbl2->render(&p);
+    }
+    return img;
+}
+
+Widget::~Widget()
+{
+    delete ui;
+}
+
+void Widget::changeEvent(QEvent* e)
+{
+    QWidget::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        ui->retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
+void Widget::compare(const QVariant& a, const QVariant& b)
+{
+    QCOMPARE(a, b);
+}
+
+void Widget::imageSlot(const QImage& img)
+{
+    QCOMPARE(img.size(), ui->lbl3->size());
+    emit pixmapSignal(QPixmap::fromImage(img));
+}
+
+void Widget::pixmapSlot(const QPixmap& pxm)
+{
+    QCOMPARE(pxm.size(), ui->lbl2->size());
+    emit imageSignal(ui->lbl4->pixmap()->toImage());
+}
+
+void Widget::randomSlot(const QPixmap& pxm)
+{
+    QVERIFY(pxm.isNull());
+}
diff --git a/WebKit/qt/tests/hybridPixmap/widget.h b/WebKit/qt/tests/hybridPixmap/widget.h
new file mode 100644
index 0000000..fab935e
--- /dev/null
+++ b/WebKit/qt/tests/hybridPixmap/widget.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef widget_h
+#define widget_h
+
+#include <QImage>
+#include <QPixmap>
+#include <QWidget>
+
+namespace Ui {
+class Widget;
+}
+
+class Widget : public QWidget {
+    Q_OBJECT
+    Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
+    Q_PROPERTY(QImage image READ image WRITE setImage)
+
+public:
+    Widget(QWidget* parent = 0);
+    ~Widget();
+    void setPixmap(const QPixmap&);
+    QPixmap pixmap() const;
+    void setImage(const QImage&);
+    QImage image() const;
+
+private slots:
+    void refreshJS();
+
+public slots:
+    void completeTest();
+    void start();
+    void compare(const QVariant& a, const QVariant& b);
+    void imageSlot(const QImage&);
+    void pixmapSlot(const QPixmap&);
+    void randomSlot(const QPixmap&);
+
+signals:
+    void testComplete();
+    void imageSignal(const QImage&);
+    void pixmapSignal(const QPixmap&);
+
+protected:
+    void changeEvent(QEvent* e);
+
+private:
+    Ui::Widget* ui;
+};
+
+#endif // widget_h
diff --git a/WebKit/qt/tests/hybridPixmap/widget.ui b/WebKit/qt/tests/hybridPixmap/widget.ui
new file mode 100644
index 0000000..95de928
--- /dev/null
+++ b/WebKit/qt/tests/hybridPixmap/widget.ui
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget</class>
+ <widget class="QWidget" name="Widget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>600</width>
+    <height>400</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Widget</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QWebView" name="webView">
+     <property name="url">
+      <url>
+       <string>about:blank</string>
+      </url>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="lbl1">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="lbl2">
+       <property name="minimumSize">
+        <size>
+         <width>120</width>
+         <height>30</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>120</width>
+         <height>30</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Image from Qt to HTML</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="lbl3">
+       <property name="text">
+        <string>Pixmap from Qt to HTML</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="lbl4">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+  <customwidget>
+   <class>QWebView</class>
+   <extends>QWidget</extends>
+   <header>QtWebKit/QWebView</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/WebKit/qt/tests/tests.pro b/WebKit/qt/tests/tests.pro
index 8e49d07..5e19202 100644
--- a/WebKit/qt/tests/tests.pro
+++ b/WebKit/qt/tests/tests.pro
@@ -1,4 +1,4 @@
 
 TEMPLATE = subdirs
-SUBDIRS = qwebframe qwebpage qwebelement qgraphicswebview qwebhistoryinterface qwebview qwebhistory qwebinspector
+SUBDIRS = qwebframe qwebpage qwebelement qgraphicswebview qwebhistoryinterface qwebview qwebhistory qwebinspector hybridPixmap
 greaterThan(QT_MINOR_VERSION, 4): SUBDIRS += benchmarks/painting benchmarks/loading

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list