1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *  * Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef platform_graphics_context_recording_h
27#define platform_graphics_context_recording_h
28
29#include "PlatformGraphicsContext.h"
30
31#include "RecordingContextCanvasProxy.h"
32#include "SkRefCnt.h"
33
34namespace WebCore {
35namespace GraphicsOperation {
36class Operation;
37}
38
39class CanvasState;
40class LinearAllocator;
41class RecordingImpl;
42class PlatformGraphicsContextSkia;
43class RecordingData;
44
45class Recording : public SkRefCnt {
46public:
47    Recording()
48        : m_recording(0)
49    {}
50    ~Recording();
51
52    void draw(SkCanvas* canvas);
53    void setRecording(RecordingImpl* impl);
54    RecordingImpl* recording() { return m_recording; }
55
56private:
57    RecordingImpl* m_recording;
58};
59
60class PlatformGraphicsContextRecording : public PlatformGraphicsContext {
61public:
62    PlatformGraphicsContextRecording(Recording* picture);
63    virtual ~PlatformGraphicsContextRecording();
64    virtual bool isPaintingDisabled();
65
66    virtual SkCanvas* recordingCanvas();
67    virtual void setTextOffset(FloatSize offset) { m_textOffset = offset; }
68
69    virtual ContextType type() { return RecordingContext; }
70
71    // State management
72    virtual void beginTransparencyLayer(float opacity);
73    virtual void endTransparencyLayer();
74    virtual void save();
75    virtual void restore();
76
77    // State values
78    virtual void setAlpha(float alpha);
79    virtual void setCompositeOperation(CompositeOperator op);
80    virtual bool setFillColor(const Color& c);
81    virtual bool setFillShader(SkShader* fillShader);
82    virtual void setLineCap(LineCap cap);
83    virtual void setLineDash(const DashArray& dashes, float dashOffset);
84    virtual void setLineJoin(LineJoin join);
85    virtual void setMiterLimit(float limit);
86    virtual void setShadow(int radius, int dx, int dy, SkColor c);
87    virtual void setShouldAntialias(bool useAA);
88    virtual bool setStrokeColor(const Color& c);
89    virtual bool setStrokeShader(SkShader* strokeShader);
90    virtual void setStrokeStyle(StrokeStyle style);
91    virtual void setStrokeThickness(float f);
92
93    // Matrix operations
94    virtual void concatCTM(const AffineTransform& affine);
95    virtual void rotate(float angleInRadians);
96    virtual void scale(const FloatSize& size);
97    virtual void translate(float x, float y);
98    virtual const SkMatrix& getTotalMatrix();
99
100    // Clipping
101    virtual void addInnerRoundedRectClip(const IntRect& rect, int thickness);
102    virtual void canvasClip(const Path& path);
103    virtual bool clip(const FloatRect& rect);
104    virtual bool clip(const Path& path);
105    virtual bool clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
106    virtual bool clipOut(const IntRect& r);
107    virtual bool clipOut(const Path& p);
108    virtual bool clipPath(const Path& pathToClip, WindRule clipRule);
109    virtual SkIRect getTotalClipBounds() { return enclosingIntRect(mRecordingStateStack.last().mBounds); }
110
111    // Drawing
112    virtual void clearRect(const FloatRect& rect);
113    virtual void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
114                           CompositeOperator compositeOp, const FloatRect& destRect);
115    virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* srcPtr,
116                        const SkRect& dst, CompositeOperator op = CompositeSourceOver);
117    virtual void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
118                           bool shouldAntialias);
119    virtual void drawEllipse(const IntRect& rect);
120    virtual void drawFocusRing(const Vector<IntRect>& rects, int /* width */,
121                       int /* offset */, const Color& color);
122    virtual void drawHighlightForText(const Font& font, const TextRun& run,
123                              const FloatPoint& point, int h,
124                              const Color& backgroundColor, ColorSpace colorSpace,
125                              int from, int to, bool isActive);
126    virtual void drawLine(const IntPoint& point1, const IntPoint& point2);
127    virtual void drawLineForText(const FloatPoint& pt, float width);
128    virtual void drawLineForTextChecking(const FloatPoint& pt, float width,
129                                         GraphicsContext::TextCheckingLineStyle);
130    virtual void drawRect(const IntRect& rect);
131    virtual void fillPath(const Path& pathToFill, WindRule fillRule);
132    virtual void fillRect(const FloatRect& rect);
133    virtual void fillRect(const FloatRect& rect, const Color& color);
134    virtual void fillRoundedRect(const IntRect& rect, const IntSize& topLeft,
135                         const IntSize& topRight, const IntSize& bottomLeft,
136                         const IntSize& bottomRight, const Color& color);
137    virtual void strokeArc(const IntRect& r, int startAngle, int angleSpan);
138    virtual void strokePath(const Path& pathToStroke);
139    virtual void strokeRect(const FloatRect& rect, float lineWidth);
140
141    virtual void drawPosText(const void* text, size_t byteLength,
142                             const SkPoint pos[], const SkPaint& paint);
143    virtual void drawMediaButton(const IntRect& rect, RenderSkinMediaButton::MediaButton buttonType,
144                                 bool translucent = false, bool drawBackground = true,
145                                 const IntRect& thumb = IntRect());
146
147    float maxZoomScale() { return m_maxZoomScale; }
148    bool isEmpty() { return m_isEmpty; }
149private:
150
151    virtual bool shadowsIgnoreTransforms() const {
152        return false;
153    }
154
155    void clipState(const FloatRect& clip);
156    void appendDrawingOperation(GraphicsOperation::Operation* operation, const FloatRect& bounds);
157    void appendStateOperation(GraphicsOperation::Operation* operation);
158    void pushStateOperation(CanvasState* canvasState);
159    void popStateOperation();
160    void pushMatrix();
161    void popMatrix();
162    IntRect calculateFinalBounds(FloatRect bounds);
163    IntRect calculateCoveredBounds(FloatRect bounds);
164    LinearAllocator* heap();
165
166    SkPicture* mPicture;
167    SkMatrix* mCurrentMatrix;
168
169    Recording* mRecording;
170    class RecordingState {
171    public:
172        RecordingState(CanvasState* state, const RecordingState* parent)
173            : mCanvasState(state)
174            , mHasDrawing(false)
175            , mHasClip(parent ? parent->mHasClip : false)
176            , mOpaqueTrackingDisabled(parent ? parent->mOpaqueTrackingDisabled : false)
177            , mBounds(parent ? parent->mBounds : FloatRect())
178        {}
179
180        RecordingState(const RecordingState& other)
181            : mCanvasState(other.mCanvasState)
182            , mHasDrawing(other.mHasDrawing)
183            , mHasClip(other.mHasClip)
184            , mOpaqueTrackingDisabled(other.mOpaqueTrackingDisabled)
185            , mBounds(other.mBounds)
186        {}
187
188        void disableOpaqueTracking() { mOpaqueTrackingDisabled = true; }
189
190        void clip(const FloatRect& rect)
191        {
192            if (mHasClip)
193                mBounds.intersect(rect);
194            else {
195                mBounds = rect;
196                mHasClip = true;
197            }
198        }
199
200        CanvasState* mCanvasState;
201        bool mHasDrawing;
202        bool mHasClip;
203        bool mOpaqueTrackingDisabled;
204        FloatRect mBounds;
205    };
206    Vector<RecordingState> mRecordingStateStack;
207    Vector<SkMatrix> mMatrixStack;
208    State* mOperationState;
209
210    float m_maxZoomScale;
211    bool m_isEmpty;
212    RecordingContextCanvasProxy m_canvasProxy;
213    FloatSize m_textOffset;
214};
215
216}
217#endif
218