| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, Google Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> | 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> |
| 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions are | 7 * modification, are permitted provided that the following conditions are |
| 8 * met: | 8 * met: |
| 9 * | 9 * |
| 10 * * Redistributions of source code must retain the above copyright | 10 * * Redistributions of source code must retain the above copyright |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 */ | 31 */ |
| 32 | 32 |
| 33 #include "config.h" | 33 #include "config.h" |
| 34 #include "platform/graphics/ImageBuffer.h" | 34 #include "platform/graphics/ImageBuffer.h" |
| 35 | 35 |
| 36 #include "platform/MIMETypeRegistry.h" | 36 #include "platform/MIMETypeRegistry.h" |
| 37 #include "platform/geometry/IntRect.h" | 37 #include "platform/geometry/IntRect.h" |
| 38 #include "platform/graphics/BitmapImage.h" | 38 #include "platform/graphics/BitmapImage.h" |
| 39 #include "platform/graphics/GraphicsContext.h" | 39 #include "platform/graphics/GraphicsContext.h" |
| 40 #include "platform/graphics/GraphicsTypes3D.h" | 40 #include "platform/graphics/GraphicsTypes3D.h" |
| 41 #include "platform/graphics/ImageBufferClient.h" |
| 41 #include "platform/graphics/UnacceleratedImageBufferSurface.h" | 42 #include "platform/graphics/UnacceleratedImageBufferSurface.h" |
| 42 #include "platform/graphics/gpu/DrawingBuffer.h" | 43 #include "platform/graphics/gpu/DrawingBuffer.h" |
| 43 #include "platform/graphics/gpu/Extensions3DUtil.h" | 44 #include "platform/graphics/gpu/Extensions3DUtil.h" |
| 44 #include "platform/graphics/skia/NativeImageSkia.h" | 45 #include "platform/graphics/skia/NativeImageSkia.h" |
| 45 #include "platform/graphics/skia/SkiaUtils.h" | 46 #include "platform/graphics/skia/SkiaUtils.h" |
| 46 #include "platform/image-encoders/skia/JPEGImageEncoder.h" | 47 #include "platform/image-encoders/skia/JPEGImageEncoder.h" |
| 47 #include "platform/image-encoders/skia/PNGImageEncoder.h" | 48 #include "platform/image-encoders/skia/PNGImageEncoder.h" |
| 48 #include "platform/image-encoders/skia/WEBPImageEncoder.h" | 49 #include "platform/image-encoders/skia/WEBPImageEncoder.h" |
| 49 #include "public/platform/Platform.h" | 50 #include "public/platform/Platform.h" |
| 50 #include "public/platform/WebExternalTextureMailbox.h" | 51 #include "public/platform/WebExternalTextureMailbox.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 69 PassOwnPtr<ImageBuffer> ImageBuffer::create(const IntSize& size, OpacityMode opa
cityMode) | 70 PassOwnPtr<ImageBuffer> ImageBuffer::create(const IntSize& size, OpacityMode opa
cityMode) |
| 70 { | 71 { |
| 71 OwnPtr<ImageBufferSurface> surface = adoptPtr(new UnacceleratedImageBufferSu
rface(size, opacityMode)); | 72 OwnPtr<ImageBufferSurface> surface = adoptPtr(new UnacceleratedImageBufferSu
rface(size, opacityMode)); |
| 72 if (!surface->isValid()) | 73 if (!surface->isValid()) |
| 73 return nullptr; | 74 return nullptr; |
| 74 return adoptPtr(new ImageBuffer(surface.release())); | 75 return adoptPtr(new ImageBuffer(surface.release())); |
| 75 } | 76 } |
| 76 | 77 |
| 77 ImageBuffer::ImageBuffer(PassOwnPtr<ImageBufferSurface> surface) | 78 ImageBuffer::ImageBuffer(PassOwnPtr<ImageBufferSurface> surface) |
| 78 : m_surface(surface) | 79 : m_surface(surface) |
| 80 , m_client(0) |
| 79 { | 81 { |
| 82 m_surface->setImageBuffer(this); |
| 80 if (m_surface->canvas()) { | 83 if (m_surface->canvas()) { |
| 81 m_context = adoptPtr(new GraphicsContext(m_surface->canvas())); | 84 m_context = adoptPtr(new GraphicsContext(m_surface->canvas())); |
| 82 m_context->setCertainlyOpaque(m_surface->opacityMode() == Opaque); | 85 m_context->setCertainlyOpaque(m_surface->opacityMode() == Opaque); |
| 83 m_context->setAccelerated(m_surface->isAccelerated()); | 86 m_context->setAccelerated(m_surface->isAccelerated()); |
| 84 } | 87 } |
| 85 } | 88 } |
| 86 | 89 |
| 87 ImageBuffer::~ImageBuffer() | 90 ImageBuffer::~ImageBuffer() |
| 88 { | 91 { |
| 89 } | 92 } |
| 90 | 93 |
| 91 GraphicsContext* ImageBuffer::context() const | 94 GraphicsContext* ImageBuffer::context() const |
| 92 { | 95 { |
| 96 if (!isSurfaceValid()) |
| 97 return 0; |
| 93 m_surface->willUse(); | 98 m_surface->willUse(); |
| 94 ASSERT(m_context.get()); | 99 ASSERT(m_context.get()); |
| 95 return m_context.get(); | 100 return m_context.get(); |
| 96 } | 101 } |
| 97 | 102 |
| 98 const SkBitmap& ImageBuffer::bitmap() const | 103 const SkBitmap& ImageBuffer::bitmap() const |
| 99 { | 104 { |
| 100 m_surface->willUse(); | 105 m_surface->willUse(); |
| 101 return m_surface->bitmap(); | 106 return m_surface->bitmap(); |
| 102 } | 107 } |
| 103 | 108 |
| 104 bool ImageBuffer::isValid() const | 109 bool ImageBuffer::isSurfaceValid() const |
| 105 { | 110 { |
| 106 return m_surface->isValid(); | 111 return m_surface->isValid(); |
| 107 } | 112 } |
| 108 | 113 |
| 114 bool ImageBuffer::restoreSurface() const |
| 115 { |
| 116 return m_surface->isValid() || m_surface->restore(); |
| 117 } |
| 118 |
| 119 void ImageBuffer::notifySurfaceInvalid() |
| 120 { |
| 121 if (m_client) |
| 122 m_client->notifySurfaceInvalid(); |
| 123 } |
| 124 |
| 109 static SkBitmap deepSkBitmapCopy(const SkBitmap& bitmap) | 125 static SkBitmap deepSkBitmapCopy(const SkBitmap& bitmap) |
| 110 { | 126 { |
| 111 SkBitmap tmp; | 127 SkBitmap tmp; |
| 112 if (!bitmap.deepCopyTo(&tmp)) | 128 if (!bitmap.deepCopyTo(&tmp)) |
| 113 bitmap.copyTo(&tmp, bitmap.colorType()); | 129 bitmap.copyTo(&tmp, bitmap.colorType()); |
| 114 | 130 |
| 115 return tmp; | 131 return tmp; |
| 116 } | 132 } |
| 117 | 133 |
| 118 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
avior) const | 134 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
avior) const |
| 119 { | 135 { |
| 120 if (!isValid()) | 136 if (!isSurfaceValid()) |
| 121 return BitmapImage::create(NativeImageSkia::create()); | 137 return BitmapImage::create(NativeImageSkia::create()); |
| 122 | 138 |
| 123 const SkBitmap& bitmap = m_surface->bitmap(); | 139 const SkBitmap& bitmap = m_surface->bitmap(); |
| 124 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki
ngStore ? deepSkBitmapCopy(bitmap) : bitmap)); | 140 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki
ngStore ? deepSkBitmapCopy(bitmap) : bitmap)); |
| 125 } | 141 } |
| 126 | 142 |
| 127 BackingStoreCopy ImageBuffer::fastCopyImageMode() | 143 BackingStoreCopy ImageBuffer::fastCopyImageMode() |
| 128 { | 144 { |
| 129 return DontCopyBackingStore; | 145 return DontCopyBackingStore; |
| 130 } | 146 } |
| 131 | 147 |
| 132 blink::WebLayer* ImageBuffer::platformLayer() const | 148 blink::WebLayer* ImageBuffer::platformLayer() const |
| 133 { | 149 { |
| 134 return m_surface->layer(); | 150 return m_surface->layer(); |
| 135 } | 151 } |
| 136 | 152 |
| 137 bool ImageBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Pl
atform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, boo
l premultiplyAlpha, bool flipY) | 153 bool ImageBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Pl
atform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, boo
l premultiplyAlpha, bool flipY) |
| 138 { | 154 { |
| 139 if (!m_surface->isAccelerated() || !platformLayer() || !isValid()) | 155 if (!m_surface->isAccelerated() || !platformLayer() || !isSurfaceValid()) |
| 140 return false; | 156 return false; |
| 141 | 157 |
| 142 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, l
evel)) | 158 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, l
evel)) |
| 143 return false; | 159 return false; |
| 144 | 160 |
| 145 OwnPtr<blink::WebGraphicsContext3DProvider> provider = adoptPtr(blink::Platf
orm::current()->createSharedOffscreenGraphicsContext3DProvider()); | 161 OwnPtr<blink::WebGraphicsContext3DProvider> provider = adoptPtr(blink::Platf
orm::current()->createSharedOffscreenGraphicsContext3DProvider()); |
| 146 if (!provider) | 162 if (!provider) |
| 147 return false; | 163 return false; |
| 148 blink::WebGraphicsContext3D* sharedContext = provider->context3d(); | 164 blink::WebGraphicsContext3D* sharedContext = provider->context3d(); |
| 149 if (!sharedContext || !sharedContext->makeContextCurrent()) | 165 if (!sharedContext || !sharedContext->makeContextCurrent()) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 Platform3DObject tex = m_surface->getBackingTexture(); | 226 Platform3DObject tex = m_surface->getBackingTexture(); |
| 211 if (!context3D || !tex) | 227 if (!context3D || !tex) |
| 212 return false; | 228 return false; |
| 213 m_surface->invalidateCachedBitmap(); | 229 m_surface->invalidateCachedBitmap(); |
| 214 return drawingBuffer->copyToPlatformTexture(context3D, tex, GL_RGBA, | 230 return drawingBuffer->copyToPlatformTexture(context3D, tex, GL_RGBA, |
| 215 GL_UNSIGNED_BYTE, 0, true, false); | 231 GL_UNSIGNED_BYTE, 0, true, false); |
| 216 } | 232 } |
| 217 | 233 |
| 218 void ImageBuffer::draw(GraphicsContext* context, const FloatRect& destRect, cons
t FloatRect& srcRect, CompositeOperator op, blink::WebBlendMode blendMode) | 234 void ImageBuffer::draw(GraphicsContext* context, const FloatRect& destRect, cons
t FloatRect& srcRect, CompositeOperator op, blink::WebBlendMode blendMode) |
| 219 { | 235 { |
| 220 if (!isValid()) | 236 if (!isSurfaceValid()) |
| 221 return; | 237 return; |
| 222 | 238 |
| 223 SkBitmap bitmap = m_surface->bitmap(); | 239 SkBitmap bitmap = m_surface->bitmap(); |
| 224 // For ImageBufferSurface that enables cachedBitmap, Use the cached Bitmap f
or CPU side usage | 240 // For ImageBufferSurface that enables cachedBitmap, Use the cached Bitmap f
or CPU side usage |
| 225 // if it is available, otherwise generate and use it. | 241 // if it is available, otherwise generate and use it. |
| 226 if (!context->isAccelerated() && m_surface->isAccelerated() && m_surface->ca
chedBitmapEnabled() && m_surface->isValid()) { | 242 if (!context->isAccelerated() && m_surface->isAccelerated() && m_surface->ca
chedBitmapEnabled() && isSurfaceValid()) { |
| 227 m_surface->updateCachedBitmapIfNeeded(); | 243 m_surface->updateCachedBitmapIfNeeded(); |
| 228 bitmap = m_surface->cachedBitmap(); | 244 bitmap = m_surface->cachedBitmap(); |
| 229 } | 245 } |
| 230 | 246 |
| 231 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); | 247 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); |
| 232 | 248 |
| 233 context->drawImage(image.get(), destRect, srcRect, op, blendMode, DoNotRespe
ctImageOrientation); | 249 context->drawImage(image.get(), destRect, srcRect, op, blendMode, DoNotRespe
ctImageOrientation); |
| 234 } | 250 } |
| 235 | 251 |
| 236 void ImageBuffer::flush() | 252 void ImageBuffer::flush() |
| 237 { | 253 { |
| 238 if (m_surface->canvas()) { | 254 if (m_surface->canvas()) { |
| 239 m_surface->canvas()->flush(); | 255 m_surface->canvas()->flush(); |
| 240 } | 256 } |
| 241 } | 257 } |
| 242 | 258 |
| 243 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect
, const FloatSize& scale, | 259 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect
, const FloatSize& scale, |
| 244 const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect, bl
ink::WebBlendMode blendMode, const IntSize& repeatSpacing) | 260 const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect, bl
ink::WebBlendMode blendMode, const IntSize& repeatSpacing) |
| 245 { | 261 { |
| 246 if (!isValid()) | 262 if (!isSurfaceValid()) |
| 247 return; | 263 return; |
| 248 | 264 |
| 249 const SkBitmap& bitmap = m_surface->bitmap(); | 265 const SkBitmap& bitmap = m_surface->bitmap(); |
| 250 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); | 266 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); |
| 251 image->drawPattern(context, srcRect, scale, phase, op, destRect, blendMode,
repeatSpacing); | 267 image->drawPattern(context, srcRect, scale, phase, op, destRect, blendMode,
repeatSpacing); |
| 252 } | 268 } |
| 253 | 269 |
| 254 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo
lorSpace) | 270 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo
lorSpace) |
| 255 { | 271 { |
| 256 const uint8_t* lookUpTable = ColorSpaceUtilities::getConversionLUT(dstColorS
pace, srcColorSpace); | 272 const uint8_t* lookUpTable = ColorSpaceUtilities::getConversionLUT(dstColorS
pace, srcColorSpace); |
| 257 if (!lookUpTable) | 273 if (!lookUpTable) |
| 258 return; | 274 return; |
| 259 | 275 |
| 260 // FIXME: Disable color space conversions on accelerated canvases (for now). | 276 // FIXME: Disable color space conversions on accelerated canvases (for now). |
| 261 if (context()->isAccelerated() || !isValid()) | 277 if (context()->isAccelerated() || !isSurfaceValid()) |
| 262 return; | 278 return; |
| 263 | 279 |
| 264 const SkBitmap& bitmap = m_surface->bitmap(); | 280 const SkBitmap& bitmap = m_surface->bitmap(); |
| 265 if (bitmap.isNull()) | 281 if (bitmap.isNull()) |
| 266 return; | 282 return; |
| 267 | 283 |
| 268 ASSERT(bitmap.colorType() == kPMColor_SkColorType); | 284 ASSERT(bitmap.colorType() == kPMColor_SkColorType); |
| 269 IntSize size = m_surface->size(); | 285 IntSize size = m_surface->size(); |
| 270 SkAutoLockPixels bitmapLock(bitmap); | 286 SkAutoLockPixels bitmapLock(bitmap); |
| 271 for (int y = 0; y < size.height(); ++y) { | 287 for (int y = 0; y < size.height(); ++y) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 | 324 |
| 309 SkAlphaType alphaType = (multiplied == Premultiplied) ? kPremul_SkAlphaType
: kUnpremul_SkAlphaType; | 325 SkAlphaType alphaType = (multiplied == Premultiplied) ? kPremul_SkAlphaType
: kUnpremul_SkAlphaType; |
| 310 SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), kRGBA_8888
_SkColorType, alphaType); | 326 SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), kRGBA_8888
_SkColorType, alphaType); |
| 311 | 327 |
| 312 context->readPixels(info, result->data(), 4 * rect.width(), rect.x(), rect.y
()); | 328 context->readPixels(info, result->data(), 4 * rect.width(), rect.x(), rect.y
()); |
| 313 return result.release(); | 329 return result.release(); |
| 314 } | 330 } |
| 315 | 331 |
| 316 PassRefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRec
t& rect) const | 332 PassRefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRec
t& rect) const |
| 317 { | 333 { |
| 318 if (!isValid()) | 334 if (!isSurfaceValid()) |
| 319 return Uint8ClampedArray::create(rect.width() * rect.height() * 4); | 335 return Uint8ClampedArray::create(rect.width() * rect.height() * 4); |
| 320 return getImageData<Unmultiplied>(rect, context(), m_surface->size()); | 336 return getImageData<Unmultiplied>(rect, context(), m_surface->size()); |
| 321 } | 337 } |
| 322 | 338 |
| 323 PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRe
ct& rect) const | 339 PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRe
ct& rect) const |
| 324 { | 340 { |
| 325 if (!isValid()) | 341 if (!isSurfaceValid()) |
| 326 return Uint8ClampedArray::create(rect.width() * rect.height() * 4); | 342 return Uint8ClampedArray::create(rect.width() * rect.height() * 4); |
| 327 return getImageData<Premultiplied>(rect, context(), m_surface->size()); | 343 return getImageData<Premultiplied>(rect, context(), m_surface->size()); |
| 328 } | 344 } |
| 329 | 345 |
| 330 void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c
onst IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint) | 346 void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c
onst IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint) |
| 331 { | 347 { |
| 332 if (!isValid()) | 348 if (!isSurfaceValid()) |
| 333 return; | 349 return; |
| 334 | 350 |
| 335 ASSERT(sourceRect.width() > 0); | 351 ASSERT(sourceRect.width() > 0); |
| 336 ASSERT(sourceRect.height() > 0); | 352 ASSERT(sourceRect.height() > 0); |
| 337 | 353 |
| 338 int originX = sourceRect.x(); | 354 int originX = sourceRect.x(); |
| 339 int destX = destPoint.x() + sourceRect.x(); | 355 int destX = destPoint.x() + sourceRect.x(); |
| 340 ASSERT(destX >= 0); | 356 ASSERT(destX >= 0); |
| 341 ASSERT(destX < m_surface->size().width()); | 357 ASSERT(destX < m_surface->size().width()); |
| 342 ASSERT(originX >= 0); | 358 ASSERT(originX >= 0); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 } | 397 } |
| 382 | 398 |
| 383 return true; | 399 return true; |
| 384 } | 400 } |
| 385 | 401 |
| 386 String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
st | 402 String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
st |
| 387 { | 403 { |
| 388 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); | 404 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); |
| 389 | 405 |
| 390 Vector<char> encodedImage; | 406 Vector<char> encodedImage; |
| 391 if (!isValid() || !encodeImage(m_surface->bitmap(), mimeType, quality, &enco
dedImage)) | 407 if (!isSurfaceValid() || !encodeImage(m_surface->bitmap(), mimeType, quality
, &encodedImage)) |
| 392 return "data:,"; | 408 return "data:,"; |
| 393 Vector<char> base64Data; | 409 Vector<char> base64Data; |
| 394 base64Encode(encodedImage, base64Data); | 410 base64Encode(encodedImage, base64Data); |
| 395 | 411 |
| 396 return "data:" + mimeType + ";base64," + base64Data; | 412 return "data:" + mimeType + ";base64," + base64Data; |
| 397 } | 413 } |
| 398 | 414 |
| 399 String ImageDataToDataURL(const ImageDataBuffer& imageData, const String& mimeTy
pe, const double* quality) | 415 String ImageDataToDataURL(const ImageDataBuffer& imageData, const String& mimeTy
pe, const double* quality) |
| 400 { | 416 { |
| 401 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); | 417 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); |
| 402 | 418 |
| 403 Vector<char> encodedImage; | 419 Vector<char> encodedImage; |
| 404 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) | 420 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) |
| 405 return "data:,"; | 421 return "data:,"; |
| 406 | 422 |
| 407 Vector<char> base64Data; | 423 Vector<char> base64Data; |
| 408 base64Encode(encodedImage, base64Data); | 424 base64Encode(encodedImage, base64Data); |
| 409 | 425 |
| 410 return "data:" + mimeType + ";base64," + base64Data; | 426 return "data:" + mimeType + ";base64," + base64Data; |
| 411 } | 427 } |
| 412 | 428 |
| 413 } // namespace WebCore | 429 } // namespace WebCore |
| OLD | NEW |