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/ImageOrientation.h"
38#include "platform/graphics/GraphicsContextAnnotation.h"
39#include "platform/graphics/GraphicsContextState.h"
40#include "platform/graphics/skia/OpaqueRegionSkia.h"
41#include "wtf/FastAllocBase.h"
42#include "wtf/Forward.h"
43#include "wtf/Noncopyable.h"
44#include "wtf/PassOwnPtr.h"
45
46class SkBitmap;
47class SkPaint;
48class SkPath;
49class SkRRect;
50struct SkRect;
51
52namespace WebCore {
53
54class DisplayList;
55class ImageBuffer;
56class KURL;
57
58typedef SkImageFilter ImageFilter;
59
60class PLATFORM_EXPORT GraphicsContext {
61    WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
62public:
63    enum AntiAliasingMode {
64        NotAntiAliased,
65        AntiAliased
66    };
67    enum AccessMode {
68        ReadOnly,
69        ReadWrite
70    };
71
72    enum DisabledMode {
73        NothingDisabled = 0, // Run as normal.
74        PaintingDisabled = 1, // Do not issue painting calls to the canvas but maintain state correctly.
75        FullyDisabled = 2 // Do absolutely minimal work to remove the cost of the context from performance tests.
76    };
77
78    explicit GraphicsContext(SkCanvas*, DisabledMode = NothingDisabled);
79    ~GraphicsContext();
80
81    // Returns the canvas used for painting. Must not be called if painting is disabled.
82    // Accessing the backing canvas this way flushes all queued save ops,
83    // so it should be avoided. Use the corresponding draw/matrix/clip methods instead.
84    SkCanvas* canvas()
85    {
86        ASSERT(!paintingDisabled());
87
88        // Flush any pending saves.
89        realizeCanvasSave();
90
91        return m_canvas;
92    }
93    const SkCanvas* canvas() const
94    {
95        ASSERT(!paintingDisabled());
96        return m_canvas;
97    }
98    bool paintingDisabled() const { return m_disabledState & PaintingDisabled; }
99    bool contextDisabled() const { return m_disabledState; }
100
101    // This is just a heuristic that currently happens to work. We need either
102    // a more reliable way to know that we are recording, or (better) we need
103    // to obviate the need for this query, and address whatever the caller
104    // needed in some other way.
105    // See bug# 372110
106    bool isRecordingCanvas() const
107    {
108        return m_canvas->imageInfo().colorType() == kUnknown_SkColorType;
109    }
110
111    // ---------- State management methods -----------------
112    void save();
113    void restore();
114    unsigned saveCount() { return m_canvasStateStack.size(); }
115#if ASSERT_ENABLED
116    void disableDestructionChecks() { m_disableDestructionChecks = true; }
117#endif
118
119    void saveLayer(const SkRect* bounds, const SkPaint*);
120    void restoreLayer();
121
122    float strokeThickness() const { return immutableState()->strokeData().thickness(); }
123    void setStrokeThickness(float thickness) { mutableState()->setStrokeThickness(thickness); }
124
125    StrokeStyle strokeStyle() const { return immutableState()->strokeData().style(); }
126    void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); }
127
128    Color strokeColor() const { return immutableState()->strokeData().color(); }
129    void setStrokeColor(const Color& color) { mutableState()->setStrokeColor(color); }
130    SkColor effectiveStrokeColor() const { return immutableState()->effectiveStrokeColor(); }
131
132    Pattern* strokePattern() const { return immutableState()->strokeData().pattern(); }
133    void setStrokePattern(PassRefPtr<Pattern>);
134
135    Gradient* strokeGradient() const { return immutableState()->strokeData().gradient(); }
136    void setStrokeGradient(PassRefPtr<Gradient>);
137
138    void setLineCap(LineCap cap) { mutableState()->setLineCap(cap); }
139    void setLineDash(const DashArray& dashes, float dashOffset) { mutableState()->setLineDash(dashes, dashOffset); }
140    void setLineJoin(LineJoin join) { mutableState()->setLineJoin(join); }
141    void setMiterLimit(float limit) { mutableState()->setMiterLimit(limit); }
142
143    WindRule fillRule() const { return immutableState()->fillRule(); }
144    void setFillRule(WindRule fillRule) { mutableState()->setFillRule(fillRule); }
145
146    Color fillColor() const { return immutableState()->fillColor(); }
147    void setFillColor(const Color& color) { mutableState()->setFillColor(color); }
148    SkColor effectiveFillColor() const { return immutableState()->effectiveFillColor(); }
149
150    void setFillPattern(PassRefPtr<Pattern>);
151    Pattern* fillPattern() const { return immutableState()->fillPattern(); }
152
153    void setFillGradient(PassRefPtr<Gradient>);
154    Gradient* fillGradient() const { return immutableState()->fillGradient(); }
155
156    SkDrawLooper* drawLooper() const { return immutableState()->drawLooper(); }
157
158    bool getTransformedClipBounds(FloatRect* bounds) const;
159    SkMatrix getTotalMatrix() const;
160
161    void setShouldAntialias(bool antialias) { mutableState()->setShouldAntialias(antialias); }
162    bool shouldAntialias() const { return immutableState()->shouldAntialias(); }
163
164    // Disable the anti-aliasing optimization for scales/multiple-of-90-degrees
165    // rotations of thin ("hairline") images.
166    // Note: This will only be reliable when the device pixel scale/ratio is
167    // fixed (e.g. when drawing to context backed by an ImageBuffer).
168    void disableAntialiasingOptimizationForHairlineImages() { ASSERT(!isRecording()); m_antialiasHairlineImages = true; }
169    bool shouldAntialiasHairlineImages() const { return m_antialiasHairlineImages; }
170
171    void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->setShouldClampToSourceRect(clampToSourceRect); }
172    bool shouldClampToSourceRect() const { return immutableState()->shouldClampToSourceRect(); }
173
174    void setShouldSmoothFonts(bool smoothFonts) { mutableState()->setShouldSmoothFonts(smoothFonts); }
175    bool shouldSmoothFonts() const { return immutableState()->shouldSmoothFonts(); }
176
177    // Turn off LCD text for the paint if not supported on this context.
178    void adjustTextRenderMode(SkPaint*);
179    bool couldUseLCDRenderedText();
180
181    void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->setTextDrawingMode(mode); }
182    TextDrawingModeFlags textDrawingMode() const { return immutableState()->textDrawingMode(); }
183
184    void setAlphaAsFloat(float alpha) { mutableState()->setAlphaAsFloat(alpha);}
185    int getNormalizedAlpha() const
186    {
187        int alpha = immutableState()->alpha();
188        return alpha > 255 ? 255 : alpha;
189    }
190
191    void setImageInterpolationQuality(InterpolationQuality quality) { mutableState()->setInterpolationQuality(quality); }
192    InterpolationQuality imageInterpolationQuality() const { return immutableState()->interpolationQuality(); }
193
194    void setCompositeOperation(CompositeOperator, blink::WebBlendMode = blink::WebBlendModeNormal);
195    CompositeOperator compositeOperation() const { return immutableState()->compositeOperator(); }
196    blink::WebBlendMode blendModeOperation() const { return immutableState()->blendMode(); }
197
198    // Change the way document markers are rendered.
199    // Any deviceScaleFactor higher than 1.5 is enough to justify setting this flag.
200    void setUseHighResMarkers(bool isHighRes) { m_useHighResMarker = isHighRes; }
201
202    // If true we are (most likely) rendering to a web page and the
203    // canvas has been prepared with an opaque background. If false,
204    // the canvas may have transparency (as is the case when rendering
205    // to a canvas object).
206    void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; }
207    bool isCertainlyOpaque() const { return m_isCertainlyOpaque; }
208
209    // Returns if the context is a printing context instead of a display
210    // context. Bitmap shouldn't be resampled when printing to keep the best
211    // possible quality.
212    bool printing() const { return m_printing; }
213    void setPrinting(bool printing) { m_printing = printing; }
214
215    bool isAccelerated() const { return m_accelerated; }
216    void setAccelerated(bool accelerated) { m_accelerated = accelerated; }
217
218    // The opaque region is empty until tracking is turned on.
219    // It is never clerared by the context.
220    void setTrackOpaqueRegion(bool track) { m_trackOpaqueRegion = track; }
221    const OpaqueRegionSkia& opaqueRegion() const { return m_opaqueRegion; }
222
223    // The text region is empty until tracking is turned on.
224    // It is never clerared by the context.
225    void setTrackTextRegion(bool track) { m_trackTextRegion = track; }
226    const SkRect& textRegion() const { return m_textRegion; }
227
228    bool updatingControlTints() const { return m_updatingControlTints; }
229    void setUpdatingControlTints(bool updatingTints) { m_updatingControlTints = updatingTints; }
230
231    AnnotationModeFlags annotationMode() const { return m_annotationMode; }
232    void setAnnotationMode(const AnnotationModeFlags mode) { m_annotationMode = mode; }
233
234    SkColorFilter* colorFilter();
235    void setColorFilter(ColorFilter);
236    // ---------- End state management methods -----------------
237
238    // Get the contents of the image buffer
239    bool readPixels(const SkImageInfo&, void* pixels, size_t rowBytes, int x, int y);
240
241    // Get the current fill style.
242    const SkPaint& fillPaint() const { return immutableState()->fillPaint(); }
243
244    // Get the current stroke style.
245    const SkPaint& strokePaint() const { return immutableState()->strokePaint(); }
246
247    // These draw methods will do both stroking and filling.
248    // FIXME: ...except drawRect(), which fills properly but always strokes
249    // using a 1-pixel stroke inset from the rect borders (of the correct
250    // stroke color).
251    void drawRect(const IntRect&);
252    void drawLine(const IntPoint&, const IntPoint&);
253    void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
254
255    void fillPath(const Path&);
256    void strokePath(const Path&);
257
258    void fillEllipse(const FloatRect&);
259    void strokeEllipse(const FloatRect&);
260
261    void fillRect(const FloatRect&);
262    void fillRect(const FloatRect&, const Color&);
263    void fillRect(const FloatRect&, const Color&, CompositeOperator);
264    void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&);
265    void fillRoundedRect(const RoundedRect&, const Color&);
266
267    void clearRect(const FloatRect&);
268
269    void strokeRect(const FloatRect&);
270    void strokeRect(const FloatRect&, float lineWidth);
271
272    void fillBetweenRoundedRects(const IntRect&, const IntSize& outerTopLeft, const IntSize& outerTopRight, const IntSize& outerBottomLeft, const IntSize& outerBottomRight,
273        const IntRect&, const IntSize& innerTopLeft, const IntSize& innerTopRight, const IntSize& innerBottomLeft, const IntSize& innerBottomRight, const Color&);
274    void fillBetweenRoundedRects(const RoundedRect&, const RoundedRect&, const Color&);
275
276    void drawDisplayList(DisplayList*);
277
278    void drawImage(Image*, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
279    void drawImage(Image*, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
280    void drawImage(Image*, const FloatRect& destRect);
281    void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
282    void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, blink::WebBlendMode, RespectImageOrientationEnum = DoNotRespectImageOrientation);
283
284    void drawTiledImage(Image*, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
285        CompositeOperator = CompositeSourceOver, blink::WebBlendMode = blink::WebBlendModeNormal, const IntSize& repeatSpacing = IntSize());
286    void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect,
287        const FloatSize& tileScaleFactor, Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
288        CompositeOperator = CompositeSourceOver);
289
290    void drawImageBuffer(ImageBuffer*, const FloatRect& destRect, const FloatRect* srcRect = 0, CompositeOperator = CompositeSourceOver);
291
292    // These methods write to the canvas and modify the opaque region, if tracked.
293    // Also drawLine(const IntPoint& point1, const IntPoint& point2) and fillRoundedRect
294    void writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
295    void writePixels(const SkBitmap&, int x, int y);
296    void drawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint* = 0);
297    void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint* = 0);
298    void drawOval(const SkRect&, const SkPaint&);
299    void drawPath(const SkPath&, const SkPaint&);
300    // After drawing directly to the context's canvas, use this function to notify the context so
301    // it can track the opaque region.
302    // FIXME: this is still needed only because ImageSkia::paintSkBitmap() may need to notify for a
303    //        smaller rect than the one drawn to, due to its clipping logic.
304    void didDrawRect(const SkRect&, const SkPaint&, const SkBitmap* = 0);
305    void drawRect(const SkRect&, const SkPaint&);
306    void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkRect& textRect, const SkPaint&);
307
308    void clip(const IntRect& rect) { clipRect(rect); }
309    void clip(const FloatRect& rect) { clipRect(rect); }
310    void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op);
311    void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); }
312    void clipOutRoundedRect(const RoundedRect&);
313    void clipPath(const Path&, WindRule = RULE_EVENODD);
314    void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
315    void clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
316
317    void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
318    void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&);
319    void drawBidiText(const Font&, const TextRunPaintInfo&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady);
320    void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1);
321
322    void drawLineForText(const FloatPoint&, float width, bool printing);
323    enum DocumentMarkerLineStyle {
324        DocumentMarkerSpellingLineStyle,
325        DocumentMarkerGrammarLineStyle
326    };
327    void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
328
329    void beginTransparencyLayer(float opacity, const FloatRect* = 0);
330    void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone, ImageFilter* = 0);
331    void endLayer();
332
333    void beginCull(const FloatRect&);
334    void endCull();
335
336    // Instead of being dispatched to the active canvas, draw commands following beginRecording()
337    // are stored in a display list that can be replayed at a later time.
338    void beginRecording(const FloatRect& bounds);
339    PassRefPtr<DisplayList> endRecording();
340
341    bool hasShadow() const;
342    void setShadow(const FloatSize& offset, float blur, const Color&,
343        DrawLooperBuilder::ShadowTransformMode = DrawLooperBuilder::ShadowRespectsTransforms,
344        DrawLooperBuilder::ShadowAlphaMode = DrawLooperBuilder::ShadowRespectsAlpha);
345    void clearShadow() { clearDrawLooper(); }
346
347    // It is assumed that this draw looper is used only for shadows
348    // (i.e. a draw looper is set if and only if there is a shadow).
349    // The builder passed into this method will be destroyed.
350    void setDrawLooper(PassOwnPtr<DrawLooperBuilder>);
351    void clearDrawLooper();
352
353    void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
354    void drawFocusRing(const Path&, int width, int offset, const Color&);
355
356    enum Edge {
357        NoEdge = 0,
358        TopEdge = 1 << 1,
359        RightEdge = 1 << 2,
360        BottomEdge = 1 << 3,
361        LeftEdge = 1 << 4
362    };
363    typedef unsigned Edges;
364    void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
365
366    // This clip function is used only by <canvas> code. It allows
367    // implementations to handle clipping on the canvas differently since
368    // the discipline is different.
369    void canvasClip(const Path&, WindRule = RULE_EVENODD);
370    void clipOut(const Path&);
371
372    // ---------- Transformation methods -----------------
373    // Note that the getCTM method returns only the current transform from Blink's perspective,
374    // which is not the final transform used to place content on screen. It cannot be relied upon
375    // for testing where a point will appear on screen or how large it will be.
376    AffineTransform getCTM() const;
377    void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); }
378    void setCTM(const AffineTransform& affine) { setMatrix(affineTransformToSkMatrix(affine)); }
379    void setMatrix(const SkMatrix&);
380
381    void scale(float x, float y);
382    void rotate(float angleInRadians);
383    void translate(float x, float y);
384
385    // This function applies the device scale factor to the context, making the context capable of
386    // acting as a base-level context for a HiDPI environment.
387    void applyDeviceScaleFactor(float deviceScaleFactor) { scale(deviceScaleFactor, deviceScaleFactor); }
388    // ---------- End transformation methods -----------------
389
390    // URL drawing
391    void setURLForRect(const KURL&, const IntRect&);
392    void setURLFragmentForRect(const String& name, const IntRect&);
393    void addURLTargetAtPoint(const String& name, const IntPoint&);
394    bool supportsURLFragments() { return printing(); }
395
396    // Create an image buffer compatible with this context, with suitable resolution
397    // for drawing into the buffer and then into this context.
398    PassOwnPtr<ImageBuffer> createCompatibleBuffer(const IntSize&, OpacityMode = NonOpaque) const;
399
400    static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
401
402    void beginAnnotation(const char*, const char*, const String&, const String&, const String&);
403    void endAnnotation();
404
405private:
406    const GraphicsContextState* immutableState() const { return m_paintState; }
407
408    GraphicsContextState* mutableState()
409    {
410        realizePaintSave();
411        return m_paintState;
412    }
413
414    static void setPathFromConvexPoints(SkPath*, size_t, const FloatPoint*);
415    static void setRadii(SkVector*, IntSize, IntSize, IntSize, IntSize);
416
417    static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter);
418
419#if OS(MACOSX)
420    static inline int getFocusRingOutset(int offset) { return offset + 2; }
421#else
422    static inline int getFocusRingOutset(int offset) { return 0; }
423    static const SkPMColor lineColors(int);
424    static const SkPMColor antiColors1(int);
425    static const SkPMColor antiColors2(int);
426    static void draw1xMarker(SkBitmap*, int);
427    static void draw2xMarker(SkBitmap*, int);
428#endif
429
430    // Helpers for drawing a focus ring (drawFocusRing)
431    void drawOuterPath(const SkPath&, SkPaint&, int);
432    void drawInnerPath(const SkPath&, SkPaint&, int);
433
434    // SkCanvas wrappers.
435    void clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
436    void clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
437
438    void concat(const SkMatrix&);
439
440    // Apply deferred paint state saves
441    void realizePaintSave()
442    {
443        if (contextDisabled())
444            return;
445
446        if (m_paintState->saveCount()) {
447            m_paintState->decrementSaveCount();
448            ++m_paintStateIndex;
449            if (m_paintStateStack.size() == m_paintStateIndex) {
450                m_paintStateStack.append(GraphicsContextState::createAndCopy(*m_paintState));
451                m_paintState = m_paintStateStack[m_paintStateIndex].get();
452            } else {
453                GraphicsContextState* priorPaintState = m_paintState;
454                m_paintState = m_paintStateStack[m_paintStateIndex].get();
455                m_paintState->copy(*priorPaintState);
456            }
457        }
458    }
459
460    // Apply deferred canvas state saves
461    void realizeCanvasSave()
462    {
463        if (!m_pendingCanvasSave || contextDisabled())
464            return;
465
466        m_canvas->save();
467        m_pendingCanvasSave = false;
468    }
469
470    void didDrawTextInRect(const SkRect& textRect);
471
472    void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&);
473
474    bool isRecording() const;
475
476    // null indicates painting is contextDisabled. Never delete this object.
477    SkCanvas* m_canvas;
478
479    // Paint states stack. Enables local drawing state change with save()/restore() calls.
480    // This state controls the appearance of drawn content.
481    // We do not delete from this stack to avoid memory churn.
482    Vector<OwnPtr<GraphicsContextState> > m_paintStateStack;
483    // Current index on the stack. May not be the last thing on the stack.
484    unsigned m_paintStateIndex;
485    // Raw pointer to the current state.
486    GraphicsContextState* m_paintState;
487
488    // Currently pending save flags for Skia Canvas state.
489    // Canvas state includes the canavs, it's matrix and clips. Think of it as _where_
490    // the draw operations will happen.
491    struct CanvasSaveState;
492    Vector<CanvasSaveState> m_canvasStateStack;
493    bool m_pendingCanvasSave;
494
495    AnnotationModeFlags m_annotationMode;
496
497    struct RecordingState;
498    Vector<RecordingState> m_recordingStateStack;
499
500#if ASSERT_ENABLED
501    unsigned m_annotationCount;
502    unsigned m_layerCount;
503    bool m_disableDestructionChecks;
504#endif
505    // Tracks the region painted opaque via the GraphicsContext.
506    OpaqueRegionSkia m_opaqueRegion;
507
508    // Tracks the region where text is painted via the GraphicsContext.
509    SkRect m_textRegion;
510
511    unsigned m_disabledState;
512
513    // Activation for the above region tracking features
514    bool m_trackOpaqueRegion : 1;
515    bool m_trackTextRegion : 1;
516
517    // Are we on a high DPI display? If so, spelling and grammar markers are larger.
518    bool m_useHighResMarker : 1;
519    // FIXME: Make this go away: crbug.com/236892
520    bool m_updatingControlTints : 1;
521    bool m_accelerated : 1;
522    bool m_isCertainlyOpaque : 1;
523    bool m_printing : 1;
524    bool m_antialiasHairlineImages : 1;
525};
526
527} // namespace WebCore
528
529#endif // GraphicsContext_h
530