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/TraceEvent.h"
33#include "platform/fonts/Font.h"
34#include "platform/geometry/FloatRect.h"
35#include "platform/graphics/DashArray.h"
36#include "platform/graphics/DrawLooper.h"
37#include "platform/graphics/ImageBufferSurface.h"
38#include "platform/graphics/ImageOrientation.h"
39#include "platform/graphics/GraphicsContextAnnotation.h"
40#include "platform/graphics/GraphicsContextState.h"
41#include "platform/graphics/skia/OpaqueRegionSkia.h"
42#include "platform/graphics/skia/SkiaUtils.h"
43// TODO(robertphillips): replace this include with "class SkBaseDevice;"
44#include "third_party/skia/include/core/SkDevice.h"
45#include "wtf/FastAllocBase.h"
46#include "wtf/Forward.h"
47#include "wtf/Noncopyable.h"
48#include "wtf/PassOwnPtr.h"
49
50class SkBitmap;
51class SkPaint;
52class SkPath;
53class SkRRect;
54struct SkRect;
55
56namespace WebCore {
57
58class DisplayList;
59class ImageBuffer;
60class KURL;
61
62class PLATFORM_EXPORT GraphicsContext {
63    WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
64public:
65    enum AntiAliasingMode {
66        NotAntiAliased,
67        AntiAliased
68    };
69    enum AccessMode {
70        ReadOnly,
71        ReadWrite
72    };
73
74    explicit GraphicsContext(SkCanvas*);
75    ~GraphicsContext();
76
77    // Returns the canvas used for painting, NOT guaranteed to be non-null.
78    // Accessing the backing canvas this way flushes all queued save ops,
79    // so it should be avoided. Use the corresponding draw/matrix/clip methods instead.
80    SkCanvas* canvas()
81    {
82        // Flush any pending saves.
83        realizeSave(SkCanvas::kMatrixClip_SaveFlag);
84
85        return m_canvas;
86    }
87    const SkCanvas* canvas() const { return m_canvas; }
88    bool paintingDisabled() const { return !m_canvas; }
89
90    const SkBitmap* bitmap() const;
91    const SkBitmap& layerBitmap(AccessMode = ReadOnly) const;
92
93    // ---------- State management methods -----------------
94    void save();
95    void restore();
96
97    void saveLayer(const SkRect* bounds, const SkPaint*, SkCanvas::SaveFlags = SkCanvas::kARGB_ClipLayer_SaveFlag);
98    void restoreLayer();
99
100    float strokeThickness() const { return m_state->m_strokeData.thickness(); }
101    void setStrokeThickness(float thickness) { m_state->m_strokeData.setThickness(thickness); }
102
103    StrokeStyle strokeStyle() const { return m_state->m_strokeData.style(); }
104    void setStrokeStyle(StrokeStyle style) { m_state->m_strokeData.setStyle(style); }
105
106    Color strokeColor() const { return m_state->m_strokeData.color(); }
107    void setStrokeColor(const Color&);
108
109    Pattern* strokePattern() const { return m_state->m_strokeData.pattern(); }
110    void setStrokePattern(PassRefPtr<Pattern>);
111
112    Gradient* strokeGradient() const { return m_state->m_strokeData.gradient(); }
113    void setStrokeGradient(PassRefPtr<Gradient>);
114
115    void setLineCap(LineCap cap) { m_state->m_strokeData.setLineCap(cap); }
116    void setLineDash(const DashArray& dashes, float dashOffset) { m_state->m_strokeData.setLineDash(dashes, dashOffset); }
117    void setLineJoin(LineJoin join) { m_state->m_strokeData.setLineJoin(join); }
118    void setMiterLimit(float limit) { m_state->m_strokeData.setMiterLimit(limit); }
119
120    WindRule fillRule() const { return m_state->m_fillRule; }
121    void setFillRule(WindRule fillRule) { m_state->m_fillRule = fillRule; }
122
123    Color fillColor() const { return m_state->m_fillColor; }
124    void setFillColor(const Color&);
125    SkColor effectiveFillColor() const { return m_state->applyAlpha(m_state->m_fillColor.rgb()); }
126
127    void setFillPattern(PassRefPtr<Pattern>);
128    Pattern* fillPattern() const { return m_state->m_fillPattern.get(); }
129
130    void setFillGradient(PassRefPtr<Gradient>);
131    Gradient* fillGradient() const { return m_state->m_fillGradient.get(); }
132
133    SkDrawLooper* drawLooper() const { return m_state->m_looper.get(); }
134    SkColor effectiveStrokeColor() const { return m_state->applyAlpha(m_state->m_strokeData.color().rgb()); }
135
136    int getNormalizedAlpha() const;
137
138    bool getClipBounds(SkRect* bounds) const;
139    bool getTransformedClipBounds(FloatRect* bounds) const;
140    SkMatrix getTotalMatrix() const;
141    bool isPrintingDevice() const;
142
143    void setShouldAntialias(bool antialias) { m_state->m_shouldAntialias = antialias; }
144    bool shouldAntialias() const { return m_state->m_shouldAntialias; }
145
146    void setShouldClampToSourceRect(bool clampToSourceRect) { m_state->m_shouldClampToSourceRect = clampToSourceRect; }
147    bool shouldClampToSourceRect() const { return m_state->m_shouldClampToSourceRect; }
148
149    void setShouldSmoothFonts(bool smoothFonts) { m_state->m_shouldSmoothFonts = smoothFonts; }
150    bool shouldSmoothFonts() const { return m_state->m_shouldSmoothFonts; }
151
152    // Turn off LCD text for the paint if not supported on this context.
153    void adjustTextRenderMode(SkPaint*);
154    bool couldUseLCDRenderedText();
155
156    TextDrawingModeFlags textDrawingMode() const { return m_state->m_textDrawingMode; }
157    void setTextDrawingMode(TextDrawingModeFlags mode) { m_state->m_textDrawingMode = mode; }
158
159    void setAlpha(float alpha) { m_state->m_alpha = alpha; }
160
161    void setImageInterpolationQuality(InterpolationQuality quality) { m_state->m_interpolationQuality = quality; }
162    InterpolationQuality imageInterpolationQuality() const { return m_state->m_interpolationQuality; }
163
164    void setCompositeOperation(CompositeOperator, blink::WebBlendMode = blink::WebBlendModeNormal);
165    CompositeOperator compositeOperation() const { return m_state->m_compositeOperator; }
166    blink::WebBlendMode blendModeOperation() const { return m_state->m_blendMode; }
167
168    // Change the way document markers are rendered.
169    // Any deviceScaleFactor higher than 1.5 is enough to justify setting this flag.
170    void setUseHighResMarkers(bool isHighRes) { m_useHighResMarker = isHighRes; }
171
172    // If true we are (most likely) rendering to a web page and the
173    // canvas has been prepared with an opaque background. If false,
174    // the canvas may havbe transparency (as is the case when rendering
175    // to a canvas object).
176    void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; }
177    bool isCertainlyOpaque() const { return m_isCertainlyOpaque; }
178
179    // Returns if the context is a printing context instead of a display
180    // context. Bitmap shouldn't be resampled when printing to keep the best
181    // possible quality.
182    bool printing() const { return m_printing; }
183    void setPrinting(bool printing) { m_printing = printing; }
184
185    bool isAccelerated() const { return m_accelerated; }
186    void setAccelerated(bool accelerated) { m_accelerated = accelerated; }
187
188    // The opaque region is empty until tracking is turned on.
189    // It is never clerared by the context.
190    void setTrackOpaqueRegion(bool track) { m_trackOpaqueRegion = track; }
191    const OpaqueRegionSkia& opaqueRegion() const { return m_opaqueRegion; }
192
193    // The text region is empty until tracking is turned on.
194    // It is never clerared by the context.
195    void setTrackTextRegion(bool track) { m_trackTextRegion = track; }
196    const SkRect& textRegion() const { return m_textRegion; }
197
198    bool updatingControlTints() const { return m_updatingControlTints; }
199    void setUpdatingControlTints(bool updatingTints) { m_updatingControlTints = updatingTints; }
200
201    AnnotationModeFlags annotationMode() const { return m_annotationMode; }
202    void setAnnotationMode(const AnnotationModeFlags mode) { m_annotationMode = mode; }
203
204    SkColorFilter* colorFilter();
205    void setColorFilter(ColorFilter);
206    // ---------- End state management methods -----------------
207
208    // Get the contents of the image buffer
209    bool readPixels(SkBitmap*, int, int, SkCanvas::Config8888 = SkCanvas::kNative_Premul_Config8888);
210
211    // Sets up the paint for the current fill style.
212    void setupPaintForFilling(SkPaint*) const;
213
214    // Sets up the paint for stroking. Returns a float representing the
215    // effective width of the pen. If a non-zero length is provided, the
216    // number of dashes/dots on a dashed/dotted line will be adjusted to
217    // start and end that length with a dash/dot.
218    float setupPaintForStroking(SkPaint*, int length = 0) const;
219
220    // These draw methods will do both stroking and filling.
221    // FIXME: ...except drawRect(), which fills properly but always strokes
222    // using a 1-pixel stroke inset from the rect borders (of the correct
223    // stroke color).
224    void drawRect(const IntRect&);
225    void drawLine(const IntPoint&, const IntPoint&);
226    void drawEllipse(const IntRect&);
227    void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
228
229    void fillPath(const Path&);
230    void strokePath(const Path&);
231
232    void fillEllipse(const FloatRect&);
233    void strokeEllipse(const FloatRect&);
234
235    void fillRect(const FloatRect&);
236    void fillRect(const FloatRect&, const Color&);
237    void fillRect(const FloatRect&, const Color&, CompositeOperator);
238    void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&);
239    void fillRoundedRect(const RoundedRect&, const Color&);
240
241    void clearRect(const FloatRect&);
242
243    void strokeRect(const FloatRect&, float lineWidth);
244
245    void drawDisplayList(DisplayList*);
246
247    void drawImage(Image*, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
248    void drawImage(Image*, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
249    void drawImage(Image*, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
250    void drawImage(Image*, const FloatRect& destRect);
251    void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
252    void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, blink::WebBlendMode, RespectImageOrientationEnum = DoNotRespectImageOrientation, bool useLowQualityScale = false);
253
254    void drawTiledImage(Image*, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
255        CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false, blink::WebBlendMode = blink::WebBlendModeNormal, const IntSize& repeatSpacing = IntSize());
256    void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect,
257        const FloatSize& tileScaleFactor, Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
258        CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
259
260    void drawImageBuffer(ImageBuffer*, const IntPoint&, CompositeOperator = CompositeSourceOver, blink::WebBlendMode = blink::WebBlendModeNormal);
261    void drawImageBuffer(ImageBuffer*, const IntRect&, CompositeOperator = CompositeSourceOver, blink::WebBlendMode = blink::WebBlendModeNormal, bool useLowQualityScale = false);
262    void drawImageBuffer(ImageBuffer*, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, blink::WebBlendMode = blink::WebBlendModeNormal);
263    void drawImageBuffer(ImageBuffer*, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, blink::WebBlendMode = blink::WebBlendModeNormal, bool useLowQualityScale = false);
264    void drawImageBuffer(ImageBuffer*, const FloatRect& destRect);
265    void drawImageBuffer(ImageBuffer*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, blink::WebBlendMode = blink::WebBlendModeNormal, bool useLowQualityScale = false);
266
267    // These methods write to the canvas and modify the opaque region, if tracked.
268    // Also drawLine(const IntPoint& point1, const IntPoint& point2) and fillRoundedRect
269    void writePixels(const SkBitmap&, int x, int y, SkCanvas::Config8888 = SkCanvas::kNative_Premul_Config8888);
270    void drawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint* = 0);
271    void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint* = 0);
272    void drawOval(const SkRect&, const SkPaint&);
273    void drawPath(const SkPath&, const SkPaint&);
274    // After drawing directly to the context's canvas, use this function to notify the context so
275    // it can track the opaque region.
276    // FIXME: this is still needed only because ImageSkia::paintSkBitmap() may need to notify for a
277    //        smaller rect than the one drawn to, due to its clipping logic.
278    void didDrawRect(const SkRect&, const SkPaint&, const SkBitmap* = 0);
279    void drawRect(const SkRect&, const SkPaint&);
280    void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkRect& textRect, const SkPaint&);
281    void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkRect& textRect, const SkPaint&);
282    void drawTextOnPath(const void* text, size_t byteLength, const SkPath&, const SkRect& textRect, const SkMatrix*, const SkPaint&);
283
284    void clip(const IntRect& rect) { clip(FloatRect(rect)); }
285    void clip(const FloatRect& rect) { clipRect(rect); }
286    void clipRoundedRect(const RoundedRect&);
287    void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); }
288    void clipOutRoundedRect(const RoundedRect&);
289    void clipPath(const Path&, WindRule = RULE_EVENODD);
290    void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
291    bool clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
292
293    void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
294    void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&);
295    void drawBidiText(const Font&, const TextRunPaintInfo&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady);
296    void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1);
297
298    void drawLineForText(const FloatPoint&, float width, bool printing);
299    enum DocumentMarkerLineStyle {
300        DocumentMarkerSpellingLineStyle,
301        DocumentMarkerGrammarLineStyle
302    };
303    void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
304
305    void beginTransparencyLayer(float opacity, const FloatRect* = 0);
306    void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone);
307    void endLayer();
308
309    // Instead of being dispatched to the active canvas, draw commands following beginRecording()
310    // are stored in a display list that can be replayed at a later time.
311    void beginRecording(const FloatRect& bounds);
312    PassRefPtr<DisplayList> endRecording();
313
314    bool hasShadow() const;
315    void setShadow(const FloatSize& offset, float blur, const Color&,
316        DrawLooper::ShadowTransformMode = DrawLooper::ShadowRespectsTransforms,
317        DrawLooper::ShadowAlphaMode = DrawLooper::ShadowRespectsAlpha);
318    void clearShadow() { clearDrawLooper(); }
319
320    // It is assumed that this draw looper is used only for shadows
321    // (i.e. a draw looper is set if and only if there is a shadow).
322    void setDrawLooper(const DrawLooper&);
323    void clearDrawLooper();
324
325    void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
326    void drawFocusRing(const Path&, int width, int offset, const Color&);
327
328    enum Edge {
329        NoEdge = 0,
330        TopEdge = 1 << 1,
331        RightEdge = 1 << 2,
332        BottomEdge = 1 << 3,
333        LeftEdge = 1 << 4
334    };
335    typedef unsigned Edges;
336    void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
337
338    // This clip function is used only by <canvas> code. It allows
339    // implementations to handle clipping on the canvas differently since
340    // the discipline is different.
341    void canvasClip(const Path&, WindRule = RULE_EVENODD);
342    void clipOut(const Path&);
343
344    // ---------- Transformation methods -----------------
345    enum IncludeDeviceScale { DefinitelyIncludeDeviceScale, PossiblyIncludeDeviceScale };
346    AffineTransform getCTM(IncludeDeviceScale includeScale = PossiblyIncludeDeviceScale) const;
347    void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); }
348    void setCTM(const AffineTransform& affine) { setMatrix(affineTransformToSkMatrix(affine)); }
349    void setMatrix(const SkMatrix&);
350
351    void scale(const FloatSize&);
352    void rotate(float angleInRadians);
353    void translate(const FloatSize& size) { translate(size.width(), size.height()); }
354    void translate(float x, float y);
355
356    // This function applies the device scale factor to the context, making the context capable of
357    // acting as a base-level context for a HiDPI environment.
358    void applyDeviceScaleFactor(float deviceScaleFactor) { scale(FloatSize(deviceScaleFactor, deviceScaleFactor)); }
359    // ---------- End transformation methods -----------------
360
361    // URL drawing
362    void setURLForRect(const KURL&, const IntRect&);
363    void setURLFragmentForRect(const String& name, const IntRect&);
364    void addURLTargetAtPoint(const String& name, const IntPoint&);
365    bool supportsURLFragments() { return printing(); }
366
367    // Create an image buffer compatible with this context, with suitable resolution
368    // for drawing into the buffer and then into this context.
369    PassOwnPtr<ImageBuffer> createCompatibleBuffer(const IntSize&, OpacityMode = NonOpaque) const;
370
371    static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
372
373    void beginAnnotation(const char*, const char*, const String&, const String&, const String&);
374    void endAnnotation();
375
376private:
377    static void addCornerArc(SkPath*, const SkRect&, const IntSize&, int);
378    static void setPathFromConvexPoints(SkPath*, size_t, const FloatPoint*);
379    static void setRadii(SkVector*, IntSize, IntSize, IntSize, IntSize);
380
381    static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter);
382
383#if OS(MACOSX)
384    static inline int getFocusRingOutset(int offset) { return offset + 2; }
385#else
386    static inline int getFocusRingOutset(int offset) { return 0; }
387    static const SkPMColor lineColors(int);
388    static const SkPMColor antiColors1(int);
389    static const SkPMColor antiColors2(int);
390    static void draw1xMarker(SkBitmap*, int);
391    static void draw2xMarker(SkBitmap*, int);
392#endif
393
394    // Return value % max, but account for value possibly being negative.
395    static int fastMod(int value, int max)
396    {
397        bool isNeg = false;
398        if (value < 0) {
399            value = -value;
400            isNeg = true;
401        }
402        if (value >= max)
403            value %= max;
404        if (isNeg)
405            value = -value;
406        return value;
407    }
408
409    // Sets up the common flags on a paint for antialiasing, effects, etc.
410    // This is implicitly called by setupPaintFill and setupPaintStroke, but
411    // you may wish to call it directly sometimes if you don't want that other
412    // behavior.
413    void setupPaintCommon(SkPaint*) const;
414
415    // Helpers for drawing a focus ring (drawFocusRing)
416    void drawOuterPath(const SkPath&, SkPaint&, int);
417    void drawInnerPath(const SkPath&, SkPaint&, int);
418
419    // SkCanvas wrappers.
420    bool isDrawingToLayer() const { return m_canvas->isDrawingToLayer(); }
421
422    bool clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
423    bool clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
424
425    bool concat(const SkMatrix&);
426
427    // common code between setupPaintFor[Filling,Stroking]
428    void setupShader(SkPaint*, Gradient*, Pattern*, SkColor) const;
429
430    // Apply deferred saves
431    void realizeSave(SkCanvas::SaveFlags flags)
432    {
433        if (m_deferredSaveFlags & flags) {
434            m_canvas->save((SkCanvas::SaveFlags)m_deferredSaveFlags);
435            m_deferredSaveFlags = 0;
436        }
437    }
438
439    void didDrawTextInRect(const SkRect& textRect);
440
441    void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&);
442
443    bool isRecording() const;
444
445    // null indicates painting is disabled. Never delete this object.
446    SkCanvas* m_canvas;
447
448    // Pointer to the current drawing state. This is a cached value of m_stateStack.last().
449    GraphicsContextState* m_state;
450    // States stack. Enables local drawing state change with save()/restore() calls.
451    // Use OwnPtr to avoid copying the large state structure.
452    Vector<OwnPtr<GraphicsContextState> > m_stateStack;
453
454    // Currently pending save flags.
455    // FIXME: While defined as a bitmask of SkCanvas::SaveFlags, this is mostly used as a bool.
456    //        It will come in handy when adding granular save() support (clip vs. matrix vs. paint).
457    // crbug.com/233713
458    struct DeferredSaveState;
459    unsigned m_deferredSaveFlags;
460    Vector<DeferredSaveState> m_saveStateStack;
461
462    AnnotationModeFlags m_annotationMode;
463
464    struct RecordingState;
465    Vector<RecordingState> m_recordingStateStack;
466
467#if !ASSERT_DISABLED
468    unsigned m_annotationCount;
469    unsigned m_layerCount;
470#endif
471    // Tracks the region painted opaque via the GraphicsContext.
472    OpaqueRegionSkia m_opaqueRegion;
473    bool m_trackOpaqueRegion : 1;
474
475    // Tracks the region where text is painted via the GraphicsContext.
476    bool m_trackTextRegion : 1;
477    SkRect m_textRegion;
478
479    // Are we on a high DPI display? If so, spelling and grammar markers are larger.
480    bool m_useHighResMarker : 1;
481    // FIXME: Make this go away: crbug.com/236892
482    bool m_updatingControlTints : 1;
483    bool m_accelerated : 1;
484    bool m_isCertainlyOpaque : 1;
485    bool m_printing : 1;
486};
487
488} // namespace WebCore
489
490#endif // GraphicsContext_h
491