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 "core/html/canvas/Canvas2DContextAttributes.h" 30 #include "core/html/canvas/CanvasPathMethods.h" 31 #include "core/html/canvas/CanvasRenderingContext.h" 32 #include "core/platform/graphics/Color.h" 33 #include "core/platform/graphics/FloatSize.h" 34 #include "core/platform/graphics/Font.h" 35 #include "core/platform/graphics/GraphicsTypes.h" 36 #include "core/platform/graphics/ImageBuffer.h" 37 #include "core/platform/graphics/Path.h" 38 #include "core/platform/graphics/transforms/AffineTransform.h" 39 #include "wtf/HashMap.h" 40 #include "wtf/Vector.h" 41 #include "wtf/text/WTFString.h" 42 43 namespace WebKit { class WebLayer; } 44 45 namespace WebCore { 46 47 class CanvasGradient; 48 class CanvasPattern; 49 class CanvasStyle; 50 class DOMPath; 51 class Element; 52 class ExceptionState; 53 class FloatRect; 54 class GraphicsContext; 55 class HTMLCanvasElement; 56 class HTMLImageElement; 57 class HTMLVideoElement; 58 class ImageBitmap; 59 class ImageData; 60 class TextMetrics; 61 62 typedef HashMap<String, RefPtr<MutableStylePropertySet> > MutableStylePropertyMap; 63 64 class CanvasRenderingContext2D : public CanvasRenderingContext, public CanvasPathMethods { 65 public: 66 static PassOwnPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode) 67 { 68 return adoptPtr(new CanvasRenderingContext2D(canvas, attrs, usesCSSCompatibilityParseMode)); 69 } 70 virtual ~CanvasRenderingContext2D(); 71 72 CanvasStyle* strokeStyle() const; 73 void setStrokeStyle(PassRefPtr<CanvasStyle>); 74 75 CanvasStyle* fillStyle() const; 76 void setFillStyle(PassRefPtr<CanvasStyle>); 77 78 float lineWidth() const; 79 void setLineWidth(float); 80 81 String lineCap() const; 82 void setLineCap(const String&); 83 84 String lineJoin() const; 85 void setLineJoin(const String&); 86 87 float miterLimit() const; 88 void setMiterLimit(float); 89 90 const Vector<float>& getLineDash() const; 91 void setLineDash(const Vector<float>&); 92 void setWebkitLineDash(const Vector<float>&); 93 94 float lineDashOffset() const; 95 void setLineDashOffset(float); 96 float webkitLineDashOffset() const; 97 void setWebkitLineDashOffset(float); 98 99 float shadowOffsetX() const; 100 void setShadowOffsetX(float); 101 102 float shadowOffsetY() const; 103 void setShadowOffsetY(float); 104 105 float shadowBlur() const; 106 void setShadowBlur(float); 107 108 String shadowColor() const; 109 void setShadowColor(const String&); 110 111 float globalAlpha() const; 112 void setGlobalAlpha(float); 113 114 String globalCompositeOperation() const; 115 void setGlobalCompositeOperation(const String&); 116 117 void save() { ++m_unrealizedSaveCount; } 118 void restore(); 119 120 void scale(float sx, float sy); 121 void rotate(float angleInRadians); 122 void translate(float tx, float ty); 123 void transform(float m11, float m12, float m21, float m22, float dx, float dy); 124 void setTransform(float m11, float m12, float m21, float m22, float dx, float dy); 125 126 void setStrokeColor(const String& color); 127 void setStrokeColor(float grayLevel); 128 void setStrokeColor(const String& color, float alpha); 129 void setStrokeColor(float grayLevel, float alpha); 130 void setStrokeColor(float r, float g, float b, float a); 131 void setStrokeColor(float c, float m, float y, float k, float a); 132 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 PassRefPtr<DOMPath> currentPath(); 143 void setCurrentPath(DOMPath*); 144 void fill(const String& winding = "nonzero"); 145 void stroke(); 146 void clip(const String& winding = "nonzero"); 147 148 bool isPointInPath(const float x, const float y, const String& winding = "nonzero"); 149 bool isPointInStroke(const float x, const float y); 150 151 void clearRect(float x, float y, float width, float height); 152 void fillRect(float x, float y, float width, float height); 153 void strokeRect(float x, float y, float width, float height); 154 155 void setShadow(float width, float height, float blur); 156 void setShadow(float width, float height, float blur, const String& color); 157 void setShadow(float width, float height, float blur, float grayLevel); 158 void setShadow(float width, float height, float blur, const String& color, float alpha); 159 void setShadow(float width, float height, float blur, float grayLevel, float alpha); 160 void setShadow(float width, float height, float blur, float r, float g, float b, float a); 161 void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a); 162 163 void clearShadow(); 164 165 void drawImage(ImageBitmap*, float x, float y, ExceptionState&); 166 void drawImage(ImageBitmap*, float x, float y, float width, float height, ExceptionState&); 167 void drawImage(ImageBitmap*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&); 168 void drawImage(HTMLImageElement*, float x, float y, ExceptionState&); 169 void drawImage(HTMLImageElement*, float x, float y, float width, float height, ExceptionState&); 170 void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&); 171 void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&); 172 void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const BlendMode&, ExceptionState&); 173 void drawImage(HTMLCanvasElement*, float x, float y, ExceptionState&); 174 void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionState&); 175 void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&); 176 void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&); 177 void drawImage(HTMLVideoElement*, float x, float y, ExceptionState&); 178 void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionState&); 179 void drawImage(HTMLVideoElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&); 180 void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&); 181 182 void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0, 183 float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString()); 184 185 void setAlpha(float); 186 187 void setCompositeOperation(const String&); 188 189 PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionState&); 190 PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState&); 191 PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionState&); 192 PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionState&); 193 194 PassRefPtr<ImageData> createImageData(PassRefPtr<ImageData>, ExceptionState&) const; 195 PassRefPtr<ImageData> createImageData(float width, float height, ExceptionState&) const; 196 PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionState&) const; 197 PassRefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionState&) const; 198 void putImageData(ImageData*, float dx, float dy, ExceptionState&); 199 void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionState&); 200 void webkitPutImageDataHD(ImageData*, float dx, float dy, ExceptionState&); 201 void webkitPutImageDataHD(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionState&); 202 203 float webkitBackingStorePixelRatio() const { return canvas()->deviceScaleFactor(); } 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 void fillText(const String& text, float x, float y); 217 void fillText(const String& text, float x, float y, float maxWidth); 218 void strokeText(const String& text, float x, float y); 219 void strokeText(const String& text, float x, float y, float maxWidth); 220 PassRefPtr<TextMetrics> measureText(const String& text); 221 222 LineCap getLineCap() const { return state().m_lineCap; } 223 LineJoin getLineJoin() const { return state().m_lineJoin; } 224 225 bool imageSmoothingEnabled() const; 226 void setImageSmoothingEnabled(bool); 227 228 PassRefPtr<Canvas2DContextAttributes> getContextAttributes() const; 229 230 void drawSystemFocusRing(Element*); 231 bool drawCustomFocusRing(Element*); 232 233 private: 234 struct State : FontSelectorClient { 235 State(); 236 virtual ~State(); 237 238 State(const State&); 239 State& operator=(const State&); 240 241 virtual void fontsNeedUpdate(FontSelector*) OVERRIDE; 242 243 String m_unparsedStrokeColor; 244 String m_unparsedFillColor; 245 RefPtr<CanvasStyle> m_strokeStyle; 246 RefPtr<CanvasStyle> m_fillStyle; 247 float m_lineWidth; 248 LineCap m_lineCap; 249 LineJoin m_lineJoin; 250 float m_miterLimit; 251 FloatSize m_shadowOffset; 252 float m_shadowBlur; 253 RGBA32 m_shadowColor; 254 float m_globalAlpha; 255 CompositeOperator m_globalComposite; 256 BlendMode m_globalBlend; 257 AffineTransform m_transform; 258 bool m_invertibleCTM; 259 Vector<float> m_lineDash; 260 float m_lineDashOffset; 261 bool m_imageSmoothingEnabled; 262 263 // Text state. 264 TextAlign m_textAlign; 265 TextBaseline m_textBaseline; 266 267 String m_unparsedFont; 268 Font m_font; 269 bool m_realizedFont; 270 }; 271 272 enum CanvasDidDrawOption { 273 CanvasDidDrawApplyNone = 0, 274 CanvasDidDrawApplyTransform = 1, 275 CanvasDidDrawApplyShadow = 1 << 1, 276 CanvasDidDrawApplyClip = 1 << 2, 277 CanvasDidDrawApplyAll = 0xffffffff 278 }; 279 280 CanvasRenderingContext2D(HTMLCanvasElement*, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode); 281 282 State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); } 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 drawImageInternal(Image*, const FloatRect&, const FloatRect&, const CompositeOperator&, const BlendMode&); 291 void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll); 292 void didDrawEntireCanvas(); 293 294 GraphicsContext* drawingContext() const; 295 296 void unwindStateStack(); 297 void realizeSaves() 298 { 299 if (m_unrealizedSaveCount) 300 realizeSavesLoop(); 301 } 302 void realizeSavesLoop(); 303 304 void applyStrokePattern(); 305 void applyFillPattern(); 306 307 void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false); 308 309 const Font& accessFont(); 310 311 void clearCanvas(); 312 Path transformAreaToDevice(const Path&) const; 313 Path transformAreaToDevice(const FloatRect&) const; 314 bool rectContainsCanvas(const FloatRect&) const; 315 316 template<class T> IntRect calculateCompositingBufferRect(const T&, IntSize*); 317 PassOwnPtr<ImageBuffer> createCompositingBuffer(const IntRect&); 318 void compositeBuffer(ImageBuffer*, const IntRect&, CompositeOperator); 319 320 void inflateStrokeRect(FloatRect&) const; 321 322 template<class T> void fullCanvasCompositedFill(const T&); 323 template<class T> void fullCanvasCompositedDrawImage(T*, const FloatRect&, const FloatRect&, CompositeOperator); 324 325 PassRefPtr<ImageData> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh, ExceptionState&) const; 326 void putImageData(ImageData*, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionState&); 327 328 bool focusRingCallIsValid(const Path&, Element*); 329 void updateFocusRingAccessibility(const Path&, Element*); 330 void drawFocusRing(const Path&); 331 332 virtual bool is2d() const OVERRIDE { return true; } 333 virtual bool isAccelerated() const OVERRIDE; 334 virtual bool hasAlpha() const OVERRIDE { return m_hasAlpha; } 335 336 virtual bool isTransformInvertible() const { return state().m_invertibleCTM; } 337 338 virtual WebKit::WebLayer* platformLayer() const OVERRIDE; 339 340 Vector<State, 1> m_stateStack; 341 unsigned m_unrealizedSaveCount; 342 bool m_usesCSSCompatibilityParseMode; 343 bool m_hasAlpha; 344 MutableStylePropertyMap m_fetchedFonts; 345 }; 346 347 } // namespace WebCore 348 349 #endif 350