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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 #include "platform/graphics/gpu/WebGLImageBufferSurface.h" | 55 #include "platform/graphics/gpu/WebGLImageBufferSurface.h" |
56 #include "platform/transforms/AffineTransform.h" | 56 #include "platform/transforms/AffineTransform.h" |
57 #include "public/platform/Platform.h" | 57 #include "public/platform/Platform.h" |
58 #include <math.h> | 58 #include <math.h> |
59 #include <v8.h> | 59 #include <v8.h> |
60 | 60 |
61 namespace blink { | 61 namespace blink { |
62 | 62 |
63 using namespace HTMLNames; | 63 using namespace HTMLNames; |
64 | 64 |
65 namespace { | |
66 | |
65 // These values come from the WhatWG spec. | 67 // These values come from the WhatWG spec. |
66 static const int DefaultWidth = 300; | 68 const int DefaultWidth = 300; |
67 static const int DefaultHeight = 150; | 69 const int DefaultHeight = 150; |
68 | 70 |
69 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it | 71 // Firefox limits width/height to 32767 pixels, but slows down dramatically befo re it |
70 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions, | 72 // reaches that limit. We limit by area instead, giving us larger maximum dimens ions, |
71 // in exchange for a smaller maximum canvas size. | 73 // in exchange for a smaller maximum canvas size. |
72 static const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pix els | 74 const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels |
73 | 75 |
74 //In Skia, we will also limit width/height to 32767. | 76 //In Skia, we will also limit width/height to 32767. |
75 static const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. | 77 const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels. |
78 | |
79 CanvasRenderingContext::SourceBuffer convertSourceBuffer(HTMLCanvasElement::Sour ceBuffer sourceBuffer) | |
80 { | |
81 return static_cast<CanvasRenderingContext::SourceBuffer>(sourceBuffer); | |
82 } | |
83 | |
84 } // namespace | |
76 | 85 |
77 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); | 86 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); |
78 | 87 |
79 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) | 88 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) |
80 : HTMLElement(canvasTag, document) | 89 : HTMLElement(canvasTag, document) |
81 , DocumentVisibilityObserver(document) | 90 , DocumentVisibilityObserver(document) |
82 , m_size(DefaultWidth, DefaultHeight) | 91 , m_size(DefaultWidth, DefaultHeight) |
83 , m_ignoreReset(false) | 92 , m_ignoreReset(false) |
84 , m_accelerationDisabled(false) | 93 , m_accelerationDisabled(false) |
85 , m_externallyAllocatedMemory(0) | 94 , m_externallyAllocatedMemory(0) |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 | 383 |
375 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). | 384 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread). |
376 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType)) | 385 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod ing(lowercaseMimeType)) |
377 lowercaseMimeType = "image/png"; | 386 lowercaseMimeType = "image/png"; |
378 | 387 |
379 return lowercaseMimeType; | 388 return lowercaseMimeType; |
380 } | 389 } |
381 | 390 |
382 const AtomicString HTMLCanvasElement::imageSourceURL() const | 391 const AtomicString HTMLCanvasElement::imageSourceURL() const |
383 { | 392 { |
384 return AtomicString(toDataURLInternal("image/png", 0, true)); | 393 return AtomicString(toDataURLInternal("image/png", 0, Front)); |
385 } | 394 } |
386 | 395 |
387 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double * quality, bool isSaving) const | 396 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double * quality, SourceBuffer sourceBuffer) const |
388 { | 397 { |
389 if (m_size.isEmpty() || !buffer()) | 398 if (m_size.isEmpty() || !buffer()) |
390 return String("data:,"); | 399 return String("data:,"); |
391 | 400 |
401 if (m_context && m_context->is3d()) | |
402 m_context->paintRenderingResultsToCanvas(convertSourceBuffer(sourceBuffe r)); | |
403 | |
392 String encodingMimeType = toEncodingMimeType(mimeType); | 404 String encodingMimeType = toEncodingMimeType(mimeType); |
393 | |
394 // Try to get ImageData first, as that may avoid lossy conversions. | |
dshwang
2014/11/20 21:14:28
comment is wrong. buffer() contains not-lossy cont
| |
395 RefPtrWillBeRawPtr<ImageData> imageData = getImageData(); | |
396 | |
397 if (imageData) | |
398 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData-> data()), encodingMimeType, quality); | |
399 | |
400 if (m_context && m_context->is3d()) { | |
401 m_context->paintRenderingResultsToCanvas(isSaving ? CanvasRenderingConte xt::Front : CanvasRenderingContext::Back); | |
402 } | |
403 | |
404 return buffer()->toDataURL(encodingMimeType, quality); | 405 return buffer()->toDataURL(encodingMimeType, quality); |
405 } | 406 } |
406 | 407 |
407 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit y, ExceptionState& exceptionState) const | 408 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit y, ExceptionState& exceptionState) const |
408 { | 409 { |
409 if (!m_originClean) { | 410 if (!m_originClean) { |
410 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); | 411 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); |
411 return String(); | 412 return String(); |
412 } | 413 } |
413 | 414 |
414 return toDataURLInternal(mimeType, quality); | 415 return toDataURLInternal(mimeType, quality, Back); |
415 } | |
416 | |
417 PassRefPtrWillBeRawPtr<ImageData> HTMLCanvasElement::getImageData() const | |
418 { | |
419 if (!m_context || !m_context->is3d()) | |
420 return nullptr; | |
421 return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImag eData(); | |
422 } | 416 } |
423 | 417 |
424 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 418 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
425 { | 419 { |
426 return document().securityOrigin(); | 420 return document().securityOrigin(); |
427 } | 421 } |
428 | 422 |
429 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const | 423 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const |
430 { | 424 { |
431 if (m_context && !m_context->is2d()) | 425 if (m_context && !m_context->is2d()) |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
659 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() | 653 void HTMLCanvasElement::ensureUnacceleratedImageBuffer() |
660 { | 654 { |
661 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea teImageBuffer) | 655 if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCrea teImageBuffer) |
662 return; | 656 return; |
663 discardImageBuffer(); | 657 discardImageBuffer(); |
664 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; | 658 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; |
665 m_imageBuffer = ImageBuffer::create(size(), opacityMode); | 659 m_imageBuffer = ImageBuffer::create(size(), opacityMode); |
666 m_didFailToCreateImageBuffer = !m_imageBuffer; | 660 m_didFailToCreateImageBuffer = !m_imageBuffer; |
667 } | 661 } |
668 | 662 |
669 Image* HTMLCanvasElement::copiedImage() const | 663 Image* HTMLCanvasElement::copiedImage(SourceBuffer sourceBuffer) const |
670 { | 664 { |
671 if (!m_copiedImage && buffer()) { | 665 if (!m_copiedImage && buffer()) { |
672 if (m_context && m_context->is3d()) { | 666 if (m_context && m_context->is3d()) |
673 m_context->paintRenderingResultsToCanvas(CanvasRenderingContext::Fro nt); | 667 m_context->paintRenderingResultsToCanvas(convertSourceBuffer(sourceB uffer)); |
674 } | |
675 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); | 668 m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled); |
676 updateExternallyAllocatedMemory(); | 669 updateExternallyAllocatedMemory(); |
677 } | 670 } |
678 return m_copiedImage.get(); | 671 return m_copiedImage.get(); |
679 } | 672 } |
680 | 673 |
681 void HTMLCanvasElement::clearImageBuffer() | 674 void HTMLCanvasElement::clearImageBuffer() |
682 { | 675 { |
683 ASSERT(hasImageBuffer() && !m_didFailToCreateImageBuffer); | 676 ASSERT(hasImageBuffer() && !m_didFailToCreateImageBuffer); |
684 ASSERT(!m_didClearImageBuffer); | 677 ASSERT(!m_didClearImageBuffer); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
778 { | 771 { |
779 return !originClean(); | 772 return !originClean(); |
780 } | 773 } |
781 | 774 |
782 FloatSize HTMLCanvasElement::sourceSize() const | 775 FloatSize HTMLCanvasElement::sourceSize() const |
783 { | 776 { |
784 return FloatSize(width(), height()); | 777 return FloatSize(width(), height()); |
785 } | 778 } |
786 | 779 |
787 } | 780 } |
OLD | NEW |