Home | History | Annotate | Download | only in skia
      1 /*
      2  * Copyright (c) 2008, Google 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 are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifndef PlatformContextSkia_h
     32 #define PlatformContextSkia_h
     33 
     34 #include "GraphicsContext.h"
     35 #include "Noncopyable.h"
     36 
     37 #include "SkDashPathEffect.h"
     38 #include "SkDrawLooper.h"
     39 #include "SkDeque.h"
     40 #include "skia/ext/platform_canvas.h"
     41 #include "SkPaint.h"
     42 #include "SkPath.h"
     43 
     44 #include <wtf/Vector.h>
     45 
     46 // This class holds the platform-specific state for GraphicsContext. We put
     47 // most of our Skia wrappers on this class. In theory, a lot of this stuff could
     48 // be moved to GraphicsContext directly, except that some code external to this
     49 // would like to poke at our graphics layer as well (like the Image and Font
     50 // stuff, which needs some amount of our wrappers and state around SkCanvas).
     51 //
     52 // So in general, this class uses just Skia types except when there's no easy
     53 // conversion. GraphicsContext is responsible for converting the WebKit types to
     54 // Skia types and setting up the eventual call to the Skia functions.
     55 //
     56 // This class then keeps track of all the current Skia state. WebKit expects
     57 // that the graphics state that is pushed and popped by save() and restore()
     58 // includes things like colors and pen styles. Skia does this differently, where
     59 // push and pop only includes transforms and bitmaps, and the application is
     60 // responsible for managing the painting state which is store in separate
     61 // SkPaint objects. This class provides the adaptor that allows the painting
     62 // state to be pushed and popped along with the bitmap.
     63 class PlatformContextSkia : public Noncopyable {
     64 public:
     65     // For printing, there shouldn't be any canvas. canvas can be NULL. If you
     66     // supply a NULL canvas, you can also call setCanvas later.
     67     PlatformContextSkia(skia::PlatformCanvas*);
     68     ~PlatformContextSkia();
     69 
     70     // Sets the canvas associated with this context. Use when supplying NULL
     71     // to the constructor.
     72     void setCanvas(skia::PlatformCanvas*);
     73 
     74 #if OS(WINDOWS)
     75     // If false we're rendering to a GraphicsContext for a web page, if false
     76     // we're not (as is the case when rendering to a canvas object).
     77     // If this is true the contents have not been marked up with the magic
     78     // color and all text drawing needs to go to a layer so that the alpha is
     79     // correctly updated.
     80     void setDrawingToImageBuffer(bool);
     81     bool isDrawingToImageBuffer() const;
     82 #endif
     83 
     84     void save();
     85     void restore();
     86 
     87     // Begins a layer that is clipped to the image |imageBuffer| at the location
     88     // |rect|. This layer is implicitly restored when the next restore is
     89     // invoked.
     90     // NOTE: |imageBuffer| may be deleted before the |restore| is invoked.
     91 #if OS(LINUX) || OS(WINDOWS)
     92     void beginLayerClippedToImage(const WebCore::FloatRect&,
     93                                   const WebCore::ImageBuffer*);
     94 #endif
     95     void clipPathAntiAliased(const SkPath&);
     96 
     97     // Sets up the common flags on a paint for antialiasing, effects, etc.
     98     // This is implicitly called by setupPaintFill and setupPaintStroke, but
     99     // you may wish to call it directly sometimes if you don't want that other
    100     // behavior.
    101     void setupPaintCommon(SkPaint*) const;
    102 
    103     // Sets up the paint for the current fill style.
    104     void setupPaintForFilling(SkPaint*) const;
    105 
    106     // Sets up the paint for stroking. Returns an int representing the width of
    107     // the pen, or 1 if the pen's width is 0 if a non-zero length is provided,
    108     // the number of dashes/dots on a dashed/dotted line will be adjusted to
    109     // start and end that length with a dash/dot.
    110     float setupPaintForStroking(SkPaint*, SkRect*, int length) const;
    111 
    112     // State setting functions.
    113     void setDrawLooper(SkDrawLooper*);  // Note: takes an additional ref.
    114     void setMiterLimit(float);
    115     void setAlpha(float);
    116     void setLineCap(SkPaint::Cap);
    117     void setLineJoin(SkPaint::Join);
    118     void setFillRule(SkPath::FillType);
    119     void setXfermodeMode(SkXfermode::Mode);
    120     void setFillColor(SkColor);
    121     void setFillShader(SkShader*);
    122     void setStrokeStyle(WebCore::StrokeStyle);
    123     void setStrokeColor(SkColor);
    124     void setStrokeThickness(float thickness);
    125     void setStrokeShader(SkShader*);
    126     void setTextDrawingMode(int mode);
    127     void setUseAntialiasing(bool enable);
    128     void setDashPathEffect(SkDashPathEffect*);
    129 
    130     SkDrawLooper* getDrawLooper() const;
    131     WebCore::StrokeStyle getStrokeStyle() const;
    132     float getStrokeThickness() const;
    133     int getTextDrawingMode() const;
    134     float getAlpha() const;
    135 
    136     void beginPath();
    137     void addPath(const SkPath&);
    138     SkPath currentPathInLocalCoordinates() const;
    139 
    140     // Returns the fill color. The returned color has it's alpha adjusted
    141     // by the current alpha.
    142     SkColor effectiveFillColor() const;
    143 
    144     // Returns the stroke color. The returned color has it's alpha adjusted
    145     // by the current alpha.
    146     SkColor effectiveStrokeColor() const;
    147 
    148     skia::PlatformCanvas* canvas() { return m_canvas; }
    149 
    150     // FIXME: This should be pushed down to GraphicsContext.
    151     void drawRect(SkRect rect);
    152 
    153     // FIXME: I'm still unsure how I will serialize this call.
    154     void paintSkPaint(const SkRect&, const SkPaint&);
    155 
    156     const SkBitmap* bitmap() const;
    157 
    158     // Returns the canvas used for painting, NOT guaranteed to be non-NULL.
    159     //
    160     // Warning: This function is deprecated so the users are reminded that they
    161     // should use this layer of indirection instead of using the canvas
    162     // directly. This is to help with the eventual serialization.
    163     skia::PlatformCanvas* canvas() const;
    164 
    165     // Returns if the context is a printing context instead of a display
    166     // context. Bitmap shouldn't be resampled when printing to keep the best
    167     // possible quality.
    168     bool isPrinting();
    169 
    170 private:
    171 #if OS(LINUX) || OS(WINDOWS)
    172     // Used when restoring and the state has an image clip. Only shows the pixels in
    173     // m_canvas that are also in imageBuffer.
    174     void applyClipFromImage(const WebCore::FloatRect&, const SkBitmap&);
    175 #endif
    176     void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
    177 
    178     // Defines drawing style.
    179     struct State;
    180 
    181     // NULL indicates painting is disabled. Never delete this object.
    182     skia::PlatformCanvas* m_canvas;
    183 
    184     // States stack. Enables local drawing state change with save()/restore()
    185     // calls.
    186     WTF::Vector<State> m_stateStack;
    187     // Pointer to the current drawing state. This is a cached value of
    188     // mStateStack.back().
    189     State* m_state;
    190 
    191     // Current path in global coordinates.
    192     SkPath m_path;
    193 
    194 #if OS(WINDOWS)
    195     bool m_drawingToImageBuffer;
    196 #endif
    197 };
    198 
    199 #endif  // PlatformContextSkia_h
    200