Home | History | Annotate | Download | only in canvas
      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:
     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 
    120     void save() { ++m_stateStack.last()->m_unrealizedSaveCount; }
    121     void restore();
    122 
    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 
    219     LineCap getLineCap() const { return state().m_lineCap; }
    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 
    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 
    282     State& modifiableState() { ASSERT(!state().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 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 
    338     virtual bool is2d() const OVERRIDE { return true; }
    339     virtual bool isAccelerated() const OVERRIDE;
    340     virtual bool hasAlpha() const OVERRIDE { return m_hasAlpha; }
    341 
    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