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.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
28 #ifndef GraphicsContext_h
29 #define GraphicsContext_h
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 #include "wtf/FastAllocBase.h"
44 #include "wtf/Forward.h"
45 #include "wtf/Noncopyable.h"
46 #include "wtf/PassOwnPtr.h"
60 typedef SkImageFilter ImageFilter;
62 class PLATFORM_EXPORT GraphicsContext {
63 WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
65 enum AntiAliasingMode {
74 explicit GraphicsContext(SkCanvas*);
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.
82 // Flush any pending saves.
83 realizeCanvasSave(SkCanvas::kMatrixClip_SaveFlag);
87 const SkCanvas* canvas() const { return m_canvas; }
88 bool paintingDisabled() const { return !m_canvas; }
90 const SkBitmap* bitmap() const;
91 const SkBitmap& layerBitmap(AccessMode = ReadOnly) const;
93 // ---------- State management methods -----------------
97 void saveLayer(const SkRect* bounds, const SkPaint*, SkCanvas::SaveFlags = SkCanvas::kARGB_ClipLayer_SaveFlag);
100 float strokeThickness() const { return m_paintState->m_strokeData.thickness(); }
101 void setStrokeThickness(float thickness) { mutableState()->m_strokeData.setThickness(thickness); }
103 StrokeStyle strokeStyle() const { return m_paintState->m_strokeData.style(); }
104 void setStrokeStyle(StrokeStyle style) { mutableState()->m_strokeData.setStyle(style); }
106 Color strokeColor() const { return m_paintState->m_strokeData.color(); }
107 void setStrokeColor(const Color&);
109 Pattern* strokePattern() const { return m_paintState->m_strokeData.pattern(); }
110 void setStrokePattern(PassRefPtr<Pattern>);
112 Gradient* strokeGradient() const { return m_paintState->m_strokeData.gradient(); }
113 void setStrokeGradient(PassRefPtr<Gradient>);
115 void setLineCap(LineCap cap) { mutableState()->m_strokeData.setLineCap(cap); }
116 void setLineDash(const DashArray& dashes, float dashOffset) { mutableState()->m_strokeData.setLineDash(dashes, dashOffset); }
117 void setLineJoin(LineJoin join) { mutableState()->m_strokeData.setLineJoin(join); }
118 void setMiterLimit(float limit) { mutableState()->m_strokeData.setMiterLimit(limit); }
120 WindRule fillRule() const { return m_paintState->m_fillRule; }
121 void setFillRule(WindRule fillRule) { mutableState()->m_fillRule = fillRule; }
123 Color fillColor() const { return m_paintState->m_fillColor; }
124 void setFillColor(const Color&);
125 SkColor effectiveFillColor() const { return m_paintState->applyAlpha(m_paintState->m_fillColor.rgb()); }
127 void setFillPattern(PassRefPtr<Pattern>);
128 Pattern* fillPattern() const { return m_paintState->m_fillPattern.get(); }
130 void setFillGradient(PassRefPtr<Gradient>);
131 Gradient* fillGradient() const { return m_paintState->m_fillGradient.get(); }
133 SkDrawLooper* drawLooper() const { return m_paintState->m_looper.get(); }
134 SkColor effectiveStrokeColor() const { return m_paintState->applyAlpha(m_paintState->m_strokeData.color().rgb()); }
136 int getNormalizedAlpha() const;
138 FloatRect getClipBounds() const;
139 bool getTransformedClipBounds(FloatRect* bounds) const;
140 SkMatrix getTotalMatrix() const;
141 bool isPrintingDevice() const;
143 void setShouldAntialias(bool antialias) { mutableState()->m_shouldAntialias = antialias; }
144 bool shouldAntialias() const { return m_paintState->m_shouldAntialias; }
146 void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->m_shouldClampToSourceRect = clampToSourceRect; }
147 bool shouldClampToSourceRect() const { return m_paintState->m_shouldClampToSourceRect; }
149 void setShouldSmoothFonts(bool smoothFonts) { mutableState()->m_shouldSmoothFonts = smoothFonts; }
150 bool shouldSmoothFonts() const { return m_paintState->m_shouldSmoothFonts; }
152 // Turn off LCD text for the paint if not supported on this context.
153 void adjustTextRenderMode(SkPaint*);
154 bool couldUseLCDRenderedText();
156 void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->m_textDrawingMode = mode; }
157 TextDrawingModeFlags textDrawingMode() const { return m_paintState->m_textDrawingMode; }
159 void setAlpha(float alpha) { mutableState()->m_alpha = alpha;}
161 void setImageInterpolationQuality(InterpolationQuality quality) { mutableState()->m_interpolationQuality = quality; }
162 InterpolationQuality imageInterpolationQuality() const { return m_paintState->m_interpolationQuality; }
164 void setCompositeOperation(CompositeOperator, blink::WebBlendMode = blink::WebBlendModeNormal);
165 CompositeOperator compositeOperation() const { return m_paintState->m_compositeOperator; }
166 blink::WebBlendMode blendModeOperation() const { return m_paintState->m_blendMode; }
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; }
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 have 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; }
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
182 bool printing() const { return m_printing; }
183 void setPrinting(bool printing) { m_printing = printing; }
185 bool isAccelerated() const { return m_accelerated; }
186 void setAccelerated(bool accelerated) { m_accelerated = accelerated; }
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; }
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; }
198 bool updatingControlTints() const { return m_updatingControlTints; }
199 void setUpdatingControlTints(bool updatingTints) { m_updatingControlTints = updatingTints; }
201 AnnotationModeFlags annotationMode() const { return m_annotationMode; }
202 void setAnnotationMode(const AnnotationModeFlags mode) { m_annotationMode = mode; }
204 SkColorFilter* colorFilter();
205 void setColorFilter(ColorFilter);
206 // ---------- End state management methods -----------------
208 // Get the contents of the image buffer
209 bool readPixels(SkBitmap*, int, int, SkCanvas::Config8888 = SkCanvas::kNative_Premul_Config8888);
211 // Sets up the paint for the current fill style.
212 void setupPaintForFilling(SkPaint*) const;
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;
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
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);
229 void fillPath(const Path&);
230 void strokePath(const Path&);
232 void fillEllipse(const FloatRect&);
233 void strokeEllipse(const FloatRect&);
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&);
241 void clearRect(const FloatRect&);
243 void strokeRect(const FloatRect&, float lineWidth);
245 void drawDisplayList(DisplayList*);
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);
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);
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);
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&);
284 void clip(const IntRect& rect) { clip(FloatRect(rect)); }
285 void clip(const FloatRect& rect) { clipRect(rect); }
286 bool clipRectReplace(const FloatRect& rect) { return clipRect(rect, NotAntiAliased, SkRegion::kReplace_Op); }
287 void clipRoundedRect(const RoundedRect&);
288 void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); }
289 void clipOutRoundedRect(const RoundedRect&);
290 void clipPath(const Path&, WindRule = RULE_EVENODD);
291 void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
292 bool clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
294 void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
295 void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&);
296 void drawBidiText(const Font&, const TextRunPaintInfo&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady);
297 void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1);
299 void drawLineForText(const FloatPoint&, float width, bool printing);
300 enum DocumentMarkerLineStyle {
301 DocumentMarkerSpellingLineStyle,
302 DocumentMarkerGrammarLineStyle
304 void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
306 void beginTransparencyLayer(float opacity, const FloatRect* = 0);
307 void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone, ImageFilter* = 0);
310 // Instead of being dispatched to the active canvas, draw commands following beginRecording()
311 // are stored in a display list that can be replayed at a later time.
312 void beginRecording(const FloatRect& bounds);
313 PassRefPtr<DisplayList> endRecording();
315 bool hasShadow() const;
316 void setShadow(const FloatSize& offset, float blur, const Color&,
317 DrawLooper::ShadowTransformMode = DrawLooper::ShadowRespectsTransforms,
318 DrawLooper::ShadowAlphaMode = DrawLooper::ShadowRespectsAlpha);
319 void clearShadow() { clearDrawLooper(); }
321 // It is assumed that this draw looper is used only for shadows
322 // (i.e. a draw looper is set if and only if there is a shadow).
323 void setDrawLooper(const DrawLooper&);
324 void clearDrawLooper();
326 void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
327 void drawFocusRing(const Path&, int width, int offset, const Color&);
336 typedef unsigned Edges;
337 void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
339 // This clip function is used only by <canvas> code. It allows
340 // implementations to handle clipping on the canvas differently since
341 // the discipline is different.
342 void canvasClip(const Path&, WindRule = RULE_EVENODD);
343 void clipOut(const Path&);
345 // ---------- Transformation methods -----------------
346 enum IncludeDeviceScale { DefinitelyIncludeDeviceScale, PossiblyIncludeDeviceScale };
347 AffineTransform getCTM(IncludeDeviceScale includeScale = PossiblyIncludeDeviceScale) const;
348 void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); }
349 void setCTM(const AffineTransform& affine) { setMatrix(affineTransformToSkMatrix(affine)); }
350 void setMatrix(const SkMatrix&);
352 void scale(const FloatSize&);
353 void rotate(float angleInRadians);
354 void translate(const FloatSize& size) { translate(size.width(), size.height()); }
355 void translate(float x, float y);
357 // This function applies the device scale factor to the context, making the context capable of
358 // acting as a base-level context for a HiDPI environment.
359 void applyDeviceScaleFactor(float deviceScaleFactor) { scale(FloatSize(deviceScaleFactor, deviceScaleFactor)); }
360 // ---------- End transformation methods -----------------
363 void setURLForRect(const KURL&, const IntRect&);
364 void setURLFragmentForRect(const String& name, const IntRect&);
365 void addURLTargetAtPoint(const String& name, const IntPoint&);
366 bool supportsURLFragments() { return printing(); }
368 // Create an image buffer compatible with this context, with suitable resolution
369 // for drawing into the buffer and then into this context.
370 PassOwnPtr<ImageBuffer> createCompatibleBuffer(const IntSize&, OpacityMode = NonOpaque) const;
372 static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
374 void beginAnnotation(const char*, const char*, const String&, const String&, const String&);
375 void endAnnotation();
378 const GraphicsContextState* immutableState() const { return m_paintState; }
380 GraphicsContextState* mutableState()
386 static void addCornerArc(SkPath*, const SkRect&, const IntSize&, int);
387 static void setPathFromConvexPoints(SkPath*, size_t, const FloatPoint*);
388 static void setRadii(SkVector*, IntSize, IntSize, IntSize, IntSize);
390 static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter);
393 static inline int getFocusRingOutset(int offset) { return offset + 2; }
395 static inline int getFocusRingOutset(int offset) { return 0; }
396 static const SkPMColor lineColors(int);
397 static const SkPMColor antiColors1(int);
398 static const SkPMColor antiColors2(int);
399 static void draw1xMarker(SkBitmap*, int);
400 static void draw2xMarker(SkBitmap*, int);
403 // Return value % max, but account for value possibly being negative.
404 static int fastMod(int value, int max)
418 // Sets up the common flags on a paint for antialiasing, effects, etc.
419 // This is implicitly called by setupPaintFill and setupPaintStroke, but
420 // you may wish to call it directly sometimes if you don't want that other
422 void setupPaintCommon(SkPaint*) const;
424 // Helpers for drawing a focus ring (drawFocusRing)
425 void drawOuterPath(const SkPath&, SkPaint&, int);
426 void drawInnerPath(const SkPath&, SkPaint&, int);
428 // SkCanvas wrappers.
429 bool isDrawingToLayer() const { return m_canvas->isDrawingToLayer(); }
431 bool clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
432 bool clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
434 bool concat(const SkMatrix&);
436 // common code between setupPaintFor[Filling,Stroking]
437 void setupShader(SkPaint*, Gradient*, Pattern*, SkColor) const;
439 // Apply deferred paint state saves
440 void realizePaintSave()
442 if (m_paintState->m_saveCount) {
443 --m_paintState->m_saveCount;
445 if (m_paintStateStack.size() == m_paintStateIndex)
446 m_paintStateStack.append(GraphicsContextState::create());
447 GraphicsContextState* priorPaintState = m_paintState;
448 m_paintState = m_paintStateStack[m_paintStateIndex].get();
449 m_paintState->copy(priorPaintState);
453 // Apply deferred canvas state saves
454 void realizeCanvasSave(SkCanvas::SaveFlags flags)
456 if (m_canvasSaveFlags & flags) {
457 m_canvas->save((SkCanvas::SaveFlags)m_canvasSaveFlags);
458 m_canvasSaveFlags = 0;
462 void didDrawTextInRect(const SkRect& textRect);
464 void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&);
466 bool isRecording() const;
468 // null indicates painting is disabled. Never delete this object.
471 // Paint states stack. Enables local drawing state change with save()/restore() calls.
472 // This state controls the appearance of drawn content.
473 // We do not delete from this stack to avoid memory churn.
474 Vector<OwnPtr<GraphicsContextState> > m_paintStateStack;
475 // Current index on the stack. May not be the last thing on the stack.
476 unsigned m_paintStateIndex;
477 // Raw pointer to the current state.
478 GraphicsContextState* m_paintState;
480 // Currently pending save flags for Skia Canvas state.
481 // Canvas state includes the canavs, it's matrix and clips. Think of it as _where_
482 // the draw operations will happen.
483 // FIXME: While defined as a bitmask of SkCanvas::SaveFlags, this is mostly used as a bool.
484 // It will come in handy when adding granular save() support (clip vs. matrix vs. paint).
486 struct CanvasSaveState;
487 unsigned m_canvasSaveFlags;
488 Vector<CanvasSaveState> m_canvasStateStack;
490 AnnotationModeFlags m_annotationMode;
492 struct RecordingState;
493 Vector<RecordingState> m_recordingStateStack;
496 unsigned m_annotationCount;
497 unsigned m_layerCount;
499 // Tracks the region painted opaque via the GraphicsContext.
500 OpaqueRegionSkia m_opaqueRegion;
501 bool m_trackOpaqueRegion : 1;
503 // Tracks the region where text is painted via the GraphicsContext.
504 bool m_trackTextRegion : 1;
507 // Are we on a high DPI display? If so, spelling and grammar markers are larger.
508 bool m_useHighResMarker : 1;
509 // FIXME: Make this go away: crbug.com/236892
510 bool m_updatingControlTints : 1;
511 bool m_accelerated : 1;
512 bool m_isCertainlyOpaque : 1;
516 } // namespace WebCore
518 #endif // GraphicsContext_h