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 47 namespace blink { class WebLayer; } 48 49 namespace blink { 50 51 class CanvasImageSource; 52 class CanvasGradient; 53 class CanvasPattern; 54 class CanvasStyle; 55 class Path2D; 56 class Element; 57 class ExceptionState; 58 class FloatRect; 59 class GraphicsContext; 60 class HTMLCanvasElement; 61 class HTMLImageElement; 62 class HTMLVideoElement; 63 class HitRegionOptions; 64 class ImageBitmap; 65 class ImageData; 66 class TextMetrics; 67 68 typedef WillBeHeapHashMap<String, RefPtrWillBeMember<MutableStylePropertySet> > MutableStylePropertyMap; 69 70 class CanvasRenderingContext2D FINAL: public CanvasRenderingContext, public ScriptWrappable, public CanvasPathMethods { 71 DEFINE_WRAPPERTYPEINFO(); 72 public: 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 247 private: 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 386 DEFINE_TYPE_CASTS(CanvasRenderingContext2D, CanvasRenderingContext, context, context->is2d(), context.is2d()); 387 388 } // namespace blink 389 390 #endif // CanvasRenderingContext2D_h 391