#include "platform/graphics/DashArray.h"
#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/ImageBufferSurface.h"
+#include "platform/graphics/ImageFilter.h"
#include "platform/graphics/ImageOrientation.h"
#include "platform/graphics/GraphicsContextAnnotation.h"
#include "platform/graphics/GraphicsContextState.h"
#include "platform/graphics/RegionTracker.h"
+#include "platform/graphics/skia/SkiaUtils.h"
#include "wtf/FastAllocBase.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
class SkPaint;
class SkPath;
class SkRRect;
+class SkTextBlob;
struct SkRect;
namespace blink {
class ImageBuffer;
class KURL;
-typedef SkImageFilter ImageFilter;
-
class PLATFORM_EXPORT GraphicsContext {
WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
public:
FullyDisabled = 1 // Do absolutely minimal work to remove the cost of the context from performance tests.
};
+ // A 0 canvas is allowed, but in such cases the context must only have canvas
+ // related commands called when within a beginRecording/endRecording block.
+ // Furthermore, save/restore calls must be balanced any time the canvas is 0.
explicit GraphicsContext(SkCanvas*, DisabledMode = NothingDisabled);
+
~GraphicsContext();
- // Returns the canvas used for painting. Must not be called if painting is disabled.
- // Accessing the backing canvas this way flushes all queued save ops,
- // so it should be avoided. Use the corresponding draw/matrix/clip methods instead.
- SkCanvas* canvas()
- {
- // Flush any pending saves.
- realizeCanvasSave();
-
- return m_canvas;
- }
- const SkCanvas* canvas() const
- {
- return m_canvas;
- }
+ SkCanvas* canvas() { return m_canvas; }
+ const SkCanvas* canvas() const { return m_canvas; }
void resetCanvas(SkCanvas*);
// ---------- State management methods -----------------
void save();
void restore();
- unsigned saveCount() { return m_canvasStateStack.size(); }
+
#if ENABLE(ASSERT)
+ unsigned saveCount() const;
void disableDestructionChecks() { m_disableDestructionChecks = true; }
#endif
- void saveLayer(const SkRect* bounds, const SkPaint*);
- void restoreLayer();
-
bool hasStroke() const { return strokeStyle() != NoStroke && strokeThickness() > 0; }
float strokeThickness() const { return immutableState()->strokeData().thickness(); }
StrokeStyle strokeStyle() const { return immutableState()->strokeData().style(); }
void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); }
- Color strokeColor() const { return immutableState()->strokeData().color(); }
+ Color strokeColor() const { return immutableState()->strokeColor(); }
void setStrokeColor(const Color& color) { mutableState()->setStrokeColor(color); }
SkColor effectiveStrokeColor() const { return immutableState()->effectiveStrokeColor(); }
- Pattern* strokePattern() const { return immutableState()->strokeData().pattern(); }
+ Pattern* strokePattern() const { return immutableState()->strokePattern(); }
void setStrokePattern(PassRefPtr<Pattern>);
- Gradient* strokeGradient() const { return immutableState()->strokeData().gradient(); }
+ Gradient* strokeGradient() const { return immutableState()->strokeGradient(); }
void setStrokeGradient(PassRefPtr<Gradient>);
void setLineCap(LineCap cap) { mutableState()->setLineCap(cap); }
void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->setShouldClampToSourceRect(clampToSourceRect); }
bool shouldClampToSourceRect() const { return immutableState()->shouldClampToSourceRect(); }
- void setShouldSmoothFonts(bool smoothFonts) { mutableState()->setShouldSmoothFonts(smoothFonts); }
- bool shouldSmoothFonts() const { return immutableState()->shouldSmoothFonts(); }
+ // FIXME: the setter is only used once, at construction time; convert to a constructor param,
+ // and possibly consolidate with other flags (paintDisabled, isPrinting, ...)
+ void setShouldSmoothFonts(bool smoothFonts) { m_shouldSmoothFonts = smoothFonts; }
+ bool shouldSmoothFonts() const { return m_shouldSmoothFonts; }
// Turn off LCD text for the paint if not supported on this context.
- void adjustTextRenderMode(SkPaint*);
- bool couldUseLCDRenderedText();
+ void adjustTextRenderMode(SkPaint*) const;
+ bool couldUseLCDRenderedText() const;
void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->setTextDrawingMode(mode); }
TextDrawingModeFlags textDrawingMode() const { return immutableState()->textDrawingMode(); }
// stroke color).
void drawRect(const IntRect&);
void drawLine(const IntPoint&, const IntPoint&);
- void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
+
+ void fillPolygon(size_t numPoints, const FloatPoint*, const Color&, bool shouldAntialias);
void fillPath(const Path&);
void strokePath(const Path&);
void fillBetweenRoundedRects(const RoundedRect&, const RoundedRect&, const Color&);
void drawDisplayList(DisplayList*);
+ void drawPicture(SkPicture*, const FloatPoint& location);
+ void drawPicture(SkPicture*, const FloatRect& dest, const FloatRect& src, CompositeOperator, WebBlendMode);
void drawImage(Image*, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
void drawImage(Image*, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
void drawImageBuffer(ImageBuffer*, const FloatRect& destRect, const FloatRect* srcRect = 0, CompositeOperator = CompositeSourceOver, WebBlendMode = WebBlendModeNormal);
- void drawPicture(PassRefPtr<SkPicture>, const FloatRect& dest, const FloatRect& src, CompositeOperator, WebBlendMode);
-
// These methods write to the canvas and modify the opaque region, if tracked.
// Also drawLine(const IntPoint& point1, const IntPoint& point2) and fillRoundedRect
void writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
- void writePixels(const SkBitmap&, int x, int y);
void drawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint* = 0);
void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint* = 0);
void drawOval(const SkRect&, const SkPaint&);
void drawRect(const SkRect&, const SkPaint&);
void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkRect& textRect, const SkPaint&);
void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkRect& textRect, const SkPaint&);
+ void drawTextBlob(const SkTextBlob*, const SkPoint& origin, const SkPaint&);
void clip(const IntRect& rect) { clipRect(rect); }
void clip(const FloatRect& rect) { clipRect(rect); }
void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op);
void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); }
+ void clipOut(const Path&);
void clipOutRoundedRect(const RoundedRect&);
void clipPath(const Path&, WindRule = RULE_EVENODD);
- void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
+ void clipPolygon(size_t numPoints, const FloatPoint*, bool antialias);
void clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
+ // This clip function is used only by <canvas> code. It allows
+ // implementations to handle clipping on the canvas differently since
+ // the discipline is different.
+ void canvasClip(const Path&, WindRule = RULE_EVENODD, AntiAliasingMode = NotAntiAliased);
void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&);
};
void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
+ // beginLayer()/endLayer() behaves like save()/restore() for only CTM and clip states.
void beginTransparencyLayer(float opacity, const FloatRect* = 0);
+ // Apply CompositeOperator when the layer is composited on the backdrop (i.e. endLayer()).
+ // Don't change the current CompositeOperator state.
void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone, ImageFilter* = 0);
void endLayer();
void endCull();
// Instead of being dispatched to the active canvas, draw commands following beginRecording()
- // are stored in a display list that can be replayed at a later time.
- void beginRecording(const FloatRect& bounds);
+ // are stored in a display list that can be replayed at a later time. Pass in the bounding
+ // rectangle for the content in the list.
+ void beginRecording(const FloatRect&, uint32_t = 0);
PassRefPtr<DisplayList> endRecording();
bool hasShadow() const;
void setShadow(const FloatSize& offset, float blur, const Color&,
DrawLooperBuilder::ShadowTransformMode = DrawLooperBuilder::ShadowRespectsTransforms,
- DrawLooperBuilder::ShadowAlphaMode = DrawLooperBuilder::ShadowRespectsAlpha);
- void clearShadow() { clearDrawLooper(); }
+ DrawLooperBuilder::ShadowAlphaMode = DrawLooperBuilder::ShadowRespectsAlpha, ShadowMode = DrawShadowAndForeground);
+ void clearShadow() { clearDrawLooper(); clearDropShadowImageFilter(); }
// It is assumed that this draw looper is used only for shadows
// (i.e. a draw looper is set if and only if there is a shadow).
typedef unsigned Edges;
void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
- // This clip function is used only by <canvas> code. It allows
- // implementations to handle clipping on the canvas differently since
- // the discipline is different.
- void canvasClip(const Path&, WindRule = RULE_EVENODD);
- void clipOut(const Path&);
-
// ---------- Transformation methods -----------------
// Note that the getCTM method returns only the current transform from Blink's perspective,
// which is not the final transform used to place content on screen. It cannot be relied upon
void setURLForRect(const KURL&, const IntRect&);
void setURLFragmentForRect(const String& name, const IntRect&);
void addURLTargetAtPoint(const String& name, const IntPoint&);
- bool supportsURLFragments() { return printing(); }
// Create an image buffer compatible with this context, with suitable resolution
// for drawing into the buffer and then into this context.
const SkRect& destRect,
CompositeOperator,
WebBlendMode,
+ bool isBitmapWithAlpha,
bool isLazyDecoded = false,
bool isDataComplete = true) const;
return m_paintState;
}
- static void setPathFromConvexPoints(SkPath*, size_t, const FloatPoint*);
+ static void setPathFromPoints(SkPath*, size_t, const FloatPoint*);
static void setRadii(SkVector*, IntSize, IntSize, IntSize, IntSize);
static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter);
#else
static inline int focusRingOutset(int offset) { return 0; }
static inline int focusRingWidth(int width) { return 1; }
- static const SkPMColor lineColors(int);
- static const SkPMColor antiColors1(int);
- static const SkPMColor antiColors2(int);
+ static SkPMColor lineColors(int);
+ static SkPMColor antiColors1(int);
+ static SkPMColor antiColors2(int);
static void draw1xMarker(SkBitmap*, int);
static void draw2xMarker(SkBitmap*, int);
#endif
+ void saveLayer(const SkRect* bounds, const SkPaint*);
+ void restoreLayer();
+
// Helpers for drawing a focus ring (drawFocusRing)
float prepareFocusRingPaint(SkPaint&, const Color&, int width) const;
void drawFocusRingPath(const SkPath&, const Color&, int width);
void drawFocusRingRect(const SkRect&, const Color&, int width);
-
// SkCanvas wrappers.
void clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
void clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
void concat(const SkMatrix&);
void drawRRect(const SkRRect&, const SkPaint&);
+ void setDropShadowImageFilter(PassRefPtr<SkImageFilter>);
+ void clearDropShadowImageFilter();
+ SkImageFilter* dropShadowImageFilter() const { return immutableState()->dropShadowImageFilter(); }
+
// Apply deferred paint state saves
void realizePaintSave()
{
}
}
- // Apply deferred canvas state saves
- void realizeCanvasSave()
- {
- if (!m_pendingCanvasSave || contextDisabled())
- return;
-
- m_canvas->save();
- m_pendingCanvasSave = false;
- }
-
void didDrawTextInRect(const SkRect& textRect);
void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&);
// Raw pointer to the current state.
GraphicsContextState* m_paintState;
- // Currently pending save flags for Skia Canvas state.
- // Canvas state includes the canavs, it's matrix and clips. Think of it as _where_
- // the draw operations will happen.
- struct CanvasSaveState;
- Vector<CanvasSaveState> m_canvasStateStack;
- bool m_pendingCanvasSave;
-
AnnotationModeFlags m_annotationMode;
struct RecordingState;
// Activation for the above region tracking features
unsigned m_regionTrackingMode : 2;
- bool m_trackTextRegion : 1;
+ unsigned m_trackTextRegion : 1;
- bool m_accelerated : 1;
- bool m_isCertainlyOpaque : 1;
- bool m_printing : 1;
- bool m_antialiasHairlineImages : 1;
+ unsigned m_accelerated : 1;
+ unsigned m_isCertainlyOpaque : 1;
+ unsigned m_printing : 1;
+ unsigned m_antialiasHairlineImages : 1;
+ unsigned m_shouldSmoothFonts : 1;
};
} // namespace blink