/* * Copyright (c) 2008, Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef PlatformContextSkia_h #define PlatformContextSkia_h #include "GraphicsContext.h" #include "OpaqueRegionSkia.h" #include "SkCanvas.h" #include "SkDashPathEffect.h" #include "SkDrawLooper.h" #include "SkPaint.h" #include "SkPath.h" #include #include namespace WebCore { enum CompositeOperator; class Texture; // This class holds the platform-specific state for GraphicsContext. We put // most of our Skia wrappers on this class. In theory, a lot of this stuff could // be moved to GraphicsContext directly, except that some code external to this // would like to poke at our graphics layer as well (like the Image and Font // stuff, which needs some amount of our wrappers and state around SkCanvas). // // So in general, this class uses just Skia types except when there's no easy // conversion. GraphicsContext is responsible for converting the WebKit types to // Skia types and setting up the eventual call to the Skia functions. // // This class then keeps track of all the current Skia state. WebKit expects // that the graphics state that is pushed and popped by save() and restore() // includes things like colors and pen styles. Skia does this differently, where // push and pop only includes transforms and bitmaps, and the application is // responsible for managing the painting state which is store in separate // SkPaint objects. This class provides the adaptor that allows the painting // state to be pushed and popped along with the bitmap. class PlatformContextSkia { WTF_MAKE_NONCOPYABLE(PlatformContextSkia); public: // For printing, there shouldn't be any canvas. canvas can be NULL. If you // supply a NULL canvas, you can also call setCanvas later. PlatformContextSkia(SkCanvas*); ~PlatformContextSkia(); // Sets the graphics context associated with this context. // GraphicsContextSkia calls this from its constructor. void setGraphicsContext(const GraphicsContext* gc) { m_gc = gc; } // Sets the canvas associated with this context. Use when supplying NULL // to the constructor. void setCanvas(SkCanvas*); // If false we're rendering to a GraphicsContext for a web page, if false // we're not (as is the case when rendering to a canvas object). // If this is true the contents have not been marked up with the magic // color and all text drawing needs to go to a layer so that the alpha is // correctly updated. void setDrawingToImageBuffer(bool); bool isDrawingToImageBuffer() const; void save(); void restore(); void saveLayer(const SkRect* bounds, const SkPaint*); void saveLayer(const SkRect* bounds, const SkPaint*, SkCanvas::SaveFlags); void restoreLayer(); // Begins a layer that is clipped to the image |imageBuffer| at the location // |rect|. This layer is implicitly restored when the next restore is // invoked. // NOTE: |imageBuffer| may be deleted before the |restore| is invoked. void beginLayerClippedToImage(const FloatRect&, const ImageBuffer*); void clipPathAntiAliased(const SkPath&); // Sets up the common flags on a paint for antialiasing, effects, etc. // This is implicitly called by setupPaintFill and setupPaintStroke, but // you may wish to call it directly sometimes if you don't want that other // behavior. void setupPaintCommon(SkPaint*) const; // Sets up the paint for the current fill style. void setupPaintForFilling(SkPaint*) const; // Sets up the paint for stroking. Returns an int representing the width of // the pen, or 1 if the pen's width is 0 if a non-zero length is provided, // the number of dashes/dots on a dashed/dotted line will be adjusted to // start and end that length with a dash/dot. float setupPaintForStroking(SkPaint*, SkRect*, int length) const; // State setting functions. void setDrawLooper(SkDrawLooper*); // Note: takes an additional ref. void setMiterLimit(float); void setAlpha(float); void setLineCap(SkPaint::Cap); void setLineJoin(SkPaint::Join); void setXfermodeMode(SkXfermode::Mode); void setFillColor(SkColor); void setStrokeStyle(StrokeStyle); void setStrokeColor(SkColor); void setStrokeThickness(float thickness); void setTextDrawingMode(TextDrawingModeFlags mode); void setUseAntialiasing(bool enable); void setDashPathEffect(SkDashPathEffect*); SkDrawLooper* getDrawLooper() const; StrokeStyle getStrokeStyle() const; float getStrokeThickness() const; TextDrawingModeFlags getTextDrawingMode() const; float getAlpha() const; int getNormalizedAlpha() const; SkXfermode::Mode getXfermodeMode() const; void canvasClipPath(const SkPath&); // Returns the fill color. The returned color has it's alpha adjusted // by the current alpha. SkColor effectiveFillColor() const; // Returns the stroke color. The returned color has it's alpha adjusted // by the current alpha. SkColor effectiveStrokeColor() const; // Returns the canvas used for painting, NOT guaranteed to be non-null. SkCanvas* canvas() { return m_canvas; } const SkCanvas* canvas() const { return m_canvas; } InterpolationQuality interpolationQuality() const; void setInterpolationQuality(InterpolationQuality interpolationQuality); // FIXME: This should be pushed down to GraphicsContext. void drawRect(SkRect rect); // FIXME: I'm still unsure how I will serialize this call. void paintSkPaint(const SkRect&, const SkPaint&); const SkBitmap* bitmap() const; // Returns if the context is a printing context instead of a display // context. Bitmap shouldn't be resampled when printing to keep the best // possible quality. bool printing() const { return m_printing; } void setPrinting(bool p) { m_printing = p; } // Returns if the context allows rendering of fonts using native platform // APIs. If false is returned font rendering is performed using the skia // text drawing APIs. // if USE(SKIA_TEXT) is enabled, this always returns false bool isNativeFontRenderingAllowed(); bool isAccelerated() const { return m_accelerated; } void setAccelerated(bool accelerated) { m_accelerated = accelerated; } // True if this context is deferring draw calls to be executed later. // We need to know this for context-to-context draws, in order to know if // the source bitmap needs to be copied. bool isDeferred() const { return m_deferred; } void setDeferred(bool deferred) { m_deferred = deferred; } float deviceScaleFactor() const { return m_deviceScaleFactor; } void setDeviceScaleFactor(float scale) { m_deviceScaleFactor = scale; } void setTrackOpaqueRegion(bool track) { m_trackOpaqueRegion = track; } // This will be an empty region unless tracking is enabled. const OpaqueRegionSkia& opaqueRegion() const { return m_opaqueRegion; } // After drawing in the context's canvas, use these functions to notify the context so it can track the opaque region. void didDrawRect(const SkRect&, const SkPaint&, const SkBitmap* = 0); void didDrawPath(const SkPath&, const SkPaint&); void didDrawPoints(SkCanvas::PointMode, int numPoints, const SkPoint[], const SkPaint&); // For drawing operations that do not fill the entire rect. void didDrawBounded(const SkRect&, const SkPaint&); // Turn off LCD text for the paint if not supported on this context. void adjustTextRenderMode(SkPaint*); bool couldUseLCDRenderedText(); #if defined(SK_SUPPORT_HINTING_SCALE_FACTOR) void setHintingScaleFactor(SkScalar factor) { m_hintingScaleFactor = factor; } SkScalar hintingScaleFactor() const { return m_hintingScaleFactor; } #endif private: // Used when restoring and the state has an image clip. Only shows the pixels in // m_canvas that are also in imageBuffer. // The clipping rectangle is given in absolute coordinates. void applyClipFromImage(const SkRect&, const SkBitmap&); // common code between setupPaintFor[Filling,Stroking] void setupShader(SkPaint*, Gradient*, Pattern*, SkColor) const; // Defines drawing style. struct State; // NULL indicates painting is disabled. Never delete this object. SkCanvas* m_canvas; const GraphicsContext* m_gc; // States stack. Enables local drawing state change with save()/restore() // calls. WTF::Vector m_stateStack; // Pointer to the current drawing state. This is a cached value of // mStateStack.back(). State* m_state; // Tracks the region painted opaque via the GraphicsContext. OpaqueRegionSkia m_opaqueRegion; bool m_trackOpaqueRegion; bool m_printing; bool m_accelerated; bool m_deferred; bool m_drawingToImageBuffer; float m_deviceScaleFactor; #if defined(SK_SUPPORT_HINTING_SCALE_FACTOR) SkScalar m_hintingScaleFactor; #endif }; } #endif // PlatformContextSkia_h