Changeset 127440 in webkit
- Timestamp:
- Sep 3, 2012 11:37:37 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r127438 r127440 1 2012-08-31 Simon Hausmann <simon.hausmann@nokia.com> 2 3 [Qt] Port the Qt pixmap JS bindings to use the JSC C API 4 https://bugs.webkit.org/show_bug.cgi?id=94702 5 6 Reviewed by Kenneth Rohde Christiansen. 7 8 Based on patch by Noam Rosenthal. 9 10 The conversion uses a simple JSClassRef based binding and only a few 11 uses of private JSC API for the HTML element DOM bindings remain. 12 13 This is essentially used for wrapping QPixmap and QImage types in 14 JavaScript and the other way around, for retrieving the image data 15 out of a HTML image element when converting from JS/DOM to Qt. 16 17 * bridge/qt/qt_pixmapruntime.cpp: 18 (JSC::Bindings::copyPixels): 19 (JSC::Bindings::toPixmap): 20 (JSC::Bindings::toImage): 21 (JSC::Bindings::imageSizeForVariant): 22 (JSC::Bindings::getPixmapWidth): 23 (JSC::Bindings::getPixmapHeight): 24 (JSC::Bindings::assignToHTMLImageElement): 25 (JSC::Bindings::pixmapToImageData): 26 (JSC::Bindings::pixmapToDataUrl): 27 (JSC::Bindings::pixmapToString): 28 (JSC::Bindings::QtPixmapRuntime::toJS): 29 (JSC::Bindings::QtPixmapRuntime::toQt): 30 (JSC::Bindings::QtPixmapRuntime::canHandle): 31 (JSC::Bindings::QtPixmapRuntime::getClassRef): 32 * bridge/qt/qt_pixmapruntime.h: 33 (QtPixmapRuntime): 34 * bridge/qt/qt_runtime.cpp: 35 (JSC::Bindings::convertValueToQVariant): 36 (JSC::Bindings::convertQVariantToValue): 37 1 38 2012-09-03 Andreas Kling <kling@webkit.org> 2 39 -
trunk/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp
r127191 r127440 20 20 #include "qt_pixmapruntime.h" 21 21 22 #include "APICast.h" 22 23 #include "CachedImage.h" 23 24 #include "HTMLImageElement.h" … … 28 29 #include "JSHTMLImageElement.h" 29 30 #include "JSImageData.h" 30 #include "JS Lock.h"31 #include " ObjectPrototype.h"31 #include "JSRetainPtr.h" 32 #include "JavaScript.h" 32 33 #include "StillImageQt.h" 33 34 #include <QtEndian> … … 38 39 #include <QPixmap> 39 40 #include <QVariant> 40 #include <runtime_method.h>41 #include <runtime_object.h>42 #include <runtime_root.h>43 #include "runtime/FunctionPrototype.h"44 41 45 42 using namespace WebCore; … … 48 45 namespace Bindings { 49 46 50 class QtPixmapClass : public Class { 51 public: 52 QtPixmapClass(); 53 virtual MethodList methodsNamed(PropertyName, Instance*) const; 54 virtual Field* fieldNamed(PropertyName, Instance*) const; 55 }; 56 57 58 class QtPixmapWidthField : public Field { 59 public: 60 static const char* name() { return "width"; } 61 virtual JSValue valueFromInstance(ExecState*, const Instance* instance) const 62 { 63 return jsNumber(static_cast<const QtPixmapInstance*>(instance)->width()); 47 static void copyPixelsInto(const QImage& sourceImage, int width, int height, unsigned char* destPixels) 48 { 49 QImage image(sourceImage); 50 switch (image.format()) { 51 case QImage::Format_RGB888: 52 for (int y = 0; y < height; y++) { 53 const uchar* scanLine = image.scanLine(y); 54 for (int x = 0; x < width; x++) { 55 *(destPixels++) = *(scanLine++); 56 *(destPixels++) = *(scanLine++); 57 *(destPixels++) = *(scanLine++); 58 *(destPixels++) = 0xFF; 59 } 60 } 61 break; 62 default: 63 image = image.convertToFormat(QImage::Format_ARGB32); 64 // Fall through 65 case QImage::Format_RGB32: 66 case QImage::Format_ARGB32: 67 for (int y = 0; y < height; y++) { 68 const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(image.scanLine(y)); 69 for (int x = 0; x < width; x++) { 70 QRgb pixel = scanLine[x]; 71 qToBigEndian<quint32>((pixel << 8) | qAlpha(pixel), destPixels); 72 destPixels += 4; 73 } 74 } 75 break; 64 76 } 65 virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const {} 66 }; 67 68 class QtPixmapHeightField : public Field { 69 public: 70 static const char* name() { return "height"; } 71 virtual JSValue valueFromInstance(ExecState*, const Instance* instance) const 72 { 73 return jsNumber(static_cast<const QtPixmapInstance*>(instance)->height()); 74 } 75 virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const {} 76 }; 77 78 class QtPixmapRuntimeMethod : public Method { 79 public: 80 virtual int numParameters() const 81 { 82 return 0; 83 } 84 virtual JSValue invoke(ExecState* exec, QtPixmapInstance*) = 0; 85 86 }; 87 88 class QtPixmapToImageDataMethod : public QtPixmapRuntimeMethod { 89 public: 90 static const char* name() { return "toImageData"; } 91 JSValue invoke(ExecState* exec, QtPixmapInstance* instance) 92 { 93 int width = instance->width(); 94 int height = instance->height(); 95 RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); 96 copyPixels(instance->toImage(), width, height, imageData->data()->data()); 97 return toJS(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), imageData.get()); 98 } 99 private: 100 void copyPixels(const QImage& sourceImage, int width, int height, unsigned char* destPixels) 101 { 102 QImage image(sourceImage); 103 switch (image.format()) { 104 case QImage::Format_RGB888: 105 for (int y = 0; y < height; y++) { 106 const uchar* scanLine = image.scanLine(y); 107 for (int x = 0; x < width; x++) { 108 *(destPixels++) = *(scanLine++); 109 *(destPixels++) = *(scanLine++); 110 *(destPixels++) = *(scanLine++); 111 *(destPixels++) = 0xFF; 112 } 113 } 114 break; 115 default: 116 image = image.convertToFormat(QImage::Format_ARGB32); 117 // Fall through 118 case QImage::Format_RGB32: 119 case QImage::Format_ARGB32: 120 for (int y = 0; y < height; y++) { 121 const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(image.scanLine(y)); 122 for (int x = 0; x < width; x++) { 123 QRgb pixel = scanLine[x]; 124 qToBigEndian<quint32>((pixel << 8) | qAlpha(pixel), destPixels); 125 destPixels += 4; 126 } 127 } 128 break; 129 } 130 } 131 }; 132 133 // this function receives an HTML image element as a parameter, makes it display the pixmap/image from Qt 134 class QtPixmapAssignToElementMethod : public QtPixmapRuntimeMethod { 135 public: 136 static const char* name() { return "assignToHTMLImageElement"; } 137 JSValue invoke(ExecState* exec, QtPixmapInstance* instance) 138 { 139 if (!exec->argumentCount()) 140 return jsUndefined(); 141 142 JSObject* objectArg = exec->argument(0).toObject(exec); 143 if (!objectArg) 144 return jsUndefined(); 145 146 if (!objectArg->inherits(&JSHTMLImageElement::s_info)) 147 return jsUndefined(); 148 149 // we now know that we have a valid <img> element as the argument, we can attach the image to it. 150 RefPtr<StillImage> stillImage = WebCore::StillImage::create(instance->toImage()); 151 HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(objectArg)->impl()); 152 imageElement->setCachedImage(new CachedImage(stillImage.get())); 153 JSDOMGlobalObject* global = static_cast<JSDOMGlobalObject*>(instance->rootObject()->globalObject()); 154 toJS(exec, global, imageElement->document()); 155 return jsUndefined(); 156 } 157 158 virtual int numParameters() const 159 { 160 return 1; 161 } 162 }; 163 164 // this function encodes the image to a dataUrl, to be used in background etc. Note: very slow. 165 class QtPixmapToDataUrlMethod : public QtPixmapRuntimeMethod { 166 public: 167 static const char* name() { return "toDataUrl"; } 168 JSValue invoke(ExecState* exec, QtPixmapInstance* instance) 169 { 170 QByteArray byteArray; 171 QBuffer buffer(&byteArray); 172 instance->toImage().save(&buffer, "PNG"); 173 const QString encodedString = QLatin1String("data:image/png;base64,") + QLatin1String(byteArray.toBase64()); 174 const String ustring((UChar*)encodedString.utf16(), encodedString.length()); 175 return JSC::jsString(exec, ustring); 176 } 177 }; 178 179 class QtPixmapToStringMethod : public QtPixmapRuntimeMethod { 180 public: 181 static const char* name() { return "toString"; } 182 JSValue invoke(ExecState* exec, QtPixmapInstance* instance) 183 { 184 return instance->valueOf(exec); 185 } 186 }; 187 188 struct QtPixmapMetaData { 189 QtPixmapToDataUrlMethod toDataUrlMethod; 190 QtPixmapToImageDataMethod toImageDataMethod; 191 QtPixmapAssignToElementMethod assignToElementMethod; 192 QtPixmapToStringMethod toStringMethod; 193 QtPixmapHeightField heightField; 194 QtPixmapWidthField widthField; 195 QtPixmapClass cls; 196 } qt_pixmap_metaData; 197 198 // Derived RuntimeObject 199 class QtPixmapRuntimeObject : public RuntimeObject { 200 public: 201 typedef RuntimeObject Base; 202 203 static QtPixmapRuntimeObject* create(ExecState* exec, JSGlobalObject* globalObject, PassRefPtr<Instance> instance) 204 { 205 Structure* domStructure = WebCore::deprecatedGetDOMStructure<QtPixmapRuntimeObject>(exec); 206 QtPixmapRuntimeObject* object = new (allocateCell<QtPixmapRuntimeObject>(*exec->heap())) QtPixmapRuntimeObject(exec, globalObject, domStructure, instance); 207 object->finishCreation(globalObject); 208 return object; 209 } 210 211 static const ClassInfo s_info; 212 213 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) 214 { 215 return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); 216 } 217 218 protected: 219 static const unsigned StructureFlags = RuntimeObject::StructureFlags | OverridesVisitChildren; 220 221 private: 222 QtPixmapRuntimeObject(ExecState*, JSGlobalObject*, Structure*, PassRefPtr<Instance>); 223 }; 224 225 QtPixmapRuntimeObject::QtPixmapRuntimeObject(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, PassRefPtr<Instance> instance) 226 : RuntimeObject(exec, globalObject, structure, instance) 227 { 228 } 229 230 const ClassInfo QtPixmapRuntimeObject::s_info = { "QtPixmapRuntimeObject", &RuntimeObject::s_info, 0, 0, CREATE_METHOD_TABLE(QtPixmapRuntimeObject) }; 231 232 QtPixmapClass::QtPixmapClass() 233 { 234 } 235 236 237 Class* QtPixmapInstance::getClass() const 238 { 239 return &qt_pixmap_metaData.cls; 240 } 241 242 JSValue QtPixmapInstance::getMethod(ExecState* exec, PropertyName propertyName) 243 { 244 MethodList methodList = getClass()->methodsNamed(propertyName, this); 245 return RuntimeMethod::create(exec, exec->lexicalGlobalObject(), WebCore::deprecatedGetDOMStructure<RuntimeMethod>(exec), propertyName.publicName(), methodList); 246 } 247 248 JSValue QtPixmapInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod) 249 { 250 const MethodList& methods = *runtimeMethod->methods(); 251 252 if (methods.size() == 1) { 253 QtPixmapRuntimeMethod* method = static_cast<QtPixmapRuntimeMethod*>(methods[0]); 254 return method->invoke(exec, this); 255 } 256 return jsUndefined(); 257 } 258 259 MethodList QtPixmapClass::methodsNamed(PropertyName identifier, Instance*) const 260 { 261 MethodList methods; 262 String ustring(identifier.publicName()); 263 if (ustring == QtPixmapToDataUrlMethod::name()) 264 methods.append(&qt_pixmap_metaData.toDataUrlMethod); 265 else if (ustring == QtPixmapToImageDataMethod::name()) 266 methods.append(&qt_pixmap_metaData.toImageDataMethod); 267 else if (ustring == QtPixmapAssignToElementMethod::name()) 268 methods.append(&qt_pixmap_metaData.assignToElementMethod); 269 else if (ustring == QtPixmapToStringMethod::name()) 270 methods.append(&qt_pixmap_metaData.toStringMethod); 271 return methods; 272 } 273 274 Field* QtPixmapClass::fieldNamed(PropertyName identifier, Instance*) const 275 { 276 String ustring(identifier.publicName()); 277 if (ustring == QtPixmapWidthField::name()) 278 return &qt_pixmap_metaData.widthField; 279 if (ustring == QtPixmapHeightField::name()) 280 return &qt_pixmap_metaData.heightField; 281 return 0; 282 } 283 284 void QtPixmapInstance::getPropertyNames(ExecState*exec, PropertyNameArray& arr) 285 { 286 arr.add(Identifier(exec, String(QtPixmapToDataUrlMethod::name()))); 287 arr.add(Identifier(exec, String(QtPixmapToImageDataMethod::name()))); 288 arr.add(Identifier(exec, String(QtPixmapAssignToElementMethod::name()))); 289 arr.add(Identifier(exec, String(QtPixmapToStringMethod::name()))); 290 arr.add(Identifier(exec, String(QtPixmapWidthField::name()))); 291 arr.add(Identifier(exec, String(QtPixmapHeightField::name()))); 292 } 293 294 JSValue QtPixmapInstance::defaultValue(ExecState* exec, PreferredPrimitiveType ptype) const 295 { 296 if (ptype == PreferNumber) { 297 return jsBoolean( 298 (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>()) && !(data.value<QImage>()).isNull()) 299 || (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>()) && !data.value<QPixmap>().isNull())); 300 } 301 302 if (ptype == PreferString) 303 return valueOf(exec); 304 305 return jsUndefined(); 306 } 307 308 JSValue QtPixmapInstance::valueOf(ExecState* exec) const 309 { 310 const QString stringValue = QString::fromLatin1("[Qt Native Pixmap %1,%2]").arg(width()).arg(height()); 311 String ustring((UChar*)stringValue.utf16(), stringValue.length()); 312 return JSC::jsString(exec, ustring); 313 } 314 315 QtPixmapInstance::QtPixmapInstance(PassRefPtr<RootObject> rootObj, const QVariant& d) 316 :Instance(rootObj), data(d) 317 { 318 } 319 320 int QtPixmapInstance::width() const 321 { 322 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) 323 return data.value<QPixmap>().width(); 324 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) 325 return data.value<QImage>().width(); 326 return 0; 327 } 328 329 int QtPixmapInstance::height() const 330 { 331 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) 332 return data.value<QPixmap>().height(); 333 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) 334 return data.value<QImage>().height(); 335 return 0; 336 } 337 338 QPixmap QtPixmapInstance::toPixmap() 77 } 78 79 static QPixmap toPixmap(const QVariant& data) 339 80 { 340 81 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) 341 82 return data.value<QPixmap>(); 342 83 343 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) { 344 const QPixmap pixmap = QPixmap::fromImage(data.value<QImage>()); 345 data = QVariant::fromValue<QPixmap>(pixmap); 346 return pixmap; 347 } 84 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) 85 return QPixmap::fromImage(data.value<QImage>()); 348 86 349 87 return QPixmap(); 350 88 } 351 89 352 QImage QtPixmapInstance::toImage()90 static QImage toImage(const QVariant& data) 353 91 { 354 92 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) 355 93 return data.value<QImage>(); 356 94 357 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) { 358 const QImage image = data.value<QPixmap>().toImage(); 359 data = QVariant::fromValue<QImage>(image); 360 return image; 95 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) 96 return data.value<QPixmap>().toImage(); 97 98 return QImage(); 99 } 100 101 static QSize imageSizeForVariant(const QVariant& data) 102 { 103 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QPixmap>())) 104 return data.value<QPixmap>().size(); 105 if (data.type() == static_cast<QVariant::Type>(qMetaTypeId<QImage>())) 106 return data.value<QImage>().size(); 107 return QSize(0, 0); 108 } 109 110 static JSValueRef getPixmapWidth(JSContextRef context, JSObjectRef object, JSStringRef, JSValueRef*) 111 { 112 QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object)); 113 return JSValueMakeNumber(context, imageSizeForVariant(data).width()); 114 } 115 116 static JSValueRef getPixmapHeight(JSContextRef context, JSObjectRef object, JSStringRef, JSValueRef*) 117 { 118 QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object)); 119 return JSValueMakeNumber(context, imageSizeForVariant(data).height()); 120 } 121 122 static JSValueRef assignToHTMLImageElement(JSContextRef context, JSObjectRef function, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 123 { 124 if (!argumentCount) 125 return JSValueMakeUndefined(context); 126 127 JSObjectRef objectArg = JSValueToObject(context, arguments[0], exception); 128 if (!objectArg) 129 return JSValueMakeUndefined(context); 130 131 JSObject* jsObject = ::toJS(objectArg); 132 133 if (!jsObject->inherits(&JSHTMLImageElement::s_info)) 134 return JSValueMakeUndefined(context); 135 136 QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object)); 137 138 // We now know that we have a valid <img> element as the argument, we can attach the image to it. 139 RefPtr<StillImage> stillImage = WebCore::StillImage::create(toImage(data)); 140 HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(jsObject)->impl()); 141 imageElement->setCachedImage(new CachedImage(stillImage.get())); 142 return JSValueMakeUndefined(context); 143 } 144 145 static JSValueRef pixmapToImageData(JSContextRef context, JSObjectRef function, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 146 { 147 QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object)); 148 QImage image = toImage(data); 149 int width = image.width(); 150 int height = image.height(); 151 152 RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); 153 copyPixelsInto(image, width, height, imageData->data()->data()); 154 JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(::toJS(JSContextGetGlobalObject(context))); 155 JSC::ExecState* exec = ::toJS(context); 156 return ::toRef(exec, toJS(exec, globalObject, imageData.get())); 157 } 158 159 static JSValueRef pixmapToDataUrl(JSContextRef context, JSObjectRef function, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 160 { 161 QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object)); 162 QByteArray byteArray; 163 QBuffer buffer(&byteArray); 164 toImage(data).save(&buffer, "PNG"); 165 QByteArray encoded = QByteArray("data:image/png;base64,") + byteArray.toBase64(); 166 JSRetainPtr<JSStringRef> str(Adopt, JSStringCreateWithUTF8CString(encoded.constData())); 167 JSValueRef value = JSValueMakeString(context, str.get()); 168 169 return value; 170 } 171 172 static JSValueRef pixmapToString(JSContextRef context, JSObjectRef function, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 173 { 174 QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object)); 175 QSize size = imageSizeForVariant(data); 176 QString stringValue = QString::fromLatin1("[Qt Native Pixmap %1,%2]").arg(size.width()).arg(size.height()); 177 JSRetainPtr<JSStringRef> str(Adopt, JSStringCreateWithUTF8CString(stringValue.toUtf8().constData())); 178 JSValueRef value = JSValueMakeString(context, str.get()); 179 180 return value; 181 } 182 183 static void finalizePixmap(JSObjectRef object) 184 { 185 delete static_cast<QVariant*>(JSObjectGetPrivate(object)); 186 } 187 188 JSObjectRef QtPixmapRuntime::toJS(JSContextRef context, const QVariant& value, JSValueRef* exception) 189 { 190 return JSObjectMake(context, getClassRef(), new QVariant(value)); 191 } 192 193 static QVariant emptyVariantForHint(QMetaType::Type hint) 194 { 195 if (hint == qMetaTypeId<QPixmap>()) 196 return QVariant::fromValue(QPixmap()); 197 if (hint == qMetaTypeId<QImage>()) 198 return QVariant::fromValue(QImage()); 199 return QVariant(); 200 } 201 202 QVariant QtPixmapRuntime::toQt(JSContextRef context, JSObjectRef obj, QMetaType::Type hint, JSValueRef* exception) 203 { 204 if (!obj) 205 return emptyVariantForHint(hint); 206 207 if (JSValueIsObjectOfClass(context, obj, QtPixmapRuntime::getClassRef())) { 208 QVariant* originalVariant = static_cast<QVariant*>(JSObjectGetPrivate(obj)); 209 if (hint == qMetaTypeId<QPixmap>()) 210 return QVariant::fromValue<QPixmap>(toPixmap(*originalVariant)); 211 212 if (hint == qMetaTypeId<QImage>()) 213 return QVariant::fromValue<QImage>(toImage(*originalVariant)); 361 214 } 362 215 363 return QImage(); 364 } 365 366 QVariant QtPixmapInstance::variantFromObject(JSObject* object, QMetaType::Type hint) 367 { 368 if (!object) 369 goto returnEmptyVariant; 370 371 if (object->inherits(&JSHTMLImageElement::s_info)) { 372 JSHTMLImageElement* elementJSWrapper = static_cast<JSHTMLImageElement*>(object); 373 HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(elementJSWrapper->impl()); 374 375 if (!imageElement) 376 goto returnEmptyVariant; 377 378 CachedImage* cachedImage = imageElement->cachedImage(); 379 if (!cachedImage) 380 goto returnEmptyVariant; 381 382 Image* image = cachedImage->imageForRenderer(imageElement->renderer()); 383 if (!image) 384 goto returnEmptyVariant; 385 386 QImage* nativeImage = image->nativeImageForCurrentFrame(); 387 if (!nativeImage) 388 goto returnEmptyVariant; 389 390 return (hint == static_cast<QMetaType::Type>(qMetaTypeId<QPixmap>())) 391 ? QVariant::fromValue<QPixmap>(QPixmap::fromImage(*nativeImage)) 392 : QVariant::fromValue<QImage>(*nativeImage); 393 } 394 395 if (object->inherits(&QtPixmapRuntimeObject::s_info)) { 396 QtPixmapRuntimeObject* runtimeObject = static_cast<QtPixmapRuntimeObject*>(object); 397 QtPixmapInstance* instance = static_cast<QtPixmapInstance*>(runtimeObject->getInternalInstance()); 398 if (!instance) 399 goto returnEmptyVariant; 400 401 if (hint == qMetaTypeId<QPixmap>()) 402 return QVariant::fromValue<QPixmap>(instance->toPixmap()); 403 404 if (hint == qMetaTypeId<QImage>()) 405 return QVariant::fromValue<QImage>(instance->toImage()); 406 } 407 408 returnEmptyVariant: 409 if (hint == qMetaTypeId<QPixmap>()) 410 return QVariant::fromValue<QPixmap>(QPixmap()); 411 if (hint == qMetaTypeId<QImage>()) 412 return QVariant::fromValue<QImage>(QImage()); 413 return QVariant(); 414 } 415 416 RuntimeObject* QtPixmapInstance::newRuntimeObject(ExecState* exec) 417 { 418 return QtPixmapRuntimeObject::create(exec, exec->lexicalGlobalObject(), this); 419 } 420 421 JSObject* QtPixmapInstance::createPixmapRuntimeObject(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& data) 422 { 423 JSLockHolder lock(exec); 424 RefPtr<QtPixmapInstance> instance = adoptRef(new QtPixmapInstance(root, data)); 425 return instance->createRuntimeObject(exec); 426 } 427 428 bool QtPixmapInstance::canHandle(QMetaType::Type hint) 216 JSObject* jsObject = ::toJS(obj); 217 if (!jsObject->inherits(&JSHTMLImageElement::s_info)) 218 return emptyVariantForHint(hint); 219 220 JSHTMLImageElement* elementJSWrapper = static_cast<JSHTMLImageElement*>(jsObject); 221 HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(elementJSWrapper->impl()); 222 223 if (!imageElement) 224 return emptyVariantForHint(hint); 225 226 CachedImage* cachedImage = imageElement->cachedImage(); 227 if (!cachedImage) 228 return emptyVariantForHint(hint); 229 230 Image* image = cachedImage->imageForRenderer(imageElement->renderer()); 231 if (!image) 232 return emptyVariantForHint(hint); 233 234 QImage* nativeImage = image->nativeImageForCurrentFrame(); 235 if (!nativeImage) 236 return emptyVariantForHint(hint); 237 238 return (hint == static_cast<QMetaType::Type>(qMetaTypeId<QPixmap>())) 239 ? QVariant::fromValue<QPixmap>(QPixmap::fromImage(*nativeImage)) 240 : QVariant::fromValue<QImage>(*nativeImage); 241 } 242 243 bool QtPixmapRuntime::canHandle(QMetaType::Type hint) 429 244 { 430 245 return hint == qMetaTypeId<QImage>() || hint == qMetaTypeId<QPixmap>(); 431 246 } 432 247 433 } 434 435 } 248 JSClassRef QtPixmapRuntime::getClassRef() 249 { 250 static const JSStaticValue staticValues[] = { 251 { "width", getPixmapWidth, 0, 0 }, 252 { "height", getPixmapHeight, 0, 0 } 253 }; 254 255 static const JSStaticFunction staticFunctions[] = { 256 { "assignTo", assignToHTMLImageElement, 0 }, 257 { "toDataUrl", pixmapToDataUrl, 0 }, 258 { "toImageData", pixmapToImageData, 0 }, 259 { "toString", pixmapToString, 0 } 260 }; 261 262 static const JSClassDefinition classDefinition = { 263 0, 0, "QtPixmapRuntimeObject", 0, staticValues, staticFunctions, 264 0, finalizePixmap, 0, 0, 0, 0, 0, 0, 0, 0, 0 265 }; 266 267 static JSClassRef classRef = JSClassCreate(&classDefinition); 268 return classRef; 269 } 270 271 272 } 273 274 } -
trunk/Source/WebCore/bridge/qt/qt_pixmapruntime.h
r116828 r127440 22 22 23 23 #include "BridgeJSC.h" 24 #include "JavaScript.h" 24 25 #include <QVariant> 25 26 … … 28 29 namespace Bindings { 29 30 30 class QtPixmapInstance : public Instance { 31 QVariant data; 31 class QtPixmapRuntime { 32 32 public: 33 QtPixmapInstance(PassRefPtr<RootObject> rootObj, const QVariant& newData); 34 virtual Class* getClass() const; 35 virtual JSValue getMethod(ExecState*, PropertyName); 36 virtual JSValue invokeMethod(ExecState*, RuntimeMethod*); 37 virtual void getPropertyNames(ExecState*, PropertyNameArray&); 33 static JSObjectRef toJS(JSContextRef, const QVariant&, JSValueRef* exception); 34 static QVariant toQt(JSContextRef, JSObjectRef, QMetaType::Type hint, JSValueRef* exception); 35 static bool canHandle(QMetaType::Type hint); 38 36 39 virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const; 40 virtual JSValue valueOf(ExecState*) const; 41 int width() const; 42 int height() const; 43 QPixmap toPixmap(); 44 QImage toImage(); 45 RuntimeObject* newRuntimeObject(ExecState*); 46 static JSObject* createPixmapRuntimeObject(ExecState*, PassRefPtr<RootObject>, const QVariant&); 47 static QVariant variantFromObject(JSObject*, QMetaType::Type hint); 48 static bool canHandle(QMetaType::Type hint); 37 static JSClassRef getClassRef(); 49 38 }; 50 39 -
trunk/Source/WebCore/bridge/qt/qt_runtime.cpp
r127238 r127440 624 624 break; 625 625 } 626 if (QtPixmap Instance::canHandle(static_cast<QMetaType::Type>(hint))) {627 ret = QtPixmap Instance::variantFromObject(toJS(object), static_cast<QMetaType::Type>(hint));626 if (QtPixmapRuntime::canHandle(static_cast<QMetaType::Type>(hint))) { 627 ret = QtPixmapRuntime::toQt(context, object, static_cast<QMetaType::Type>(hint), exception); 628 628 } else if (customRuntimeConversions()->contains(hint)) { 629 629 ret = customRuntimeConversions()->value(hint).toVariantFunc(toJS(object), &dist, visitedObjects); … … 741 741 } 742 742 743 if (QtPixmapInstance::canHandle(static_cast<QMetaType::Type>(variant.type()))) { 744 ExecState* exec = toJS(context); 745 return toRef(exec, QtPixmapInstance::createPixmapRuntimeObject(exec, root, variant)); 746 } 743 if (QtPixmapRuntime::canHandle(static_cast<QMetaType::Type>(variant.type()))) 744 return QtPixmapRuntime::toJS(context, variant, exception); 747 745 748 746 if (customRuntimeConversions()->contains(type)) {
Note: See TracChangeset
for help on using the changeset viewer.