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

📄 canvasrenderingcontext2d.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2007 Alp Toker <alp@atoker.com> * Copyright (C) 2008 Eric Seidel <eric@webkit.org> * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> * * 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 "CanvasRenderingContext2D.h"#include "TransformationMatrix.h"#include "CSSParser.h"#include "CachedImage.h"#include "CanvasGradient.h"#include "CanvasPattern.h"#include "CanvasStyle.h"#include "CSSPropertyNames.h"#include "CSSStyleSelector.h"#include "Document.h"#include "ExceptionCode.h"#include "FloatConversion.h"#include "Frame.h"#include "GraphicsContext.h"#include "HTMLCanvasElement.h"#include "HTMLImageElement.h"#include "HTMLNames.h"#include "ImageBuffer.h"#include "ImageData.h"#include "KURL.h"#include "NotImplemented.h"#include "Page.h"#include "RenderHTMLCanvas.h"#include "SecurityOrigin.h"#include "Settings.h"#include "StrokeStyleApplier.h"#include "TextMetrics.h"#include <stdio.h>#include <wtf/ByteArray.h>#include <wtf/MathExtras.h>using namespace std;namespace WebCore {using namespace HTMLNames;static const char* const defaultFont = "10px sans-serif";class CanvasStrokeStyleApplier : public StrokeStyleApplier {public:    CanvasStrokeStyleApplier(CanvasRenderingContext2D* canvasContext)        : m_canvasContext(canvasContext)    {    }        virtual void strokeStyle(GraphicsContext* c)    {        c->setStrokeThickness(m_canvasContext->lineWidth());        c->setLineCap(m_canvasContext->getLineCap());        c->setLineJoin(m_canvasContext->getLineJoin());        c->setMiterLimit(m_canvasContext->miterLimit());    }private:    CanvasRenderingContext2D* m_canvasContext;};CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas)    : m_canvas(canvas)    , m_stateStack(1){}void CanvasRenderingContext2D::ref(){    m_canvas->ref();}void CanvasRenderingContext2D::deref(){    m_canvas->deref(); }void CanvasRenderingContext2D::reset(){    m_stateStack.resize(1);    m_stateStack.first() = State();}CanvasRenderingContext2D::State::State()    : m_strokeStyle(CanvasStyle::create("black"))    , m_fillStyle(CanvasStyle::create("black"))    , m_lineWidth(1)    , m_lineCap(ButtCap)    , m_lineJoin(MiterJoin)    , m_miterLimit(10)    , m_shadowBlur(0)    , m_shadowColor("black")    , m_globalAlpha(1)    , m_globalComposite(CompositeSourceOver)    , m_invertibleCTM(true)    , m_textAlign(StartTextAlign)    , m_textBaseline(AlphabeticTextBaseline)    , m_unparsedFont(defaultFont)    , m_realizedFont(false){}void CanvasRenderingContext2D::save(){    ASSERT(m_stateStack.size() >= 1);    m_stateStack.append(state());    GraphicsContext* c = drawingContext();    if (!c)        return;    c->save();}void CanvasRenderingContext2D::restore(){    ASSERT(m_stateStack.size() >= 1);    if (m_stateStack.size() <= 1)        return;    m_path.transform(state().m_transform);    m_stateStack.removeLast();    m_path.transform(state().m_transform.inverse());    GraphicsContext* c = drawingContext();    if (!c)        return;    c->restore();}CanvasStyle* CanvasRenderingContext2D::strokeStyle() const{    return state().m_strokeStyle.get();}void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> style){    if (!style)        return;    if (m_canvas->originClean()) {        if (CanvasPattern* pattern = style->canvasPattern()) {            if (!pattern->originClean())                m_canvas->setOriginTainted();        }    }    state().m_strokeStyle = style;    GraphicsContext* c = drawingContext();    if (!c)        return;    state().m_strokeStyle->applyStrokeColor(c);}CanvasStyle* CanvasRenderingContext2D::fillStyle() const{    return state().m_fillStyle.get();}void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> style){    if (!style)        return;     if (m_canvas->originClean()) {        if (CanvasPattern* pattern = style->canvasPattern()) {            if (!pattern->originClean())                m_canvas->setOriginTainted();        }    }    state().m_fillStyle = style;    GraphicsContext* c = drawingContext();    if (!c)        return;    state().m_fillStyle->applyFillColor(c);}float CanvasRenderingContext2D::lineWidth() const{    return state().m_lineWidth;}void CanvasRenderingContext2D::setLineWidth(float width){    if (!(width > 0))        return;    state().m_lineWidth = width;    GraphicsContext* c = drawingContext();    if (!c)        return;    c->setStrokeThickness(width);}String CanvasRenderingContext2D::lineCap() const{    return lineCapName(state().m_lineCap);}void CanvasRenderingContext2D::setLineCap(const String& s){    LineCap cap;    if (!parseLineCap(s, cap))        return;    state().m_lineCap = cap;    GraphicsContext* c = drawingContext();    if (!c)        return;    c->setLineCap(cap);}String CanvasRenderingContext2D::lineJoin() const{    return lineJoinName(state().m_lineJoin);}void CanvasRenderingContext2D::setLineJoin(const String& s){    LineJoin join;    if (!parseLineJoin(s, join))        return;    state().m_lineJoin = join;    GraphicsContext* c = drawingContext();    if (!c)        return;    c->setLineJoin(join);}float CanvasRenderingContext2D::miterLimit() const{    return state().m_miterLimit;}void CanvasRenderingContext2D::setMiterLimit(float limit){    if (!(limit > 0))        return;    state().m_miterLimit = limit;    GraphicsContext* c = drawingContext();    if (!c)        return;    c->setMiterLimit(limit);}float CanvasRenderingContext2D::shadowOffsetX() const{    return state().m_shadowOffset.width();}void CanvasRenderingContext2D::setShadowOffsetX(float x){    state().m_shadowOffset.setWidth(x);    applyShadow();}float CanvasRenderingContext2D::shadowOffsetY() const{    return state().m_shadowOffset.height();}void CanvasRenderingContext2D::setShadowOffsetY(float y){    state().m_shadowOffset.setHeight(y);    applyShadow();}float CanvasRenderingContext2D::shadowBlur() const{    return state().m_shadowBlur;}void CanvasRenderingContext2D::setShadowBlur(float blur){    state().m_shadowBlur = blur;    applyShadow();}String CanvasRenderingContext2D::shadowColor() const{    // FIXME: What should this return if you called setShadow with a non-string color?    return state().m_shadowColor;}void CanvasRenderingContext2D::setShadowColor(const String& color){    state().m_shadowColor = color;    applyShadow();}float CanvasRenderingContext2D::globalAlpha() const{    return state().m_globalAlpha;}void CanvasRenderingContext2D::setGlobalAlpha(float alpha){    if (!(alpha >= 0 && alpha <= 1))        return;    state().m_globalAlpha = alpha;    GraphicsContext* c = drawingContext();    if (!c)        return;    c->setAlpha(alpha);}String CanvasRenderingContext2D::globalCompositeOperation() const{    return compositeOperatorName(state().m_globalComposite);}void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operation){    CompositeOperator op;    if (!parseCompositeOperator(operation, op))        return;    state().m_globalComposite = op;    GraphicsContext* c = drawingContext();    if (!c)        return;    c->setCompositeOperation(op);}void CanvasRenderingContext2D::scale(float sx, float sy){    GraphicsContext* c = drawingContext();    if (!c)        return;    if (!state().m_invertibleCTM)        return;    TransformationMatrix newTransform = state().m_transform;    newTransform.scaleNonUniform(sx, sy);    if (!newTransform.isInvertible()) {        state().m_invertibleCTM = false;        return;    }    state().m_transform = newTransform;    c->scale(FloatSize(sx, sy));    m_path.transform(TransformationMatrix().scaleNonUniform(1.0/sx, 1.0/sy));}void CanvasRenderingContext2D::rotate(float angleInRadians){    GraphicsContext* c = drawingContext();    if (!c)        return;    if (!state().m_invertibleCTM)        return;    TransformationMatrix newTransform = state().m_transform;    newTransform.rotate(angleInRadians / piDouble * 180.0);    if (!newTransform.isInvertible()) {        state().m_invertibleCTM = false;        return;    }    state().m_transform = newTransform;    c->rotate(angleInRadians);    m_path.transform(TransformationMatrix().rotate(-angleInRadians / piDouble * 180.0));}void CanvasRenderingContext2D::translate(float tx, float ty){    GraphicsContext* c = drawingContext();    if (!c)        return;    if (!state().m_invertibleCTM)        return;    TransformationMatrix newTransform = state().m_transform;    newTransform.translate(tx, ty);    if (!newTransform.isInvertible()) {        state().m_invertibleCTM = false;        return;    }    state().m_transform = newTransform;    c->translate(tx, ty);    m_path.transform(TransformationMatrix().translate(-tx, -ty));}void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy){    GraphicsContext* c = drawingContext();    if (!c)        return;    if (!state().m_invertibleCTM)        return;        // HTML5 3.14.11.1 -- ignore any calls that pass non-finite numbers    if (!isfinite(m11) | !isfinite(m21) | !isfinite(dx) |         !isfinite(m12) | !isfinite(m22) | !isfinite(dy))        return;    TransformationMatrix transform(m11, m12, m21, m22, dx, dy);    TransformationMatrix newTransform = transform * state().m_transform;    if (!newTransform.isInvertible()) {        state().m_invertibleCTM = false;        return;    }    state().m_transform = newTransform;    c->concatCTM(transform);    m_path.transform(transform.inverse());}void CanvasRenderingContext2D::setTransform(float m11, float m12, float m21, float m22, float dx, float dy){    GraphicsContext* c = drawingContext();    if (!c)        return;        // HTML5 3.14.11.1 -- ignore any calls that pass non-finite numbers    if (!isfinite(m11) | !isfinite(m21) | !isfinite(dx) |         !isfinite(m12) | !isfinite(m22) | !isfinite(dy))        return;    TransformationMatrix ctm = state().m_transform;    if (!ctm.isInvertible())        return;    c->concatCTM(c->getCTM().inverse());    c->concatCTM(m_canvas->baseTransform());    state().m_transform.multiply(ctm.inverse());    m_path.transform(ctm);    state().m_invertibleCTM = true;    transform(m11, m12, m21, m22, dx, dy);}void CanvasRenderingContext2D::setStrokeColor(const String& color){    setStrokeStyle(CanvasStyle::create(color));}void CanvasRenderingContext2D::setStrokeColor(float grayLevel){    setStrokeStyle(CanvasStyle::create(grayLevel, 1));}void CanvasRenderingContext2D::setStrokeColor(const String& color, float alpha){    setStrokeStyle(CanvasStyle::create(color, alpha));}void CanvasRenderingContext2D::setStrokeColor(float grayLevel, float alpha){    setStrokeStyle(CanvasStyle::create(grayLevel, alpha));}void CanvasRenderingContext2D::setStrokeColor(float r, float g, float b, float a){    setStrokeStyle(CanvasStyle::create(r, g, b, a));}void CanvasRenderingContext2D::setStrokeColor(float c, float m, float y, float k, float a){    setStrokeStyle(CanvasStyle::create(c, m, y, k, a));}

⌨️ 快捷键说明

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