⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmlcanvaselement.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. * Copyright (C) 2007 Alp Toker <alp@atoker.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "HTMLCanvasElement.h"#include "CanvasGradient.h"#include "CanvasPattern.h"#include "CanvasRenderingContext2D.h"#include "CanvasStyle.h"#include "Chrome.h"#include "Document.h"#include "ExceptionCode.h"#include "Frame.h"#include "GraphicsContext.h"#include "HTMLNames.h"#include "ImageBuffer.h"#include "MIMETypeRegistry.h"#include "Page.h"#include "RenderHTMLCanvas.h"#include "Settings.h"#include <math.h>#include <stdio.h>namespace WebCore {using namespace HTMLNames;// These values come from the WhatWG spec.static const int defaultWidth = 300;static const int defaultHeight = 150;// Firefox limits width/height to 32767 pixels, but slows down dramatically before it // reaches that limit. We limit by area instead, giving us larger maximum dimensions,// in exchange for a smaller maximum canvas size.const float HTMLCanvasElement::MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixelsHTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document* doc)    : HTMLElement(tagName, doc)    , m_size(defaultWidth, defaultHeight)    , m_observer(0)    , m_originClean(true)    , m_ignoreReset(false)    , m_createdImageBuffer(false){    ASSERT(hasTagName(canvasTag));}HTMLCanvasElement::~HTMLCanvasElement(){}#if ENABLE(DASHBOARD_SUPPORT)HTMLTagStatus HTMLCanvasElement::endTagRequirement() const {    Settings* settings = document()->settings();    if (settings && settings->usesDashboardBackwardCompatibilityMode())        return TagStatusForbidden;     return HTMLElement::endTagRequirement();}int HTMLCanvasElement::tagPriority() const {     Settings* settings = document()->settings();    if (settings && settings->usesDashboardBackwardCompatibilityMode())        return 0;     return HTMLElement::tagPriority();}#endifvoid HTMLCanvasElement::parseMappedAttribute(MappedAttribute* attr){    const QualifiedName& attrName = attr->name();    if (attrName == widthAttr || attrName == heightAttr)        reset();    HTMLElement::parseMappedAttribute(attr);}RenderObject* HTMLCanvasElement::createRenderer(RenderArena* arena, RenderStyle* style){    Settings* settings = document()->settings();    if (settings && settings->isJavaScriptEnabled()) {        m_rendererIsCanvas = true;        return new (arena) RenderHTMLCanvas(this);    }    m_rendererIsCanvas = false;    return HTMLElement::createRenderer(arena, style);}void HTMLCanvasElement::setHeight(int value){    setAttribute(heightAttr, String::number(value));}void HTMLCanvasElement::setWidth(int value){    setAttribute(widthAttr, String::number(value));}String HTMLCanvasElement::toDataURL(const String& mimeType, ExceptionCode& ec){    if (!m_originClean) {        ec = SECURITY_ERR;        return String();    }    if (m_size.isEmpty())        return String("data:,");    if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType))        return buffer()->toDataURL("image/png");    return buffer()->toDataURL(mimeType);}CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type){    if (type == "2d") {        if (!m_2DContext)            m_2DContext.set(new CanvasRenderingContext2D(this));        return m_2DContext.get();    }    return 0;}void HTMLCanvasElement::willDraw(const FloatRect& rect){    m_imageBuffer->clearImage();        if (RenderBox* ro = renderBox()) {        FloatRect destRect = ro->contentBoxRect();        FloatRect r = mapRect(rect, FloatRect(0, 0, m_size.width(), m_size.height()), destRect);        r.intersect(destRect);        if (m_dirtyRect.contains(r))            return;        m_dirtyRect.unite(r);        ro->repaintRectangle(enclosingIntRect(m_dirtyRect));    }        if (m_observer)        m_observer->canvasChanged(this, rect);}void HTMLCanvasElement::reset(){    if (m_ignoreReset)        return;    bool ok;    int w = getAttribute(widthAttr).toInt(&ok);    if (!ok)        w = defaultWidth;    int h = getAttribute(heightAttr).toInt(&ok);    if (!ok)        h = defaultHeight;    IntSize oldSize = m_size;    m_size = IntSize(w, h);    bool hadImageBuffer = m_createdImageBuffer;    m_createdImageBuffer = false;    m_imageBuffer.clear();    if (m_2DContext)        m_2DContext->reset();    if (RenderObject* ro = renderer())        if (m_rendererIsCanvas) {            if (oldSize != m_size)                static_cast<RenderHTMLCanvas*>(ro)->canvasSizeChanged();            if (hadImageBuffer)                ro->repaint();        }            if (m_observer)        m_observer->canvasResized(this);}void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r){    // Clear the dirty rect    m_dirtyRect = FloatRect();    if (context->paintingDisabled())        return;        if (m_imageBuffer) {        Image* image = m_imageBuffer->image();        if (image)            context->drawImage(image, r);    }}IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const{    return IntRect(convertLogicalToDevice(logicalRect.location()), convertLogicalToDevice(logicalRect.size()));}IntSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const{    float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f;    float wf = ceilf(logicalSize.width() * pageScaleFactor);    float hf = ceilf(logicalSize.height() * pageScaleFactor);        if (!(wf >= 1 && hf >= 1 && wf * hf <= MaxCanvasArea))        return IntSize();    return IntSize(static_cast<unsigned>(wf), static_cast<unsigned>(hf));}IntPoint HTMLCanvasElement::convertLogicalToDevice(const FloatPoint& logicalPos) const{    float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f;    float xf = logicalPos.x() * pageScaleFactor;    float yf = logicalPos.y() * pageScaleFactor;        return IntPoint(static_cast<unsigned>(xf), static_cast<unsigned>(yf));}void HTMLCanvasElement::createImageBuffer() const{    ASSERT(!m_imageBuffer);    m_createdImageBuffer = true;        FloatSize unscaledSize(width(), height());    IntSize size = convertLogicalToDevice(unscaledSize);    if (!size.width() || !size.height())        return;    m_imageBuffer.set(ImageBuffer::create(size, false).release());    m_imageBuffer->context()->scale(FloatSize(size.width() / unscaledSize.width(), size.height() / unscaledSize.height()));    m_imageBuffer->context()->setShadowsIgnoreTransforms(true);}GraphicsContext* HTMLCanvasElement::drawingContext() const{    return buffer() ? m_imageBuffer->context() : 0;}ImageBuffer* HTMLCanvasElement::buffer() const{    if (!m_createdImageBuffer)        createImageBuffer();    return m_imageBuffer.get();}    TransformationMatrix HTMLCanvasElement::baseTransform() const{    ASSERT(m_createdImageBuffer);    FloatSize unscaledSize(width(), height());    IntSize size = convertLogicalToDevice(unscaledSize);    TransformationMatrix transform;    if (size.width() && size.height())        transform.scaleNonUniform(size.width() / unscaledSize.width(), size.height() / unscaledSize.height());    transform.multiply(m_imageBuffer->baseTransform());    return transform;}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -