| 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 bool canCreateImageBuffer(const IntSize& deviceSize) |
| 80 { |
| 81 if (deviceSize.width() * deviceSize.height() > MaxCanvasArea) |
| 82 return false; |
| 83 if (deviceSize.width() > MaxSkiaDim || deviceSize.height() > MaxSkiaDim) |
| 84 return false; |
| 85 if (!deviceSize.width() || !deviceSize.height()) |
| 86 return false; |
| 87 return true; |
| 88 } |
| 89 |
| 90 } // namespace |
| 76 | 91 |
| 77 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); | 92 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); |
| 78 | 93 |
| 79 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) | 94 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) |
| 80 : HTMLElement(canvasTag, document) | 95 : HTMLElement(canvasTag, document) |
| 81 , DocumentVisibilityObserver(document) | 96 , DocumentVisibilityObserver(document) |
| 82 , m_size(DefaultWidth, DefaultHeight) | 97 , m_size(DefaultWidth, DefaultHeight) |
| 83 , m_ignoreReset(false) | 98 , m_ignoreReset(false) |
| 84 , m_accelerationDisabled(false) | 99 , m_accelerationDisabled(false) |
| 85 , m_externallyAllocatedMemory(0) | 100 , m_externallyAllocatedMemory(0) |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 return lowercaseMimeType; | 403 return lowercaseMimeType; |
| 389 } | 404 } |
| 390 | 405 |
| 391 const AtomicString HTMLCanvasElement::imageSourceURL() const | 406 const AtomicString HTMLCanvasElement::imageSourceURL() const |
| 392 { | 407 { |
| 393 return AtomicString(toDataURLInternal("image/png", 0, true)); | 408 return AtomicString(toDataURLInternal("image/png", 0, true)); |
| 394 } | 409 } |
| 395 | 410 |
| 396 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
* quality, bool isSaving) const | 411 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
* quality, bool isSaving) const |
| 397 { | 412 { |
| 398 if (m_size.isEmpty() || !buffer()) | 413 if (m_size.isEmpty() || !canCreateImageBuffer(size())) |
| 399 return String("data:,"); | 414 return String("data:,"); |
| 400 | 415 |
| 401 String encodingMimeType = toEncodingMimeType(mimeType); | 416 String encodingMimeType = toEncodingMimeType(mimeType); |
| 417 if (!m_context) { |
| 418 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(m_size); |
| 419 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->
data()), encodingMimeType, quality); |
| 420 } |
| 402 | 421 |
| 403 // Try to get ImageData first, as that may avoid lossy conversions. | 422 // Try to get ImageData first, as that may avoid lossy conversions. |
| 404 RefPtrWillBeRawPtr<ImageData> imageData = getImageData(); | 423 RefPtrWillBeRawPtr<ImageData> imageData = getImageData(); |
| 405 | 424 |
| 406 if (imageData) | 425 if (imageData) |
| 407 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->
data()), encodingMimeType, quality); | 426 return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->
data()), encodingMimeType, quality); |
| 408 | 427 |
| 409 if (m_context && m_context->is3d()) { | 428 if (m_context->is3d()) { |
| 410 m_context->paintRenderingResultsToCanvas(isSaving ? CanvasRenderingConte
xt::Front : CanvasRenderingContext::Back); | 429 m_context->paintRenderingResultsToCanvas(isSaving ? CanvasRenderingConte
xt::Front : CanvasRenderingContext::Back); |
| 411 } | 430 } |
| 412 | 431 |
| 413 return buffer()->toDataURL(encodingMimeType, quality); | 432 return buffer()->toDataURL(encodingMimeType, quality); |
| 414 } | 433 } |
| 415 | 434 |
| 416 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
y, ExceptionState& exceptionState) const | 435 String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
y, ExceptionState& exceptionState) const |
| 417 { | 436 { |
| 418 if (!m_originClean) { | 437 if (!m_originClean) { |
| 419 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); | 438 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 } | 568 } |
| 550 | 569 |
| 551 void HTMLCanvasElement::createImageBufferInternal() | 570 void HTMLCanvasElement::createImageBufferInternal() |
| 552 { | 571 { |
| 553 ASSERT(!m_imageBuffer); | 572 ASSERT(!m_imageBuffer); |
| 554 ASSERT(!m_contextStateSaver); | 573 ASSERT(!m_contextStateSaver); |
| 555 | 574 |
| 556 m_didFailToCreateImageBuffer = true; | 575 m_didFailToCreateImageBuffer = true; |
| 557 m_imageBufferIsClear = true; | 576 m_imageBufferIsClear = true; |
| 558 | 577 |
| 559 IntSize deviceSize = size(); | 578 if (!canCreateImageBuffer(size())) |
| 560 if (deviceSize.width() * deviceSize.height() > MaxCanvasArea) | |
| 561 return; | |
| 562 | |
| 563 if (deviceSize.width() > MaxSkiaDim || deviceSize.height() > MaxSkiaDim) | |
| 564 return; | |
| 565 | |
| 566 if (!deviceSize.width() || !deviceSize.height()) | |
| 567 return; | 579 return; |
| 568 | 580 |
| 569 int msaaSampleCount; | 581 int msaaSampleCount; |
| 570 OwnPtr<ImageBufferSurface> surface = createImageBufferSurface(deviceSize, &m
saaSampleCount); | 582 OwnPtr<ImageBufferSurface> surface = createImageBufferSurface(size(), &msaaS
ampleCount); |
| 571 if (!surface->isValid()) | 583 if (!surface->isValid()) |
| 572 return; | 584 return; |
| 573 | 585 |
| 574 m_imageBuffer = ImageBuffer::create(surface.release()); | 586 m_imageBuffer = ImageBuffer::create(surface.release()); |
| 575 m_imageBuffer->setClient(this); | 587 m_imageBuffer->setClient(this); |
| 576 | 588 |
| 577 m_didFailToCreateImageBuffer = false; | 589 m_didFailToCreateImageBuffer = false; |
| 578 | 590 |
| 579 updateExternallyAllocatedMemory(); | 591 updateExternallyAllocatedMemory(); |
| 580 | 592 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 { | 783 { |
| 772 return !originClean(); | 784 return !originClean(); |
| 773 } | 785 } |
| 774 | 786 |
| 775 FloatSize HTMLCanvasElement::sourceSize() const | 787 FloatSize HTMLCanvasElement::sourceSize() const |
| 776 { | 788 { |
| 777 return FloatSize(width(), height()); | 789 return FloatSize(width(), height()); |
| 778 } | 790 } |
| 779 | 791 |
| 780 } | 792 } |
| OLD | NEW |