Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(690)

Unified Diff: third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp

Issue 1739553002: Pull up a subset of CanvasRenderingContext2D into BaseRenderingContext2D. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
similarity index 43%
copy from third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
copy to third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
index 69aca02f0e59173f476b8e1a260fa0e05dc9a2ac..7072ec0678cc326f28819648969157fa2994574a 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -1,324 +1,50 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2010 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>
- * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
- * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved.
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * 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 "modules/canvas2d/CanvasRenderingContext2D.h"
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/canvas2d/BaseRenderingContext2D.h"
#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/ExceptionStatePlaceholder.h"
-#include "core/CSSPropertyNames.h"
-#include "core/css/StylePropertySet.h"
#include "core/css/parser/CSSParser.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/AXObjectCache.h"
-#include "core/dom/StyleEngine.h"
-#include "core/events/Event.h"
#include "core/frame/ImageBitmap.h"
-#include "core/frame/Settings.h"
+#include "core/html/HTMLCanvasElement.h"
+#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLVideoElement.h"
#include "core/html/ImageData.h"
-#include "core/html/TextMetrics.h"
-#include "core/html/canvas/CanvasFontCache.h"
-#include "core/layout/LayoutBox.h"
-#include "core/layout/LayoutTheme.h"
#include "modules/canvas2d/CanvasGradient.h"
#include "modules/canvas2d/CanvasPattern.h"
-#include "modules/canvas2d/CanvasRenderingContext2DState.h"
#include "modules/canvas2d/CanvasStyle.h"
-#include "modules/canvas2d/HitRegion.h"
#include "modules/canvas2d/Path2D.h"
-#include "platform/fonts/FontCache.h"
#include "platform/geometry/FloatQuad.h"
-#include "platform/graphics/DrawLooperBuilder.h"
+#include "platform/graphics/Color.h"
#include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
+#include "platform/graphics/Image.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/StrokeData.h"
#include "platform/graphics/skia/SkiaUtils.h"
-#include "platform/text/BidiTextRun.h"
-#include "public/platform/Platform.h"
-#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImageFilter.h"
-#include "wtf/ArrayBufferContents.h"
-#include "wtf/CheckedArithmetic.h"
-#include "wtf/MathExtras.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/text/StringBuilder.h"
namespace blink {
-static const char defaultFont[] = "10px sans-serif";
-static const char inherit[] = "inherit";
-static const char rtl[] = "rtl";
-static const char ltr[] = "ltr";
-static const double TryRestoreContextInterval = 0.5;
-static const unsigned MaxTryRestoreContextAttempts = 4;
-static const double cDeviceScaleFactor = 1.0; // Canvas is device independent
-
-static bool contextLostRestoredEventsEnabled()
-{
- return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
-}
-
-// Drawing methods need to use this instead of SkAutoCanvasRestore in case overdraw
-// detection substitutes the recording canvas (to discard overdrawn draw calls).
-class CanvasRenderingContext2DAutoRestoreSkCanvas {
- STACK_ALLOCATED();
-public:
- explicit CanvasRenderingContext2DAutoRestoreSkCanvas(CanvasRenderingContext2D* context)
- : m_context(context)
- , m_saveCount(0)
- {
- ASSERT(m_context);
- SkCanvas* c = m_context->drawingCanvas();
- if (c) {
- m_saveCount = c->getSaveCount();
- }
- }
-
- ~CanvasRenderingContext2DAutoRestoreSkCanvas()
- {
- SkCanvas* c = m_context->drawingCanvas();
- if (c)
- c->restoreToCount(m_saveCount);
- m_context->validateStateStack();
- }
-private:
- RawPtrWillBeMember<CanvasRenderingContext2D> m_context;
- int m_saveCount;
-};
-
-CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, const CanvasContextCreationAttributes& attrs, Document& document)
- : CanvasRenderingContext(canvas)
- , m_clipAntialiasing(NotAntiAliased)
- , m_hasAlpha(attrs.alpha())
- , m_contextLostMode(NotLostContext)
- , m_contextRestorable(true)
- , m_tryRestoreContextAttemptCount(0)
- , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchContextLostEvent)
- , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispatchContextRestoredEvent)
- , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreContextEvent)
- , m_pruneLocalFontCacheScheduled(false)
-{
- if (document.settings() && document.settings()->antialiasedClips2dCanvasEnabled())
- m_clipAntialiasing = AntiAliased;
- m_stateStack.append(CanvasRenderingContext2DState::create());
- setShouldAntialias(true);
-#if ENABLE(OILPAN)
- ThreadState::current()->registerPreFinalizer(this);
-#endif
-}
-
-void CanvasRenderingContext2D::unwindStateStack()
-{
- if (size_t stackSize = m_stateStack.size()) {
- if (SkCanvas* skCanvas = canvas()->existingDrawingCanvas()) {
- while (--stackSize)
- skCanvas->restore();
- }
- }
-}
-
-CanvasRenderingContext2D::~CanvasRenderingContext2D()
+BaseRenderingContext2D::BaseRenderingContext2D()
+ : m_clipAntialiasing(NotAntiAliased)
{
- if (m_pruneLocalFontCacheScheduled) {
- Platform::current()->currentThread()->removeTaskObserver(this);
- }
-#if !ENABLE(OILPAN)
- dispose();
-#endif
-}
-
-void CanvasRenderingContext2D::dispose()
-{
- clearFilterReferences();
+ m_stateStack.append(CanvasRenderingContext2DState::create());
}
-void CanvasRenderingContext2D::validateStateStack()
+BaseRenderingContext2D::~BaseRenderingContext2D()
{
-#if ENABLE(ASSERT)
- SkCanvas* skCanvas = canvas()->existingDrawingCanvas();
- if (skCanvas && m_contextLostMode == NotLostContext) {
- ASSERT(static_cast<size_t>(skCanvas->getSaveCount()) == m_stateStack.size());
- }
-#endif
}
-CanvasRenderingContext2DState& CanvasRenderingContext2D::modifiableState()
+CanvasRenderingContext2DState& BaseRenderingContext2D::modifiableState()
{
realizeSaves();
return *m_stateStack.last();
}
-bool CanvasRenderingContext2D::isAccelerated() const
-{
- if (!canvas()->hasImageBuffer())
- return false;
- return canvas()->buffer()->isAccelerated();
-}
-
-void CanvasRenderingContext2D::stop()
-{
- if (!isContextLost()) {
- // Never attempt to restore the context because the page is being torn down.
- loseContext(SyntheticLostContext);
- }
-}
-
-bool CanvasRenderingContext2D::isContextLost() const
-{
- return m_contextLostMode != NotLostContext;
-}
-
-void CanvasRenderingContext2D::loseContext(LostContextMode lostMode)
-{
- if (m_contextLostMode != NotLostContext)
- return;
- m_contextLostMode = lostMode;
- if (m_contextLostMode == SyntheticLostContext) {
- canvas()->discardImageBuffer();
- }
- m_dispatchContextLostEventTimer.startOneShot(0, BLINK_FROM_HERE);
-}
-
-void CanvasRenderingContext2D::didSetSurfaceSize()
-{
- if (!m_contextRestorable)
- return;
- // This code path is for restoring from an eviction
- // Restoring from surface failure is handled internally
- ASSERT(m_contextLostMode != NotLostContext && !canvas()->hasImageBuffer());
-
- if (canvas()->buffer()) {
- if (contextLostRestoredEventsEnabled()) {
- m_dispatchContextRestoredEventTimer.startOneShot(0, BLINK_FROM_HERE);
- } else {
- // legacy synchronous context restoration.
- reset();
- m_contextLostMode = NotLostContext;
- }
- }
-}
-
-DEFINE_TRACE(CanvasRenderingContext2D)
-{
- visitor->trace(m_stateStack);
- visitor->trace(m_hitRegionManager);
- CanvasRenderingContext::trace(visitor);
-}
-
-void CanvasRenderingContext2D::dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*)
-{
- if (contextLostRestoredEventsEnabled()) {
- RefPtrWillBeRawPtr<Event> event = Event::createCancelable(EventTypeNames::contextlost);
- canvas()->dispatchEvent(event);
- if (event->defaultPrevented()) {
- m_contextRestorable = false;
- }
- }
-
- // If RealLostContext, it means the context was not lost due to surface failure
- // but rather due to a an eviction, which means image buffer exists.
- if (m_contextRestorable && m_contextLostMode == RealLostContext) {
- m_tryRestoreContextAttemptCount = 0;
- m_tryRestoreContextEventTimer.startRepeating(TryRestoreContextInterval, BLINK_FROM_HERE);
- }
-}
-
-void CanvasRenderingContext2D::tryRestoreContextEvent(Timer<CanvasRenderingContext2D>* timer)
-{
- if (m_contextLostMode == NotLostContext) {
- // Canvas was already restored (possibly thanks to a resize), so stop trying.
- m_tryRestoreContextEventTimer.stop();
- return;
- }
-
- ASSERT(m_contextLostMode == RealLostContext);
- if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) {
- m_tryRestoreContextEventTimer.stop();
- dispatchContextRestoredEvent(nullptr);
- }
-
- if (++m_tryRestoreContextAttemptCount > MaxTryRestoreContextAttempts) {
- // final attempt: allocate a brand new image buffer instead of restoring
- canvas()->discardImageBuffer();
- m_tryRestoreContextEventTimer.stop();
- if (canvas()->buffer())
- dispatchContextRestoredEvent(nullptr);
- }
-}
-
-void CanvasRenderingContext2D::dispatchContextRestoredEvent(Timer<CanvasRenderingContext2D>*)
-{
- if (m_contextLostMode == NotLostContext)
- return;
- reset();
- m_contextLostMode = NotLostContext;
- if (contextLostRestoredEventsEnabled()) {
- RefPtrWillBeRawPtr<Event> event(Event::create(EventTypeNames::contextrestored));
- canvas()->dispatchEvent(event);
- }
-}
-
-void CanvasRenderingContext2D::reset()
-{
- validateStateStack();
- unwindStateStack();
- m_stateStack.resize(1);
- m_stateStack.first() = CanvasRenderingContext2DState::create();
- m_path.clear();
- SkCanvas* c = canvas()->existingDrawingCanvas();
- if (c) {
- c->resetMatrix();
- c->clipRect(SkRect::MakeWH(canvas()->width(), canvas()->height()), SkRegion::kReplace_Op);
- }
- validateStateStack();
-}
-
-void CanvasRenderingContext2D::restoreCanvasMatrixClipStack(SkCanvas* c) const
-{
- if (!c)
- return;
- WillBeHeapVector<OwnPtrWillBeMember<CanvasRenderingContext2DState>>::const_iterator currState;
- ASSERT(m_stateStack.begin() < m_stateStack.end());
- for (currState = m_stateStack.begin(); currState < m_stateStack.end(); currState++) {
- c->setMatrix(SkMatrix::I());
- currState->get()->playbackClips(c);
- c->setMatrix(affineTransformToSkMatrix(currState->get()->transform()));
- c->save();
- }
- c->restore();
-}
-
-void CanvasRenderingContext2D::realizeSaves()
+void BaseRenderingContext2D::realizeSaves()
{
validateStateStack();
if (state().hasUnrealizedSaves()) {
@@ -339,12 +65,12 @@ void CanvasRenderingContext2D::realizeSaves()
}
}
-void CanvasRenderingContext2D::save()
+void BaseRenderingContext2D::save()
{
m_stateStack.last()->save();
}
-void CanvasRenderingContext2D::restore()
+void BaseRenderingContext2D::restore()
{
validateStateStack();
if (state().hasUnrealizedSaves()) {
@@ -379,12 +105,12 @@ static inline void convertCanvasStyleToUnionType(CanvasStyle* style, StringOrCan
returnValue.setString(style->color());
}
-void CanvasRenderingContext2D::strokeStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
+void BaseRenderingContext2D::strokeStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
{
convertCanvasStyleToUnionType(state().strokeStyle(), returnValue);
}
-void CanvasRenderingContext2D::setStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& style)
+void BaseRenderingContext2D::setStrokeStyle(const StringOrCanvasGradientOrCanvasPattern& style)
{
ASSERT(!style.isNull());
@@ -395,7 +121,7 @@ void CanvasRenderingContext2D::setStrokeStyle(const StringOrCanvasGradientOrCanv
if (colorString == state().unparsedStrokeColor())
return;
Color parsedColor = 0;
- if (!parseColorOrCurrentColor(parsedColor, colorString, canvas()))
+ if (!parseColorOrCurrentColor(parsedColor, colorString))
return;
if (state().strokeStyle()->isEquivalentRGBA(parsedColor.rgb())) {
modifiableState().setUnparsedStrokeColor(colorString);
@@ -407,8 +133,8 @@ void CanvasRenderingContext2D::setStrokeStyle(const StringOrCanvasGradientOrCanv
} else if (style.isCanvasPattern()) {
CanvasPattern* canvasPattern = style.getAsCanvasPattern();
- if (canvas()->originClean() && !canvasPattern->originClean())
- canvas()->setOriginTainted();
+ if (originClean() && !canvasPattern->originClean())
+ setOriginTainted();
canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
}
@@ -420,12 +146,12 @@ void CanvasRenderingContext2D::setStrokeStyle(const StringOrCanvasGradientOrCanv
modifiableState().clearResolvedFilter();
}
-void CanvasRenderingContext2D::fillStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
+void BaseRenderingContext2D::fillStyle(StringOrCanvasGradientOrCanvasPattern& returnValue) const
{
convertCanvasStyleToUnionType(state().fillStyle(), returnValue);
}
-void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvasPattern& style)
+void BaseRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvasPattern& style)
{
ASSERT(!style.isNull());
validateStateStack();
@@ -436,7 +162,7 @@ void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvas
if (colorString == state().unparsedFillColor())
return;
Color parsedColor = 0;
- if (!parseColorOrCurrentColor(parsedColor, colorString, canvas()))
+ if (!parseColorOrCurrentColor(parsedColor, colorString))
return;
if (state().fillStyle()->isEquivalentRGBA(parsedColor.rgb())) {
modifiableState().setUnparsedFillColor(colorString);
@@ -448,10 +174,10 @@ void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvas
} else if (style.isCanvasPattern()) {
CanvasPattern* canvasPattern = style.getAsCanvasPattern();
- if (canvas()->originClean() && !canvasPattern->originClean())
- canvas()->setOriginTainted();
+ if (originClean() && !canvasPattern->originClean())
+ setOriginTainted();
if (canvasPattern->pattern()->isTextureBacked())
- canvas()->disableDeferral(DisableDeferralReasonUsingTextureBackedPattern);
+ disableDeferral(DisableDeferralReasonUsingTextureBackedPattern);
canvasStyle = CanvasStyle::createFromPattern(canvasPattern);
}
@@ -461,12 +187,12 @@ void CanvasRenderingContext2D::setFillStyle(const StringOrCanvasGradientOrCanvas
modifiableState().clearResolvedFilter();
}
-double CanvasRenderingContext2D::lineWidth() const
+double BaseRenderingContext2D::lineWidth() const
{
return state().lineWidth();
}
-void CanvasRenderingContext2D::setLineWidth(double width)
+void BaseRenderingContext2D::setLineWidth(double width)
{
if (!std::isfinite(width) || width <= 0)
return;
@@ -475,12 +201,12 @@ void CanvasRenderingContext2D::setLineWidth(double width)
modifiableState().setLineWidth(width);
}
-String CanvasRenderingContext2D::lineCap() const
+String BaseRenderingContext2D::lineCap() const
{
return lineCapName(state().lineCap());
}
-void CanvasRenderingContext2D::setLineCap(const String& s)
+void BaseRenderingContext2D::setLineCap(const String& s)
{
LineCap cap;
if (!parseLineCap(s, cap))
@@ -490,12 +216,12 @@ void CanvasRenderingContext2D::setLineCap(const String& s)
modifiableState().setLineCap(cap);
}
-String CanvasRenderingContext2D::lineJoin() const
+String BaseRenderingContext2D::lineJoin() const
{
return lineJoinName(state().lineJoin());
}
-void CanvasRenderingContext2D::setLineJoin(const String& s)
+void BaseRenderingContext2D::setLineJoin(const String& s)
{
LineJoin join;
if (!parseLineJoin(s, join))
@@ -505,12 +231,12 @@ void CanvasRenderingContext2D::setLineJoin(const String& s)
modifiableState().setLineJoin(join);
}
-double CanvasRenderingContext2D::miterLimit() const
+double BaseRenderingContext2D::miterLimit() const
{
return state().miterLimit();
}
-void CanvasRenderingContext2D::setMiterLimit(double limit)
+void BaseRenderingContext2D::setMiterLimit(double limit)
{
if (!std::isfinite(limit) || limit <= 0)
return;
@@ -519,12 +245,12 @@ void CanvasRenderingContext2D::setMiterLimit(double limit)
modifiableState().setMiterLimit(limit);
}
-double CanvasRenderingContext2D::shadowOffsetX() const
+double BaseRenderingContext2D::shadowOffsetX() const
{
return state().shadowOffset().width();
}
-void CanvasRenderingContext2D::setShadowOffsetX(double x)
+void BaseRenderingContext2D::setShadowOffsetX(double x)
{
if (!std::isfinite(x))
return;
@@ -533,12 +259,12 @@ void CanvasRenderingContext2D::setShadowOffsetX(double x)
modifiableState().setShadowOffsetX(x);
}
-double CanvasRenderingContext2D::shadowOffsetY() const
+double BaseRenderingContext2D::shadowOffsetY() const
{
return state().shadowOffset().height();
}
-void CanvasRenderingContext2D::setShadowOffsetY(double y)
+void BaseRenderingContext2D::setShadowOffsetY(double y)
{
if (!std::isfinite(y))
return;
@@ -547,12 +273,12 @@ void CanvasRenderingContext2D::setShadowOffsetY(double y)
modifiableState().setShadowOffsetY(y);
}
-double CanvasRenderingContext2D::shadowBlur() const
+double BaseRenderingContext2D::shadowBlur() const
{
return state().shadowBlur();
}
-void CanvasRenderingContext2D::setShadowBlur(double blur)
+void BaseRenderingContext2D::setShadowBlur(double blur)
{
if (!std::isfinite(blur) || blur < 0)
return;
@@ -561,22 +287,22 @@ void CanvasRenderingContext2D::setShadowBlur(double blur)
modifiableState().setShadowBlur(blur);
}
-String CanvasRenderingContext2D::shadowColor() const
+String BaseRenderingContext2D::shadowColor() const
{
return Color(state().shadowColor()).serialized();
}
-void CanvasRenderingContext2D::setShadowColor(const String& colorString)
+void BaseRenderingContext2D::setShadowColor(const String& colorString)
{
Color color;
- if (!parseColorOrCurrentColor(color, colorString, canvas()))
+ if (!parseColorOrCurrentColor(color, colorString))
return;
if (state().shadowColor() == color)
return;
modifiableState().setShadowColor(color.rgb());
}
-const Vector<double>& CanvasRenderingContext2D::getLineDash() const
+const Vector<double>& BaseRenderingContext2D::getLineDash() const
{
return state().lineDash();
}
@@ -590,31 +316,31 @@ static bool lineDashSequenceIsValid(const Vector<double>& dash)
return true;
}
-void CanvasRenderingContext2D::setLineDash(const Vector<double>& dash)
+void BaseRenderingContext2D::setLineDash(const Vector<double>& dash)
{
if (!lineDashSequenceIsValid(dash))
return;
modifiableState().setLineDash(dash);
}
-double CanvasRenderingContext2D::lineDashOffset() const
+double BaseRenderingContext2D::lineDashOffset() const
{
return state().lineDashOffset();
}
-void CanvasRenderingContext2D::setLineDashOffset(double offset)
+void BaseRenderingContext2D::setLineDashOffset(double offset)
{
if (!std::isfinite(offset) || state().lineDashOffset() == offset)
return;
modifiableState().setLineDashOffset(offset);
}
-double CanvasRenderingContext2D::globalAlpha() const
+double BaseRenderingContext2D::globalAlpha() const
{
return state().globalAlpha();
}
-void CanvasRenderingContext2D::setGlobalAlpha(double alpha)
+void BaseRenderingContext2D::setGlobalAlpha(double alpha)
{
if (!(alpha >= 0 && alpha <= 1))
return;
@@ -623,22 +349,12 @@ void CanvasRenderingContext2D::setGlobalAlpha(double alpha)
modifiableState().setGlobalAlpha(alpha);
}
-bool CanvasRenderingContext2D::shouldAntialias() const
-{
- return state().shouldAntialias();
-}
-
-void CanvasRenderingContext2D::setShouldAntialias(bool doAA)
-{
- modifiableState().setShouldAntialias(doAA);
-}
-
-String CanvasRenderingContext2D::globalCompositeOperation() const
+String BaseRenderingContext2D::globalCompositeOperation() const
{
return compositeOperatorName(compositeOperatorFromSkia(state().globalComposite()), blendModeFromSkia(state().globalComposite()));
}
-void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operation)
+void BaseRenderingContext2D::setGlobalCompositeOperation(const String& operation)
{
CompositeOperator op = CompositeSourceOver;
WebBlendMode blendMode = WebBlendModeNormal;
@@ -650,12 +366,12 @@ void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati
modifiableState().setGlobalComposite(xfermode);
}
-String CanvasRenderingContext2D::filter() const
+String BaseRenderingContext2D::filter() const
{
return state().unparsedFilter();
}
-void CanvasRenderingContext2D::setFilter(const String& filterString)
+void BaseRenderingContext2D::setFilter(const String& filterString)
{
if (filterString == state().unparsedFilter())
return;
@@ -669,19 +385,19 @@ void CanvasRenderingContext2D::setFilter(const String& filterString)
modifiableState().setFilter(filterValue.release());
}
-PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransform() const
+PassRefPtrWillBeRawPtr<SVGMatrixTearOff> BaseRenderingContext2D::currentTransform() const
{
return SVGMatrixTearOff::create(state().transform());
}
-void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMatrixTearOff> passMatrixTearOff)
+void BaseRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMatrixTearOff> passMatrixTearOff)
{
RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
const AffineTransform& transform = matrixTearOff->value();
setTransform(transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f());
}
-void CanvasRenderingContext2D::scale(double sx, double sy)
+void BaseRenderingContext2D::scale(double sx, double sy)
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -703,7 +419,7 @@ void CanvasRenderingContext2D::scale(double sx, double sy)
m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
}
-void CanvasRenderingContext2D::rotate(double angleInRadians)
+void BaseRenderingContext2D::rotate(double angleInRadians)
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -724,7 +440,7 @@ void CanvasRenderingContext2D::rotate(double angleInRadians)
m_path.transform(AffineTransform().rotateRadians(-angleInRadians));
}
-void CanvasRenderingContext2D::translate(double tx, double ty)
+void BaseRenderingContext2D::translate(double tx, double ty)
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -747,7 +463,7 @@ void CanvasRenderingContext2D::translate(double tx, double ty)
m_path.transform(AffineTransform().translate(-tx, -ty));
}
-void CanvasRenderingContext2D::transform(double m11, double m12, double m21, double m22, double dx, double dy)
+void BaseRenderingContext2D::transform(double m11, double m12, double m21, double m22, double dx, double dy)
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -769,7 +485,7 @@ void CanvasRenderingContext2D::transform(double m11, double m12, double m21, dou
m_path.transform(transform.inverse());
}
-void CanvasRenderingContext2D::resetTransform()
+void BaseRenderingContext2D::resetTransform()
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -784,7 +500,7 @@ void CanvasRenderingContext2D::resetTransform()
// resetTransform() resolves the non-invertible CTM state.
modifiableState().resetTransform();
- c->setMatrix(affineTransformToSkMatrix(canvas()->baseTransform()));
+ c->setMatrix(affineTransformToSkMatrix(baseTransform()));
if (invertibleCTM)
m_path.transform(ctm);
@@ -792,7 +508,7 @@ void CanvasRenderingContext2D::resetTransform()
// It means that resetTransform() restores m_path just before CTM became non-invertible.
}
-void CanvasRenderingContext2D::setTransform(double m11, double m12, double m21, double m22, double dx, double dy)
+void BaseRenderingContext2D::setTransform(double m11, double m12, double m21, double m22, double dx, double dy)
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -805,7 +521,7 @@ void CanvasRenderingContext2D::setTransform(double m11, double m12, double m21,
transform(m11, m12, m21, m22, dx, dy);
}
-void CanvasRenderingContext2D::beginPath()
+void BaseRenderingContext2D::beginPath()
{
m_path.clear();
}
@@ -831,7 +547,7 @@ static bool validateRectForCanvas(double& x, double& y, double& width, double& h
return true;
}
-static bool isFullCanvasCompositeMode(SkXfermode::Mode op)
+bool BaseRenderingContext2D::isFullCanvasCompositeMode(SkXfermode::Mode op)
{
// See 4.8.11.1.3 Compositing
// CompositeSourceAtop and CompositeDestinationOut are not listed here as the platforms already
@@ -839,90 +555,6 @@ static bool isFullCanvasCompositeMode(SkXfermode::Mode op)
return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode;
}
-template<typename DrawFunc>
-void CanvasRenderingContext2D::compositedDraw(const DrawFunc& drawFunc, SkCanvas* c, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
-{
- SkImageFilter* filter = state().getFilter(canvas(), accessFont(), canvas()->size(), this);
- ASSERT(isFullCanvasCompositeMode(state().globalComposite()) || filter);
- SkMatrix ctm = c->getTotalMatrix();
- c->resetMatrix();
- SkPaint compositePaint;
- compositePaint.setXfermodeMode(state().globalComposite());
- if (state().shouldDrawShadows()) {
- // unroll into two independently composited passes if drawing shadows
- SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, imageType);
- int saveCount = c->getSaveCount();
- if (filter) {
- SkPaint filterPaint;
- filterPaint.setImageFilter(filter);
- // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
- // does not affect transparent black regions.
- c->saveLayer(nullptr, &shadowPaint);
- c->saveLayer(nullptr, &filterPaint);
- SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, imageType);
- c->setMatrix(ctm);
- drawFunc(c, &foregroundPaint);
- } else {
- ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
- c->saveLayer(nullptr, &compositePaint);
- shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
- c->setMatrix(ctm);
- drawFunc(c, &shadowPaint);
- }
- c->restoreToCount(saveCount);
- }
-
- compositePaint.setImageFilter(filter);
- // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
- // does not affect transparent black regions *and* !isFullCanvasCompositeMode
- c->saveLayer(nullptr, &compositePaint);
- SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, imageType);
- foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
- c->setMatrix(ctm);
- drawFunc(c, &foregroundPaint);
- c->restore();
- c->setMatrix(ctm);
-}
-
-template<typename DrawFunc, typename ContainsFunc>
-bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc& drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
-{
- if (!state().isTransformInvertible())
- return false;
-
- SkIRect clipBounds;
- if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds))
- return false;
-
- // If gradient size is zero, then paint nothing.
- CanvasStyle* style = state().style(paintType);
- if (style) {
- CanvasGradient* gradient = style->canvasGradient();
- if (gradient && gradient->gradient()->isZeroSize())
- return false;
- }
-
- if (isFullCanvasCompositeMode(state().globalComposite()) || state().hasFilter(canvas(), accessFont(), canvas()->size(), this)) {
- compositedDraw(drawFunc, drawingCanvas(), paintType, imageType);
- didDraw(clipBounds);
- } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
- clearCanvas(); // takes care of checkOverdraw()
- const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, imageType);
- drawFunc(drawingCanvas(), paint);
- didDraw(clipBounds);
- } else {
- SkIRect dirtyRect;
- if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
- const SkPaint* paint = state().getPaint(paintType, DrawShadowAndForeground, imageType);
- if (paintType != CanvasRenderingContext2DState::StrokePaintType && drawCoversClipBounds(clipBounds))
- checkOverdraw(bounds, paint, imageType, ClipFill);
- drawFunc(drawingCanvas(), paint);
- didDraw(dirtyRect);
- }
- }
- return true;
-}
-
static bool isPathExpensive(const Path& path)
{
const SkPath& skPath = path.skPath();
@@ -935,7 +567,7 @@ static bool isPathExpensive(const Path& path)
return false;
}
-void CanvasRenderingContext2D::drawPathInternal(const Path& path, CanvasRenderingContext2DState::PaintType paintType, SkPath::FillType fillType)
+void BaseRenderingContext2D::drawPathInternal(const Path& path, CanvasRenderingContext2DState::PaintType paintType, SkPath::FillType fillType)
{
if (path.isEmpty())
return;
@@ -960,7 +592,7 @@ void CanvasRenderingContext2D::drawPathInternal(const Path& path, CanvasRenderin
return false;
}, bounds, paintType)) {
if (isPathExpensive(path)) {
- ImageBuffer* buffer = canvas()->buffer();
+ ImageBuffer* buffer = imageBuffer();
if (buffer)
buffer->setHasExpensiveOp();
}
@@ -978,27 +610,27 @@ static SkPath::FillType parseWinding(const String& windingRuleString)
return SkPath::kEvenOdd_FillType;
}
-void CanvasRenderingContext2D::fill(const String& windingRuleString)
+void BaseRenderingContext2D::fill(const String& windingRuleString)
{
drawPathInternal(m_path, CanvasRenderingContext2DState::FillPaintType, parseWinding(windingRuleString));
}
-void CanvasRenderingContext2D::fill(Path2D* domPath, const String& windingRuleString)
+void BaseRenderingContext2D::fill(Path2D* domPath, const String& windingRuleString)
{
drawPathInternal(domPath->path(), CanvasRenderingContext2DState::FillPaintType, parseWinding(windingRuleString));
}
-void CanvasRenderingContext2D::stroke()
+void BaseRenderingContext2D::stroke()
{
drawPathInternal(m_path, CanvasRenderingContext2DState::StrokePaintType);
}
-void CanvasRenderingContext2D::stroke(Path2D* domPath)
+void BaseRenderingContext2D::stroke(Path2D* domPath)
{
drawPathInternal(domPath->path(), CanvasRenderingContext2DState::StrokePaintType);
}
-void CanvasRenderingContext2D::fillRect(double x, double y, double width, double height)
+void BaseRenderingContext2D::fillRect(double x, double y, double width, double height)
{
if (!validateRectForCanvas(x, y, width, height))
return;
@@ -1033,7 +665,7 @@ static void strokeRectOnCanvas(const FloatRect& rect, SkCanvas* canvas, const Sk
canvas->drawRect(rect, *paint);
}
-void CanvasRenderingContext2D::strokeRect(double x, double y, double width, double height)
+void BaseRenderingContext2D::strokeRect(double x, double y, double width, double height)
{
if (!validateRectForCanvas(x, y, width, height))
return;
@@ -1055,7 +687,7 @@ void CanvasRenderingContext2D::strokeRect(double x, double y, double width, doub
}, bounds, CanvasRenderingContext2DState::StrokePaintType);
}
-void CanvasRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
+void BaseRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
{
SkCanvas* c = drawingCanvas();
if (!c) {
@@ -1069,32 +701,32 @@ void CanvasRenderingContext2D::clipInternal(const Path& path, const String& wind
skPath.setFillType(parseWinding(windingRuleString));
modifiableState().clipPath(skPath, m_clipAntialiasing);
c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAliased);
- if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive && !skPath.isRect(0) && canvas()->hasImageBuffer()) {
- canvas()->buffer()->setHasExpensiveOp();
+ if (ExpensiveCanvasHeuristicParameters::ComplexClipsAreExpensive && !skPath.isRect(0) && hasImageBuffer()) {
+ imageBuffer()->setHasExpensiveOp();
}
}
-void CanvasRenderingContext2D::clip(const String& windingRuleString)
+void BaseRenderingContext2D::clip(const String& windingRuleString)
{
clipInternal(m_path, windingRuleString);
}
-void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleString)
+void BaseRenderingContext2D::clip(Path2D* domPath, const String& windingRuleString)
{
clipInternal(domPath->path(), windingRuleString);
}
-bool CanvasRenderingContext2D::isPointInPath(const double x, const double y, const String& windingRuleString)
+bool BaseRenderingContext2D::isPointInPath(const double x, const double y, const String& windingRuleString)
{
return isPointInPathInternal(m_path, x, y, windingRuleString);
}
-bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const double x, const double y, const String& windingRuleString)
+bool BaseRenderingContext2D::isPointInPath(Path2D* domPath, const double x, const double y, const String& windingRuleString)
{
return isPointInPathInternal(domPath->path(), x, y, windingRuleString);
}
-bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const double x, const double y, const String& windingRuleString)
+bool BaseRenderingContext2D::isPointInPathInternal(const Path& path, const double x, const double y, const String& windingRuleString)
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -1111,17 +743,17 @@ bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const dou
return path.contains(transformedPoint, SkFillTypeToWindRule(parseWinding(windingRuleString)));
}
-bool CanvasRenderingContext2D::isPointInStroke(const double x, const double y)
+bool BaseRenderingContext2D::isPointInStroke(const double x, const double y)
{
return isPointInStrokeInternal(m_path, x, y);
}
-bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const double x, const double y)
+bool BaseRenderingContext2D::isPointInStroke(Path2D* domPath, const double x, const double y)
{
return isPointInStrokeInternal(domPath->path(), x, y);
}
-bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, const double x, const double y)
+bool BaseRenderingContext2D::isPointInStrokeInternal(const Path& path, const double x, const double y)
{
SkCanvas* c = drawingCanvas();
if (!c)
@@ -1146,46 +778,7 @@ bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, const d
return path.strokeContains(transformedPoint, strokeData);
}
-void CanvasRenderingContext2D::scrollPathIntoView()
-{
- scrollPathIntoViewInternal(m_path);
-}
-
-void CanvasRenderingContext2D::scrollPathIntoView(Path2D* path2d)
-{
- scrollPathIntoViewInternal(path2d->path());
-}
-
-void CanvasRenderingContext2D::scrollPathIntoViewInternal(const Path& path)
-{
- if (!state().isTransformInvertible() || path.isEmpty())
- return;
-
- canvas()->document().updateLayoutIgnorePendingStylesheets();
-
- LayoutObject* renderer = canvas()->layoutObject();
- LayoutBox* layoutBox = canvas()->layoutBox();
- if (!renderer || !layoutBox)
- return;
-
- // Apply transformation and get the bounding rect
- Path transformedPath = path;
- transformedPath.transform(state().transform());
- FloatRect boundingRect = transformedPath.boundingRect();
-
- // Offset by the canvas rect
- LayoutRect pathRect(boundingRect);
- IntRect canvasRect = layoutBox->absoluteContentBox();
- pathRect.moveBy(canvasRect.location());
-
- renderer->scrollRectToVisible(
- pathRect, ScrollAlignment::alignCenterAlways, ScrollAlignment::alignTopAlways);
-
- // TODO: should implement "inform the user" that the caret and/or
- // selection the specified rectangle of the canvas. See http://crbug.com/357987
-}
-
-void CanvasRenderingContext2D::clearRect(double x, double y, double width, double height)
+void BaseRenderingContext2D::clearRect(double x, double y, double width, double height)
{
if (!validateRectForCanvas(x, y, width, height))
return;
@@ -1217,10 +810,6 @@ void CanvasRenderingContext2D::clearRect(double x, double y, double width, doubl
didDraw(dirtyRect);
}
}
-
- if (m_hitRegionManager) {
- m_hitRegionManager->removeHitRegionsInRect(rect, state().transform());
- }
}
static inline FloatRect normalizeRect(const FloatRect& rect)
@@ -1264,7 +853,7 @@ static inline CanvasImageSource* toImageSourceInternal(const CanvasImageSourceUn
return nullptr;
}
-void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSource, double x, double y, ExceptionState& exceptionState)
+void BaseRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSource, double x, double y, ExceptionState& exceptionState)
{
CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource);
FloatSize sourceRectSize = imageSourceInternal->elementSize();
@@ -1272,7 +861,7 @@ void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour
drawImage(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, destRectSize.width(), destRectSize.height(), exceptionState);
}
-void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSource,
+void BaseRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSource,
double x, double y, double width, double height, ExceptionState& exceptionState)
{
CanvasImageSource* imageSourceInternal = toImageSourceInternal(imageSource);
@@ -1280,7 +869,7 @@ void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour
drawImage(imageSourceInternal, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, width, height, exceptionState);
}
-void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSource,
+void BaseRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSource,
double sx, double sy, double sw, double sh,
double dx, double dy, double dw, double dh, ExceptionState& exceptionState)
{
@@ -1288,9 +877,9 @@ void CanvasRenderingContext2D::drawImage(const CanvasImageSourceUnion& imageSour
drawImage(imageSourceInternal, sx, sy, sw, sh, dx, dy, dw, dh, exceptionState);
}
-bool CanvasRenderingContext2D::shouldDrawImageAntialiased(const FloatRect& destRect) const
+bool BaseRenderingContext2D::shouldDrawImageAntialiased(const FloatRect& destRect) const
{
- if (!shouldAntialias())
+ if (!state().shouldAntialias())
return false;
SkCanvas* c = drawingCanvas();
ASSERT(c);
@@ -1315,7 +904,7 @@ bool CanvasRenderingContext2D::shouldDrawImageAntialiased(const FloatRect& destR
return destRect.width() * fabs(widthExpansion) < 1 || destRect.height() * fabs(heightExpansion) < 1;
}
-void CanvasRenderingContext2D::drawImageInternal(SkCanvas* c, CanvasImageSource* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const SkPaint* paint)
+void BaseRenderingContext2D::drawImageInternal(SkCanvas* c, CanvasImageSource* imageSource, Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const SkPaint* paint)
{
int initialSaveCount = c->getSaveCount();
SkPaint imagePaint = *paint;
@@ -1374,7 +963,7 @@ bool shouldDisableDeferral(CanvasImageSource* imageSource, DisableDeferralReason
return false;
}
-void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
+void BaseRenderingContext2D::drawImage(CanvasImageSource* imageSource,
double sx, double sy, double sw, double sh,
double dx, double dy, double dw, double dh, ExceptionState& exceptionState)
{
@@ -1384,7 +973,7 @@ void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
RefPtr<Image> image;
SourceImageStatus sourceImageStatus = InvalidSourceImageStatus;
if (!imageSource->isVideoElement()) {
- AccelerationHint hint = canvas()->buffer()->isAccelerated() ? PreferAcceleration : PreferNoAcceleration;
+ AccelerationHint hint = imageBuffer()->isAccelerated() ? PreferAcceleration : PreferNoAcceleration;
image = imageSource->getSourceImageForCanvas(&sourceImageStatus, hint, SnapshotReasonDrawImage);
if (sourceImageStatus == UndecodableSourceImageStatus)
exceptionState.throwDOMException(InvalidStateError, "The HTMLImageElement provided is in the 'broken' state.");
@@ -1412,7 +1001,7 @@ void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
DisableDeferralReason reason = DisableDeferralReasonUnknown;
if (shouldDisableDeferral(imageSource, &reason) || image->isTextureBacked())
- canvas()->disableDeferral(reason);
+ disableDeferral(reason);
validateStateStack();
@@ -1434,11 +1023,11 @@ void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && imageSource->isSVGSource())
isExpensive = true;
- if (imageSource->elementSize().width() * imageSource->elementSize().height() > canvas()->width() * canvas()->height() * ExpensiveCanvasHeuristicParameters::ExpensiveImageSizeRatio)
+ if (imageSource->elementSize().width() * imageSource->elementSize().height() > width() * height() * ExpensiveCanvasHeuristicParameters::ExpensiveImageSizeRatio)
isExpensive = true;
if (isExpensive) {
- ImageBuffer* buffer = canvas()->buffer();
+ ImageBuffer* buffer = imageBuffer();
if (buffer)
buffer->setHasExpensiveOp();
}
@@ -1446,36 +1035,36 @@ void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
if (imageSource->isCanvasElement() && static_cast<HTMLCanvasElement*>(imageSource)->is3D()) {
// WebGL to 2D canvas: must flush graphics context to prevent a race
// FIXME: crbug.com/516331 Fix the underlying synchronization issue so this flush can be eliminated.
- canvas()->buffer()->flushGpu(FlushReasonDrawImageOfWebGL);
+ imageBuffer()->flushGpu(FlushReasonDrawImageOfWebGL);
}
- if (canvas()->originClean() && wouldTaintOrigin(imageSource))
- canvas()->setOriginTainted();
+ if (originClean() && wouldTaintOrigin(imageSource))
+ setOriginTainted();
}
-void CanvasRenderingContext2D::clearCanvas()
+void BaseRenderingContext2D::clearCanvas()
{
- FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
+ FloatRect canvasRect(0, 0, width(), height());
checkOverdraw(canvasRect, 0, CanvasRenderingContext2DState::NoImage, ClipFill);
SkCanvas* c = drawingCanvas();
if (c)
- c->clear(m_hasAlpha ? SK_ColorTRANSPARENT : SK_ColorBLACK);
+ c->clear(hasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK);
}
-bool CanvasRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect, const SkIRect& transformedRect) const
+bool BaseRenderingContext2D::rectContainsTransformedRect(const FloatRect& rect, const SkIRect& transformedRect) const
{
FloatQuad quad(rect);
FloatQuad transformedQuad(FloatRect(transformedRect.x(), transformedRect.y(), transformedRect.width(), transformedRect.height()));
return state().transform().mapQuad(quad).containsQuad(transformedQuad);
}
-CanvasGradient* CanvasRenderingContext2D::createLinearGradient(double x0, double y0, double x1, double y1)
+CanvasGradient* BaseRenderingContext2D::createLinearGradient(double x0, double y0, double x1, double y1)
{
CanvasGradient* gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
return gradient;
}
-CanvasGradient* CanvasRenderingContext2D::createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1, ExceptionState& exceptionState)
+CanvasGradient* BaseRenderingContext2D::createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1, ExceptionState& exceptionState)
{
if (r0 < 0 || r1 < 0) {
exceptionState.throwDOMException(IndexSizeError, String::format("The %s provided is less than 0.", r0 < 0 ? "r0" : "r1"));
@@ -1486,7 +1075,7 @@ CanvasGradient* CanvasRenderingContext2D::createRadialGradient(double x0, double
return gradient;
}
-CanvasPattern* CanvasRenderingContext2D::createPattern(const CanvasImageSourceUnion& imageSource, const String& repetitionType, ExceptionState& exceptionState)
+CanvasPattern* BaseRenderingContext2D::createPattern(const CanvasImageSourceUnion& imageSource, const String& repetitionType, ExceptionState& exceptionState)
{
Pattern::RepeatMode repeatMode = CanvasPattern::parseRepetitionType(repetitionType, exceptionState);
if (exceptionState.hadException())
@@ -1521,7 +1110,7 @@ CanvasPattern* CanvasRenderingContext2D::createPattern(const CanvasImageSourceUn
return CanvasPattern::create(imageForRendering.release(), repeatMode, originClean);
}
-bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, SkIRect* dirtyRect)
+bool BaseRenderingContext2D::computeDirtyRect(const FloatRect& localRect, SkIRect* dirtyRect)
{
SkIRect clipBounds;
if (!drawingCanvas()->getClipDeviceBounds(&clipBounds))
@@ -1529,7 +1118,7 @@ bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, SkIR
return computeDirtyRect(localRect, clipBounds, dirtyRect);
}
-bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, const SkIRect& transformedClipBounds, SkIRect* dirtyRect)
+bool BaseRenderingContext2D::computeDirtyRect(const FloatRect& localRect, const SkIRect& transformedClipBounds, SkIRect* dirtyRect)
{
FloatRect canvasRect = state().transform().mapRect(localRect);
@@ -1551,33 +1140,12 @@ bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, cons
return true;
}
-void CanvasRenderingContext2D::didDraw(const SkIRect& dirtyRect)
-{
- if (dirtyRect.isEmpty())
- return;
-
- if (ExpensiveCanvasHeuristicParameters::BlurredShadowsAreExpensive && state().shouldDrawShadows() && state().shadowBlur() > 0) {
- ImageBuffer* buffer = canvas()->buffer();
- if (buffer)
- buffer->setHasExpensiveOp();
- }
-
- canvas()->didDraw(SkRect::Make(dirtyRect));
-}
-
-SkCanvas* CanvasRenderingContext2D::drawingCanvas() const
-{
- if (isContextLost())
- return nullptr;
- return canvas()->drawingCanvas();
-}
-
-ImageData* CanvasRenderingContext2D::createImageData(ImageData* imageData) const
+ImageData* BaseRenderingContext2D::createImageData(ImageData* imageData) const
{
return ImageData::create(imageData->size());
}
-ImageData* CanvasRenderingContext2D::createImageData(double sw, double sh, ExceptionState& exceptionState) const
+ImageData* BaseRenderingContext2D::createImageData(double sw, double sh, ExceptionState& exceptionState) const
{
if (!sw || !sh) {
exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));
@@ -1597,9 +1165,9 @@ ImageData* CanvasRenderingContext2D::createImageData(double sw, double sh, Excep
return ImageData::create(size);
}
-ImageData* CanvasRenderingContext2D::getImageData(double sx, double sy, double sw, double sh, ExceptionState& exceptionState) const
+ImageData* BaseRenderingContext2D::getImageData(double sx, double sy, double sw, double sh, ExceptionState& exceptionState) const
{
- if (!canvas()->originClean())
+ if (!originClean())
exceptionState.throwSecurityError("The canvas has been tainted by cross-origin data.");
else if (!sw || !sh)
exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));
@@ -1625,7 +1193,7 @@ ImageData* CanvasRenderingContext2D::getImageData(double sx, double sy, double s
return nullptr;
IntRect imageDataRect = enclosingIntRect(logicalRect);
- ImageBuffer* buffer = canvas()->buffer();
+ ImageBuffer* buffer = imageBuffer();
if (!buffer || isContextLost())
return ImageData::create(imageDataRect.size());
@@ -1639,18 +1207,18 @@ ImageData* CanvasRenderingContext2D::getImageData(double sx, double sy, double s
DOMUint8ClampedArray::create(arrayBuffer, 0, arrayBuffer->byteLength()));
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, double dx, double dy, ExceptionState& exceptionState)
+void BaseRenderingContext2D::putImageData(ImageData* data, double dx, double dy, ExceptionState& exceptionState)
{
putImageData(data, dx, dy, 0, 0, data->width(), data->height(), exceptionState);
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight, ExceptionState& exceptionState)
+void BaseRenderingContext2D::putImageData(ImageData* data, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight, ExceptionState& exceptionState)
{
if (data->data()->bufferBase()->isNeutered()) {
exceptionState.throwDOMException(InvalidStateError, "The source data has been neutered.");
return;
}
- ImageBuffer* buffer = canvas()->buffer();
+ ImageBuffer* buffer = imageBuffer();
if (!buffer)
return;
@@ -1682,383 +1250,7 @@ void CanvasRenderingContext2D::putImageData(ImageData* data, double dx, double d
didDraw(destRect);
}
-String CanvasRenderingContext2D::font() const
-{
- if (!state().hasRealizedFont())
- return defaultFont;
-
- canvas()->document().canvasFontCache()->willUseCurrentFont();
- StringBuilder serializedFont;
- const FontDescription& fontDescription = state().font().fontDescription();
-
- if (fontDescription.style() == FontStyleItalic)
- serializedFont.appendLiteral("italic ");
- if (fontDescription.weight() == FontWeightBold)
- serializedFont.appendLiteral("bold ");
- if (fontDescription.variant() == FontVariantSmallCaps)
- serializedFont.appendLiteral("small-caps ");
-
- serializedFont.appendNumber(fontDescription.computedPixelSize());
- serializedFont.appendLiteral("px");
-
- const FontFamily& firstFontFamily = fontDescription.family();
- for (const FontFamily* fontFamily = &firstFontFamily; fontFamily; fontFamily = fontFamily->next()) {
- if (fontFamily != &firstFontFamily)
- serializedFont.append(',');
-
- // FIXME: We should append family directly to serializedFont rather than building a temporary string.
- String family = fontFamily->family();
- if (family.startsWith("-webkit-"))
- family = family.substring(8);
- if (family.contains(' '))
- family = "\"" + family + "\"";
-
- serializedFont.append(' ');
- serializedFont.append(family);
- }
-
- return serializedFont.toString();
-}
-
-void CanvasRenderingContext2D::setFont(const String& newFont)
-{
- // The style resolution required for rendering text is not available in frame-less documents.
- if (!canvas()->document().frame())
- return;
-
- canvas()->document().updateLayoutTreeForNode(canvas());
-
- // The following early exit is dependent on the cache not being empty
- // because an empty cache may indicate that a style change has occured
- // which would require that the font be re-resolved. This check has to
- // come after the layout tree update to flush pending style changes.
- if (newFont == state().unparsedFont() && state().hasRealizedFont() && m_fontsResolvedUsingCurrentStyle.size() > 0)
- return;
-
- CanvasFontCache* canvasFontCache = canvas()->document().canvasFontCache();
-
- // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
- // relative to the canvas.
- RefPtr<ComputedStyle> fontStyle;
- const ComputedStyle* computedStyle = canvas()->ensureComputedStyle();
- if (computedStyle) {
- HashMap<String, Font>::iterator i = m_fontsResolvedUsingCurrentStyle.find(newFont);
- if (i != m_fontsResolvedUsingCurrentStyle.end()) {
- ASSERT(m_fontLRUList.contains(newFont));
- m_fontLRUList.remove(newFont);
- m_fontLRUList.add(newFont);
- modifiableState().setFont(i->value, canvas()->document().styleEngine().fontSelector());
- } else {
- MutableStylePropertySet* parsedStyle = canvasFontCache->parseFont(newFont);
- if (!parsedStyle)
- return;
- fontStyle = ComputedStyle::create();
- FontDescription elementFontDescription(computedStyle->fontDescription());
- // Reset the computed size to avoid inheriting the zoom factor from the <canvas> element.
- elementFontDescription.setComputedSize(elementFontDescription.specifiedSize());
- fontStyle->setFontDescription(elementFontDescription);
- fontStyle->font().update(fontStyle->font().fontSelector());
- canvas()->document().ensureStyleResolver().computeFont(fontStyle.get(), *parsedStyle);
- m_fontsResolvedUsingCurrentStyle.add(newFont, fontStyle->font());
- ASSERT(!m_fontLRUList.contains(newFont));
- m_fontLRUList.add(newFont);
- pruneLocalFontCache(canvasFontCache->hardMaxFonts()); // hard limit
- schedulePruneLocalFontCacheIfNeeded(); // soft limit
- modifiableState().setFont(fontStyle->font(), canvas()->document().styleEngine().fontSelector());
- }
- } else {
- Font resolvedFont;
- if (!canvasFontCache->getFontUsingDefaultStyle(newFont, resolvedFont))
- return;
- modifiableState().setFont(resolvedFont, canvas()->document().styleEngine().fontSelector());
- }
-
- // The parse succeeded.
- String newFontSafeCopy(newFont); // Create a string copy since newFont can be deleted inside realizeSaves.
- modifiableState().setUnparsedFont(newFontSafeCopy);
-}
-
-void CanvasRenderingContext2D::schedulePruneLocalFontCacheIfNeeded()
-{
- if (m_pruneLocalFontCacheScheduled)
- return;
- m_pruneLocalFontCacheScheduled = true;
- Platform::current()->currentThread()->addTaskObserver(this);
-}
-
-void CanvasRenderingContext2D::didProcessTask()
-{
- // The rendering surface needs to be prepared now because it will be too late
- // to create a layer once we are in the paint invalidation phase.
- canvas()->prepareSurfaceForPaintingIfNeeded();
-
- pruneLocalFontCache(canvas()->document().canvasFontCache()->maxFonts());
- m_pruneLocalFontCacheScheduled = false;
- Platform::current()->currentThread()->removeTaskObserver(this);
-}
-
-void CanvasRenderingContext2D::pruneLocalFontCache(size_t targetSize)
-{
- if (targetSize == 0) {
- // Short cut: LRU does not matter when evicting everything
- m_fontLRUList.clear();
- m_fontsResolvedUsingCurrentStyle.clear();
- return;
- }
- while (m_fontLRUList.size() > targetSize) {
- m_fontsResolvedUsingCurrentStyle.remove(m_fontLRUList.first());
- m_fontLRUList.removeFirst();
- }
-}
-
-void CanvasRenderingContext2D::styleDidChange(const ComputedStyle* oldStyle, const ComputedStyle& newStyle)
-{
- if (oldStyle && oldStyle->font() == newStyle.font())
- return;
- pruneLocalFontCache(0);
-}
-
-void CanvasRenderingContext2D::filterNeedsInvalidation()
-{
- state().clearResolvedFilter();
-}
-
-String CanvasRenderingContext2D::textAlign() const
-{
- return textAlignName(state().textAlign());
-}
-
-void CanvasRenderingContext2D::setTextAlign(const String& s)
-{
- TextAlign align;
- if (!parseTextAlign(s, align))
- return;
- if (state().textAlign() == align)
- return;
- modifiableState().setTextAlign(align);
-}
-
-String CanvasRenderingContext2D::textBaseline() const
-{
- return textBaselineName(state().textBaseline());
-}
-
-void CanvasRenderingContext2D::setTextBaseline(const String& s)
-{
- TextBaseline baseline;
- if (!parseTextBaseline(s, baseline))
- return;
- if (state().textBaseline() == baseline)
- return;
- modifiableState().setTextBaseline(baseline);
-}
-
-static inline TextDirection toTextDirection(CanvasRenderingContext2DState::Direction direction, HTMLCanvasElement* canvas, const ComputedStyle** computedStyle = 0)
-{
- const ComputedStyle* style = (computedStyle || direction == CanvasRenderingContext2DState::DirectionInherit) ? canvas->ensureComputedStyle() : nullptr;
- if (computedStyle)
- *computedStyle = style;
- switch (direction) {
- case CanvasRenderingContext2DState::DirectionInherit:
- return style ? style->direction() : LTR;
- case CanvasRenderingContext2DState::DirectionRTL:
- return RTL;
- case CanvasRenderingContext2DState::DirectionLTR:
- return LTR;
- }
- ASSERT_NOT_REACHED();
- return LTR;
-}
-
-String CanvasRenderingContext2D::direction() const
-{
- if (state().direction() == CanvasRenderingContext2DState::DirectionInherit)
- canvas()->document().updateLayoutTreeForNode(canvas());
- return toTextDirection(state().direction(), canvas()) == RTL ? rtl : ltr;
-}
-
-void CanvasRenderingContext2D::setDirection(const String& directionString)
-{
- CanvasRenderingContext2DState::Direction direction;
- if (directionString == inherit)
- direction = CanvasRenderingContext2DState::DirectionInherit;
- else if (directionString == rtl)
- direction = CanvasRenderingContext2DState::DirectionRTL;
- else if (directionString == ltr)
- direction = CanvasRenderingContext2DState::DirectionLTR;
- else
- return;
-
- if (state().direction() == direction)
- return;
-
- modifiableState().setDirection(direction);
-}
-
-void CanvasRenderingContext2D::fillText(const String& text, double x, double y)
-{
- drawTextInternal(text, x, y, CanvasRenderingContext2DState::FillPaintType);
-}
-
-void CanvasRenderingContext2D::fillText(const String& text, double x, double y, double maxWidth)
-{
- drawTextInternal(text, x, y, CanvasRenderingContext2DState::FillPaintType, &maxWidth);
-}
-
-void CanvasRenderingContext2D::strokeText(const String& text, double x, double y)
-{
- drawTextInternal(text, x, y, CanvasRenderingContext2DState::StrokePaintType);
-}
-
-void CanvasRenderingContext2D::strokeText(const String& text, double x, double y, double maxWidth)
-{
- drawTextInternal(text, x, y, CanvasRenderingContext2DState::StrokePaintType, &maxWidth);
-}
-
-TextMetrics* CanvasRenderingContext2D::measureText(const String& text)
-{
- TextMetrics* metrics = TextMetrics::create();
-
- // The style resolution required for rendering text is not available in frame-less documents.
- if (!canvas()->document().frame())
- return metrics;
-
- canvas()->document().updateLayoutTreeForNode(canvas());
- const Font& font = accessFont();
-
- TextDirection direction;
- if (state().direction() == CanvasRenderingContext2DState::DirectionInherit)
- direction = determineDirectionality(text);
- else
- direction = toTextDirection(state().direction(), canvas());
- TextRun textRun(text, 0, 0, TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, direction, false);
- textRun.setNormalizeSpace(true);
- FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font.fontDescription().computedSize(), 0, -1, true);
-
- // x direction
- metrics->setWidth(font.width(textRun));
- metrics->setActualBoundingBoxLeft(-textBounds.x());
- metrics->setActualBoundingBoxRight(textBounds.maxX());
-
- // y direction
- const FontMetrics& fontMetrics = font.fontMetrics();
- const float ascent = fontMetrics.floatAscent();
- const float descent = fontMetrics.floatDescent();
- const float baselineY = getFontBaseline(fontMetrics);
-
- metrics->setFontBoundingBoxAscent(ascent - baselineY);
- metrics->setFontBoundingBoxDescent(descent + baselineY);
- metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY);
- metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY);
-
- // Note : top/bottom and ascend/descend are currently the same, so there's no difference
- // between the EM box's top and bottom and the font's ascend and descend
- metrics->setEmHeightAscent(0);
- metrics->setEmHeightDescent(0);
-
- metrics->setHangingBaseline(-0.8f * ascent + baselineY);
- metrics->setAlphabeticBaseline(baselineY);
- metrics->setIdeographicBaseline(descent + baselineY);
- return metrics;
-}
-
-void CanvasRenderingContext2D::drawTextInternal(const String& text, double x, double y, CanvasRenderingContext2DState::PaintType paintType, double* maxWidth)
-{
- // The style resolution required for rendering text is not available in frame-less documents.
- if (!canvas()->document().frame())
- return;
-
- // accessFont needs the style to be up to date, but updating style can cause script to run,
- // (e.g. due to autofocus) which can free the canvas (set size to 0, for example), so update
- // style before grabbing the drawingCanvas.
- canvas()->document().updateLayoutTreeForNode(canvas());
-
- SkCanvas* c = drawingCanvas();
- if (!c)
- return;
-
- if (!std::isfinite(x) || !std::isfinite(y))
- return;
- if (maxWidth && (!std::isfinite(*maxWidth) || *maxWidth <= 0))
- return;
-
- // Currently, SkPictureImageFilter does not support subpixel text anti-aliasing, which
- // is expected when !m_hasAlpha, so we need to fall out of display list mode when
- // drawing text to an opaque canvas
- // crbug.com/583809
- if (!m_hasAlpha && !isAccelerated())
- canvas()->disableDeferral(DisableDeferralReasonSubPixelTextAntiAliasingSupport);
-
- const Font& font = accessFont();
- if (!font.primaryFont())
- return;
-
- const FontMetrics& fontMetrics = font.fontMetrics();
-
- // FIXME: Need to turn off font smoothing.
-
- const ComputedStyle* computedStyle = 0;
- TextDirection direction = toTextDirection(state().direction(), canvas(), &computedStyle);
- bool isRTL = direction == RTL;
- bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : false;
-
- TextRun textRun(text, 0, 0, TextRun::AllowTrailingExpansion, direction, override);
- textRun.setNormalizeSpace(true);
- // Draw the item text at the correct point.
- FloatPoint location(x, y + getFontBaseline(fontMetrics));
- double fontWidth = font.width(textRun);
-
- bool useMaxWidth = (maxWidth && *maxWidth < fontWidth);
- double width = useMaxWidth ? *maxWidth : fontWidth;
-
- TextAlign align = state().textAlign();
- if (align == StartTextAlign)
- align = isRTL ? RightTextAlign : LeftTextAlign;
- else if (align == EndTextAlign)
- align = isRTL ? LeftTextAlign : RightTextAlign;
-
- switch (align) {
- case CenterTextAlign:
- location.setX(location.x() - width / 2);
- break;
- case RightTextAlign:
- location.setX(location.x() - width);
- break;
- default:
- break;
- }
-
- // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text.
- TextRunPaintInfo textRunPaintInfo(textRun);
- textRunPaintInfo.bounds = FloatRect(location.x() - fontMetrics.height() / 2,
- location.y() - fontMetrics.ascent() - fontMetrics.lineGap(),
- width + fontMetrics.height(),
- fontMetrics.lineSpacing());
- if (paintType == CanvasRenderingContext2DState::StrokePaintType)
- inflateStrokeRect(textRunPaintInfo.bounds);
-
- CanvasRenderingContext2DAutoRestoreSkCanvas stateRestorer(this);
- if (useMaxWidth) {
- drawingCanvas()->save();
- drawingCanvas()->translate(location.x(), location.y());
- // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
- drawingCanvas()->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1);
- location = FloatPoint();
- }
-
- draw(
- [&font, this, &textRunPaintInfo, &location](SkCanvas* c, const SkPaint* paint) // draw lambda
- {
- font.drawBidiText(c, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady, cDeviceScaleFactor, *paint);
- },
- [](const SkIRect& rect) // overdraw test lambda
- {
- return false;
- },
- textRunPaintInfo.bounds, paintType);
-}
-
-void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
+void BaseRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
{
// Fast approximation of the stroke's bounding rect.
// This yields a slightly oversized rect but is very fast
@@ -2073,61 +1265,12 @@ void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
rect.inflate(delta);
}
-const Font& CanvasRenderingContext2D::accessFont()
-{
- if (!state().hasRealizedFont())
- setFont(state().unparsedFont());
- canvas()->document().canvasFontCache()->willUseCurrentFont();
- return state().font();
-}
-
-int CanvasRenderingContext2D::getFontBaseline(const FontMetrics& fontMetrics) const
-{
- switch (state().textBaseline()) {
- case TopTextBaseline:
- return fontMetrics.ascent();
- case HangingTextBaseline:
- // According to http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
- // "FOP (Formatting Objects Processor) puts the hanging baseline at 80% of the ascender height"
- return (fontMetrics.ascent() * 4) / 5;
- case BottomTextBaseline:
- case IdeographicTextBaseline:
- return -fontMetrics.descent();
- case MiddleTextBaseline:
- return -fontMetrics.descent() + fontMetrics.height() / 2;
- case AlphabeticTextBaseline:
- default:
- // Do nothing.
- break;
- }
- return 0;
-}
-
-void CanvasRenderingContext2D::setIsHidden(bool hidden)
-{
- if (canvas()->hasImageBuffer())
- canvas()->buffer()->setIsHidden(hidden);
- if (hidden) {
- pruneLocalFontCache(0);
- }
-}
-
-bool CanvasRenderingContext2D::isTransformInvertible() const
-{
- return state().isTransformInvertible();
-}
-
-WebLayer* CanvasRenderingContext2D::platformLayer() const
-{
- return canvas()->buffer() ? canvas()->buffer()->platformLayer() : 0;
-}
-
-bool CanvasRenderingContext2D::imageSmoothingEnabled() const
+bool BaseRenderingContext2D::imageSmoothingEnabled() const
{
return state().imageSmoothingEnabled();
}
-void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
+void BaseRenderingContext2D::setImageSmoothingEnabled(bool enabled)
{
if (enabled == state().imageSmoothingEnabled())
return;
@@ -2135,12 +1278,12 @@ void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
modifiableState().setImageSmoothingEnabled(enabled);
}
-String CanvasRenderingContext2D::imageSmoothingQuality() const
+String BaseRenderingContext2D::imageSmoothingQuality() const
{
return state().imageSmoothingQuality();
}
-void CanvasRenderingContext2D::setImageSmoothingQuality(const String& quality)
+void BaseRenderingContext2D::setImageSmoothingQuality(const String& quality)
{
if (quality == state().imageSmoothingQuality())
return;
@@ -2148,169 +1291,10 @@ void CanvasRenderingContext2D::setImageSmoothingQuality(const String& quality)
modifiableState().setImageSmoothingQuality(quality);
}
-void CanvasRenderingContext2D::getContextAttributes(Canvas2DContextAttributes& attrs) const
-{
- attrs.setAlpha(m_hasAlpha);
-}
-
-void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element)
-{
- drawFocusIfNeededInternal(m_path, element);
-}
-
-void CanvasRenderingContext2D::drawFocusIfNeeded(Path2D* path2d, Element* element)
-{
- drawFocusIfNeededInternal(path2d->path(), element);
-}
-
-void CanvasRenderingContext2D::drawFocusIfNeededInternal(const Path& path, Element* element)
-{
- if (!focusRingCallIsValid(path, element))
- return;
-
- // Note: we need to check document->focusedElement() rather than just calling
- // element->focused(), because element->focused() isn't updated until after
- // focus events fire.
- if (element->document().focusedElement() == element) {
- scrollPathIntoViewInternal(path);
- drawFocusRing(path);
- }
-
- // Update its accessible bounds whether it's focused or not.
- updateElementAccessibility(path, element);
-}
-
-bool CanvasRenderingContext2D::focusRingCallIsValid(const Path& path, Element* element)
-{
- ASSERT(element);
- if (!state().isTransformInvertible())
- return false;
- if (path.isEmpty())
- return false;
- if (!element->isDescendantOf(canvas()))
- return false;
-
- return true;
-}
-
-void CanvasRenderingContext2D::drawFocusRing(const Path& path)
-{
- if (!drawingCanvas())
- return;
-
- SkColor color = LayoutTheme::theme().focusRingColor().rgb();
- const int focusRingWidth = 5;
-
- drawPlatformFocusRing(path.skPath(), drawingCanvas(), color, focusRingWidth);
-
- // We need to add focusRingWidth to dirtyRect.
- StrokeData strokeData;
- strokeData.setThickness(focusRingWidth);
-
- SkIRect dirtyRect;
- if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect))
- return;
-
- didDraw(dirtyRect);
-}
-
-void CanvasRenderingContext2D::updateElementAccessibility(const Path& path, Element* element)
-{
- element->document().updateLayoutIgnorePendingStylesheets();
- AXObjectCache* axObjectCache = element->document().existingAXObjectCache();
- LayoutBoxModelObject* lbmo = canvas()->layoutBoxModelObject();
- LayoutObject* renderer = canvas()->layoutObject();
- if (!axObjectCache || !lbmo || !renderer)
- return;
-
- // Get the transformed path.
- Path transformedPath = path;
- transformedPath.transform(state().transform());
-
- // Offset by the canvas rect, taking border and padding into account.
- IntRect canvasRect = renderer->absoluteBoundingBoxRect();
- canvasRect.move(lbmo->borderLeft() + lbmo->paddingLeft(), lbmo->borderTop() + lbmo->paddingTop());
- LayoutRect elementRect = enclosingLayoutRect(transformedPath.boundingRect());
- elementRect.moveBy(canvasRect.location());
- axObjectCache->setCanvasObjectBounds(element, elementRect);
-}
-
-void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions& options, ExceptionState& exceptionState)
-{
- if (options.id().isEmpty() && !options.control()) {
- exceptionState.throwDOMException(NotSupportedError, "Both id and control are null.");
- return;
- }
-
- if (options.control() && !canvas()->isSupportedInteractiveCanvasFallback(*options.control())) {
- exceptionState.throwDOMException(NotSupportedError, "The control is neither null nor a supported interactive canvas fallback element.");
- return;
- }
-
- Path hitRegionPath = options.hasPath() ? options.path()->path() : m_path;
-
- SkCanvas* c = drawingCanvas();
-
- if (hitRegionPath.isEmpty() || !c || !state().isTransformInvertible()
- || !c->getClipDeviceBounds(0)) {
- exceptionState.throwDOMException(NotSupportedError, "The specified path has no pixels.");
- return;
- }
-
- hitRegionPath.transform(state().transform());
-
- if (state().hasClip()) {
- hitRegionPath.intersectPath(state().getCurrentClipPath());
- if (hitRegionPath.isEmpty())
- exceptionState.throwDOMException(NotSupportedError, "The specified path has no pixels.");
- }
-
- if (!m_hitRegionManager)
- m_hitRegionManager = HitRegionManager::create();
-
- // Remove previous region (with id or control)
- m_hitRegionManager->removeHitRegionById(options.id());
- m_hitRegionManager->removeHitRegionByControl(options.control().get());
-
- RefPtrWillBeRawPtr<HitRegion> hitRegion = HitRegion::create(hitRegionPath, options);
- Element* element = hitRegion->control();
- if (element && element->isDescendantOf(canvas()))
- updateElementAccessibility(hitRegion->path(), hitRegion->control());
- m_hitRegionManager->addHitRegion(hitRegion.release());
-}
-
-void CanvasRenderingContext2D::removeHitRegion(const String& id)
-{
- if (m_hitRegionManager)
- m_hitRegionManager->removeHitRegionById(id);
-}
-
-void CanvasRenderingContext2D::clearHitRegions()
-{
- if (m_hitRegionManager)
- m_hitRegionManager->removeAllHitRegions();
-}
-
-HitRegion* CanvasRenderingContext2D::hitRegionAtPoint(const FloatPoint& point)
-{
- if (m_hitRegionManager)
- return m_hitRegionManager->getHitRegionAtPoint(point);
-
- return nullptr;
-}
-
-unsigned CanvasRenderingContext2D::hitRegionsCount() const
-{
- if (m_hitRegionManager)
- return m_hitRegionManager->getHitRegionsCount();
-
- return 0;
-}
-
-void CanvasRenderingContext2D::checkOverdraw(const SkRect& rect, const SkPaint* paint, CanvasRenderingContext2DState::ImageType imageType, DrawType drawType)
+void BaseRenderingContext2D::checkOverdraw(const SkRect& rect, const SkPaint* paint, CanvasRenderingContext2DState::ImageType imageType, DrawType drawType)
{
SkCanvas* c = drawingCanvas();
- if (!c || !canvas()->buffer()->isRecording())
+ if (!c || !imageBuffer()->isRecording())
return;
SkRect deviceRect;
@@ -2357,7 +1341,7 @@ void CanvasRenderingContext2D::checkOverdraw(const SkRect& rect, const SkPaint*
SkShader* shader = paint->getShader();
if (shader) {
if (shader->isOpaque() && alpha == 0xFF)
- canvas()->buffer()->willOverwriteCanvas();
+ imageBuffer()->willOverwriteCanvas();
return;
}
}
@@ -2371,7 +1355,12 @@ void CanvasRenderingContext2D::checkOverdraw(const SkRect& rect, const SkPaint*
return;
}
- canvas()->buffer()->willOverwriteCanvas();
+ imageBuffer()->willOverwriteCanvas();
+}
+
+DEFINE_TRACE(BaseRenderingContext2D)
+{
+ visitor->trace(m_stateStack);
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698