Next batch of conversions to use C++ enum class instead of strings for enumerations
[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 #pragma once
27
28 #include "AffineTransform.h"
29 #include "CanvasPathMethods.h"
30 #include "CanvasRenderingContext.h"
31 #include "CanvasStyle.h"
32 #include "Color.h"
33 #include "FloatSize.h"
34 #include "FontCascade.h"
35 #include "FontSelectorClient.h"
36 #include "GraphicsContext.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 enum class CanvasWindingRule { Nonzero, Evenodd };
61 enum class ImageSmoothingQuality { Low, Medium, High };
62
63 class CanvasRenderingContext2D final : public CanvasRenderingContext, public CanvasPathMethods {
64 public:
65     CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
66     virtual ~CanvasRenderingContext2D();
67
68     const CanvasStyle& strokeStyle() const { return state().strokeStyle; }
69     void setStrokeStyle(CanvasStyle);
70
71     const CanvasStyle& fillStyle() const { return state().fillStyle; }
72     void setFillStyle(CanvasStyle);
73
74     float lineWidth() const;
75     void setLineWidth(float);
76
77     String lineCap() const;
78     void setLineCap(const String&);
79
80     String lineJoin() const;
81     void setLineJoin(const String&);
82
83     float miterLimit() const;
84     void setMiterLimit(float);
85
86     const Vector<float>& getLineDash() const;
87     void setLineDash(const Vector<float>&);
88     void setWebkitLineDash(const Vector<float>&);
89
90     float lineDashOffset() const;
91     void setLineDashOffset(float);
92     float webkitLineDashOffset() const;
93     void setWebkitLineDashOffset(float);
94
95     float shadowOffsetX() const;
96     void setShadowOffsetX(float);
97
98     float shadowOffsetY() const;
99     void setShadowOffsetY(float);
100
101     float shadowBlur() const;
102     void setShadowBlur(float);
103
104     String shadowColor() const;
105     void setShadowColor(const String&);
106
107     float globalAlpha() const;
108     void setGlobalAlpha(float);
109
110     String globalCompositeOperation() const;
111     void setGlobalCompositeOperation(const String&);
112
113     void save() { ++m_unrealizedSaveCount; }
114     void restore();
115
116     void scale(float sx, float sy);
117     void rotate(float angleInRadians);
118     void translate(float tx, float ty);
119     void transform(float m11, float m12, float m21, float m22, float dx, float dy);
120     void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
121
122     void setStrokeColor(const String& color, Optional<float> alpha = Nullopt);
123     void setStrokeColor(float grayLevel, float alpha = 1.0);
124     void setStrokeColor(float r, float g, float b, float a);
125     void setStrokeColor(float c, float m, float y, float k, float a);
126
127     void setFillColor(const String& color, Optional<float> alpha = Nullopt);
128     void setFillColor(float grayLevel, float alpha = 1.0f);
129     void setFillColor(float r, float g, float b, float a);
130     void setFillColor(float c, float m, float y, float k, float a);
131
132     void beginPath();
133
134     void fill(CanvasWindingRule = CanvasWindingRule::Nonzero);
135     void stroke();
136     void clip(CanvasWindingRule = CanvasWindingRule::Nonzero);
137
138     void fill(DOMPath&, CanvasWindingRule = CanvasWindingRule::Nonzero);
139     void stroke(DOMPath&);
140     void clip(DOMPath&, CanvasWindingRule = CanvasWindingRule::Nonzero);
141
142     bool isPointInPath(float x, float y, CanvasWindingRule = CanvasWindingRule::Nonzero);
143     bool isPointInStroke(float x, float y);
144
145     bool isPointInPath(DOMPath&, float x, float y, CanvasWindingRule = CanvasWindingRule::Nonzero);
146     bool isPointInStroke(DOMPath&, float x, float y);
147
148     void clearRect(float x, float y, float width, float height);
149     void fillRect(float x, float y, float width, float height);
150     void strokeRect(float x, float y, float width, float height);
151
152     void setShadow(float width, float height, float blur, const String& color = String(), Optional<float> alpha = Nullopt);
153     void setShadow(float width, float height, float blur, float grayLevel, float alpha = 1.0);
154     void setShadow(float width, float height, float blur, float r, float g, float b, float a);
155     void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
156
157     void clearShadow();
158
159     void drawImage(HTMLImageElement&, float x, float y, ExceptionCode&);
160     void drawImage(HTMLImageElement&, float x, float y, float width, float height, ExceptionCode&);
161     void drawImage(HTMLImageElement&, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
162     void drawImage(HTMLImageElement&, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
163     void drawImage(HTMLCanvasElement&, float x, float y, ExceptionCode&);
164     void drawImage(HTMLCanvasElement&, float x, float y, float width, float height, ExceptionCode&);
165     void drawImage(HTMLCanvasElement&, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
166     void drawImage(HTMLCanvasElement&, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
167     void drawImage(HTMLImageElement&, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&, ExceptionCode&);
168 #if ENABLE(VIDEO)
169     void drawImage(HTMLVideoElement&, float x, float y, ExceptionCode&);
170     void drawImage(HTMLVideoElement&, float x, float y, float width, float height, ExceptionCode&);
171     void drawImage(HTMLVideoElement&, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionCode&);
172     void drawImage(HTMLVideoElement&, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
173 #endif
174
175     void drawImageFromRect(HTMLImageElement&, float sx = 0, float sy = 0, float sw = 0, float sh = 0,
176                            float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
177
178     void setAlpha(float);
179
180     void setCompositeOperation(const String&);
181
182     RefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode&);
183     RefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode&);
184     RefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&);
185     RefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&);
186
187     RefPtr<ImageData> createImageData(RefPtr<ImageData>&&, ExceptionCode&) const;
188     RefPtr<ImageData> createImageData(float width, float height, ExceptionCode&) const;
189     RefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionCode&) const;
190     RefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionCode&) const;
191     void putImageData(ImageData*, float dx, float dy, ExceptionCode&);
192     void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
193     void webkitPutImageDataHD(ImageData*, float dx, float dy, ExceptionCode&);
194     void webkitPutImageDataHD(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
195
196     void drawFocusIfNeeded(Element*);
197     void drawFocusIfNeeded(DOMPath&, Element*);
198
199     float webkitBackingStorePixelRatio() const { return 1; }
200
201     void reset();
202
203     String font() const;
204     void setFont(const String&);
205
206     String textAlign() const;
207     void setTextAlign(const String&);
208
209     String textBaseline() const;
210     void setTextBaseline(const String&);
211
212     String direction() const;
213     void setDirection(const String&);
214
215     void fillText(const String& text, float x, float y, Optional<float> maxWidth = Nullopt);
216     void strokeText(const String& text, float x, float y, Optional<float> maxWidth = Nullopt);
217     Ref<TextMetrics> measureText(const String& text);
218
219     LineCap getLineCap() const { return state().lineCap; }
220     LineJoin getLineJoin() const { return state().lineJoin; }
221
222     bool imageSmoothingEnabled() const;
223     void setImageSmoothingEnabled(bool);
224
225     ImageSmoothingQuality imageSmoothingQuality() const;
226     void setImageSmoothingQuality(ImageSmoothingQuality);
227
228     bool usesDisplayListDrawing() const { return m_usesDisplayListDrawing; };
229     void setUsesDisplayListDrawing(bool flag) { m_usesDisplayListDrawing = flag; };
230
231     bool tracksDisplayListReplay() const { return m_tracksDisplayListReplay; }
232     void setTracksDisplayListReplay(bool);
233
234     String displayListAsText(DisplayList::AsTextFlags) const;
235     String replayDisplayListAsText(DisplayList::AsTextFlags) const;
236
237 private:
238     enum class Direction {
239         Inherit,
240         RTL,
241         LTR
242     };
243
244     class FontProxy : public FontSelectorClient {
245     public:
246         FontProxy() = default;
247         virtual ~FontProxy();
248         FontProxy(const FontProxy&);
249         FontProxy& operator=(const FontProxy&);
250
251         bool realized() const { return m_font.fontSelector(); }
252         void initialize(FontSelector&, const RenderStyle&);
253         FontMetrics fontMetrics() const;
254         const FontCascadeDescription& fontDescription() const;
255         float width(const TextRun&) const;
256         void drawBidiText(GraphicsContext&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction) const;
257
258     private:
259         void update(FontSelector&);
260         void fontsNeedUpdate(FontSelector&) override;
261
262         FontCascade m_font;
263     };
264
265     struct State final {
266         State();
267
268         State(const State&);
269         State& operator=(const State&);
270
271         String unparsedStrokeColor;
272         String unparsedFillColor;
273         CanvasStyle strokeStyle;
274         CanvasStyle fillStyle;
275         float lineWidth;
276         LineCap lineCap;
277         LineJoin lineJoin;
278         float miterLimit;
279         FloatSize shadowOffset;
280         float shadowBlur;
281         RGBA32 shadowColor;
282         float globalAlpha;
283         CompositeOperator globalComposite;
284         BlendMode globalBlend;
285         AffineTransform transform;
286         bool hasInvertibleTransform;
287         Vector<float> lineDash;
288         float lineDashOffset;
289         bool imageSmoothingEnabled;
290         ImageSmoothingQuality imageSmoothingQuality;
291
292         // Text state.
293         TextAlign textAlign;
294         TextBaseline textBaseline;
295         Direction direction;
296
297         String unparsedFont;
298         FontProxy font;
299     };
300
301     enum CanvasDidDrawOption {
302         CanvasDidDrawApplyNone = 0,
303         CanvasDidDrawApplyTransform = 1,
304         CanvasDidDrawApplyShadow = 1 << 1,
305         CanvasDidDrawApplyClip = 1 << 2,
306         CanvasDidDrawApplyAll = 0xffffffff
307     };
308
309     State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); }
310     const State& state() const { return m_stateStack.last(); }
311
312     void applyLineDash() const;
313     void setShadow(const FloatSize& offset, float blur, RGBA32 color);
314     void applyShadow();
315     bool shouldDrawShadows() const;
316
317     void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
318     void didDrawEntireCanvas();
319
320     void paintRenderingResultsToCanvas() override;
321
322     GraphicsContext* drawingContext() const;
323
324     void unwindStateStack();
325     void realizeSaves()
326     {
327         if (m_unrealizedSaveCount)
328             realizeSavesLoop();
329     }
330     void realizeSavesLoop();
331
332     void applyStrokePattern();
333     void applyFillPattern();
334
335     void drawTextInternal(const String& text, float x, float y, bool fill, Optional<float> maxWidth = Nullopt);
336
337     // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants.
338     // Therefore, all font operations must pass through the State.
339     const FontProxy& fontProxy();
340
341 #if ENABLE(DASHBOARD_SUPPORT)
342     void clearPathForDashboardBackwardCompatibilityMode();
343 #endif
344
345     void beginCompositeLayer();
346     void endCompositeLayer();
347
348     void fillInternal(const Path&, CanvasWindingRule);
349     void strokeInternal(const Path&);
350     void clipInternal(const Path&, CanvasWindingRule);
351
352     bool isPointInPathInternal(const Path&, float x, float y, CanvasWindingRule);
353     bool isPointInStrokeInternal(const Path&, float x, float y);
354
355     void drawFocusIfNeededInternal(const Path&, Element*);
356
357     void clearCanvas();
358     Path transformAreaToDevice(const Path&) const;
359     Path transformAreaToDevice(const FloatRect&) const;
360     bool rectContainsCanvas(const FloatRect&) const;
361
362     template<class T> IntRect calculateCompositingBufferRect(const T&, IntSize*);
363     std::unique_ptr<ImageBuffer> createCompositingBuffer(const IntRect&);
364     void compositeBuffer(ImageBuffer&, const IntRect&, CompositeOperator);
365
366     void inflateStrokeRect(FloatRect&) const;
367
368     template<class T> void fullCanvasCompositedDrawImage(T&, const FloatRect&, const FloatRect&, CompositeOperator);
369
370     void prepareGradientForDashboard(CanvasGradient& gradient) const;
371
372     RefPtr<ImageData> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh, ExceptionCode&) const;
373     void putImageData(ImageData*, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
374
375     bool is2d() const override { return true; }
376     bool isAccelerated() const override;
377
378     bool hasInvertibleTransform() const override { return state().hasInvertibleTransform; }
379     TextDirection toTextDirection(Direction, const RenderStyle** computedStyle = nullptr) const;
380
381 #if ENABLE(ACCELERATED_2D_CANVAS)
382     PlatformLayer* platformLayer() const override;
383 #endif
384
385     Vector<State, 1> m_stateStack;
386     unsigned m_unrealizedSaveCount { 0 };
387     bool m_usesCSSCompatibilityParseMode;
388 #if ENABLE(DASHBOARD_SUPPORT)
389     bool m_usesDashboardCompatibilityMode;
390 #endif
391
392     bool m_usesDisplayListDrawing { false };
393     bool m_tracksDisplayListReplay { false };
394     mutable std::unique_ptr<struct DisplayListDrawingContext> m_recordingContext;
395 };
396
397 } // namespace WebCore
398
399 SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::CanvasRenderingContext2D, is2d())