61567fea1ad24fa3e2bb202945095664d2fb862b
[WebKit-https.git] / Source / WebCore / html / canvas / CanvasRenderingContext2D.h
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 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 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 "AffineTransform.h"
30 #include "CanvasPathMethods.h"
31 #include "CanvasRenderingContext.h"
32 #include "CanvasStyle.h"
33 #include "Color.h"
34 #include "ColorSpace.h"
35 #include "FloatSize.h"
36 #include "FontCascade.h"
37 #include "GraphicsTypes.h"
38 #include "ImageBuffer.h"
39 #include "Path.h"
40 #include "PlatformLayer.h"
41 #include "TextFlags.h"
42 #include <wtf/Vector.h>
43 #include <wtf/text/WTFString.h>
44
45 namespace WebCore {
46
47 class CanvasGradient;
48 class CanvasPattern;
49 class DOMPath;
50 class FloatRect;
51 class GraphicsContext;
52 class HTMLCanvasElement;
53 class HTMLImageElement;
54 class HTMLVideoElement;
55 class ImageData;
56 class TextMetrics;
57
58 typedef int ExceptionCode;
59
60 class CanvasRenderingContext2D final : public CanvasRenderingContext, public CanvasPathMethods {
61 public:
62     CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
63     virtual ~CanvasRenderingContext2D();
64
65     const CanvasStyle& strokeStyle() const { return state().m_strokeStyle; }
66     void setStrokeStyle(CanvasStyle);
67
68     const CanvasStyle& fillStyle() const { return state().m_fillStyle; }
69     void setFillStyle(CanvasStyle);
70
71     float lineWidth() const;
72     void setLineWidth(float);
73
74     String lineCap() const;
75     void setLineCap(const String&);
76
77     String lineJoin() const;
78     void setLineJoin(const String&);
79
80     float miterLimit() const;
81     void setMiterLimit(float);
82
83     const Vector<float>& getLineDash() const;
84     void setLineDash(const Vector<float>&);
85     void setWebkitLineDash(const Vector<float>&);
86
87     float lineDashOffset() const;
88     void setLineDashOffset(float);
89     float webkitLineDashOffset() const;
90     void setWebkitLineDashOffset(float);
91
92     float shadowOffsetX() const;
93     void setShadowOffsetX(float);
94
95     float shadowOffsetY() const;
96     void setShadowOffsetY(float);
97
98     float shadowBlur() const;
99     void setShadowBlur(float);
100
101     String shadowColor() const;
102     void setShadowColor(const String&);
103
104     float globalAlpha() const;
105     void setGlobalAlpha(float);
106
107     String globalCompositeOperation() const;
108     void setGlobalCompositeOperation(const String&);
109
110     void save() { ++m_unrealizedSaveCount; }
111     void restore();
112
113     void scale(float sx, float sy);
114     void rotate(float angleInRadians);
115     void translate(float tx, float ty);
116     void transform(float m11, float m12, float m21, float m22, float dx, float dy);
117     void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
118
119     void setStrokeColor(const String& color);
120     void setStrokeColor(float grayLevel);
121     void setStrokeColor(const String& color, float alpha);
122     void setStrokeColor(float grayLevel, float alpha);
123     void setStrokeColor(float r, float g, float b, float a);
124     void setStrokeColor(float c, float m, float y, float k, float a);
125
126     void setFillColor(const String& color);
127     void setFillColor(float grayLevel);
128     void setFillColor(const String& color, float alpha);
129     void setFillColor(float grayLevel, float alpha);
130     void setFillColor(float r, float g, float b, float a);
131     void setFillColor(float c, float m, float y, float k, float a);
132
133     void beginPath();
134
135     void fill(const String& winding = ASCIILiteral("nonzero"));
136     void stroke();
137     void clip(const String& winding = ASCIILiteral("nonzero"));
138
139     void fill(DOMPath*, const String& winding = ASCIILiteral("nonzero"));
140     void stroke(DOMPath*);
141     void clip(DOMPath*, const String& winding = ASCIILiteral("nonzero"));
142
143     bool isPointInPath(const float x, const float y, const String& winding = ASCIILiteral("nonzero"));
144     bool isPointInStroke(const float x, const float y);
145
146     bool isPointInPath(DOMPath*, const float x, const float y, const String& winding = ASCIILiteral("nonzero"));
147     bool isPointInStroke(DOMPath*, const float x, const float y);
148
149     void clearRect(float x, float y, float width, float height);
150     void fillRect(float x, float y, float width, float height);
151     void strokeRect(float x, float y, float width, float height);
152
153     void setShadow(float width, float height, float blur);
154     void setShadow(float width, float height, float blur, const String& color);
155     void setShadow(float width, float height, float blur, float grayLevel);
156     void setShadow(float width, float height, float blur, const String& color, float alpha);
157     void setShadow(float width, float height, float blur, float grayLevel, float alpha);
158     void setShadow(float width, float height, float blur, float r, float g, float b, float a);
159     void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
160
161     void clearShadow();
162
163     void drawImage(HTMLImageElement*, float x, float y, ExceptionCode&);
164     void drawImage(HTMLImageElement*, float x, float y, float width, float height, ExceptionCode&);
165     void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
166     void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
167     void drawImage(HTMLCanvasElement*, float x, float y, ExceptionCode&);
168     void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionCode&);
169     void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
170     void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
171     void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&, ExceptionCode&);
172 #if ENABLE(VIDEO)
173     void drawImage(HTMLVideoElement*, float x, float y, ExceptionCode&);
174     void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionCode&);
175     void drawImage(HTMLVideoElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
176     void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
177 #endif
178
179     void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0,
180                            float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
181
182     void setAlpha(float);
183
184     void setCompositeOperation(const String&);
185
186     RefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode&);
187     RefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode&);
188     RefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&);
189     RefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&);
190
191     RefPtr<ImageData> createImageData(RefPtr<ImageData>&&, ExceptionCode&) const;
192     RefPtr<ImageData> createImageData(float width, float height, ExceptionCode&) const;
193     RefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionCode&) const;
194     RefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode&) const;
195     void putImageData(ImageData*, float dx, float dy, ExceptionCode&);
196     void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
197     void webkitPutImageDataHD(ImageData*, float dx, float dy, ExceptionCode&);
198     void webkitPutImageDataHD(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
199
200     void drawFocusIfNeeded(Element*);
201     void drawFocusIfNeeded(DOMPath*, Element*);
202
203     float webkitBackingStorePixelRatio() const { return 1; }
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     Ref<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 private:
232     enum class Direction {
233         Inherit,
234         RTL,
235         LTR
236     };
237
238     class FontProxy : public FontSelectorClient {
239     public:
240         FontProxy() = default;
241         virtual ~FontProxy();
242         FontProxy(const FontProxy&);
243         FontProxy& operator=(const FontProxy&);
244
245         bool realized() const { return m_font.fontSelector(); }
246         void initialize(FontSelector&, RenderStyle&);
247         FontMetrics fontMetrics() const;
248         const FontDescription& fontDescription() const;
249         float width(const TextRun&) const;
250         void drawBidiText(GraphicsContext&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction) const;
251
252     private:
253         void update(FontSelector&);
254         virtual void fontsNeedUpdate(FontSelector&) override;
255
256         FontCascade m_font;
257     };
258
259     struct State final {
260         State();
261
262         State(const State&);
263         State& operator=(const State&);
264
265         String m_unparsedStrokeColor;
266         String m_unparsedFillColor;
267         CanvasStyle m_strokeStyle;
268         CanvasStyle m_fillStyle;
269         float m_lineWidth;
270         LineCap m_lineCap;
271         LineJoin m_lineJoin;
272         float m_miterLimit;
273         FloatSize m_shadowOffset;
274         float m_shadowBlur;
275         RGBA32 m_shadowColor;
276         float m_globalAlpha;
277         CompositeOperator m_globalComposite;
278         BlendMode m_globalBlend;
279         AffineTransform m_transform;
280         bool m_hasInvertibleTransform;
281         Vector<float> m_lineDash;
282         float m_lineDashOffset;
283         bool m_imageSmoothingEnabled;
284
285         // Text state.
286         TextAlign m_textAlign;
287         TextBaseline m_textBaseline;
288         Direction m_direction;
289
290         String m_unparsedFont;
291         FontProxy m_font;
292     };
293
294     enum CanvasDidDrawOption {
295         CanvasDidDrawApplyNone = 0,
296         CanvasDidDrawApplyTransform = 1,
297         CanvasDidDrawApplyShadow = 1 << 1,
298         CanvasDidDrawApplyClip = 1 << 2,
299         CanvasDidDrawApplyAll = 0xffffffff
300     };
301
302     State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); }
303     const State& state() const { return m_stateStack.last(); }
304
305     void applyLineDash() const;
306     void setShadow(const FloatSize& offset, float blur, RGBA32 color);
307     void applyShadow();
308     bool shouldDrawShadows() const;
309
310     void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
311     void didDrawEntireCanvas();
312
313     GraphicsContext* drawingContext() const;
314
315     void unwindStateStack();
316     void realizeSaves()
317     {
318         if (m_unrealizedSaveCount)
319             realizeSavesLoop();
320     }
321     void realizeSavesLoop();
322
323     void applyStrokePattern();
324     void applyFillPattern();
325
326     void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
327
328     // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants.
329     // Therefore, all font operations must pass through the State.
330     const FontProxy& fontProxy();
331
332 #if ENABLE(DASHBOARD_SUPPORT)
333     void clearPathForDashboardBackwardCompatibilityMode();
334 #endif
335
336     void beginCompositeLayer();
337     void endCompositeLayer();
338
339     void fillInternal(const Path&, const String& winding);
340     void strokeInternal(const Path&);
341     void clipInternal(const Path&, const String& winding);
342
343     bool isPointInPathInternal(const Path&, float x, float y, const String& winding);
344     bool isPointInStrokeInternal(const Path&, float x, float y);
345
346     void drawFocusIfNeededInternal(const Path&, Element*);
347
348     void clearCanvas();
349     Path transformAreaToDevice(const Path&) const;
350     Path transformAreaToDevice(const FloatRect&) const;
351     bool rectContainsCanvas(const FloatRect&) const;
352
353     template<class T> IntRect calculateCompositingBufferRect(const T&, IntSize*);
354     std::unique_ptr<ImageBuffer> createCompositingBuffer(const IntRect&);
355     void compositeBuffer(ImageBuffer*, const IntRect&, CompositeOperator);
356
357     void inflateStrokeRect(FloatRect&) const;
358
359     template<class T> void fullCanvasCompositedDrawImage(T*, ColorSpace, const FloatRect&, const FloatRect&, CompositeOperator);
360
361     void prepareGradientForDashboard(CanvasGradient& gradient) const;
362
363     RefPtr<ImageData> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode&) const;
364     void putImageData(ImageData*, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
365
366     virtual bool is2d() const override { return true; }
367     virtual bool isAccelerated() const override;
368
369     virtual bool hasInvertibleTransform() const override { return state().m_hasInvertibleTransform; }
370     TextDirection toTextDirection(Direction, RenderStyle** computedStyle = nullptr) const;
371
372 #if ENABLE(ACCELERATED_2D_CANVAS)
373     virtual PlatformLayer* platformLayer() const override;
374 #endif
375
376     Vector<State, 1> m_stateStack;
377     unsigned m_unrealizedSaveCount;
378     bool m_usesCSSCompatibilityParseMode;
379 #if ENABLE(DASHBOARD_SUPPORT)
380     bool m_usesDashboardCompatibilityMode;
381 #endif
382 };
383
384 } // namespace WebCore
385
386 #endif