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/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