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