1/*
2 * Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
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 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 CanvasRenderingContext2D_h
27#define CanvasRenderingContext2D_h
28
29#include "bindings/core/v8/ScriptWrappable.h"
30#include "core/css/CSSFontSelectorClient.h"
31#include "core/html/canvas/Canvas2DContextAttributes.h"
32#include "core/html/canvas/CanvasPathMethods.h"
33#include "core/html/canvas/CanvasRenderingContext.h"
34#include "core/html/canvas/HitRegion.h"
35#include "core/svg/SVGMatrixTearOff.h"
36#include "platform/fonts/Font.h"
37#include "platform/graphics/Color.h"
38#include "platform/geometry/FloatSize.h"
39#include "platform/graphics/GraphicsTypes.h"
40#include "platform/graphics/ImageBuffer.h"
41#include "platform/graphics/Path.h"
42#include "platform/transforms/AffineTransform.h"
43#include "wtf/HashMap.h"
44#include "wtf/Vector.h"
45#include "wtf/text/WTFString.h"
46
47namespace blink { class WebLayer; }
48
49namespace blink {
50
51class CanvasImageSource;
52class CanvasGradient;
53class CanvasPattern;
54class CanvasStyle;
55class Path2D;
56class Element;
57class ExceptionState;
58class FloatRect;
59class GraphicsContext;
60class HTMLCanvasElement;
61class HTMLImageElement;
62class HTMLVideoElement;
63class HitRegionOptions;
64class ImageBitmap;
65class ImageData;
66class TextMetrics;
67
68typedef WillBeHeapHashMap<String, RefPtrWillBeMember<MutableStylePropertySet> > MutableStylePropertyMap;
69
70class CanvasRenderingContext2D FINAL: public CanvasRenderingContext, public ScriptWrappable, public CanvasPathMethods {
71    DEFINE_WRAPPERTYPEINFO();
72public:
73    static PassOwnPtrWillBeRawPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
74    {
75        return adoptPtrWillBeNoop(new CanvasRenderingContext2D(canvas, attrs, usesCSSCompatibilityParseMode));
76    }
77    virtual ~CanvasRenderingContext2D();
78
79    CanvasStyle* strokeStyle() const;
80    void setStrokeStyle(PassRefPtrWillBeRawPtr<CanvasStyle>);
81
82    CanvasStyle* fillStyle() const;
83    void setFillStyle(PassRefPtrWillBeRawPtr<CanvasStyle>);
84
85    float lineWidth() const;
86    void setLineWidth(float);
87
88    String lineCap() const;
89    void setLineCap(const String&);
90
91    String lineJoin() const;
92    void setLineJoin(const String&);
93
94    float miterLimit() const;
95    void setMiterLimit(float);
96
97    const Vector<float>& getLineDash() const;
98    void setLineDash(const Vector<float>&);
99
100    float lineDashOffset() const;
101    void setLineDashOffset(float);
102
103    float shadowOffsetX() const;
104    void setShadowOffsetX(float);
105
106    float shadowOffsetY() const;
107    void setShadowOffsetY(float);
108
109    float shadowBlur() const;
110    void setShadowBlur(float);
111
112    String shadowColor() const;
113    void setShadowColor(const String&);
114
115    float globalAlpha() const;
116    void setGlobalAlpha(float);
117
118    bool isContextLost() const;
119
120    String globalCompositeOperation() const;
121    void setGlobalCompositeOperation(const String&);
122
123    void save() { ++m_stateStack.last()->m_unrealizedSaveCount; }
124    void restore();
125
126    PassRefPtr<SVGMatrixTearOff> currentTransform() const
127    {
128        return SVGMatrixTearOff::create(state().m_transform);
129    }
130    void setCurrentTransform(PassRefPtr<SVGMatrixTearOff>);
131
132    void scale(float sx, float sy);
133    void rotate(float angleInRadians);
134    void translate(float tx, float ty);
135    void transform(float m11, float m12, float m21, float m22, float dx, float dy);
136    void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
137    void resetTransform();
138
139    void setStrokeColor(const String& color);
140    void setStrokeColor(float grayLevel);
141    void setStrokeColor(const String& color, float alpha);
142    void setStrokeColor(float grayLevel, float alpha);
143    void setStrokeColor(float r, float g, float b, float a);
144    void setStrokeColor(float c, float m, float y, float k, float a);
145
146    void setFillColor(const String& color);
147    void setFillColor(float grayLevel);
148    void setFillColor(const String& color, float alpha);
149    void setFillColor(float grayLevel, float alpha);
150    void setFillColor(float r, float g, float b, float a);
151    void setFillColor(float c, float m, float y, float k, float a);
152
153    void beginPath();
154
155    void fill(const String& winding = "nonzero");
156    void fill(Path2D*, const String& winding = "nonzero");
157    void stroke();
158    void stroke(Path2D*);
159    void clip(const String& winding = "nonzero");
160    void clip(Path2D*, const String& winding = "nonzero");
161
162    bool isPointInPath(const float x, const float y, const String& winding = "nonzero");
163    bool isPointInPath(Path2D*, const float x, const float y, const String& winding = "nonzero");
164    bool isPointInStroke(const float x, const float y);
165    bool isPointInStroke(Path2D*, const float x, const float y);
166
167    void scrollPathIntoView();
168    void scrollPathIntoView(Path2D*);
169
170    void clearRect(float x, float y, float width, float height);
171    void fillRect(float x, float y, float width, float height);
172    void strokeRect(float x, float y, float width, float height);
173
174    void setShadow(float width, float height, float blur);
175    void setShadow(float width, float height, float blur, const String& color);
176    void setShadow(float width, float height, float blur, float grayLevel);
177    void setShadow(float width, float height, float blur, const String& color, float alpha);
178    void setShadow(float width, float height, float blur, float grayLevel, float alpha);
179    void setShadow(float width, float height, float blur, float r, float g, float b, float a);
180    void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
181
182    void clearShadow();
183
184    void drawImage(CanvasImageSource*, float x, float y, ExceptionState&);
185    void drawImage(CanvasImageSource*, float x, float y, float width, float height, ExceptionState&);
186    void drawImage(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
187
188    void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0,
189                           float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
190
191    void setAlpha(float);
192
193    void setCompositeOperation(const String&);
194
195    PassRefPtrWillBeRawPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1);
196    PassRefPtrWillBeRawPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState&);
197    PassRefPtrWillBeRawPtr<CanvasPattern> createPattern(CanvasImageSource*, const String& repetitionType, ExceptionState&);
198
199    PassRefPtrWillBeRawPtr<ImageData> createImageData(PassRefPtrWillBeRawPtr<ImageData>) const;
200    PassRefPtrWillBeRawPtr<ImageData> createImageData(float width, float height, ExceptionState&) const;
201    PassRefPtrWillBeRawPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionState&) const;
202    void putImageData(ImageData*, float dx, float dy);
203    void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
204
205    void reset();
206
207    String font() const;
208    void setFont(const String&);
209
210    String textAlign() const;
211    void setTextAlign(const String&);
212
213    String textBaseline() const;
214    void setTextBaseline(const String&);
215
216    String direction() const;
217    void setDirection(const String&);
218
219    void fillText(const String& text, float x, float y);
220    void fillText(const String& text, float x, float y, float maxWidth);
221    void strokeText(const String& text, float x, float y);
222    void strokeText(const String& text, float x, float y, float maxWidth);
223    PassRefPtrWillBeRawPtr<TextMetrics> measureText(const String& text);
224
225    LineCap getLineCap() const { return state().m_lineCap; }
226    LineJoin getLineJoin() const { return state().m_lineJoin; }
227
228    bool imageSmoothingEnabled() const;
229    void setImageSmoothingEnabled(bool);
230
231    PassRefPtrWillBeRawPtr<Canvas2DContextAttributes> getContextAttributes() const;
232
233    void drawFocusIfNeeded(Element*);
234    void drawFocusIfNeeded(Path2D*, Element*);
235
236    void addHitRegion(const HitRegionOptions&, ExceptionState&);
237    void removeHitRegion(const String& id);
238    void clearHitRegions();
239    HitRegion* hitRegionAtPoint(const LayoutPoint&);
240    unsigned hitRegionsCount() const;
241
242    void loseContext();
243    void restoreContext();
244
245    virtual void trace(Visitor*) OVERRIDE;
246
247private:
248    enum Direction {
249        DirectionInherit,
250        DirectionRTL,
251        DirectionLTR
252    };
253
254    class State FINAL : public CSSFontSelectorClient {
255    public:
256        State();
257        virtual ~State();
258
259        State(const State&);
260        State& operator=(const State&);
261
262        // CSSFontSelectorClient implementation
263        virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE;
264
265        virtual void trace(Visitor*) OVERRIDE;
266
267        unsigned m_unrealizedSaveCount;
268
269        String m_unparsedStrokeColor;
270        String m_unparsedFillColor;
271        RefPtrWillBeMember<CanvasStyle> m_strokeStyle;
272        RefPtrWillBeMember<CanvasStyle> m_fillStyle;
273        float m_lineWidth;
274        LineCap m_lineCap;
275        LineJoin m_lineJoin;
276        float m_miterLimit;
277        FloatSize m_shadowOffset;
278        float m_shadowBlur;
279        RGBA32 m_shadowColor;
280        float m_globalAlpha;
281        CompositeOperator m_globalComposite;
282        blink::WebBlendMode m_globalBlend;
283        AffineTransform m_transform;
284        bool m_invertibleCTM;
285        Vector<float> m_lineDash;
286        float m_lineDashOffset;
287        bool m_imageSmoothingEnabled;
288
289        // Text state.
290        TextAlign m_textAlign;
291        TextBaseline m_textBaseline;
292        Direction m_direction;
293
294        String m_unparsedFont;
295        Font m_font;
296        bool m_realizedFont;
297
298        bool m_hasClip;
299    };
300
301    CanvasRenderingContext2D(HTMLCanvasElement*, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode);
302
303    State& modifiableState() { ASSERT(!state().m_unrealizedSaveCount); return *m_stateStack.last(); }
304    const State& state() const { return *m_stateStack.last(); }
305
306    void applyLineDash() const;
307    void setShadow(const FloatSize& offset, float blur, RGBA32 color);
308    void applyShadow();
309    bool shouldDrawShadows() const;
310
311    void dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*);
312    void dispatchContextRestoredEvent(Timer<CanvasRenderingContext2D>*);
313    void tryRestoreContextEvent(Timer<CanvasRenderingContext2D>*);
314
315    bool computeDirtyRect(const FloatRect& localBounds, FloatRect*);
316    bool computeDirtyRect(const FloatRect& localBounds, const FloatRect& transformedClipBounds, FloatRect*);
317    void didDraw(const FloatRect&);
318
319    GraphicsContext* drawingContext() const;
320
321    void unwindStateStack();
322    void realizeSaves(GraphicsContext*);
323
324    void applyStrokePattern();
325    void applyFillPattern();
326
327    void drawImageInternal(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&, CompositeOperator, blink::WebBlendMode, GraphicsContext* = 0);
328    void drawVideo(HTMLVideoElement*, FloatRect srcRect, FloatRect dstRect);
329
330    void fillInternal(const Path&, const String& windingRuleString);
331    void strokeInternal(const Path&);
332    void clipInternal(const Path&, const String& windingRuleString);
333
334    bool isPointInPathInternal(const Path&, const float x, const float y, const String& windingRuleString);
335    bool isPointInStrokeInternal(const Path&, const float x, const float y);
336
337    void scrollPathIntoViewInternal(const Path&);
338
339    void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
340
341    const Font& accessFont();
342    int getFontBaseline(const FontMetrics&) const;
343
344    void clearCanvas();
345    bool rectContainsTransformedRect(const FloatRect&, const FloatRect&) const;
346
347    void inflateStrokeRect(FloatRect&) const;
348
349    template<class T> void fullCanvasCompositedFill(const T&);
350    template<class T> void fullCanvasCompositedStroke(const T&);
351    template<class T> void fullCanvasCompositedDrawImage(T*, const FloatRect&, const FloatRect&, CompositeOperator);
352
353    void drawFocusIfNeededInternal(const Path&, Element*);
354    bool focusRingCallIsValid(const Path&, Element*);
355    void drawFocusRing(const Path&);
356
357    void addHitRegionInternal(const HitRegionOptionsInternal&, ExceptionState&);
358    bool hasClip() { return state().m_hasClip; }
359
360    void validateStateStack();
361
362    virtual bool is2d() const OVERRIDE { return true; }
363    virtual bool isAccelerated() const OVERRIDE;
364    virtual bool hasAlpha() const OVERRIDE { return m_hasAlpha; }
365    virtual void setIsHidden(bool) OVERRIDE;
366
367    virtual bool isTransformInvertible() const OVERRIDE { return state().m_invertibleCTM; }
368
369    virtual blink::WebLayer* platformLayer() const OVERRIDE;
370    TextDirection toTextDirection(Direction, RenderStyle** computedStyle = nullptr) const;
371
372    WillBeHeapVector<OwnPtrWillBeMember<State> > m_stateStack;
373    OwnPtrWillBeMember<HitRegionManager> m_hitRegionManager;
374    bool m_usesCSSCompatibilityParseMode;
375    bool m_hasAlpha;
376    bool m_isContextLost;
377    bool m_contextRestorable;
378    Canvas2DContextStorage m_storageMode;
379    MutableStylePropertyMap m_fetchedFonts;
380    unsigned m_tryRestoreContextAttemptCount;
381    Timer<CanvasRenderingContext2D> m_dispatchContextLostEventTimer;
382    Timer<CanvasRenderingContext2D> m_dispatchContextRestoredEventTimer;
383    Timer<CanvasRenderingContext2D> m_tryRestoreContextEventTimer;
384};
385
386DEFINE_TYPE_CASTS(CanvasRenderingContext2D, CanvasRenderingContext, context, context->is2d(), context.is2d());
387
388} // namespace blink
389
390#endif // CanvasRenderingContext2D_h
391