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