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