1/*
2 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2008-2009 Torch Mobile, Inc.
4 * Copyright (C) 2013 Google Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef GraphicsContext_h
29#define GraphicsContext_h
30
31#include "platform/PlatformExport.h"
32#include "platform/fonts/Font.h"
33#include "platform/geometry/FloatRect.h"
34#include "platform/graphics/DashArray.h"
35#include "platform/graphics/DrawLooperBuilder.h"
36#include "platform/graphics/ImageBufferSurface.h"
37#include "platform/graphics/ImageFilter.h"
38#include "platform/graphics/ImageOrientation.h"
39#include "platform/graphics/GraphicsContextAnnotation.h"
40#include "platform/graphics/GraphicsContextState.h"
41#include "platform/graphics/RegionTracker.h"
42#include "platform/graphics/skia/SkiaUtils.h"
43#include "wtf/FastAllocBase.h"
44#include "wtf/Forward.h"
45#include "wtf/Noncopyable.h"
46#include "wtf/PassOwnPtr.h"
47
48class SkBitmap;
49class SkPaint;
50class SkPath;
51class SkRRect;
52class SkTextBlob;
53struct SkRect;
54
55namespace blink {
56
57class DisplayList;
58class ImageBuffer;
59class KURL;
60
61class PLATFORM_EXPORT GraphicsContext {
62    WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
63public:
64    enum AntiAliasingMode {
65        NotAntiAliased,
66        AntiAliased
67    };
68    enum AccessMode {
69        ReadOnly,
70        ReadWrite
71    };
72
73    enum DisabledMode {
74        NothingDisabled = 0, // Run as normal.
75        FullyDisabled = 1 // Do absolutely minimal work to remove the cost of the context from performance tests.
76    };
77
78    // A 0 canvas is allowed, but in such cases the context must only have canvas
79    // related commands called when within a beginRecording/endRecording block.
80    // Furthermore, save/restore calls must be balanced any time the canvas is 0.
81    explicit GraphicsContext(SkCanvas*, DisabledMode = NothingDisabled);
82
83    ~GraphicsContext();
84
85    // Returns the canvas used for painting. Must not be called if painting is disabled.
86    // Accessing the backing canvas this way flushes all queued save ops,
87    // so it should be avoided. Use the corresponding draw/matrix/clip methods instead.
88    SkCanvas* canvas()
89    {
90        // Flush any pending saves.
91        realizeCanvasSave();
92
93        return m_canvas;
94    }
95    const SkCanvas* canvas() const
96    {
97        return m_canvas;
98    }
99
100    void resetCanvas(SkCanvas*);
101
102    bool contextDisabled() const { return m_disabledState; }
103
104    // ---------- State management methods -----------------
105    void save();
106    void restore();
107    unsigned saveCount() { return m_canvasStateStack.size(); }
108#if ENABLE(ASSERT)
109    void disableDestructionChecks() { m_disableDestructionChecks = true; }
110#endif
111
112    void saveLayer(const SkRect* bounds, const SkPaint*);
113    void restoreLayer();
114
115    bool hasStroke() const { return strokeStyle() != NoStroke && strokeThickness() > 0; }
116
117    float strokeThickness() const { return immutableState()->strokeData().thickness(); }
118    void setStrokeThickness(float thickness) { mutableState()->setStrokeThickness(thickness); }
119
120    StrokeStyle strokeStyle() const { return immutableState()->strokeData().style(); }
121    void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); }
122
123    Color strokeColor() const { return immutableState()->strokeColor(); }
124    void setStrokeColor(const Color& color) { mutableState()->setStrokeColor(color); }
125    SkColor effectiveStrokeColor() const { return immutableState()->effectiveStrokeColor(); }
126
127    Pattern* strokePattern() const { return immutableState()->strokePattern(); }
128    void setStrokePattern(PassRefPtr<Pattern>);
129
130    Gradient* strokeGradient() const { return immutableState()->strokeGradient(); }
131    void setStrokeGradient(PassRefPtr<Gradient>);
132
133    void setLineCap(LineCap cap) { mutableState()->setLineCap(cap); }
134    void setLineDash(const DashArray& dashes, float dashOffset) { mutableState()->setLineDash(dashes, dashOffset); }
135    void setLineJoin(LineJoin join) { mutableState()->setLineJoin(join); }
136    void setMiterLimit(float limit) { mutableState()->setMiterLimit(limit); }
137
138    WindRule fillRule() const { return immutableState()->fillRule(); }
139    void setFillRule(WindRule fillRule) { mutableState()->setFillRule(fillRule); }
140
141    Color fillColor() const { return immutableState()->fillColor(); }
142    void setFillColor(const Color& color) { mutableState()->setFillColor(color); }
143    SkColor effectiveFillColor() const { return immutableState()->effectiveFillColor(); }
144
145    void setFillPattern(PassRefPtr<Pattern>);
146    Pattern* fillPattern() const { return immutableState()->fillPattern(); }
147
148    void setFillGradient(PassRefPtr<Gradient>);
149    Gradient* fillGradient() const { return immutableState()->fillGradient(); }
150
151    SkDrawLooper* drawLooper() const { return immutableState()->drawLooper(); }
152
153    bool getTransformedClipBounds(FloatRect* bounds) const;
154    SkMatrix getTotalMatrix() const;
155
156    void setShouldAntialias(bool antialias) { mutableState()->setShouldAntialias(antialias); }
157    bool shouldAntialias() const { return immutableState()->shouldAntialias(); }
158
159    // Disable the anti-aliasing optimization for scales/multiple-of-90-degrees
160    // rotations of thin ("hairline") images.
161    // Note: This will only be reliable when the device pixel scale/ratio is
162    // fixed (e.g. when drawing to context backed by an ImageBuffer).
163    void disableAntialiasingOptimizationForHairlineImages() { ASSERT(!isRecording()); m_antialiasHairlineImages = true; }
164    bool shouldAntialiasHairlineImages() const { return m_antialiasHairlineImages; }
165
166    void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->setShouldClampToSourceRect(clampToSourceRect); }
167    bool shouldClampToSourceRect() const { return immutableState()->shouldClampToSourceRect(); }
168
169    // FIXME: the setter is only used once, at construction time; convert to a constructor param,
170    // and possibly consolidate with other flags (paintDisabled, isPrinting, ...)
171    void setShouldSmoothFonts(bool smoothFonts) { m_shouldSmoothFonts = smoothFonts; }
172    bool shouldSmoothFonts() const { return m_shouldSmoothFonts; }
173
174    // Turn off LCD text for the paint if not supported on this context.
175    void adjustTextRenderMode(SkPaint*) const;
176    bool couldUseLCDRenderedText() const;
177
178    void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->setTextDrawingMode(mode); }
179    TextDrawingModeFlags textDrawingMode() const { return immutableState()->textDrawingMode(); }
180
181    void setAlphaAsFloat(float alpha) { mutableState()->setAlphaAsFloat(alpha);}
182    int getNormalizedAlpha() const
183    {
184        int alpha = immutableState()->alpha();
185        return alpha > 255 ? 255 : alpha;
186    }
187
188    void setImageInterpolationQuality(InterpolationQuality quality) { mutableState()->setInterpolationQuality(quality); }
189    InterpolationQuality imageInterpolationQuality() const { return immutableState()->interpolationQuality(); }
190
191    void setCompositeOperation(CompositeOperator, WebBlendMode = WebBlendModeNormal);
192    CompositeOperator compositeOperation() const { return immutableState()->compositeOperator(); }
193    WebBlendMode blendModeOperation() const { return immutableState()->blendMode(); }
194
195    // Speicy the device scale factor which may change the way document markers
196    // and fonts are rendered.
197    void setDeviceScaleFactor(float factor) { m_deviceScaleFactor = factor; }
198    float deviceScaleFactor() const { return m_deviceScaleFactor; }
199
200    // If true we are (most likely) rendering to a web page and the
201    // canvas has been prepared with an opaque background. If false,
202    // the canvas may have transparency (as is the case when rendering
203    // to a canvas object).
204    void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; }
205    bool isCertainlyOpaque() const { return m_isCertainlyOpaque; }
206
207    // Returns if the context is a printing context instead of a display
208    // context. Bitmap shouldn't be resampled when printing to keep the best
209    // possible quality.
210    bool printing() const { return m_printing; }
211    void setPrinting(bool printing) { m_printing = printing; }
212
213    bool isAccelerated() const { return m_accelerated; }
214    void setAccelerated(bool accelerated) { m_accelerated = accelerated; }
215
216    // The opaque region is empty until tracking is turned on.
217    // It is never clerared by the context.
218    enum RegionTrackingMode {
219        RegionTrackingDisabled = 0,
220        RegionTrackingOpaque,
221        RegionTrackingOverwrite
222    };
223    void setRegionTrackingMode(RegionTrackingMode);
224    bool regionTrackingEnabled() { return m_regionTrackingMode != RegionTrackingDisabled; }
225    const RegionTracker& opaqueRegion() const { return m_trackedRegion; }
226
227    // The text region is empty until tracking is turned on.
228    // It is never clerared by the context.
229    void setTrackTextRegion(bool track) { m_trackTextRegion = track; }
230    const SkRect& textRegion() const { return m_textRegion; }
231
232    AnnotationModeFlags annotationMode() const { return m_annotationMode; }
233    void setAnnotationMode(const AnnotationModeFlags mode) { m_annotationMode = mode; }
234
235    SkColorFilter* colorFilter() const;
236    void setColorFilter(ColorFilter);
237    // ---------- End state management methods -----------------
238
239    // Get the contents of the image buffer
240    bool readPixels(const SkImageInfo&, void* pixels, size_t rowBytes, int x, int y);
241
242    // Get the current fill style.
243    const SkPaint& fillPaint() const { return immutableState()->fillPaint(); }
244
245    // Get the current stroke style.
246    const SkPaint& strokePaint() const { return immutableState()->strokePaint(); }
247
248    // These draw methods will do both stroking and filling.
249    // FIXME: ...except drawRect(), which fills properly but always strokes
250    // using a 1-pixel stroke inset from the rect borders (of the correct
251    // stroke color).
252    void drawRect(const IntRect&);
253    void drawLine(const IntPoint&, const IntPoint&);
254    void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
255
256    void fillPath(const Path&);
257    void strokePath(const Path&);
258
259    void fillEllipse(const FloatRect&);
260    void strokeEllipse(const FloatRect&);
261
262    void fillRect(const FloatRect&);
263    void fillRect(const FloatRect&, const Color&);
264    void fillRect(const FloatRect&, const Color&, CompositeOperator);
265    void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&);
266    void fillRoundedRect(const RoundedRect&, const Color&);
267
268    void clearRect(const FloatRect&);
269
270    void strokeRect(const FloatRect&);
271    void strokeRect(const FloatRect&, float lineWidth);
272
273    void fillBetweenRoundedRects(const IntRect&, const IntSize& outerTopLeft, const IntSize& outerTopRight, const IntSize& outerBottomLeft, const IntSize& outerBottomRight,
274        const IntRect&, const IntSize& innerTopLeft, const IntSize& innerTopRight, const IntSize& innerBottomLeft, const IntSize& innerBottomRight, const Color&);
275    void fillBetweenRoundedRects(const RoundedRect&, const RoundedRect&, const Color&);
276
277    void drawDisplayList(DisplayList*);
278
279    void drawImage(Image*, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
280    void drawImage(Image*, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
281    void drawImage(Image*, const FloatRect& destRect);
282    void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
283    void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, WebBlendMode, RespectImageOrientationEnum = DoNotRespectImageOrientation);
284
285    void drawTiledImage(Image*, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
286        CompositeOperator = CompositeSourceOver, WebBlendMode = WebBlendModeNormal, const IntSize& repeatSpacing = IntSize());
287    void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect,
288        const FloatSize& tileScaleFactor, Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
289        CompositeOperator = CompositeSourceOver);
290
291    void drawImageBuffer(ImageBuffer*, const FloatRect& destRect, const FloatRect* srcRect = 0, CompositeOperator = CompositeSourceOver, WebBlendMode = WebBlendModeNormal);
292
293    void drawPicture(PassRefPtr<SkPicture>, const FloatRect& dest, const FloatRect& src, CompositeOperator, WebBlendMode);
294
295    // These methods write to the canvas and modify the opaque region, if tracked.
296    // Also drawLine(const IntPoint& point1, const IntPoint& point2) and fillRoundedRect
297    void writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
298    void writePixels(const SkBitmap&, int x, int y);
299    void drawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint* = 0);
300    void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint* = 0);
301    void drawOval(const SkRect&, const SkPaint&);
302    void drawPath(const SkPath&, const SkPaint&);
303    // After drawing directly to the context's canvas, use this function to notify the context so
304    // it can track the opaque region.
305    // FIXME: this is still needed only because ImageSkia::paintSkBitmap() may need to notify for a
306    //        smaller rect than the one drawn to, due to its clipping logic.
307    void didDrawRect(const SkRect&, const SkPaint&, const SkBitmap* = 0);
308    void drawRect(const SkRect&, const SkPaint&);
309    void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkRect& textRect, const SkPaint&);
310    void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkRect& textRect, const SkPaint&);
311    void drawTextBlob(const SkTextBlob*, const SkPoint& origin, const SkPaint&);
312
313    void clip(const IntRect& rect) { clipRect(rect); }
314    void clip(const FloatRect& rect) { clipRect(rect); }
315    void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op);
316    void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); }
317    void clipOut(const Path&);
318    void clipOutRoundedRect(const RoundedRect&);
319    void clipPath(const Path&, WindRule = RULE_EVENODD);
320    void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
321    void clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
322    // This clip function is used only by <canvas> code. It allows
323    // implementations to handle clipping on the canvas differently since
324    // the discipline is different.
325    void canvasClip(const Path&, WindRule = RULE_EVENODD);
326
327    void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
328    void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&);
329    void drawBidiText(const Font&, const TextRunPaintInfo&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady);
330    void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1);
331
332    void drawLineForText(const FloatPoint&, float width, bool printing);
333    enum DocumentMarkerLineStyle {
334        DocumentMarkerSpellingLineStyle,
335        DocumentMarkerGrammarLineStyle
336    };
337    void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
338
339    void beginTransparencyLayer(float opacity, const FloatRect* = 0);
340    void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone, ImageFilter* = 0);
341    void endLayer();
342
343    void beginCull(const FloatRect&);
344    void endCull();
345
346    // Instead of being dispatched to the active canvas, draw commands following beginRecording()
347    // are stored in a display list that can be replayed at a later time. Pass in the bounding
348    // rectangle for the content in the list.
349    void beginRecording(const FloatRect&, uint32_t = 0);
350    PassRefPtr<DisplayList> endRecording();
351
352    bool hasShadow() const;
353    void setShadow(const FloatSize& offset, float blur, const Color&,
354        DrawLooperBuilder::ShadowTransformMode = DrawLooperBuilder::ShadowRespectsTransforms,
355        DrawLooperBuilder::ShadowAlphaMode = DrawLooperBuilder::ShadowRespectsAlpha);
356    void clearShadow() { clearDrawLooper(); }
357
358    // It is assumed that this draw looper is used only for shadows
359    // (i.e. a draw looper is set if and only if there is a shadow).
360    // The builder passed into this method will be destroyed.
361    void setDrawLooper(PassOwnPtr<DrawLooperBuilder>);
362    void clearDrawLooper();
363
364    void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
365    void drawFocusRing(const Path&, int width, int offset, const Color&);
366
367    enum Edge {
368        NoEdge = 0,
369        TopEdge = 1 << 1,
370        RightEdge = 1 << 2,
371        BottomEdge = 1 << 3,
372        LeftEdge = 1 << 4
373    };
374    typedef unsigned Edges;
375    void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
376
377    // ---------- Transformation methods -----------------
378    // Note that the getCTM method returns only the current transform from Blink's perspective,
379    // which is not the final transform used to place content on screen. It cannot be relied upon
380    // for testing where a point will appear on screen or how large it will be.
381    AffineTransform getCTM() const;
382    void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); }
383    void setCTM(const AffineTransform& affine) { setMatrix(affineTransformToSkMatrix(affine)); }
384    void setMatrix(const SkMatrix&);
385
386    void scale(float x, float y);
387    void rotate(float angleInRadians);
388    void translate(float x, float y);
389
390    // This function applies the device scale factor to the context, making the context capable of
391    // acting as a base-level context for a HiDPI environment.
392    void applyDeviceScaleFactor(float deviceScaleFactor) { scale(deviceScaleFactor, deviceScaleFactor); }
393    // ---------- End transformation methods -----------------
394
395    // URL drawing
396    void setURLForRect(const KURL&, const IntRect&);
397    void setURLFragmentForRect(const String& name, const IntRect&);
398    void addURLTargetAtPoint(const String& name, const IntPoint&);
399
400    // Create an image buffer compatible with this context, with suitable resolution
401    // for drawing into the buffer and then into this context.
402    PassOwnPtr<ImageBuffer> createRasterBuffer(const IntSize&, OpacityMode = NonOpaque) const;
403
404    static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
405
406    void beginAnnotation(const AnnotationList&);
407    void endAnnotation();
408
409    void preparePaintForDrawRectToRect(
410        SkPaint*,
411        const SkRect& srcRect,
412        const SkRect& destRect,
413        CompositeOperator,
414        WebBlendMode,
415        bool isLazyDecoded = false,
416        bool isDataComplete = true) const;
417
418    static int focusRingOutsetExtent(int offset, int width)
419    {
420        return focusRingOutset(offset) + (focusRingWidth(width) + 1) / 2;
421    }
422
423private:
424    const GraphicsContextState* immutableState() const { return m_paintState; }
425
426    GraphicsContextState* mutableState()
427    {
428        realizePaintSave();
429        return m_paintState;
430    }
431
432    static void setPathFromConvexPoints(SkPath*, size_t, const FloatPoint*);
433    static void setRadii(SkVector*, IntSize, IntSize, IntSize, IntSize);
434
435    static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter);
436
437#if OS(MACOSX)
438    static inline int focusRingOutset(int offset) { return offset + 2; }
439    static inline int focusRingWidth(int width) { return width; }
440#else
441    static inline int focusRingOutset(int offset) { return 0; }
442    static inline int focusRingWidth(int width) { return 1; }
443    static SkPMColor lineColors(int);
444    static SkPMColor antiColors1(int);
445    static SkPMColor antiColors2(int);
446    static void draw1xMarker(SkBitmap*, int);
447    static void draw2xMarker(SkBitmap*, int);
448#endif
449
450    // Helpers for drawing a focus ring (drawFocusRing)
451    float prepareFocusRingPaint(SkPaint&, const Color&, int width) const;
452    void drawFocusRingPath(const SkPath&, const Color&, int width);
453    void drawFocusRingRect(const SkRect&, const Color&, int width);
454
455    // SkCanvas wrappers.
456    void clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
457    void clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
458    void concat(const SkMatrix&);
459    void drawRRect(const SkRRect&, const SkPaint&);
460
461    // Apply deferred paint state saves
462    void realizePaintSave()
463    {
464        if (contextDisabled())
465            return;
466
467        if (m_paintState->saveCount()) {
468            m_paintState->decrementSaveCount();
469            ++m_paintStateIndex;
470            if (m_paintStateStack.size() == m_paintStateIndex) {
471                m_paintStateStack.append(GraphicsContextState::createAndCopy(*m_paintState));
472                m_paintState = m_paintStateStack[m_paintStateIndex].get();
473            } else {
474                GraphicsContextState* priorPaintState = m_paintState;
475                m_paintState = m_paintStateStack[m_paintStateIndex].get();
476                m_paintState->copy(*priorPaintState);
477            }
478        }
479    }
480
481    // Apply deferred canvas state saves
482    void realizeCanvasSave()
483    {
484        if (!m_pendingCanvasSave || contextDisabled())
485            return;
486
487        ASSERT(m_canvas); // m_pendingCanvasSave should never be true when no canvas.
488        m_canvas->save();
489        m_pendingCanvasSave = false;
490    }
491
492    void didDrawTextInRect(const SkRect& textRect);
493
494    void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&);
495
496    bool isRecording() const;
497
498    // null indicates painting is contextDisabled. Never delete this object.
499    SkCanvas* m_canvas;
500
501    // Paint states stack. Enables local drawing state change with save()/restore() calls.
502    // This state controls the appearance of drawn content.
503    // We do not delete from this stack to avoid memory churn.
504    Vector<OwnPtr<GraphicsContextState> > m_paintStateStack;
505    // Current index on the stack. May not be the last thing on the stack.
506    unsigned m_paintStateIndex;
507    // Raw pointer to the current state.
508    GraphicsContextState* m_paintState;
509
510    // Currently pending save flags for Skia Canvas state.
511    // Canvas state includes the canavs, it's matrix and clips. Think of it as _where_
512    // the draw operations will happen.
513    struct CanvasSaveState;
514    Vector<CanvasSaveState> m_canvasStateStack;
515    bool m_pendingCanvasSave;
516
517    AnnotationModeFlags m_annotationMode;
518
519    struct RecordingState;
520    Vector<RecordingState> m_recordingStateStack;
521
522#if ENABLE(ASSERT)
523    unsigned m_annotationCount;
524    unsigned m_layerCount;
525    bool m_disableDestructionChecks;
526#endif
527    // Tracks the region painted opaque via the GraphicsContext.
528    RegionTracker m_trackedRegion;
529
530    // Tracks the region where text is painted via the GraphicsContext.
531    SkRect m_textRegion;
532
533    unsigned m_disabledState;
534
535    float m_deviceScaleFactor;
536
537    // Activation for the above region tracking features
538    unsigned m_regionTrackingMode : 2;
539    bool m_trackTextRegion : 1;
540
541    bool m_accelerated : 1;
542    bool m_isCertainlyOpaque : 1;
543    bool m_printing : 1;
544    bool m_antialiasHairlineImages : 1;
545    bool m_shouldSmoothFonts : 1;
546};
547
548} // namespace blink
549
550#endif // GraphicsContext_h
551