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

📄 graphicscontextskia.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2006, Google Inc. All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: *  *     * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. *     * 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. *     * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 THE COPYRIGHT * OWNER 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 "GraphicsContext.h"#include "GraphicsContextPlatformPrivate.h"#include "GraphicsContextPrivate.h"#include "Color.h"#include "FloatRect.h"#include "Gradient.h"#include "ImageBuffer.h"#include "IntRect.h"#include "NativeImageSkia.h"#include "NotImplemented.h"#include "PlatformContextSkia.h"#include "TransformationMatrix.h"#include "SkBitmap.h"#include "SkBlurDrawLooper.h"#include "SkCornerPathEffect.h"#include "skia/ext/platform_canvas.h"#include "SkiaUtils.h"#include "SkShader.h"#include <math.h>#include <wtf/Assertions.h>#include <wtf/MathExtras.h>using namespace std;namespace WebCore {namespace {// "Seatbelt" functions ------------------------------------------------------//// These functions check certain graphics primitives for being "safe".// Skia has historically crashed when sent crazy data. These functions do// additional checking to prevent crashes.//// Ideally, all of these would be fixed in the graphics layer and we would not// have to do any checking. You can uncomment the ENSURE_VALUE_SAFETY_FOR_SKIA// flag to check the graphics layer.#define ENSURE_VALUE_SAFETY_FOR_SKIAstatic bool isCoordinateSkiaSafe(float coord){#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA    // First check for valid floats.#if defined(_MSC_VER)    if (!_finite(coord))#else    if (!finite(coord))#endif        return false;    // Skia uses 16.16 fixed point and 26.6 fixed point in various places. If    // the transformed point exceeds 15 bits, we just declare that it's    // unreasonable to catch both of these cases.    static const int maxPointMagnitude = 32767;    if (coord > maxPointMagnitude || coord < -maxPointMagnitude)        return false;    return true;#else    return true;#endif}static bool isPointSkiaSafe(const SkMatrix& transform, const SkPoint& pt){#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA    // Now check for points that will overflow. We check the *transformed*    // points since this is what will be rasterized.    SkPoint xPt;    transform.mapPoints(&xPt, &pt, 1);    return isCoordinateSkiaSafe(xPt.fX) && isCoordinateSkiaSafe(xPt.fY);#else    return true;#endif}static bool isRectSkiaSafe(const SkMatrix& transform, const SkRect& rc){#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA    SkPoint topleft = {rc.fLeft, rc.fTop};    SkPoint bottomright = {rc.fRight, rc.fBottom};    return isPointSkiaSafe(transform, topleft) && isPointSkiaSafe(transform, bottomright);#else    return true;#endif}bool isPathSkiaSafe(const SkMatrix& transform, const SkPath& path){#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA    SkPoint current_points[4];    SkPath::Iter iter(path, false);    for (SkPath::Verb verb = iter.next(current_points);         verb != SkPath::kDone_Verb;         verb = iter.next(current_points)) {        switch (verb) {        case SkPath::kMove_Verb:            // This move will be duplicated in the next verb, so we can ignore.            break;        case SkPath::kLine_Verb:            // iter.next returns 2 points.            if (!isPointSkiaSafe(transform, current_points[0])                || !isPointSkiaSafe(transform, current_points[1]))                return false;            break;        case SkPath::kQuad_Verb:            // iter.next returns 3 points.            if (!isPointSkiaSafe(transform, current_points[0])                || !isPointSkiaSafe(transform, current_points[1])                || !isPointSkiaSafe(transform, current_points[2]))                return false;            break;        case SkPath::kCubic_Verb:            // iter.next returns 4 points.            if (!isPointSkiaSafe(transform, current_points[0])                || !isPointSkiaSafe(transform, current_points[1])                || !isPointSkiaSafe(transform, current_points[2])                || !isPointSkiaSafe(transform, current_points[3]))                return false;            break;        case SkPath::kClose_Verb:        case SkPath::kDone_Verb:        default:            break;        }    }    return true;#else    return true;#endif}// Local helper functions ------------------------------------------------------void addCornerArc(SkPath* path, const SkRect& rect, const IntSize& size, int startAngle){    SkIRect ir;    int rx = SkMin32(SkScalarRound(rect.width()), size.width());    int ry = SkMin32(SkScalarRound(rect.height()), size.height());    ir.set(-rx, -ry, rx, ry);    switch (startAngle) {    case 0:        ir.offset(rect.fRight - ir.fRight, rect.fBottom - ir.fBottom);        break;    case 90:        ir.offset(rect.fLeft - ir.fLeft, rect.fBottom - ir.fBottom);        break;    case 180:        ir.offset(rect.fLeft - ir.fLeft, rect.fTop - ir.fTop);        break;    case 270:        ir.offset(rect.fRight - ir.fRight, rect.fTop - ir.fTop);        break;    default:        ASSERT(0);    }    SkRect r;    r.set(ir);    path->arcTo(r, SkIntToScalar(startAngle), SkIntToScalar(90), false);}inline int fastMod(int value, int max){    int sign = SkExtractSign(value);    value = SkApplySign(value, sign);    if (value >= max)        value %= max;    return SkApplySign(value, sign);}inline float square(float n){    return n * n;}}  // namespace// -----------------------------------------------------------------------------// This may be called with a NULL pointer to create a graphics context that has// no painting.GraphicsContext::GraphicsContext(PlatformGraphicsContext* gc)    : m_common(createGraphicsContextPrivate())    , m_data(new GraphicsContextPlatformPrivate(gc)){    setPaintingDisabled(!gc || !platformContext()->canvas());}GraphicsContext::~GraphicsContext(){    delete m_data;    this->destroyGraphicsContextPrivate(m_common);}PlatformGraphicsContext* GraphicsContext::platformContext() const{    ASSERT(!paintingDisabled());    return m_data->context();}// State saving ----------------------------------------------------------------void GraphicsContext::savePlatformState(){    if (paintingDisabled())        return;    // Save our private State.    platformContext()->save();}void GraphicsContext::restorePlatformState(){    if (paintingDisabled())        return;    // Restore our private State.    platformContext()->restore();}void GraphicsContext::beginTransparencyLayer(float opacity){    if (paintingDisabled())        return;    // We need the "alpha" layer flag here because the base layer is opaque    // (the surface of the page) but layers on top may have transparent parts.    // Without explicitly setting the alpha flag, the layer will inherit the    // opaque setting of the base and some things won't work properly.    platformContext()->canvas()->saveLayerAlpha(        0,        static_cast<unsigned char>(opacity * 255),        static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag |                                         SkCanvas::kFullColorLayer_SaveFlag));}void GraphicsContext::endTransparencyLayer(){    if (paintingDisabled())        return;    platformContext()->canvas()->restore();}// Graphics primitives ---------------------------------------------------------void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness){    if (paintingDisabled())        return;    SkRect r(rect);    if (!isRectSkiaSafe(getCTM(), r))        return;    SkPath path;    path.addOval(r, SkPath::kCW_Direction);    // only perform the inset if we won't invert r    if (2 * thickness < rect.width() && 2 * thickness < rect.height()) {        r.inset(SkIntToScalar(thickness) ,SkIntToScalar(thickness));        path.addOval(r, SkPath::kCCW_Direction);    }    platformContext()->canvas()->clipPath(path);}void GraphicsContext::addPath(const Path& path){    if (paintingDisabled())        return;    platformContext()->addPath(*path.platformPath());}void GraphicsContext::beginPath(){    if (paintingDisabled())        return;    platformContext()->beginPath();}void GraphicsContext::clearPlatformShadow(){    if (paintingDisabled())        return;    platformContext()->setDrawLooper(0);}void GraphicsContext::clearRect(const FloatRect& rect){    if (paintingDisabled())        return;    SkRect r = rect;    if (!isRectSkiaSafe(getCTM(), r))        ClipRectToCanvas(*platformContext()->canvas(), r, &r);    SkPaint paint;    platformContext()->setupPaintForFilling(&paint);    paint.setPorterDuffXfermode(SkPorterDuff::kClear_Mode);    platformContext()->canvas()->drawRect(r, paint);}void GraphicsContext::clip(const FloatRect& rect){    if (paintingDisabled())        return;    SkRect r(rect);    if (!isRectSkiaSafe(getCTM(), r))        return;    platformContext()->canvas()->clipRect(r);}void GraphicsContext::clip(const Path& path){    if (paintingDisabled())        return;    const SkPath& p = *path.platformPath();    if (!isPathSkiaSafe(getCTM(), p))        return;    platformContext()->canvas()->clipPath(p);}void GraphicsContext::clipOut(const IntRect& rect){    if (paintingDisabled())        return;    SkRect r(rect);    if (!isRectSkiaSafe(getCTM(), r))        return;    platformContext()->canvas()->clipRect(r, SkRegion::kDifference_Op);}void GraphicsContext::clipOut(const Path& p){    if (paintingDisabled())        return;    const SkPath& path = *p.platformPath();    if (!isPathSkiaSafe(getCTM(), path))

⌨️ 快捷键说明

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