| 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 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 | 480 |
| 481 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
method to be used on a worker thread). | 481 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
method to be used on a worker thread). |
| 482 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod
ing(lowercaseMimeType)) | 482 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod
ing(lowercaseMimeType)) |
| 483 lowercaseMimeType = "image/png"; | 483 lowercaseMimeType = "image/png"; |
| 484 | 484 |
| 485 return lowercaseMimeType; | 485 return lowercaseMimeType; |
| 486 } | 486 } |
| 487 | 487 |
| 488 const AtomicString HTMLCanvasElement::imageSourceURL() const | 488 const AtomicString HTMLCanvasElement::imageSourceURL() const |
| 489 { | 489 { |
| 490 return AtomicString(toDataURLInternal("image/png", 0, FrontBuffer)); | 490 NonThrowableExceptionState exceptionState; |
| 491 AtomicString dataURL(toDataURLInternal("image/png", 0, FrontBuffer, exceptio
nState)); |
| 492 if (exceptionState.hadException()) |
| 493 return AtomicString("data:,"); |
| 494 return dataURL; |
| 491 } | 495 } |
| 492 | 496 |
| 493 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const | 497 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
| 494 { | 498 { |
| 495 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context | 499 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context |
| 496 if (buffer()) | 500 if (buffer()) |
| 497 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); | 501 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
| 498 } | 502 } |
| 499 | 503 |
| 500 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons
t | 504 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, Exce
ptionState& exceptionState) const |
| 501 { | 505 { |
| 502 ImageData* imageData; | 506 ImageData* imageData; |
| 503 if (is3D()) { | 507 if (is3D()) { |
| 504 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). | 508 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). |
| 505 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); | 509 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); |
| 506 if (imageData) | 510 if (imageData) |
| 507 return imageData; | 511 return imageData; |
| 508 | 512 |
| 509 m_context->paintRenderingResultsToCanvas(sourceBuffer); | 513 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 510 imageData = ImageData::create(m_size); | 514 imageData = ImageData::create(m_size, exceptionState); |
| 515 if (exceptionState.hadException()) |
| 516 return nullptr; |
| 511 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion); | 517 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion); |
| 512 if (snapshot) { | 518 if (snapshot) { |
| 513 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); | 519 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); |
| 514 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); | 520 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); |
| 515 } | 521 } |
| 516 return imageData; | 522 return imageData; |
| 517 } | 523 } |
| 518 | 524 |
| 519 imageData = ImageData::create(m_size); | 525 imageData = ImageData::create(m_size, exceptionState); |
| 526 if (exceptionState.hadException()) |
| 527 return nullptr; |
| 520 | 528 |
| 521 if (!m_context) | 529 if (!m_context) |
| 522 return imageData; | 530 return imageData; |
| 523 | 531 |
| 524 ASSERT(m_context->is2d()); | 532 ASSERT(m_context->is2d()); |
| 525 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
); | 533 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
); |
| 526 if (snapshot) { | 534 if (snapshot) { |
| 527 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); | 535 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); |
| 528 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); | 536 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); |
| 529 } | 537 } |
| 530 | 538 |
| 531 return imageData; | 539 return imageData; |
| 532 } | 540 } |
| 533 | 541 |
| 534 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer) const | 542 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer, ExceptionState& exceptionState) con
st |
| 535 { | 543 { |
| 536 if (!isPaintable()) | 544 if (!isPaintable()) |
| 537 return String("data:,"); | 545 return String("data:,"); |
| 538 | 546 |
| 539 String encodingMimeType = toEncodingMimeType(mimeType); | 547 String encodingMimeType = toEncodingMimeType(mimeType); |
| 540 | 548 |
| 541 ImageData* imageData = toImageData(sourceBuffer); | 549 ImageData* imageData = toImageData(sourceBuffer, exceptionState); |
| 550 if (exceptionState.hadException()) |
| 551 return String(); |
| 552 |
| 542 ScopedDisposal<ImageData> disposer(imageData); | 553 ScopedDisposal<ImageData> disposer(imageData); |
| 543 | 554 |
| 544 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); | 555 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); |
| 545 } | 556 } |
| 546 | 557 |
| 547 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const | 558 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const |
| 548 { | 559 { |
| 549 if (!originClean()) { | 560 if (!originClean()) { |
| 550 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); | 561 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); |
| 551 return String(); | 562 return String(); |
| 552 } | 563 } |
| 553 double quality = UndefinedQualityValue; | 564 double quality = UndefinedQualityValue; |
| 554 if (!qualityArgument.isEmpty()) { | 565 if (!qualityArgument.isEmpty()) { |
| 555 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 566 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
| 556 if (v8Value->IsNumber()) { | 567 if (v8Value->IsNumber()) { |
| 557 quality = v8Value.As<v8::Number>()->Value(); | 568 quality = v8Value.As<v8::Number>()->Value(); |
| 558 } | 569 } |
| 559 } | 570 } |
| 560 return toDataURLInternal(mimeType, quality, BackBuffer); | 571 return toDataURLInternal(mimeType, quality, BackBuffer, exceptionState); |
| 561 } | 572 } |
| 562 | 573 |
| 563 void HTMLCanvasElement::encodeImageAsync(DOMUint8ClampedArray* imageData, IntSiz
e imageSize, FileCallback* callback, const String& mimeType, double quality) | 574 void HTMLCanvasElement::encodeImageAsync(DOMUint8ClampedArray* imageData, IntSiz
e imageSize, FileCallback* callback, const String& mimeType, double quality) |
| 564 { | 575 { |
| 565 OwnPtr<Vector<char>> encodedImage(adoptPtr(new Vector<char>())); | 576 OwnPtr<Vector<char>> encodedImage(adoptPtr(new Vector<char>())); |
| 566 | 577 |
| 567 if (!ImageDataBuffer(imageSize, imageData->data()).encodeImage(mimeType, qua
lity, encodedImage.get())) { | 578 if (!ImageDataBuffer(imageSize, imageData->data()).encodeImage(mimeType, qua
lity, encodedImage.get())) { |
| 568 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin
d(&FileCallback::handleEvent, callback, nullptr)); | 579 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin
d(&FileCallback::handleEvent, callback, nullptr)); |
| 569 } else { | 580 } else { |
| 570 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, thr
eadSafeBind(&HTMLCanvasElement::createBlobAndCall, encodedImage.release(), mimeT
ype, AllowCrossThreadAccess(callback))); | 581 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, thr
eadSafeBind(&HTMLCanvasElement::createBlobAndCall, encodedImage.release(), mimeT
ype, AllowCrossThreadAccess(callback))); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 596 double quality = UndefinedQualityValue; | 607 double quality = UndefinedQualityValue; |
| 597 if (!qualityArgument.isEmpty()) { | 608 if (!qualityArgument.isEmpty()) { |
| 598 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 609 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
| 599 if (v8Value->IsNumber()) { | 610 if (v8Value->IsNumber()) { |
| 600 quality = v8Value.As<v8::Number>()->Value(); | 611 quality = v8Value.As<v8::Number>()->Value(); |
| 601 } | 612 } |
| 602 } | 613 } |
| 603 | 614 |
| 604 String encodingMimeType = toEncodingMimeType(mimeType); | 615 String encodingMimeType = toEncodingMimeType(mimeType); |
| 605 | 616 |
| 606 ImageData* imageData = toImageData(BackBuffer); | 617 ImageData* imageData = toImageData(BackBuffer, exceptionState); |
| 607 // imageData unref its data, which we still keep alive for the async toBlob
thread | 618 if (exceptionState.hadException()) |
| 619 return; |
| 620 |
| 621 // ImageData unrefs its data, which we still keep alive for the async toBlob
thread |
| 608 ScopedDisposal<ImageData> disposer(imageData); | 622 ScopedDisposal<ImageData> disposer(imageData); |
| 609 | 623 |
| 610 // Add a ref to keep image data alive until completion of encoding | 624 // Add a ref to keep image data alive until completion of encoding |
| 611 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); | 625 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |
| 612 | 626 |
| 613 getToBlobThreadInstance()->taskRunner()->postTask(FROM_HERE, new Task(thread
SafeBind(&HTMLCanvasElement::encodeImageAsync, AllowCrossThreadAccess(imageDataR
ef.release().leakRef()), imageData->size(), AllowCrossThreadAccess(callback), en
codingMimeType, quality))); | 627 getToBlobThreadInstance()->taskRunner()->postTask(FROM_HERE, new Task(thread
SafeBind(&HTMLCanvasElement::encodeImageAsync, AllowCrossThreadAccess(imageDataR
ef.release().leakRef()), imageData->size(), AllowCrossThreadAccess(callback), en
codingMimeType, quality))); |
| 614 } | 628 } |
| 615 | 629 |
| 616 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 630 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
| 617 { | 631 { |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 { | 993 { |
| 980 return FloatSize(width(), height()); | 994 return FloatSize(width(), height()); |
| 981 } | 995 } |
| 982 | 996 |
| 983 bool HTMLCanvasElement::isOpaque() const | 997 bool HTMLCanvasElement::isOpaque() const |
| 984 { | 998 { |
| 985 return m_context && !m_context->hasAlpha(); | 999 return m_context && !m_context->hasAlpha(); |
| 986 } | 1000 } |
| 987 | 1001 |
| 988 } // blink | 1002 } // blink |
| OLD | NEW |