HTMLCanvasElement.cpp revision cac0f67c402d107cdb10971b95719e2ff9c7c76b
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Alp Toker <alp@atoker.com> 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLCanvasElement.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CanvasGradient.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CanvasPattern.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CanvasRenderingContext2D.h" 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(3D_CANVAS) 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "CanvasRenderingContext3D.h" 35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CanvasStyle.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Chrome.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ExceptionCode.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ImageBuffer.h" 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MIMETypeRegistry.h" 455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "MappedAttribute.h" 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h" 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderHTMLCanvas.h" 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h" 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h> 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h> 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// These values come from the WhatWG spec. 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int defaultWidth = 300; 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int defaultHeight = 150; 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Firefox limits width/height to 32767 pixels, but slows down dramatically before it 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// reaches that limit. We limit by area instead, giving us larger maximum dimensions, 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// in exchange for a smaller maximum canvas size. 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst float HTMLCanvasElement::MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document* doc) 66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project : HTMLElement(tagName, doc) 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_size(defaultWidth, defaultHeight) 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_observer(0) 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_originClean(true) 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_ignoreReset(false) 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_createdImageBuffer(false) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 73635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(hasTagName(canvasTag)); 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLCanvasElement::~HTMLCanvasElement() 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_observer) 795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_observer->canvasDestroyed(this); 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(DASHBOARD_SUPPORT) 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLTagStatus HTMLCanvasElement::endTagRequirement() const 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Settings* settings = document()->settings(); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (settings && settings->usesDashboardBackwardCompatibilityMode()) 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return TagStatusForbidden; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return HTMLElement::endTagRequirement(); 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint HTMLCanvasElement::tagPriority() const 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Settings* settings = document()->settings(); 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (settings && settings->usesDashboardBackwardCompatibilityMode()) 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return HTMLElement::tagPriority(); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLCanvasElement::parseMappedAttribute(MappedAttribute* attr) 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const QualifiedName& attrName = attr->name(); 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (attrName == widthAttr || attrName == heightAttr) 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reset(); 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HTMLElement::parseMappedAttribute(attr); 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderObject* HTMLCanvasElement::createRenderer(RenderArena* arena, RenderStyle* style) 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Settings* settings = document()->settings(); 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (settings && settings->isJavaScriptEnabled()) { 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_rendererIsCanvas = true; 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return new (arena) RenderHTMLCanvas(this); 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_rendererIsCanvas = false; 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return HTMLElement::createRenderer(arena, style); 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLCanvasElement::setHeight(int value) 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setAttribute(heightAttr, String::number(value)); 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLCanvasElement::setWidth(int value) 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setAttribute(widthAttr, String::number(value)); 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLCanvasElement::toDataURL(const String& mimeType, ExceptionCode& ec) 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_originClean) { 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ec = SECURITY_ERR; 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return String(); 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 141cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_size.isEmpty() || !buffer()) 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return String("data:,"); 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)) 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return buffer()->toDataURL("image/png"); 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return buffer()->toDataURL(mimeType); 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCanvasRenderingContext* HTMLCanvasElement::getContext(const String& type) 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // A Canvas can either be "2D" or "3D" never both. If you request a 2D canvas and the existing 153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // context is already 2D, just return that. If the existing context is 3D, then destroy it 154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // before creating a new 2D context. Vice versa when requesting a 3D canvas. Requesting a 155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // context with any other type string will destroy any existing context. 156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME - The code depends on the context not going away once created, to prevent JS from 158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // seeing a dangling pointer. So for now we will disallow the context from being changed 159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // once it is created. 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (type == "2d") { 161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_context && !m_context->is2d()) 162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return 0; 163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_context) 164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_context = new CanvasRenderingContext2D(this); 165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return m_context.get(); 166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(3D_CANVAS) 168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Settings* settings = document()->settings(); 169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (settings && settings->webGLEnabled()) { 170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if ((type == "webkit-3d") || 171231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block (type == "GL")) { 172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_context && !m_context->is3d()) 173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return 0; 174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_context) { 175cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_context = CanvasRenderingContext3D::create(this); 176cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_context) { 177cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Need to make sure a RenderLayer and compositing layer get created for the Canvas 178cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block setNeedsStyleRecalc(SyntheticStyleChange); 179cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return m_context.get(); 182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLCanvasElement::willDraw(const FloatRect& rect) 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_imageBuffer) 191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_imageBuffer->clearImage(); 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (RenderBox* ro = renderBox()) { 194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project FloatRect destRect = ro->contentBoxRect(); 195635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project FloatRect r = mapRect(rect, FloatRect(0, 0, m_size.width(), m_size.height()), destRect); 196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project r.intersect(destRect); 197635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_dirtyRect.contains(r)) 198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_dirtyRect.unite(r); 201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ro->repaintRectangle(enclosingIntRect(m_dirtyRect)); 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_observer) 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_observer->canvasChanged(this, rect); 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLCanvasElement::reset() 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_ignoreReset) 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool ok; 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int w = getAttribute(widthAttr).toInt(&ok); 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!ok) 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project w = defaultWidth; 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int h = getAttribute(heightAttr).toInt(&ok); 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!ok) 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project h = defaultHeight; 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IntSize oldSize = m_size; 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_size = IntSize(w, h); 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool hadImageBuffer = m_createdImageBuffer; 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_createdImageBuffer = false; 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_imageBuffer.clear(); 227231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_context && m_context->is2d()) 228231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static_cast<CanvasRenderingContext2D*>(m_context.get())->reset(); 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (RenderObject* renderer = this->renderer()) { 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_rendererIsCanvas) { 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (oldSize != m_size) 2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch toRenderHTMLCanvas(renderer)->canvasSizeChanged(); 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hadImageBuffer) 2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch renderer->repaint(); 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_observer) 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_observer->canvasResized(this); 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r) 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 245635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Clear the dirty rect 246635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_dirtyRect = FloatRect(); 247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (context->paintingDisabled()) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 251231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(3D_CANVAS) 252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CanvasRenderingContext3D* context3D = NULL; 253231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_context && m_context->is3d()) { 254231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context3D = static_cast<CanvasRenderingContext3D*>(m_context.get()); 255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context3D->beginPaint(); 256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 257231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_imageBuffer) { 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Image* image = m_imageBuffer->image(); 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (image) 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project context->drawImage(image, r); 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 265231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(3D_CANVAS) 266231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (context3D != NULL) { 267231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context3D->reshape(r.width(), r.height()); 268231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context3D->endPaint(); 269231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntRect(convertLogicalToDevice(logicalRect.location()), convertLogicalToDevice(logicalRect.size())); 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f; 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float wf = ceilf(logicalSize.width() * pageScaleFactor); 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float hf = ceilf(logicalSize.height() * pageScaleFactor); 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!(wf >= 1 && hf >= 1 && wf * hf <= MaxCanvasArea)) 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntSize(); 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntSize(static_cast<unsigned>(wf), static_cast<unsigned>(hf)); 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntPoint HTMLCanvasElement::convertLogicalToDevice(const FloatPoint& logicalPos) const 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f; 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float xf = logicalPos.x() * pageScaleFactor; 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project float yf = logicalPos.y() * pageScaleFactor; 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntPoint(static_cast<unsigned>(xf), static_cast<unsigned>(yf)); 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLCanvasElement::createImageBuffer() const 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_imageBuffer); 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_createdImageBuffer = true; 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatSize unscaledSize(width(), height()); 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IntSize size = convertLogicalToDevice(unscaledSize); 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!size.width() || !size.height()) 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_imageBuffer = ImageBuffer::create(size); 3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // The convertLogicalToDevice MaxCanvasArea check should prevent common cases 3125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // where ImageBuffer::create() returns NULL, however we could still be low on memory. 3135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!m_imageBuffer) 3145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 315635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_imageBuffer->context()->scale(FloatSize(size.width() / unscaledSize.width(), size.height() / unscaledSize.height())); 316635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_imageBuffer->context()->setShadowsIgnoreTransforms(true); 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectGraphicsContext* HTMLCanvasElement::drawingContext() const 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return buffer() ? m_imageBuffer->context() : 0; 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectImageBuffer* HTMLCanvasElement::buffer() const 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_createdImageBuffer) 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project createImageBuffer(); 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_imageBuffer.get(); 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 331635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectTransformationMatrix HTMLCanvasElement::baseTransform() const 332635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 333635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_createdImageBuffer); 334635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project FloatSize unscaledSize(width(), height()); 335635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project IntSize size = convertLogicalToDevice(unscaledSize); 336635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix transform; 337635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (size.width() && size.height()) 3388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian transform.scaleNonUniform(size.width() / unscaledSize.width(), size.height() / unscaledSize.height()); 339635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project transform.multiply(m_imageBuffer->baseTransform()); 340635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return transform; 341635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(3D_CANVAS) 344231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool HTMLCanvasElement::is3D() const 345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return m_context && m_context->is3d(); 347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 351