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/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/svg/SVGMatrixTearOff.h" 35 #include "platform/fonts/Font.h" 36 #include "platform/graphics/Color.h" 37 #include "platform/geometry/FloatSize.h" 38 #include "platform/graphics/GraphicsTypes.h" 39 #include "platform/graphics/ImageBuffer.h" 40 #include "platform/graphics/Path.h" 41 #include "platform/transforms/AffineTransform.h" 42 #include "wtf/HashMap.h" 43 #include "wtf/Vector.h" 44 #include "wtf/text/WTFString.h" 45 46 namespace blink { class WebLayer; } 47 48 namespace WebCore { 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 HTMLVideoElement; 62 class ImageBitmap; 63 class ImageData; 64 class TextMetrics; 65 66 typedef WillBeHeapHashMap<String, RefPtrWillBeMember<MutableStylePropertySet> > MutableStylePropertyMap; 67 68 class CanvasRenderingContext2D FINAL: public CanvasRenderingContext, public ScriptWrappable, public CanvasPathMethods { 69 public: create(HTMLCanvasElement * canvas,const Canvas2DContextAttributes * attrs,bool usesCSSCompatibilityParseMode)70 static PassOwnPtrWillBeRawPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode) 71 { 72 return adoptPtrWillBeNoop(new CanvasRenderingContext2D(canvas, attrs, usesCSSCompatibilityParseMode)); 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 float globalAlpha() const; 113 void setGlobalAlpha(float); 114 115 bool isContextLost() const; 116 117 String globalCompositeOperation() const; 118 void setGlobalCompositeOperation(const String&); 119 save()120 void save() { ++m_stateStack.last()->m_unrealizedSaveCount; } 121 void restore(); 122 currentTransform()123 PassRefPtr<SVGMatrixTearOff> currentTransform() const 124 { 125 return SVGMatrixTearOff::create(state().m_transform); 126 } 127 void setCurrentTransform(PassRefPtr<SVGMatrixTearOff>); 128 129 void scale(float sx, float sy); 130 void rotate(float angleInRadians); 131 void translate(float tx, float ty); 132 void transform(float m11, float m12, float m21, float m22, float dx, float dy); 133 void setTransform(float m11, float m12, float m21, float m22, float dx, float dy); 134 void resetTransform(); 135 136 void setStrokeColor(const String& color); 137 void setStrokeColor(float grayLevel); 138 void setStrokeColor(const String& color, float alpha); 139 void setStrokeColor(float grayLevel, float alpha); 140 void setStrokeColor(float r, float g, float b, float a); 141 void setStrokeColor(float c, float m, float y, float k, float a); 142 143 void setFillColor(const String& color); 144 void setFillColor(float grayLevel); 145 void setFillColor(const String& color, float alpha); 146 void setFillColor(float grayLevel, float alpha); 147 void setFillColor(float r, float g, float b, float a); 148 void setFillColor(float c, float m, float y, float k, float a); 149 150 void beginPath(); 151 152 void fill(const String& winding = "nonzero"); 153 void fill(Path2D*, const String& winding = "nonzero"); 154 void stroke(); 155 void stroke(Path2D*); 156 void clip(const String& winding = "nonzero"); 157 void clip(Path2D*, const String& winding = "nonzero"); 158 159 bool isPointInPath(const float x, const float y, const String& winding = "nonzero"); 160 bool isPointInPath(Path2D*, const float x, const float y, const String& winding = "nonzero"); 161 bool isPointInStroke(const float x, const float y); 162 bool isPointInStroke(Path2D*, const float x, const float y); 163 164 void scrollPathIntoView(); 165 void scrollPathIntoView(Path2D*); 166 167 void clearRect(float x, float y, float width, float height); 168 void fillRect(float x, float y, float width, float height); 169 void strokeRect(float x, float y, float width, float height); 170 171 void setShadow(float width, float height, float blur); 172 void setShadow(float width, float height, float blur, const String& color); 173 void setShadow(float width, float height, float blur, float grayLevel); 174 void setShadow(float width, float height, float blur, const String& color, float alpha); 175 void setShadow(float width, float height, float blur, float grayLevel, float alpha); 176 void setShadow(float width, float height, float blur, float r, float g, float b, float a); 177 void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a); 178 179 void clearShadow(); 180 181 void drawImage(CanvasImageSource*, float x, float y, ExceptionState&); 182 void drawImage(CanvasImageSource*, float x, float y, float width, float height, ExceptionState&); 183 void drawImage(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&); 184 185 void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0, 186 float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString()); 187 188 void setAlpha(float); 189 190 void setCompositeOperation(const String&); 191 192 PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1); 193 PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState&); 194 PassRefPtr<CanvasPattern> createPattern(CanvasImageSource*, const String& repetitionType, ExceptionState&); 195 196 PassRefPtrWillBeRawPtr<ImageData> createImageData(PassRefPtrWillBeRawPtr<ImageData>) const; 197 PassRefPtrWillBeRawPtr<ImageData> createImageData(float width, float height, ExceptionState&) const; 198 PassRefPtrWillBeRawPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionState&) const; 199 void putImageData(ImageData*, float dx, float dy); 200 void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight); 201 202 void reset(); 203 204 String font() const; 205 void setFont(const String&); 206 207 String textAlign() const; 208 void setTextAlign(const String&); 209 210 String textBaseline() const; 211 void setTextBaseline(const String&); 212 213 void fillText(const String& text, float x, float y); 214 void fillText(const String& text, float x, float y, float maxWidth); 215 void strokeText(const String& text, float x, float y); 216 void strokeText(const String& text, float x, float y, float maxWidth); 217 PassRefPtr<TextMetrics> measureText(const String& text); 218 getLineCap()219 LineCap getLineCap() const { return state().m_lineCap; } getLineJoin()220 LineJoin getLineJoin() const { return state().m_lineJoin; } 221 222 bool imageSmoothingEnabled() const; 223 void setImageSmoothingEnabled(bool); 224 225 PassRefPtr<Canvas2DContextAttributes> getContextAttributes() const; 226 227 void drawFocusIfNeeded(Element*); 228 void drawFocusIfNeeded(Path2D*, Element*); 229 230 void loseContext(); 231 void restoreContext(); 232 233 virtual void trace(Visitor*) OVERRIDE; 234 235 private: 236 class State FINAL : public CSSFontSelectorClient { 237 public: 238 State(); 239 virtual ~State(); 240 241 State(const State&); 242 State& operator=(const State&); 243 244 // CSSFontSelectorClient implementation 245 virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE; 246 trace(Visitor * visitor)247 virtual void trace(Visitor* visitor) OVERRIDE { CSSFontSelectorClient::trace(visitor); } 248 249 unsigned m_unrealizedSaveCount; 250 251 String m_unparsedStrokeColor; 252 String m_unparsedFillColor; 253 RefPtr<CanvasStyle> m_strokeStyle; 254 RefPtr<CanvasStyle> m_fillStyle; 255 float m_lineWidth; 256 LineCap m_lineCap; 257 LineJoin m_lineJoin; 258 float m_miterLimit; 259 FloatSize m_shadowOffset; 260 float m_shadowBlur; 261 RGBA32 m_shadowColor; 262 float m_globalAlpha; 263 CompositeOperator m_globalComposite; 264 blink::WebBlendMode m_globalBlend; 265 AffineTransform m_transform; 266 bool m_invertibleCTM; 267 Vector<float> m_lineDash; 268 float m_lineDashOffset; 269 bool m_imageSmoothingEnabled; 270 271 // Text state. 272 TextAlign m_textAlign; 273 TextBaseline m_textBaseline; 274 275 String m_unparsedFont; 276 Font m_font; 277 bool m_realizedFont; 278 }; 279 280 CanvasRenderingContext2D(HTMLCanvasElement*, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode); 281 modifiableState()282 State& modifiableState() { ASSERT(!state().m_unrealizedSaveCount); return *m_stateStack.last(); } state()283 const State& state() const { return *m_stateStack.last(); } 284 285 void applyLineDash() const; 286 void setShadow(const FloatSize& offset, float blur, RGBA32 color); 287 void applyShadow(); 288 bool shouldDrawShadows() const; 289 290 void dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*); 291 void dispatchContextRestoredEvent(Timer<CanvasRenderingContext2D>*); 292 void tryRestoreContextEvent(Timer<CanvasRenderingContext2D>*); 293 294 bool computeDirtyRect(const FloatRect& localBounds, FloatRect*); 295 bool computeDirtyRect(const FloatRect& localBounds, const FloatRect& transformedClipBounds, FloatRect*); 296 void didDraw(const FloatRect&); 297 298 GraphicsContext* drawingContext() const; 299 300 void unwindStateStack(); 301 void realizeSaves(); 302 303 void applyStrokePattern(); 304 void applyFillPattern(); 305 306 void drawImageInternal(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&, CompositeOperator, blink::WebBlendMode); 307 void drawVideo(HTMLVideoElement*, FloatRect srcRect, FloatRect dstRect); 308 309 void fillInternal(const Path&, const String& windingRuleString); 310 void strokeInternal(const Path&); 311 void clipInternal(const Path&, const String& windingRuleString); 312 313 bool isPointInPathInternal(const Path&, const float x, const float y, const String& windingRuleString); 314 bool isPointInStrokeInternal(const Path&, const float x, const float y); 315 316 void scrollPathIntoViewInternal(const Path&); 317 318 void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false); 319 320 const Font& accessFont(); 321 int getFontBaseline(const FontMetrics&) const; 322 323 void clearCanvas(); 324 bool rectContainsTransformedRect(const FloatRect&, const FloatRect&) const; 325 326 void inflateStrokeRect(FloatRect&) const; 327 328 template<class T> void fullCanvasCompositedFill(const T&); 329 template<class T> void fullCanvasCompositedStroke(const T&); 330 template<class T> void fullCanvasCompositedDrawImage(T*, const FloatRect&, const FloatRect&, CompositeOperator); 331 332 void drawFocusIfNeededInternal(const Path&, Element*); 333 bool focusRingCallIsValid(const Path&, Element*); 334 void drawFocusRing(const Path&); 335 336 void validateStateStack(); 337 is2d()338 virtual bool is2d() const OVERRIDE { return true; } 339 virtual bool isAccelerated() const OVERRIDE; hasAlpha()340 virtual bool hasAlpha() const OVERRIDE { return m_hasAlpha; } 341 isTransformInvertible()342 virtual bool isTransformInvertible() const OVERRIDE { return state().m_invertibleCTM; } 343 344 virtual blink::WebLayer* platformLayer() const OVERRIDE; 345 346 WillBeHeapVector<OwnPtrWillBeMember<State> > m_stateStack; 347 bool m_usesCSSCompatibilityParseMode; 348 bool m_hasAlpha; 349 bool m_isContextLost; 350 bool m_contextRestorable; 351 Canvas2DContextStorage m_storageMode; 352 MutableStylePropertyMap m_fetchedFonts; 353 unsigned m_tryRestoreContextAttemptCount; 354 Timer<CanvasRenderingContext2D> m_dispatchContextLostEventTimer; 355 Timer<CanvasRenderingContext2D> m_dispatchContextRestoredEventTimer; 356 Timer<CanvasRenderingContext2D> m_tryRestoreContextEventTimer; 357 }; 358 359 DEFINE_TYPE_CASTS(CanvasRenderingContext2D, CanvasRenderingContext, context, context->is2d(), context.is2d()); 360 361 } // namespace WebCore 362 363 #endif 364