| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
| 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 | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 | 350 |
| 351 return true; | 351 return true; |
| 352 } | 352 } |
| 353 | 353 |
| 354 | 354 |
| 355 void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r) | 355 void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r) |
| 356 { | 356 { |
| 357 if (m_context) { | 357 if (m_context) { |
| 358 if (!paintsIntoCanvasBuffer() && !document().printing()) | 358 if (!paintsIntoCanvasBuffer() && !document().printing()) |
| 359 return; | 359 return; |
| 360 m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Front); | 360 m_context->paintRenderingResultsToCanvas(FrontBuffer); |
| 361 } | 361 } |
| 362 | 362 |
| 363 if (hasImageBuffer()) { | 363 if (hasImageBuffer()) { |
| 364 CompositeOperator compositeOperator = !m_context || m_context->hasAlpha(
) ? CompositeSourceOver : CompositeCopy; | 364 CompositeOperator compositeOperator = !m_context || m_context->hasAlpha(
) ? CompositeSourceOver : CompositeCopy; |
| 365 context->drawImageBuffer(buffer(), pixelSnappedIntRect(r), 0, compositeO
perator); | 365 context->drawImageBuffer(buffer(), pixelSnappedIntRect(r), 0, compositeO
perator); |
| 366 } else { | 366 } else { |
| 367 // When alpha is false, we should draw to opaque black. | 367 // When alpha is false, we should draw to opaque black. |
| 368 if (m_context && !m_context->hasAlpha()) | 368 if (m_context && !m_context->hasAlpha()) |
| 369 context->fillRect(FloatRect(r), Color(0, 0, 0)); | 369 context->fillRect(FloatRect(r), Color(0, 0, 0)); |
| 370 } | 370 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 398 | 398 |
| 399 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
method to be used on a worker thread). | 399 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
method to be used on a worker thread). |
| 400 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod
ing(lowercaseMimeType)) | 400 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod
ing(lowercaseMimeType)) |
| 401 lowercaseMimeType = "image/png"; | 401 lowercaseMimeType = "image/png"; |
| 402 | 402 |
| 403 return lowercaseMimeType; | 403 return lowercaseMimeType; |
| 404 } | 404 } |
| 405 | 405 |
| 406 const AtomicString HTMLCanvasElement::imageSourceURL() const | 406 const AtomicString HTMLCanvasElement::imageSourceURL() const |
| 407 { | 407 { |
| 408 return AtomicString(toDataURLInternal("image/png", 0, true)); | 408 return AtomicString(toDataURLInternal("image/png", 0, FrontBuffer)); |
| 409 } | 409 } |
| 410 | 410 |
| 411 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
* quality, bool isSaving) const | 411 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
* quality, SourceDrawingBuffer sourceBuffer) const |
| 412 { | 412 { |
| 413 if (m_size.isEmpty() || !canCreateImageBuffer(size())) | 413 if (m_size.isEmpty() || !canCreateImageBuffer(size())) |
| 414 return String("data:,"); | 414 return String("data:,"); |
| 415 | 415 |
| 416 String encodingMimeType = toEncodingMimeType(mimeType); | 416 String encodingMimeType = toEncodingMimeType(mimeType); |
| 417 if (!m_context) { | 417 if (!m_context) { |
| 418 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(m_size); | 418 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(m_size); |
| 419 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->
data()), encodingMimeType, quality); | 419 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->
data()), encodingMimeType, quality); |
| 420 } | 420 } |
| 421 | 421 |
| 422 // Try to get ImageData first, as that may avoid lossy conversions. | |
| 423 RefPtrWillBeRawPtr<ImageData> imageData = getImageData(); | |
| 424 | |
| 425 if (imageData) | |
| 426 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->
data()), encodingMimeType, quality); | |
| 427 | |
| 428 if (m_context->is3d()) { | 422 if (m_context->is3d()) { |
| 429 m_context->paintRenderingResultsToCanvas(isSaving ? CanvasRenderingConte
xt::Front : CanvasRenderingContext::Back); | 423 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). |
| 424 RefPtrWillBeRawPtr<ImageData> imageData = |
| 425 toWebGLRenderingContext(m_context.get())->paintRenderingResultsToIma
geData(sourceBuffer); |
| 426 if (imageData) |
| 427 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageDa
ta->data()), encodingMimeType, quality); |
| 428 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 430 } | 429 } |
| 431 | 430 |
| 432 return buffer()->toDataURL(encodingMimeType, quality); | 431 return buffer()->toDataURL(encodingMimeType, quality); |
| 433 } | 432 } |
| 434 | 433 |
| 435 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
y, ExceptionState& exceptionState) const | 434 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
y, ExceptionState& exceptionState) const |
| 436 { | 435 { |
| 437 if (!m_originClean) { | 436 if (!m_originClean) { |
| 438 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); | 437 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); |
| 439 return String(); | 438 return String(); |
| 440 } | 439 } |
| 441 | 440 |
| 442 return toDataURLInternal(mimeType, quality); | 441 return toDataURLInternal(mimeType, quality, BackBuffer); |
| 443 } | |
| 444 | |
| 445 PassRefPtrWillBeRawPtr<ImageData> HTMLCanvasElement::getImageData() const | |
| 446 { | |
| 447 if (!m_context || !m_context->is3d()) | |
| 448 return nullptr; | |
| 449 return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImag
eData(); | |
| 450 } | 442 } |
| 451 | 443 |
| 452 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 444 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
| 453 { | 445 { |
| 454 return document().securityOrigin(); | 446 return document().securityOrigin(); |
| 455 } | 447 } |
| 456 | 448 |
| 457 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const | 449 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const |
| 458 { | 450 { |
| 459 if (m_context && !m_context->is2d()) | 451 if (m_context && !m_context->is2d()) |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() | 672 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() |
| 681 { | 673 { |
| 682 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea
teImageBuffer) | 674 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea
teImageBuffer) |
| 683 return; | 675 return; |
| 684 discardImageBuffer(); | 676 discardImageBuffer(); |
| 685 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque :
Opaque; | 677 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque :
Opaque; |
| 686 m_imageBuffer = ImageBuffer::create(size(), opacityMode); | 678 m_imageBuffer = ImageBuffer::create(size(), opacityMode); |
| 687 m_didFailToCreateImageBuffer = !m_imageBuffer; | 679 m_didFailToCreateImageBuffer = !m_imageBuffer; |
| 688 } | 680 } |
| 689 | 681 |
| 690 Image* HTMLCanvasElement::copiedImage() const | 682 Image* HTMLCanvasElement::copiedImage(SourceDrawingBuffer sourceBuffer) const |
| 691 { | 683 { |
| 692 if (!m_copiedImage && buffer()) { | 684 if (!m_copiedImage && buffer()) { |
| 693 if (m_context && m_context->is3d()) { | 685 if (m_context && m_context->is3d()) |
| 694 m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Fro
nt); | 686 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 695 } | |
| 696 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); | 687 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); |
| 697 updateExternallyAllocatedMemory(); | 688 updateExternallyAllocatedMemory(); |
| 698 } | 689 } |
| 699 return m_copiedImage.get(); | 690 return m_copiedImage.get(); |
| 700 } | 691 } |
| 701 | 692 |
| 702 void HTMLCanvasElement::discardImageBuffer() | 693 void HTMLCanvasElement::discardImageBuffer() |
| 703 { | 694 { |
| 704 m_contextStateSaver.clear(); // uses context owned by m_imageBuffer | 695 m_contextStateSaver.clear(); // uses context owned by m_imageBuffer |
| 705 m_imageBuffer.clear(); | 696 m_imageBuffer.clear(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 *status = ZeroSizeCanvasSourceImageStatus; | 743 *status = ZeroSizeCanvasSourceImageStatus; |
| 753 return nullptr; | 744 return nullptr; |
| 754 } | 745 } |
| 755 | 746 |
| 756 if (!buffer()) { | 747 if (!buffer()) { |
| 757 *status = InvalidSourceImageStatus; | 748 *status = InvalidSourceImageStatus; |
| 758 return nullptr; | 749 return nullptr; |
| 759 } | 750 } |
| 760 | 751 |
| 761 if (m_context && m_context->is3d()) { | 752 if (m_context && m_context->is3d()) { |
| 762 m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Back); | 753 m_context->paintRenderingResultsToCanvas(BackBuffer); |
| 763 *status = ExternalSourceImageStatus; | 754 *status = ExternalSourceImageStatus; |
| 764 | 755 |
| 765 // can't create SkImage from WebGLImageBufferSurface (contains only SkBi
tmap) | 756 // can't create SkImage from WebGLImageBufferSurface (contains only SkBi
tmap) |
| 766 return m_imageBuffer->copyImage(DontCopyBackingStore, Unscaled); | 757 return m_imageBuffer->copyImage(DontCopyBackingStore, Unscaled); |
| 767 } | 758 } |
| 768 | 759 |
| 769 RefPtr<SkImage> image = m_imageBuffer->newImageSnapshot(); | 760 RefPtr<SkImage> image = m_imageBuffer->newImageSnapshot(); |
| 770 if (image) { | 761 if (image) { |
| 771 *status = NormalSourceImageStatus; | 762 *status = NormalSourceImageStatus; |
| 772 | 763 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 783 { | 774 { |
| 784 return !originClean(); | 775 return !originClean(); |
| 785 } | 776 } |
| 786 | 777 |
| 787 FloatSize HTMLCanvasElement::sourceSize() const | 778 FloatSize HTMLCanvasElement::sourceSize() const |
| 788 { | 779 { |
| 789 return FloatSize(width(), height()); | 780 return FloatSize(width(), height()); |
| 790 } | 781 } |
| 791 | 782 |
| 792 } | 783 } |
| OLD | NEW |