153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)/*
253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * modification, are permitted provided that the following conditions
753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * are met:
853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
1053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
1153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
1253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
1353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
1453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THE POSSIBILITY OF SUCH DAMAGE.
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) */
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "config.h"
28a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "platform/TraceEvent.h"
311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntRect.h"
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/RoundedRect.h"
33a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/BitmapImage.h"
3419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "platform/graphics/DisplayList.h"
35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/Gradient.h"
36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageBuffer.h"
377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/graphics/UnacceleratedImageBufferSurface.h"
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "platform/graphics/skia/SkiaUtils.h"
391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/BidiResolver.h"
40a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/text/TextRunIterator.h"
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/KURL.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "third_party/skia/include/core/SkAnnotation.h"
43197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "third_party/skia/include/core/SkClipStack.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "third_party/skia/include/core/SkColorFilter.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "third_party/skia/include/core/SkData.h"
4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "third_party/skia/include/core/SkDevice.h"
4719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "third_party/skia/include/core/SkPicture.h"
487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "third_party/skia/include/core/SkPictureRecorder.h"
49591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "third_party/skia/include/core/SkRRect.h"
5093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "third_party/skia/include/core/SkRefCnt.h"
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "third_party/skia/include/core/SkSurface.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "third_party/skia/include/effects/SkBlurMaskFilter.h"
53591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "third_party/skia/include/effects/SkCornerPathEffect.h"
541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "third_party/skia/include/effects/SkLumaColorFilter.h"
55e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "third_party/skia/include/effects/SkMatrixImageFilter.h"
56e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "third_party/skia/include/effects/SkPictureImageFilter.h"
57a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "third_party/skia/include/gpu/GrRenderTarget.h"
58a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "third_party/skia/include/gpu/GrTexture.h"
59521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/Assertions.h"
60521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/MathExtras.h"
6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
6353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct GraphicsContext::CanvasSaveState {
6507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    CanvasSaveState(bool pendingSave, int count)
6607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        : m_pendingSave(pendingSave), m_restoreCount(count) { }
6781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
6807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool m_pendingSave;
6981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    int m_restoreCount;
7081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)};
7181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
7219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)struct GraphicsContext::RecordingState {
73697ef0c10ac944be8499480c025020e4c282c980Ben Murdoch    RecordingState(SkPictureRecorder* recorder, SkCanvas* currentCanvas, const SkMatrix& currentMatrix, bool currentShouldSmoothFonts,
747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        PassRefPtr<DisplayList> displayList, RegionTrackingMode trackingMode)
757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        : m_displayList(displayList)
767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        , m_recorder(recorder)
777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        , m_savedCanvas(currentCanvas)
7851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        , m_savedMatrix(currentMatrix)
79697ef0c10ac944be8499480c025020e4c282c980Ben Murdoch        , m_savedShouldSmoothFonts(currentShouldSmoothFonts)
807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        , m_regionTrackingMode(trackingMode) { }
817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ~RecordingState() { }
8319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
8419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    RefPtr<DisplayList> m_displayList;
857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    SkPictureRecorder* m_recorder;
867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    SkCanvas* m_savedCanvas;
8751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    const SkMatrix m_savedMatrix;
88697ef0c10ac944be8499480c025020e4c282c980Ben Murdoch    bool m_savedShouldSmoothFonts;
897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RegionTrackingMode m_regionTrackingMode;
9019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)};
9119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
92323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)GraphicsContext::GraphicsContext(SkCanvas* canvas, DisabledMode disableContextOrPainting)
9381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    : m_canvas(canvas)
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_paintStateStack()
9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_paintStateIndex(0)
9607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    , m_pendingCanvasSave(false)
975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    , m_annotationMode(0)
98197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
995267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    , m_annotationCount(0)
100c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    , m_layerCount(0)
101f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    , m_disableDestructionChecks(false)
10281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#endif
103323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    , m_disabledState(disableContextOrPainting)
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    , m_deviceScaleFactor(1.0f)
105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    , m_regionTrackingMode(RegionTrackingDisabled)
10693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    , m_trackTextRegion(false)
10753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    , m_accelerated(false)
10853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    , m_isCertainlyOpaque(true)
10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    , m_printing(false)
110aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    , m_antialiasHairlineImages(false)
1119e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    , m_shouldSmoothFonts(true)
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: Do some tests to determine how many states are typically used, and allocate
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // several here.
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_paintStateStack.append(GraphicsContextState::create());
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_paintState = m_paintStateStack.last().get();
11753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
11853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)GraphicsContext::~GraphicsContext()
12053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
122f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (!m_disableDestructionChecks) {
123f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(!m_paintStateIndex);
124f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(!m_paintState->saveCount());
125f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(!m_annotationCount);
126f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(!m_layerCount);
127f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(m_recordingStateStack.isEmpty());
128f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(m_canvasStateStack.isEmpty());
129f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
130f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif
13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GraphicsContext::resetCanvas(SkCanvas* canvas)
134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_canvas = canvas;
136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_trackedRegion.reset();
137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
138c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
139c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GraphicsContext::setRegionTrackingMode(RegionTrackingMode mode)
140c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
141c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_regionTrackingMode = mode;
142c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (mode == RegionTrackingOpaque)
143c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.setTrackedRegionType(RegionTracker::Opaque);
144c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    else if (mode == RegionTrackingOverwrite)
145c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.setTrackedRegionType(RegionTracker::Overwrite);
146c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
147c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::save()
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
150323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_paintState->incrementSaveCount();
15481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (m_canvas) {
1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_canvasStateStack.append(CanvasSaveState(m_pendingCanvasSave, m_canvas->getSaveCount()));
1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_pendingCanvasSave = true;
1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
16053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::restore()
16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
163323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_paintStateIndex && !m_paintState->saveCount()) {
167a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        WTF_LOG_ERROR("ERROR void GraphicsContext::restore() stack is empty");
16853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_paintState->saveCount()) {
172d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_paintState->decrementSaveCount();
17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    } else {
17409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_paintStateIndex--;
17509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_paintState = m_paintStateStack[m_paintStateIndex].get();
17609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
17781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (m_canvas) {
1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(m_canvasStateStack.size() > 0);
1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        CanvasSaveState savedState = m_canvasStateStack.last();
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_canvasStateStack.removeLast();
1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_pendingCanvasSave = savedState.m_pendingSave;
1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_canvas->restoreToCount(savedState.m_restoreCount);
1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
18553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
18653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint)
18853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
189323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
190e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
191e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
1927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
19407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
19553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
19607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    m_canvas->saveLayer(bounds, paint);
197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
198c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.pushCanvasLayer(paint);
19953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
20053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
20153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::restoreLayer()
20253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
203323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
204e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
205e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
20881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->restore();
209c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
210c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.popCanvasLayer(this);
21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
21253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
213197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid GraphicsContext::beginAnnotation(const AnnotationList& annotations)
2145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){
215323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
2165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return;
2175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    canvas()->beginCommentGroup("GraphicsContextAnnotation");
2215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    AnnotationList::const_iterator end = annotations.end();
2235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    for (AnnotationList::const_iterator it = annotations.begin(); it != end; ++it)
2245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        canvas()->addComment(it->first, it->second.ascii().data());
2255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
226197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
2275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ++m_annotationCount;
2285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#endif
2295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
2305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::endAnnotation()
2325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){
233323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
2345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return;
2355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
237197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(m_annotationCount > 0);
2385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    canvas()->endCommentGroup();
2395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
240197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
2415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    --m_annotationCount;
2425267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#endif
2435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
2445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
24593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::setStrokePattern(PassRefPtr<Pattern> pattern)
24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
247323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
24853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
24953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
25093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT(pattern);
25193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!pattern) {
2525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        setStrokeColor(Color::black);
25353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
25453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
255d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    mutableState()->setStrokePattern(pattern);
25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
25893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::setStrokeGradient(PassRefPtr<Gradient> gradient)
25953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
260323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
26153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
262e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
26393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT(gradient);
26493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!gradient) {
2655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        setStrokeColor(Color::black);
26693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
26793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    mutableState()->setStrokeGradient(gradient);
26953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
27053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
27153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::setFillPattern(PassRefPtr<Pattern> pattern)
27253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
273323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
274e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
275e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
27653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(pattern);
27753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!pattern) {
2785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        setFillColor(Color::black);
27953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
28053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
28109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    mutableState()->setFillPattern(pattern);
28353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
28453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::setFillGradient(PassRefPtr<Gradient> gradient)
28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
287323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
288e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
289e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
29053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(gradient);
29153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!gradient) {
2925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        setFillColor(Color::black);
29353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
29453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
29509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
296d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    mutableState()->setFillGradient(gradient);
29753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
29853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
299591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid GraphicsContext::setShadow(const FloatSize& offset, float blur, const Color& color,
300d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DrawLooperBuilder::ShadowTransformMode shadowTransformMode,
301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DrawLooperBuilder::ShadowAlphaMode shadowAlphaMode)
30253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
303323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
30453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
305e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
30609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!color.alpha() || (!offset.width() && !offset.height() && !blur)) {
30793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        clearShadow();
30853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
30953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
31053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawLooperBuilder->addShadow(offset, blur, color, shadowTransformMode, shadowAlphaMode);
313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawLooperBuilder->addUnmodifiedContent();
314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    setDrawLooper(drawLooperBuilder.release());
31553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
31653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::setDrawLooper(PassOwnPtr<DrawLooperBuilder> drawLooperBuilder)
31853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
319323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
32053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
321e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
322d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    mutableState()->setDrawLooper(drawLooperBuilder->detachDrawLooper());
32353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
32453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
32593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::clearDrawLooper()
32653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
327323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
32853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
329e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
330d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    mutableState()->clearDrawLooper();
33153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
33253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
33393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool GraphicsContext::hasShadow() const
33453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !!immutableState()->drawLooper();
336e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
337e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
33806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)bool GraphicsContext::getTransformedClipBounds(FloatRect* bounds) const
33906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
340323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
34106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return false;
3427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
34306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    SkIRect skIBounds;
34406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!m_canvas->getClipDeviceBounds(&skIBounds))
34506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return false;
346323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    SkRect skBounds = SkRect::Make(skIBounds);
34706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    *bounds = FloatRect(skBounds);
34806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    return true;
34906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
35006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
35151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)SkMatrix GraphicsContext::getTotalMatrix() const
352e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
3537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (contextDisabled() || !m_canvas)
35493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return SkMatrix::I();
35551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
3577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
35851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!isRecording())
35951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return m_canvas->getTotalMatrix();
36051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
36151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    const RecordingState& recordingState = m_recordingStateStack.last();
36251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SkMatrix totalMatrix = recordingState.m_savedMatrix;
36351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    totalMatrix.preConcat(m_canvas->getTotalMatrix());
36451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
36551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return totalMatrix;
366e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
367e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
3687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid GraphicsContext::adjustTextRenderMode(SkPaint* paint) const
369e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
370323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
371e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
372e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
37393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!paint->isLCDRenderText())
37493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
37593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
37693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    paint->setLCDRenderText(couldUseLCDRenderedText());
377e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
378e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
3797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool GraphicsContext::couldUseLCDRenderedText() const
380e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
3817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
38293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Our layers only have a single alpha channel. This means that subpixel
38393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // rendered text cannot be composited correctly when the layer is
384323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    // collapsed. Therefore, subpixel text is contextDisabled when we are drawing
38593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // onto a layer.
3865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (contextDisabled() || m_canvas->isDrawingToLayer() || !isCertainlyOpaque())
38793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
388e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
38993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return shouldSmoothFonts();
390e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
391e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
392a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation, WebBlendMode blendMode)
393e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
394323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
39507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return;
396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    mutableState()->setCompositeOperation(compositeOperation, blendMode);
397e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
398e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
399c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)SkColorFilter* GraphicsContext::colorFilter() const
400c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
401d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return immutableState()->colorFilter();
4021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
4031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
4041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void GraphicsContext::setColorFilter(ColorFilter colorFilter)
4051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
40609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    GraphicsContextState* stateToSet = mutableState();
40709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // We only support one active color filter at the moment. If (when) this becomes a problem,
4091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // we should switch to using color filter chains (Skia work in progress).
410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!stateToSet->colorFilter());
411d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    stateToSet->setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter));
412c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
413c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
41407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochbool GraphicsContext::readPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, int x, int y)
415e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
416323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
41793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
41893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
4197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
42007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    return m_canvas->readPixels(info, pixels, rowBytes, x, y);
421e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
422e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
42393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::setMatrix(const SkMatrix& matrix)
424e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
425323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
42693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
42793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
4287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
42907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
43093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
43193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_canvas->setMatrix(matrix);
432e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
433e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
434d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::concat(const SkMatrix& matrix)
435e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
436323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
437d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
43809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
43909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (matrix.isIdentity())
440d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
44109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
44307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
44493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
445d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_canvas->concat(matrix);
44653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
44753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
448c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void GraphicsContext::beginTransparencyLayer(float opacity, const FloatRect* bounds)
44953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
450d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    beginLayer(opacity, immutableState()->compositeOperator(), bounds);
4518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
4528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
45309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const FloatRect* bounds, ColorFilter colorFilter, ImageFilter* imageFilter)
4548abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
455323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
45653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
45753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
45853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPaint layerPaint;
45953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255));
4607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    layerPaint.setXfermodeMode(WebCoreCompositeToSkiaComposite(op, m_paintState->blendMode()));
4611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).get());
46209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    layerPaint.setImageFilter(imageFilter);
46353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
464c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (bounds) {
465c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        SkRect skBounds = WebCoreFloatRectToSKRect(*bounds);
46607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        saveLayer(&skBounds, &layerPaint);
467c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    } else {
46807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        saveLayer(0, &layerPaint);
469c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    }
470c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
471197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
472c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ++m_layerCount;
47381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#endif
47453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
47553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
476c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void GraphicsContext::endLayer()
47753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
478323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
479e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
480e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
481c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    restoreLayer();
48253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
483c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ASSERT(m_layerCount > 0);
484197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
485c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    --m_layerCount;
486c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#endif
48753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
48853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid GraphicsContext::beginRecording(const FloatRect& bounds, uint32_t recordFlags)
49019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
4917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RefPtr<DisplayList> displayList = DisplayList::create(bounds);
49219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
49351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SkCanvas* savedCanvas = m_canvas;
49451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SkMatrix savedMatrix = getTotalMatrix();
4957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    SkPictureRecorder* recorder = 0;
49651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
497323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (!contextDisabled()) {
4987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        FloatRect bounds = displayList->bounds();
4997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        IntSize recordingSize = enclosingIntRect(bounds).size();
5007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        recorder = new SkPictureRecorder;
5017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_canvas = recorder->beginRecording(recordingSize.width(), recordingSize.height(), 0, recordFlags);
50207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
50307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // We want the bounds offset mapped to (0, 0), such that the display list content
50407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // is fully contained within the SkPictureRecord's bounds.
50507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (!toFloatSize(bounds.location()).isZero()) {
50607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            m_canvas->translate(-bounds.x(), -bounds.y());
50707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            // To avoid applying the offset repeatedly in getTotalMatrix(), we pre-apply it here.
50807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            savedMatrix.preTranslate(bounds.x(), bounds.y());
50907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        }
51051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
51151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
512697ef0c10ac944be8499480c025020e4c282c980Ben Murdoch    m_recordingStateStack.append(RecordingState(recorder, savedCanvas, savedMatrix, m_shouldSmoothFonts, displayList,
5137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        static_cast<RegionTrackingMode>(m_regionTrackingMode)));
5147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
5157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Disable region tracking during recording.
5167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    setRegionTrackingMode(RegionTrackingDisabled);
51719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
51819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
51919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)PassRefPtr<DisplayList> GraphicsContext::endRecording()
52019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
52119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ASSERT(!m_recordingStateStack.isEmpty());
52219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
52319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    RecordingState recording = m_recordingStateStack.last();
5247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!contextDisabled())
5257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        recording.m_displayList->setPicture(recording.m_recorder->endRecording());
52619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
52719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    m_canvas = recording.m_savedCanvas;
5287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    setRegionTrackingMode(recording.m_regionTrackingMode);
529697ef0c10ac944be8499480c025020e4c282c980Ben Murdoch    setShouldSmoothFonts(recording.m_savedShouldSmoothFonts);
5307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    delete recording.m_recorder;
5317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_recordingStateStack.removeLast();
53219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
5337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return recording.m_displayList;
53419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
53519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
53651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool GraphicsContext::isRecording() const
53751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
53851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return !m_recordingStateStack.isEmpty();
53951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
54051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
54119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)void GraphicsContext::drawDisplayList(DisplayList* displayList)
54219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
54309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(displayList);
5447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
54519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
546323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || displayList->bounds().isEmpty())
54719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return;
54819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
5497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool performClip = !displayList->clip().isEmpty();
5507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool performTransform = !displayList->transform().isIdentity();
5517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (performClip || performTransform) {
5527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        save();
5537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (performTransform)
5547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            concat(displayList->transform());
5557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (performClip)
5567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            clipRect(displayList->clip());
5577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
5587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
55907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
56019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
5617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const FloatPoint& location = displayList->bounds().location();
5627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (location.x() || location.y()) {
5639e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        SkMatrix m;
5647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m.setTranslate(location.x(), location.y());
5659e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        m_canvas->drawPicture(displayList->picture(), &m, 0);
5669e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    } else {
5679e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        m_canvas->drawPicture(displayList->picture());
5689e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    }
5697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
5707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (regionTrackingEnabled()) {
5717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Since we don't track regions within display lists, conservatively
5727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // mark the bounds as non-opaque.
5737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        SkPaint paint;
5747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        paint.setXfermodeMode(SkXfermode::kClear_Mode);
5757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_trackedRegion.didDrawBounded(this, displayList->bounds(), paint);
5767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
5777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
5787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (performClip || performTransform)
5797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        restore();
58019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
58119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
58253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
58353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
584323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
58553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
58653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
58753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (numPoints <= 1)
58853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
58953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
59053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath path;
59153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setPathFromConvexPoints(&path, numPoints, points);
59253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
593d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint paint(immutableState()->fillPaint());
59453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    paint.setAntiAlias(shouldAntialias);
59553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    drawPath(path, paint);
59653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
597d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (strokeStyle() != NoStroke)
598d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        drawPath(path, immutableState()->strokePaint());
59953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
60053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
601c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)float GraphicsContext::prepareFocusRingPaint(SkPaint& paint, const Color& color, int width) const
602c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
603c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setAntiAlias(true);
604c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
605c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setColor(color.rgb());
606c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setStrokeWidth(focusRingWidth(width));
607c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
608c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if OS(MACOSX)
609c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setAlpha(64);
610c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return (width - 1) * 0.5f;
611c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#else
612c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return 1;
613c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
614c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
615c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
616c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GraphicsContext::drawFocusRingPath(const SkPath& path, const Color& color, int width)
617c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
618c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    SkPaint paint;
619c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    float cornerRadius = prepareFocusRingPaint(paint, color, width);
620c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
621c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setPathEffect(SkCornerPathEffect::Create(SkFloatToScalar(cornerRadius)))->unref();
622c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
623c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Outer path
624c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    drawPath(path, paint);
625c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
626c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if OS(MACOSX)
627c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Inner path
628c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setAlpha(128);
629c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setStrokeWidth(paint.getStrokeWidth() * 0.5f);
630c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    drawPath(path, paint);
631c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
632c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
633c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
634c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GraphicsContext::drawFocusRingRect(const SkRect& rect, const Color& color, int width)
635c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
636c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    SkPaint paint;
637c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    float cornerRadius = prepareFocusRingPaint(paint, color, width);
638c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
639c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    SkRRect rrect;
640c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    rrect.setRectXY(rect, SkFloatToScalar(cornerRadius), SkFloatToScalar(cornerRadius));
641c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
642c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Outer rect
643c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    drawRRect(rrect, paint);
644c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
645c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if OS(MACOSX)
646c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Inner rect
647c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setAlpha(128);
648c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint.setStrokeWidth(paint.getStrokeWidth() * 0.5f);
649c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    drawRRect(rrect, paint);
650c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
651c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
652c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
653591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid GraphicsContext::drawFocusRing(const Path& focusRingPath, int width, int offset, const Color& color)
65453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
655591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    // FIXME: Implement support for offset.
656323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
657591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return;
658591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
659c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    drawFocusRingPath(focusRingPath.skPath(), color, width);
66053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
66153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
66253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
66353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
664323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
66553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
66653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
66753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned rectCount = rects.size();
66853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!rectCount)
66953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
67053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
67153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRegion focusRingRegion;
672c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const int outset = focusRingOutset(offset);
67353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (unsigned i = 0; i < rectCount; i++) {
67453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkIRect r = rects[i];
675c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        r.inset(-outset, -outset);
67653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        focusRingRegion.op(r, SkRegion::kUnion_Op);
67753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
67853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
679c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (focusRingRegion.isRect()) {
680c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        drawFocusRingRect(SkRect::MakeFromIRect(focusRingRegion.getBounds()), color, width);
681c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    } else {
682c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        SkPath path;
683c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (focusRingRegion.getBoundaryPath(&path))
684c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            drawFocusRingPath(path, color, width);
685c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
68653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
68753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
688591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic inline IntRect areaCastingShadowInHole(const IntRect& holeRect, int shadowBlur, int shadowSpread, const IntSize& shadowOffset)
689591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{
690591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    IntRect bounds(holeRect);
691591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
692591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    bounds.inflate(shadowBlur);
693591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
694591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (shadowSpread < 0)
695591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        bounds.inflate(-shadowSpread);
696591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
697591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    IntRect offsetBounds = bounds;
698591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    offsetBounds.move(-shadowOffset);
699591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return unionRect(bounds, offsetBounds);
700591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}
701591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
702591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid GraphicsContext::drawInnerShadow(const RoundedRect& rect, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges)
703591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{
704323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
70507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return;
70607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
707591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    IntRect holeRect(rect.rect());
708591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    holeRect.inflate(-shadowSpread);
709591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
710591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (holeRect.isEmpty()) {
711591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        if (rect.isRounded())
712591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            fillRoundedRect(rect, shadowColor);
713591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        else
714591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            fillRect(rect.rect(), shadowColor);
715591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return;
716591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
717591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
718591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (clippedEdges & LeftEdge) {
7197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        holeRect.move(-std::max(shadowOffset.width(), 0) - shadowBlur, 0);
7207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        holeRect.setWidth(holeRect.width() + std::max(shadowOffset.width(), 0) + shadowBlur);
721591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
722591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (clippedEdges & TopEdge) {
7237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        holeRect.move(0, -std::max(shadowOffset.height(), 0) - shadowBlur);
7247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        holeRect.setHeight(holeRect.height() + std::max(shadowOffset.height(), 0) + shadowBlur);
725591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
726591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (clippedEdges & RightEdge)
7277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        holeRect.setWidth(holeRect.width() - std::min(shadowOffset.width(), 0) + shadowBlur);
728591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (clippedEdges & BottomEdge)
7297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        holeRect.setHeight(holeRect.height() - std::min(shadowOffset.height(), 0) + shadowBlur);
730591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
731591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
732591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
733591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    IntRect outerRect = areaCastingShadowInHole(rect.rect(), shadowBlur, shadowSpread, shadowOffset);
734591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RoundedRect roundedHole(holeRect, rect.radii());
735591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
736591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    save();
737591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (rect.isRounded()) {
738591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        Path path;
739591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        path.addRoundedRect(rect);
740591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        clipPath(path);
741591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        roundedHole.shrinkRadii(shadowSpread);
742591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    } else {
743591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        clip(rect.rect());
744591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
745591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
746d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
747d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawLooperBuilder->addShadow(shadowOffset, shadowBlur, shadowColor,
748d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
749d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    setDrawLooper(drawLooperBuilder.release());
750591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    fillRectWithRoundedHole(outerRect, roundedHole, fillColor);
751591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    restore();
752591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    clearDrawLooper();
753591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}
754591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
75553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
75653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
7577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
758323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
75953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
76053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
76153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    StrokeStyle penStyle = strokeStyle();
76253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (penStyle == NoStroke)
76353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
76453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
76553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    FloatPoint p1 = point1;
76653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    FloatPoint p2 = point2;
76753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool isVerticalLine = (p1.x() == p2.x());
76853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int width = roundf(strokeThickness());
76953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
77053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // We know these are vertical or horizontal lines, so the length will just
77153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // be the sum of the displacement component vectors give or take 1 -
77253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // probably worth the speed up of no square root, which also won't be exact.
77353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    FloatSize disp = p2 - p1;
77409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    int length = SkScalarRoundToInt(disp.width() + disp.height());
775d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint paint(immutableState()->strokePaint(length));
77653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
77753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) {
77853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Do a rect fill of our endpoints.  This ensures we always have the
77953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // appearance of being a border.  We then draw the actual dotted/dashed line.
78053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkRect r1, r2;
78153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        r1.set(p1.x(), p1.y(), p1.x() + width, p1.y() + width);
78253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        r2.set(p2.x(), p2.y(), p2.x() + width, p2.y() + width);
78353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
78453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (isVerticalLine) {
78553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            r1.offset(-width / 2, 0);
78653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            r2.offset(-width / 2, -width);
78753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        } else {
78853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            r1.offset(0, -width / 2);
78953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            r2.offset(-width, -width / 2);
79053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
79153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPaint fillPaint;
79253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        fillPaint.setColor(paint.getColor());
79353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        drawRect(r1, fillPaint);
79453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        drawRect(r2, fillPaint);
79553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
79653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
79753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    adjustLineToPixelBoundaries(p1, p2, width, penStyle);
798a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    SkPoint pts[2] = { p1.data(), p2.data() };
79953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
80081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint);
80153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
802c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
803c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawPoints(this, SkCanvas::kLines_PointMode, 2, pts, paint);
80453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
80553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
80653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& pt, float width, DocumentMarkerLineStyle style)
80753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
808323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
80953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
81053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
811c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Use 2x resources for a device scale factor of 1.5 or above.
812c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    int deviceScaleFactor = m_deviceScaleFactor > 1.5f ? 2 : 1;
81353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
81453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Create the pattern we'll use to draw the underline.
81553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int index = style == DocumentMarkerGrammarLineStyle ? 1 : 0;
81653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static SkBitmap* misspellBitmap1x[2] = { 0, 0 };
81753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static SkBitmap* misspellBitmap2x[2] = { 0, 0 };
81853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkBitmap** misspellBitmap = deviceScaleFactor == 2 ? misspellBitmap2x : misspellBitmap1x;
81953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!misspellBitmap[index]) {
8208abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#if OS(MACOSX)
82153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Match the artwork used by the Mac.
82253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        const int rowPixels = 4 * deviceScaleFactor;
82353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        const int colPixels = 3 * deviceScaleFactor;
82443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        SkBitmap bitmap;
8257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!bitmap.tryAllocN32Pixels(rowPixels, colPixels))
82643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            return;
82753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
82843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        bitmap.eraseARGB(0, 0, 0, 0);
82953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        const uint32_t transparentColor = 0x00000000;
83053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
83153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (deviceScaleFactor == 1) {
83253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            const uint32_t colors[2][6] = {
833521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                { 0x2a2a0600, 0x57571000,  0xa8a81b00, 0xbfbf1f00,  0x70701200, 0xe0e02400 },
834521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                { 0x2a0f0f0f, 0x571e1e1e,  0xa83d3d3d, 0xbf454545,  0x70282828, 0xe0515151 }
83553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            };
83653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
83753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // Pattern: a b a   a b a
83853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //          c d c   c d c
83953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //          e f e   e f e
84053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            for (int x = 0; x < colPixels; ++x) {
84143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                uint32_t* row = bitmap.getAddr32(0, x);
84253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[0] = colors[index][x * 2];
84353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[1] = colors[index][x * 2 + 1];
84453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[2] = colors[index][x * 2];
84553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[3] = transparentColor;
84653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
84753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        } else if (deviceScaleFactor == 2) {
84853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            const uint32_t colors[2][18] = {
84953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                { 0x0a090101, 0x33320806, 0x55540f0a,  0x37360906, 0x6e6c120c, 0x6e6c120c,  0x7674140d, 0x8d8b1810, 0x8d8b1810,
85053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                  0x96941a11, 0xb3b01f15, 0xb3b01f15,  0x6d6b130c, 0xd9d62619, 0xd9d62619,  0x19180402, 0x7c7a150e, 0xcecb2418 },
851521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                { 0x0a020202, 0x33141414, 0x55232323,  0x37161616, 0x6e2e2e2e, 0x6e2e2e2e,  0x76313131, 0x8d3a3a3a, 0x8d3a3a3a,
852521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                  0x963e3e3e, 0xb34b4b4b, 0xb34b4b4b,  0x6d2d2d2d, 0xd95b5b5b, 0xd95b5b5b,  0x19090909, 0x7c343434, 0xce575757 }
85353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            };
85453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
85553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // Pattern: a b c c b a
85653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //          d e f f e d
85753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //          g h j j h g
85853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //          k l m m l k
85953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //          n o p p o n
86053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            //          q r s s r q
86153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            for (int x = 0; x < colPixels; ++x) {
86243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                uint32_t* row = bitmap.getAddr32(0, x);
86353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[0] = colors[index][x * 3];
86453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[1] = colors[index][x * 3 + 1];
86553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[2] = colors[index][x * 3 + 2];
86653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[3] = colors[index][x * 3 + 2];
86753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[4] = colors[index][x * 3 + 1];
86853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[5] = colors[index][x * 3];
86953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[6] = transparentColor;
87053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                row[7] = transparentColor;
87153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
87253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        } else
87353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            ASSERT_NOT_REACHED();
87443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
87543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        misspellBitmap[index] = new SkBitmap(bitmap);
87653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#else
87753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // We use a 2-pixel-high misspelling indicator because that seems to be
87853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // what WebKit is designed for, and how much room there is in a typical
87953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // page for it.
88053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        const int rowPixels = 32 * deviceScaleFactor; // Must be multiple of 4 for pattern below.
88153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        const int colPixels = 2 * deviceScaleFactor;
88243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        SkBitmap bitmap;
8837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!bitmap.tryAllocN32Pixels(rowPixels, colPixels))
88443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            return;
88553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
88643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        bitmap.eraseARGB(0, 0, 0, 0);
88753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (deviceScaleFactor == 1)
88843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            draw1xMarker(&bitmap, index);
88953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        else if (deviceScaleFactor == 2)
89043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            draw2xMarker(&bitmap, index);
89153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        else
89253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            ASSERT_NOT_REACHED();
89343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
89443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        misspellBitmap[index] = new SkBitmap(bitmap);
89553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#endif
89653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
89753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#if OS(MACOSX)
89953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkScalar originX = WebCoreFloatToSkScalar(pt.x()) * deviceScaleFactor;
90053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkScalar originY = WebCoreFloatToSkScalar(pt.y()) * deviceScaleFactor;
90153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
90253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Make sure to draw only complete dots.
90353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int rowPixels = misspellBitmap[index]->width();
90453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    float widthMod = fmodf(width * deviceScaleFactor, rowPixels);
90553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (rowPixels - widthMod > deviceScaleFactor)
90653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        width -= widthMod / deviceScaleFactor;
90753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#else
90853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkScalar originX = WebCoreFloatToSkScalar(pt.x());
90953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
91053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Offset it vertically by 1 so that there's some space under the text.
91153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkScalar originY = WebCoreFloatToSkScalar(pt.y()) + 1;
91253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    originX *= deviceScaleFactor;
91353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    originY *= deviceScaleFactor;
91453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#endif
91553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
916d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    SkMatrix localMatrix;
917d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    localMatrix.setTranslate(originX, originY);
9187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    RefPtr<SkShader> shader = adoptRef(SkShader::CreateBitmapShader(
919d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        *misspellBitmap[index], SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
92053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
92153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPaint paint;
9227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    paint.setShader(shader.get());
92353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
92453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRect rect;
92553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    rect.set(originX, originY, originX + WebCoreFloatToSkScalar(width) * deviceScaleFactor, originY + SkIntToScalar(misspellBitmap[index]->height()));
92653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
92753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (deviceScaleFactor == 2) {
92881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        save();
9295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        scale(0.5, 0.5);
93053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
93153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    drawRect(rect, paint);
93253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (deviceScaleFactor == 2)
93381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        restore();
93453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
93553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
93653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool printing)
93753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
938323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
93953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
94053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
94153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (width <= 0)
94253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
94353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
94453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPaint paint;
94593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    switch (strokeStyle()) {
94693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case NoStroke:
94793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case SolidStroke:
94893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case DoubleStroke:
949d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    case WavyStroke: {
950d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int thickness = SkMax32(static_cast<int>(strokeThickness()), 1);
951d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        SkRect r;
952d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        r.fLeft = WebCoreFloatToSkScalar(pt.x());
953d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // Avoid anti-aliasing lines. Currently, these are always horizontal.
954d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // Round to nearest pixel to match text and other content.
955d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        r.fTop = WebCoreFloatToSkScalar(floorf(pt.y() + 0.5f));
956d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        r.fRight = r.fLeft + WebCoreFloatToSkScalar(width);
957d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        r.fBottom = r.fTop + SkIntToScalar(thickness);
958d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        paint = immutableState()->fillPaint();
959d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // Text lines are drawn using the stroke color.
960d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        paint.setColor(effectiveStrokeColor());
961d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        drawRect(r, paint);
962d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
963d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
96493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case DottedStroke:
965d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    case DashedStroke: {
966d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int y = floorf(pt.y() + std::max<float>(strokeThickness() / 2.0f, 0.5f));
967d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        drawLine(IntPoint(pt.x(), y), IntPoint(pt.x() + width, y));
968d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
969d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
97093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
97193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
972d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT_NOT_REACHED();
97353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
97453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
97553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// Draws a filled rectangle with a stroked border.
97653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawRect(const IntRect& rect)
97753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
978323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
97953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
98053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
98153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(!rect.isEmpty());
98253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (rect.isEmpty())
98353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
98453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
98581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    SkRect skRect = rect;
986d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    int fillcolorNotTransparent = immutableState()->fillColor().rgb() & 0xFF000000;
987d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (fillcolorNotTransparent)
988d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        drawRect(skRect, immutableState()->fillPaint());
989d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
990d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (immutableState()->strokeData().style() != NoStroke
9917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        && immutableState()->strokeColor().alpha()) {
992d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // Stroke a width: 1 inset border
993d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        SkPaint paint(immutableState()->fillPaint());
994d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        paint.setColor(effectiveStrokeColor());
995d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        paint.setStyle(SkPaint::kStroke_Style);
996d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        paint.setStrokeWidth(1);
997d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
998d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skRect.inset(0.5f, 0.5f);
99981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        drawRect(skRect, paint);
100081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    }
100153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
100253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
100393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::drawText(const Font& font, const TextRunPaintInfo& runInfo, const FloatPoint& point)
100453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1005323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
100653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
100753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
100893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    font.drawText(this, runInfo, point);
100953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
101053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
101193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRunPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point)
101253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1013323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
101453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
101553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
101693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    font.drawEmphasisMarks(this, runInfo, mark, point);
101753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
101853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
101993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::drawBidiText(const Font& font, const TextRunPaintInfo& runInfo, const FloatPoint& point, Font::CustomFontNotReadyAction customFontNotReadyAction)
102053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1021323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
102253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
102353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
102493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // sub-run painting is not supported for Bidi text.
102593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const TextRun& run = runInfo.run;
102693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT((runInfo.from == 0) && (runInfo.to == run.length()));
102753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
102853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bidiResolver.setStatus(BidiStatus(run.direction(), run.directionalOverride()));
102953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0));
103053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
103153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // FIXME: This ownership should be reversed. We should pass BidiRunList
103253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // to BidiResolver in createBidiRunsForLine.
103353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs();
103453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bidiResolver.createBidiRunsForLine(TextRunIterator(&run, run.length()));
103553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!bidiRuns.runCount())
103653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
103753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
103853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    FloatPoint currPoint = point;
103953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    BidiCharacterRun* bidiRun = bidiRuns.firstRun();
10407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    float width = 0;
104153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    while (bidiRun) {
104253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        TextRun subrun = run.subRun(bidiRun->start(), bidiRun->stop() - bidiRun->start());
104353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        bool isRTL = bidiRun->level() % 2;
104453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        subrun.setDirection(isRTL ? RTL : LTR);
104553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        subrun.setDirectionalOverride(bidiRun->dirOverride(false));
104653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
104793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        TextRunPaintInfo subrunInfo(subrun);
104893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        subrunInfo.bounds = runInfo.bounds;
10497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        width = font.drawText(this, subrunInfo, currPoint, customFontNotReadyAction);
10507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
105153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
105253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        bidiRun = bidiRun->next();
105353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (bidiRun)
10547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            currPoint.move(width, 0);
105553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
105653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
105753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bidiRuns.deleteRuns();
105853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
105953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, int from, int to)
106153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1062323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
106353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
106453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    fillRect(font.selectionRectForText(run, point, h, from, to), backgroundColor);
106653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
106753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::drawImage(Image* image, const IntPoint& p, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation)
106953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
107053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!image)
107153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
10725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    drawImage(image, FloatRect(IntRect(p, image->size())), FloatRect(FloatPoint(), FloatSize(image->size())), op, shouldRespectImageOrientation);
107353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
107453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
107543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void GraphicsContext::drawImage(Image* image, const IntRect& r, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation)
107653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
107753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!image)
107853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
107943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    drawImage(image, FloatRect(r), FloatRect(FloatPoint(), FloatSize(image->size())), op, shouldRespectImageOrientation);
108053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
108153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
108243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation)
108353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1084e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    drawImage(image, dest, src, op, WebBlendModeNormal, shouldRespectImageOrientation);
108553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
108653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::drawImage(Image* image, const FloatRect& dest)
108853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
108953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!image)
109053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
10915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    drawImage(image, dest, FloatRect(IntRect(IntPoint(), image->size())));
109253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
109353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
109443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op, WebBlendMode blendMode, RespectImageOrientationEnum shouldRespectImageOrientation)
109543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles){
1096323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || !image)
109753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
10985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    image->draw(this, dest, src, op, blendMode, shouldRespectImageOrientation);
109953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
110053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
110143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void GraphicsContext::drawTiledImage(Image* image, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op, WebBlendMode blendMode, const IntSize& repeatSpacing)
110253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1103323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || !image)
110453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
110543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    image->drawTiled(this, destRect, srcPoint, tileSize, op, blendMode, repeatSpacing);
110653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
110753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::drawTiledImage(Image* image, const IntRect& dest, const IntRect& srcRect,
110943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, CompositeOperator op)
111053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1111323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || !image)
111253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
111353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
111453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (hRule == Image::StretchTile && vRule == Image::StretchTile) {
111553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Just do a scale.
11165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        drawImage(image, dest, srcRect, op);
111753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
111853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
111953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
112043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    image->drawTiled(this, dest, srcRect, tileScaleFactor, hRule, vRule, op);
112153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
112253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1123f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid GraphicsContext::drawImageBuffer(ImageBuffer* image, const FloatRect& dest,
1124c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const FloatRect* src, CompositeOperator op, WebBlendMode blendMode)
112553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1126323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || !image)
112753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
1128f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
1129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    image->draw(this, dest, src, op, blendMode);
1130c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
1131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1132c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GraphicsContext::drawPicture(PassRefPtr<SkPicture> picture, const FloatRect& dest, const FloatRect& src, CompositeOperator op, WebBlendMode blendMode)
1133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
11347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (contextDisabled() || !picture)
1136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
1137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1138e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    SkMatrix ctm = m_canvas->getTotalMatrix();
1139e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    SkRect deviceDest;
1140e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ctm.mapRect(&deviceDest, dest);
1141e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    SkRect sourceBounds = WebCoreFloatRectToSKRect(src);
1142e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
1143e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtr<SkPictureImageFilter> pictureFilter = adoptRef(SkPictureImageFilter::Create(picture.get(), sourceBounds));
1144e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    SkMatrix layerScale;
1145e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    layerScale.setScale(deviceDest.width() / src.width(), deviceDest.height() / src.height());
1146e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtr<SkMatrixImageFilter> matrixFilter = adoptRef(SkMatrixImageFilter::Create(layerScale, SkPaint::kLow_FilterLevel, pictureFilter.get()));
1147c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    SkPaint picturePaint;
11487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    picturePaint.setXfermodeMode(WebCoreCompositeToSkiaComposite(op, blendMode));
1149e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    picturePaint.setImageFilter(matrixFilter.get());
11507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    SkRect layerBounds = SkRect::MakeWH(std::max(deviceDest.width(), sourceBounds.width()), std::max(deviceDest.height(), sourceBounds.height()));
1151e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    m_canvas->save();
1152e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    m_canvas->resetMatrix();
1153e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    m_canvas->translate(deviceDest.x(), deviceDest.y());
1154e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    m_canvas->saveLayer(&layerBounds, &picturePaint);
1155e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    m_canvas->restore();
1156e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    m_canvas->restore();
115753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
115853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
116053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
11617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1162323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1163e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
1164e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
1165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_canvas->writePixels(info, pixels, rowBytes, x, y);
116653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1167c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled()) {
1168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        SkRect rect = SkRect::MakeXYWH(x, y, info.width(), info.height());
116953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPaint paint;
117053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
117153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
1172d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (kOpaque_SkAlphaType != info.alphaType())
1173c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            paint.setAlpha(0x80); // signal to m_trackedRegion that we are not fully opaque
1174d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawRect(this, rect, paint, 0);
1176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // more efficient would be to call markRectAsOpaque or MarkRectAsNonOpaque directly,
1177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // rather than cons-ing up a paint with an xfermode and alpha
1178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::writePixels(const SkBitmap& bitmap, int x, int y)
1182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1183323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
118407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return;
118507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
1186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!bitmap.getTexture()) {
1187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        SkAutoLockPixels alp(bitmap);
1188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (bitmap.getPixels())
1189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            writePixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), x, y);
119053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
119153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
119253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1193e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void GraphicsContext::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, const SkPaint* paint)
119453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
11957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1196323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1197e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
1198e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
119981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->drawBitmap(bitmap, left, top, paint);
120053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1201c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled()) {
120253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkRect rect = SkRect::MakeXYWH(left, top, bitmap.width(), bitmap.height());
1203c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawRect(this, rect, *paint, &bitmap);
120453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
120553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
120653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
12075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::drawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
120853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkRect& dst, const SkPaint* paint)
120953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
12107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1211323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1212e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
1213e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
1214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkCanvas::DrawBitmapRectFlags flags =
1215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        immutableState()->shouldClampToSourceRect() ? SkCanvas::kNone_DrawBitmapRectFlag : SkCanvas::kBleed_DrawBitmapRectFlag;
12169bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
12179bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    m_canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
121853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1219c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1220c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawRect(this, dst, *paint, &bitmap);
122153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
122253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
122353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawOval(const SkRect& oval, const SkPaint& paint)
122453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
12257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1226323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1227e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
1228e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
122981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->drawOval(oval, paint);
123053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1231c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1232c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawBounded(this, oval, paint);
123353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
123453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
123553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawPath(const SkPath& path, const SkPaint& paint)
123653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
12377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1238323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1239e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
1240e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
124181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->drawPath(path, paint);
124253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1243c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1244c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawPath(this, path, paint);
124553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
124653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
124753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawRect(const SkRect& rect, const SkPaint& paint)
124853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
12497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1250323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1251e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
1252e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
125381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->drawRect(rect, paint);
125453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1255c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1256c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawRect(this, rect, paint, 0);
1257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
1258c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1259c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GraphicsContext::drawRRect(const SkRRect& rrect, const SkPaint& paint)
1260c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
12617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1262c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (contextDisabled())
1263c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
1264c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1265c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_canvas->drawRRect(rrect, paint);
1266c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1267c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1268c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawBounded(this, rrect.rect(), paint);
126953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
127053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
127153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::didDrawRect(const SkRect& rect, const SkPaint& paint, const SkBitmap* bitmap)
127253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1273323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
127407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return;
127507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
1276c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1277c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawRect(this, rect, paint, bitmap);
127853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
127953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
128053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::drawPosText(const void* text, size_t byteLength,
1281197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const SkPoint pos[], const SkRect& textRect, const SkPaint& paint)
128253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
12837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1284323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1285e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        return;
1286e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
128781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->drawPosText(text, byteLength, pos, paint);
128893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    didDrawTextInRect(textRect);
128953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
129053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // FIXME: compute bounds for positioned text.
1291c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1292c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawUnbounded(this, paint, RegionTracker::FillOrStroke);
129353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
129453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1295197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid GraphicsContext::drawPosTextH(const void* text, size_t byteLength,
1296197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const SkScalar xpos[], SkScalar constY, const SkRect& textRect, const SkPaint& paint)
1297197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
12987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1299197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (contextDisabled())
1300197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return;
1301197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1302197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_canvas->drawPosTextH(text, byteLength, xpos, constY, paint);
1303197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    didDrawTextInRect(textRect);
1304197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1305197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // FIXME: compute bounds for positioned text.
1306c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1307c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawUnbounded(this, paint, RegionTracker::FillOrStroke);
1308197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
1309197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
13107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid GraphicsContext::drawTextBlob(const SkTextBlob* blob, const SkPoint& origin, const SkPaint& paint)
13117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
13127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
13137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (contextDisabled())
13147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
13157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
13167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_canvas->drawTextBlob(blob, origin.x(), origin.y(), paint);
13177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
13187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    SkRect bounds = blob->bounds();
13197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bounds.offset(origin);
13207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    didDrawTextInRect(bounds);
13217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
13227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // FIXME: use bounds here if it helps performance.
13237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (regionTrackingEnabled())
13247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_trackedRegion.didDrawUnbounded(this, paint, RegionTracker::FillOrStroke);
13257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
13267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
132753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::fillPath(const Path& pathToFill)
132853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1329323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || pathToFill.isEmpty())
133053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
133153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
133253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Use const_cast and temporarily modify the fill type instead of copying the path.
133353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath& path = const_cast<SkPath&>(pathToFill.skPath());
133453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath::FillType previousFillType = path.getFillType();
133553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1336e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    SkPath::FillType temporaryFillType = WebCoreWindRuleToSkFillType(immutableState()->fillRule());
133753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.setFillType(temporaryFillType);
133853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawPath(path, immutableState()->fillPaint());
134053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
134153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.setFillType(previousFillType);
134253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
134353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
134453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::fillRect(const FloatRect& rect)
134553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1346323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
134753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
134853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
134953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRect r = rect;
135053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1351d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawRect(r, immutableState()->fillPaint());
135253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
135353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
135553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1356323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
135753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
135853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
135953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRect r = rect;
1360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint paint = immutableState()->fillPaint();
136153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    paint.setColor(color.rgb());
136253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    drawRect(r, paint);
136353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
136453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1365d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::fillBetweenRoundedRects(const IntRect& outer, const IntSize& outerTopLeft, const IntSize& outerTopRight, const IntSize& outerBottomLeft, const IntSize& outerBottomRight,
13667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const IntRect& inner, const IntSize& innerTopLeft, const IntSize& innerTopRight, const IntSize& innerBottomLeft, const IntSize& innerBottomRight, const Color& color)
13677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
13687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1369323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
1371d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkVector outerRadii[4];
1373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkVector innerRadii[4];
1374d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    setRadii(outerRadii, outerTopLeft, outerTopRight, outerBottomRight, outerBottomLeft);
1375d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    setRadii(innerRadii, innerTopLeft, innerTopRight, innerBottomRight, innerBottomLeft);
1376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1377d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkRRect rrOuter;
1378d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkRRect rrInner;
1379d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    rrOuter.setRectRadii(outer, outerRadii);
1380d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    rrInner.setRectRadii(inner, innerRadii);
1381d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint paint(immutableState()->fillPaint());
1383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    paint.setColor(color.rgb());
1384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_canvas->drawDRRect(rrOuter, rrInner, paint);
1386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1387c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1388c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawBounded(this, rrOuter.getBounds(), paint);
1389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1390d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1391d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::fillBetweenRoundedRects(const RoundedRect& outer, const RoundedRect& inner, const Color& color)
1392d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
1393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    fillBetweenRoundedRects(outer.rect(), outer.radii().topLeft(), outer.radii().topRight(), outer.radii().bottomLeft(), outer.radii().bottomRight(),
1394d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        inner.rect(), inner.radii().topLeft(), inner.radii().topRight(), inner.radii().bottomLeft(), inner.radii().bottomRight(), color);
1395d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
1396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1397e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
13985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
139953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
14007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1401323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
140253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
140353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
140453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (topLeft.width() + topRight.width() > rect.width()
140553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            || bottomLeft.width() + bottomRight.width() > rect.width()
140653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            || topLeft.height() + bottomLeft.height() > rect.height()
140753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            || topRight.height() + bottomRight.height() > rect.height()) {
140853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Not all the radii fit, return a rect. This matches the behavior of
140953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Path::createRoundedRectangle. Without this we attempt to draw a round
141053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // shadow for a square box.
14115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        fillRect(rect, color);
141253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
141353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
141453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
141553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkVector radii[4];
141653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setRadii(radii, topLeft, topRight, bottomRight, bottomLeft);
141753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
141853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRRect rr;
141953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    rr.setRectRadii(rect, radii);
142053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint paint(immutableState()->fillPaint());
142253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    paint.setColor(color.rgb());
142353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
142481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->drawRRect(rr, paint);
142553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1426c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (regionTrackingEnabled())
1427c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_trackedRegion.didDrawBounded(this, rr.getBounds(), paint);
142853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
142953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
143053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::fillEllipse(const FloatRect& ellipse)
143153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1432323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
143353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
143453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
143553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRect rect = ellipse;
1436d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawOval(rect, immutableState()->fillPaint());
143753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
143853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
143953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::strokePath(const Path& pathToStroke)
144053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1441323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || pathToStroke.isEmpty())
144253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
144353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
144453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPath& path = pathToStroke.skPath();
1445d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawPath(path, immutableState()->strokePaint());
144653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
144753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
14486f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid GraphicsContext::strokeRect(const FloatRect& rect)
14496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{
14506f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    strokeRect(rect, strokeThickness());
14516f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch}
14526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
145353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
145453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1455323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
145653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
145753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1458d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint paint(immutableState()->strokePaint());
145953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth));
1460d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Reset the dash effect to account for the width
1461d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    immutableState()->strokeData().setupPaintDashPathEffect(&paint, 0);
146253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // strokerect has special rules for CSS when the rect is degenerate:
146353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // if width==0 && height==0, do nothing
146453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // if width==0 || height==0, then just draw line for the other dimension
146553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRect r(rect);
146653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool validW = r.width() > 0;
146753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool validH = r.height() > 0;
146853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (validW && validH) {
146953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        drawRect(r, paint);
147053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    } else if (validW || validH) {
147153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // we are expected to respect the lineJoin, so we can't just call
147253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // drawLine -- we have to create a path that doubles back on itself.
147353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPath path;
147453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        path.moveTo(r.fLeft, r.fTop);
147553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        path.lineTo(r.fRight, r.fBottom);
147653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        path.close();
147753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        drawPath(path, paint);
147853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
147953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
148053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
148153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::strokeEllipse(const FloatRect& ellipse)
148253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1483323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
148453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
148553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1486d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    drawOval(ellipse, immutableState()->strokePaint());
148753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
148853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1489d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::clipRoundedRect(const RoundedRect& rect, SkRegion::Op regionOp)
149053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1491323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
149253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
149353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1494d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!rect.isRounded()) {
1495d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        clipRect(rect.rect(), NotAntiAliased, regionOp);
1496d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
1497d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1498d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
149953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkVector radii[4];
150053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RoundedRect::Radii wkRadii = rect.radii();
150153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setRadii(radii, wkRadii.topLeft(), wkRadii.topRight(), wkRadii.bottomRight(), wkRadii.bottomLeft());
150253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
150353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRRect r;
150453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    r.setRectRadii(rect.rect(), radii);
150553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1506d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    clipRRect(r, AntiAliased, regionOp);
150753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
150853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
150953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::clipOut(const Path& pathToClip)
151053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1511323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
151253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
151353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
151453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Use const_cast and temporarily toggle the inverse fill type instead of copying the path.
151553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath& path = const_cast<SkPath&>(pathToClip.skPath());
151653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.toggleInverseFillType();
151781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    clipPath(path, AntiAliased);
151853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.toggleInverseFillType();
151953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
152053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
152153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule)
152253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1523323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled() || pathToClip.isEmpty())
152453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
152553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
152653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Use const_cast and temporarily modify the fill type instead of copying the path.
152753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath& path = const_cast<SkPath&>(pathToClip.skPath());
152853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath::FillType previousFillType = path.getFillType();
152953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1530e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    SkPath::FillType temporaryFillType = WebCoreWindRuleToSkFillType(clipRule);
153153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.setFillType(temporaryFillType);
153281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    clipPath(path, AntiAliased);
153353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
153453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.setFillType(previousFillType);
153553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
153653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
153753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased)
153853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1539323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
154053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
154153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
154253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (numPoints <= 1)
154353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
154453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
154553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath path;
154653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setPathFromConvexPoints(&path, numPoints, points);
154781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    clipPath(path, antialiased ? AntiAliased : NotAntiAliased);
154853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
154953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
155053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::clipOutRoundedRect(const RoundedRect& rect)
155153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1552323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
155353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
155453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1555d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    clipRoundedRect(rect, SkRegion::kDifference_Op);
155653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
155753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
155853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::canvasClip(const Path& pathToClip, WindRule clipRule)
155953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1560323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
156153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
156253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
156353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Use const_cast and temporarily modify the fill type instead of copying the path.
156453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath& path = const_cast<SkPath&>(pathToClip.skPath());
156553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath::FillType previousFillType = path.getFillType();
156653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1567e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    SkPath::FillType temporaryFillType = WebCoreWindRuleToSkFillType(clipRule);
156853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.setFillType(temporaryFillType);
156981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    clipPath(path);
157053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
157153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.setFillType(previousFillType);
157253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
157353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1574d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::clipRect(const SkRect& rect, AntiAliasingMode aa, SkRegion::Op op)
157593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
15767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1577323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1578d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
157993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
158007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
158193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1582d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_canvas->clipRect(rect, op, aa == AntiAliased);
158393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
158493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1585d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::clipPath(const SkPath& path, AntiAliasingMode aa, SkRegion::Op op)
158693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
15877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1588323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1589d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
159093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
159107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
159293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1593d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_canvas->clipPath(path, op, aa == AntiAliased);
159493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
159593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1596d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void GraphicsContext::clipRRect(const SkRRect& rect, AntiAliasingMode aa, SkRegion::Op op)
159793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
15987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1599323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
1600d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
160193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
160207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
160393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1604d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_canvas->clipRRect(rect, op, aa == AntiAliased);
160593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
160693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
160707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid GraphicsContext::beginCull(const FloatRect& rect)
160807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
16097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1610323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
161107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return;
161207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
161307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
161407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    m_canvas->pushCull(rect);
161507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
161607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
161707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid GraphicsContext::endCull()
161807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
16197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1620323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
162107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return;
162207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
162307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
162407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
162507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    m_canvas->popCull();
162607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
162707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
162853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::rotate(float angleInRadians)
162953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
16307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1631323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
163253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
163353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
163407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
163581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
163681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_canvas->rotate(WebCoreFloatToSkScalar(angleInRadians * (180.0f / 3.14159265f)));
163753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
163853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void GraphicsContext::translate(float x, float y)
164053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
16417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1642323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
164353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
164453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!x && !y)
164609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
164709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
164807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
164981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
16505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_canvas->translate(WebCoreFloatToSkScalar(x), WebCoreFloatToSkScalar(y));
165153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
165253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void GraphicsContext::scale(float x, float y)
165453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
16557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1656323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
165753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
165853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (x == 1.0f && y == 1.0f)
166009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
166109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
166207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    realizeCanvasSave();
166381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
16645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_canvas->scale(WebCoreFloatToSkScalar(x), WebCoreFloatToSkScalar(y));
166553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
166653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
166753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
166853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
16697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1670323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
167153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
167253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
167353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkAutoDataUnref url(SkData::NewWithCString(link.string().utf8().data()));
167481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    SkAnnotateRectWithURL(m_canvas, destRect, url.get());
167581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)}
167681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
167781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)void GraphicsContext::setURLFragmentForRect(const String& destName, const IntRect& rect)
167881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles){
16797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1680323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
168181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        return;
168281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
168381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    SkAutoDataUnref skDestName(SkData::NewWithCString(destName.utf8().data()));
168481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    SkAnnotateLinkToDestination(m_canvas, rect, skDestName.get());
168581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)}
168681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
168781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)void GraphicsContext::addURLTargetAtPoint(const String& name, const IntPoint& pos)
168881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles){
16897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(m_canvas);
1690323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
169181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        return;
169281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
169381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    SkAutoDataUnref nameData(SkData::NewWithCString(name.utf8().data()));
169481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    SkAnnotateNamedDestination(m_canvas, SkPoint::Make(pos.x(), pos.y()), nameData);
169553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
169653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)AffineTransform GraphicsContext::getCTM() const
169853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1699323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
170053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return AffineTransform();
170153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
170251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SkMatrix m = getTotalMatrix();
170353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return AffineTransform(SkScalarToDouble(m.getScaleX()),
170453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                           SkScalarToDouble(m.getSkewY()),
170553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                           SkScalarToDouble(m.getSkewX()),
170653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                           SkScalarToDouble(m.getScaleY()),
170753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                           SkScalarToDouble(m.getTranslateX()),
170853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                           SkScalarToDouble(m.getTranslateY()));
170953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
171053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
17115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, CompositeOperator op)
171253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1713323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
171453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
171553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
171653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    CompositeOperator previousOperator = compositeOperation();
171753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setCompositeOperation(op);
17185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    fillRect(rect, color);
171953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setCompositeOperation(previousOperator);
172053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
172153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
17225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::fillRoundedRect(const RoundedRect& rect, const Color& color)
172353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1724323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
172507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return;
172607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
172753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (rect.isRounded())
17285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        fillRoundedRect(rect.rect(), rect.radii().topLeft(), rect.radii().topRight(), rect.radii().bottomLeft(), rect.radii().bottomRight(), color);
172953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    else
17305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        fillRect(rect.rect(), color);
173153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
173253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
17335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedRect& roundedHoleRect, const Color& color)
173453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1735323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
173653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
173753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
173853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Path path;
173953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path.addRect(rect);
174053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
174153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!roundedHoleRect.radii().isZero())
174253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        path.addRoundedRect(roundedHoleRect);
174353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    else
174453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        path.addRect(roundedHoleRect.rect());
174553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
174653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WindRule oldFillRule = fillRule();
174753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Color oldFillColor = fillColor();
17485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
174953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setFillRule(RULE_EVENODD);
17505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    setFillColor(color);
175153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
175253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    fillPath(path);
17535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
175453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    setFillRule(oldFillRule);
17555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    setFillColor(oldFillColor);
175653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
175753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
175853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::clearRect(const FloatRect& rect)
175953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1760323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if (contextDisabled())
176153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
176253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
176353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkRect r = rect;
1764d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SkPaint paint(immutableState()->fillPaint());
176553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    paint.setXfermodeMode(SkXfermode::kClear_Mode);
176653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    drawRect(r, paint);
176753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
176853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
176953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle penStyle)
177053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
177153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
177253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // works out.  For example, with a border width of 3, WebKit will pass us (y1+y2)/2, e.g.,
177353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // (50+53)/2 = 103/2 = 51 when we want 51.5.  It is always true that an even width gave
177453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
177553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (penStyle == DottedStroke || penStyle == DashedStroke) {
177653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (p1.x() == p2.x()) {
177753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p1.setY(p1.y() + strokeWidth);
177853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p2.setY(p2.y() - strokeWidth);
177953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        } else {
178053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p1.setX(p1.x() + strokeWidth);
178153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p2.setX(p2.x() - strokeWidth);
178253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
178353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
178453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
178553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (static_cast<int>(strokeWidth) % 2) { //odd
178653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (p1.x() == p2.x()) {
178753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // We're a vertical line.  Adjust our x.
178853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p1.setX(p1.x() + 0.5f);
178953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p2.setX(p2.x() + 0.5f);
179053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        } else {
179153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // We're a horizontal line. Adjust our y.
179253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p1.setY(p1.y() + 0.5f);
179353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            p2.setY(p2.y() + 0.5f);
179453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
179553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
179653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
179753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1798c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)PassOwnPtr<ImageBuffer> GraphicsContext::createRasterBuffer(const IntSize& size, OpacityMode opacityMode) const
179953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
180053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Make the buffer larger if the context's transform is scaling it so we need a higher
180153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // resolution than one pixel per unit. Also set up a corresponding scale factor on the
180253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // graphics context.
180353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    AffineTransform transform = getCTM();
180553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    IntSize scaledSize(static_cast<int>(ceil(size.width() * transform.xScale())), static_cast<int>(ceil(size.height() * transform.yScale())));
180653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    OwnPtr<ImageBufferSurface> surface = adoptPtr(new UnacceleratedImageBufferSurface(scaledSize, opacityMode));
18082fb29a03d7c71253319f61b77edc6c1e3a8fc8e2Torne (Richard Coles)    if (!surface->isValid())
18092fb29a03d7c71253319f61b77edc6c1e3a8fc8e2Torne (Richard Coles)        return nullptr;
1810a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    OwnPtr<ImageBuffer> buffer = adoptPtr(new ImageBuffer(surface.release()));
181153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    buffer->context()->scale(static_cast<float>(scaledSize.width()) / size.width(),
18135d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        static_cast<float>(scaledSize.height()) / size.height());
181453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
181553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return buffer.release();
181653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
181753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
181853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::setPathFromConvexPoints(SkPath* path, size_t numPoints, const FloatPoint* points)
181953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
182053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path->incReserve(numPoints);
182153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path->moveTo(WebCoreFloatToSkScalar(points[0].x()),
182253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                 WebCoreFloatToSkScalar(points[0].y()));
182353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (size_t i = 1; i < numPoints; ++i) {
182453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        path->lineTo(WebCoreFloatToSkScalar(points[i].x()),
182553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                     WebCoreFloatToSkScalar(points[i].y()));
182653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
182753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
182853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    /*  The code used to just blindly call this
182953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            path->setIsConvex(true);
183053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        But webkit can sometimes send us non-convex 4-point values, so we mark the path's
183153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        convexity as unknown, so it will get computed by skia at draw time.
183253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        See crbug.com 108605
183353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    */
183453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SkPath::Convexity convexity = SkPath::kConvex_Convexity;
183553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (numPoints == 4)
183653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        convexity = SkPath::kUnknown_Convexity;
183753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path->setConvexity(convexity);
183853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
183953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
184053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::setRadii(SkVector* radii, IntSize topLeft, IntSize topRight, IntSize bottomRight, IntSize bottomLeft)
184153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
184253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    radii[SkRRect::kUpperLeft_Corner].set(SkIntToScalar(topLeft.width()),
184353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkIntToScalar(topLeft.height()));
184453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    radii[SkRRect::kUpperRight_Corner].set(SkIntToScalar(topRight.width()),
184553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkIntToScalar(topRight.height()));
184653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    radii[SkRRect::kLowerRight_Corner].set(SkIntToScalar(bottomRight.width()),
184753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkIntToScalar(bottomRight.height()));
184853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    radii[SkRRect::kLowerLeft_Corner].set(SkIntToScalar(bottomLeft.width()),
184953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkIntToScalar(bottomLeft.height()));
185053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
185153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PassRefPtr<SkColorFilter> GraphicsContext::WebCoreColorFilterToSkiaColorFilter(ColorFilter colorFilter)
18531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
18541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    switch (colorFilter) {
18551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    case ColorFilterLuminanceToAlpha:
18561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return adoptRef(SkLumaColorFilter::Create());
18571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    case ColorFilterLinearRGBToSRGB:
18581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return ImageBuffer::createColorSpaceFilter(ColorSpaceLinearRGB, ColorSpaceDeviceRGB);
18591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    case ColorFilterSRGBToLinearRGB:
18601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return ImageBuffer::createColorSpaceFilter(ColorSpaceDeviceRGB, ColorSpaceLinearRGB);
18611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    case ColorFilterNone:
18621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        break;
18631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    default:
18641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ASSERT_NOT_REACHED();
18651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        break;
18661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
18671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1868d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return nullptr;
18691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
18701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
18715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !OS(MACOSX)
187253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::draw2xMarker(SkBitmap* bitmap, int index)
187353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
187453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPMColor lineColor = lineColors(index);
187553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPMColor antiColor1 = antiColors1(index);
187653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPMColor antiColor2 = antiColors2(index);
187753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
187853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    uint32_t* row1 = bitmap->getAddr32(0, 0);
187953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    uint32_t* row2 = bitmap->getAddr32(0, 1);
188053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    uint32_t* row3 = bitmap->getAddr32(0, 2);
188153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    uint32_t* row4 = bitmap->getAddr32(0, 3);
188253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
188353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Pattern: X0o   o0X0o   o0
188453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    //          XX0o o0XXX0o o0X
188553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    //           o0XXX0o o0XXX0o
188653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    //            o0X0o   o0X0o
188753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPMColor row1Color[] = { lineColor, antiColor1, antiColor2, 0,          0,         0,          antiColor2, antiColor1 };
188853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPMColor row2Color[] = { lineColor, lineColor,  antiColor1, antiColor2, 0,         antiColor2, antiColor1, lineColor };
188953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPMColor row3Color[] = { 0,         antiColor2, antiColor1, lineColor,  lineColor, lineColor,  antiColor1, antiColor2 };
189053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const SkPMColor row4Color[] = { 0,         0,          antiColor2, antiColor1, lineColor, antiColor1, antiColor2, 0 };
189153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
189253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (int x = 0; x < bitmap->width() + 8; x += 8) {
189353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        int count = std::min(bitmap->width() - x, 8);
189453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (count > 0) {
189553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            memcpy(row1 + x, row1Color, count * sizeof(SkPMColor));
189653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            memcpy(row2 + x, row2Color, count * sizeof(SkPMColor));
189753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            memcpy(row3 + x, row3Color, count * sizeof(SkPMColor));
189853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            memcpy(row4 + x, row4Color, count * sizeof(SkPMColor));
189953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
190053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
190153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
190253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
190353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void GraphicsContext::draw1xMarker(SkBitmap* bitmap, int index)
190453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
190553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const uint32_t lineColor = lineColors(index);
190653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const uint32_t antiColor = antiColors2(index);
190753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
190853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Pattern: X o   o X o   o X
190953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    //            o X o   o X o
191053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    uint32_t* row1 = bitmap->getAddr32(0, 0);
191153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    uint32_t* row2 = bitmap->getAddr32(0, 1);
191253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (int x = 0; x < bitmap->width(); x++) {
191353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        switch (x % 4) {
191453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        case 0:
191553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            row1[x] = lineColor;
191653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
191753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        case 1:
191853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            row1[x] = antiColor;
191953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            row2[x] = antiColor;
192053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
192153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        case 2:
192253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            row2[x] = lineColor;
192353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
192453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        case 3:
192553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            row1[x] = antiColor;
192653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            row2[x] = antiColor;
192753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
192853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
192953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
193053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
193153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
19327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciSkPMColor GraphicsContext::lineColors(int index)
193353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
193453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const SkPMColor colors[] = {
193553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPreMultiplyARGB(0xFF, 0xFF, 0x00, 0x00), // Opaque red.
193653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPreMultiplyARGB(0xFF, 0xC0, 0xC0, 0xC0) // Opaque gray.
193753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    };
193853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
193953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return colors[index];
194053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
194153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
19427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciSkPMColor GraphicsContext::antiColors1(int index)
194353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
194453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const SkPMColor colors[] = {
194553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPreMultiplyARGB(0xB0, 0xFF, 0x00, 0x00), // Semitransparent red.
194653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPreMultiplyARGB(0xB0, 0xC0, 0xC0, 0xC0)  // Semitransparent gray.
194753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    };
194853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
194953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return colors[index];
195053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
195153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
19527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciSkPMColor GraphicsContext::antiColors2(int index)
195353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
195453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const SkPMColor colors[] = {
195553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPreMultiplyARGB(0x60, 0xFF, 0x00, 0x00), // More transparent red
195653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        SkPreMultiplyARGB(0x60, 0xC0, 0xC0, 0xC0)  // More transparent gray
195753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    };
195853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
195953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return colors[index];
196053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
196153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#endif
196253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
196393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void GraphicsContext::didDrawTextInRect(const SkRect& textRect)
196493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
196593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (m_trackTextRegion) {
19665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        TRACE_EVENT0("skia", "GraphicsContext::didDrawTextInRect");
196793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_textRegion.join(textRect);
196893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
196993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
197093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1971c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GraphicsContext::preparePaintForDrawRectToRect(
1972c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    SkPaint* paint,
1973c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const SkRect& srcRect,
1974c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const SkRect& destRect,
1975c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    CompositeOperator compositeOp,
1976e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebBlendMode blendMode,
1977c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool isLazyDecoded,
1978c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool isDataComplete) const
1979c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
19807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    paint->setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp, blendMode));
1981c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint->setColorFilter(this->colorFilter());
1982c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint->setAlpha(this->getNormalizedAlpha());
1983c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint->setLooper(this->drawLooper());
1984c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint->setAntiAlias(shouldDrawAntiAliased(this, destRect));
1985c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1986c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    InterpolationQuality resampling;
1987c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (this->isAccelerated()) {
1988c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        resampling = InterpolationLow;
1989c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    } else if (this->printing()) {
1990c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        resampling = InterpolationNone;
1991c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    } else if (isLazyDecoded) {
1992c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        resampling = InterpolationHigh;
1993c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    } else {
1994c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // Take into account scale applied to the canvas when computing sampling mode (e.g. CSS scale or page scale).
1995c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        SkRect destRectTarget = destRect;
1996c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        SkMatrix totalMatrix = this->getTotalMatrix();
1997c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (!(totalMatrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)))
1998c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            totalMatrix.mapRect(&destRectTarget, destRect);
1999c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
2000c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        resampling = computeInterpolationQuality(totalMatrix,
2001c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            SkScalarToFloat(srcRect.width()), SkScalarToFloat(srcRect.height()),
2002c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTarget.height()),
2003c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            isDataComplete);
2004c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
2005c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
2006c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (resampling == InterpolationNone) {
2007c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // FIXME: This is to not break tests (it results in the filter bitmap flag
2008c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // being set to true). We need to decide if we respect InterpolationNone
2009c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // being returned from computeInterpolationQuality.
2010c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        resampling = InterpolationLow;
2011c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
2012c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    resampling = limitInterpolationQuality(this, resampling);
2013c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    paint->setFilterLevel(static_cast<SkPaint::FilterLevel>(resampling));
2014c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
2015c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
2016e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} // namespace blink
2017