• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
46 class SkBitmap;
47 class SkPaint;
48 class SkPath;
49 class SkRRect;
50 struct SkRect;
51 
52 namespace WebCore {
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         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.
canvas()84     SkCanvas* canvas()
85     {
86         ASSERT(!paintingDisabled());
87 
88         // Flush any pending saves.
89         realizeCanvasSave();
90 
91         return m_canvas;
92     }
canvas()93     const SkCanvas* canvas() const
94     {
95         ASSERT(!paintingDisabled());
96         return m_canvas;
97     }
paintingDisabled()98     bool paintingDisabled() const { return m_disabledState & PaintingDisabled; }
contextDisabled()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
isRecordingCanvas()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();
saveCount()114     unsigned saveCount() { return m_canvasStateStack.size(); }
115 #if ASSERT_ENABLED
disableDestructionChecks()116     void disableDestructionChecks() { m_disableDestructionChecks = true; }
117 #endif
118 
119     void saveLayer(const SkRect* bounds, const SkPaint*);
120     void restoreLayer();
121 
strokeThickness()122     float strokeThickness() const { return immutableState()->strokeData().thickness(); }
setStrokeThickness(float thickness)123     void setStrokeThickness(float thickness) { mutableState()->setStrokeThickness(thickness); }
124 
strokeStyle()125     StrokeStyle strokeStyle() const { return immutableState()->strokeData().style(); }
setStrokeStyle(StrokeStyle style)126     void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); }
127 
strokeColor()128     Color strokeColor() const { return immutableState()->strokeData().color(); }
setStrokeColor(const Color & color)129     void setStrokeColor(const Color& color) { mutableState()->setStrokeColor(color); }
effectiveStrokeColor()130     SkColor effectiveStrokeColor() const { return immutableState()->effectiveStrokeColor(); }
131 
strokePattern()132     Pattern* strokePattern() const { return immutableState()->strokeData().pattern(); }
133     void setStrokePattern(PassRefPtr<Pattern>);
134 
strokeGradient()135     Gradient* strokeGradient() const { return immutableState()->strokeData().gradient(); }
136     void setStrokeGradient(PassRefPtr<Gradient>);
137 
setLineCap(LineCap cap)138     void setLineCap(LineCap cap) { mutableState()->setLineCap(cap); }
setLineDash(const DashArray & dashes,float dashOffset)139     void setLineDash(const DashArray& dashes, float dashOffset) { mutableState()->setLineDash(dashes, dashOffset); }
setLineJoin(LineJoin join)140     void setLineJoin(LineJoin join) { mutableState()->setLineJoin(join); }
setMiterLimit(float limit)141     void setMiterLimit(float limit) { mutableState()->setMiterLimit(limit); }
142 
fillRule()143     WindRule fillRule() const { return immutableState()->fillRule(); }
setFillRule(WindRule fillRule)144     void setFillRule(WindRule fillRule) { mutableState()->setFillRule(fillRule); }
145 
fillColor()146     Color fillColor() const { return immutableState()->fillColor(); }
setFillColor(const Color & color)147     void setFillColor(const Color& color) { mutableState()->setFillColor(color); }
effectiveFillColor()148     SkColor effectiveFillColor() const { return immutableState()->effectiveFillColor(); }
149 
150     void setFillPattern(PassRefPtr<Pattern>);
fillPattern()151     Pattern* fillPattern() const { return immutableState()->fillPattern(); }
152 
153     void setFillGradient(PassRefPtr<Gradient>);
fillGradient()154     Gradient* fillGradient() const { return immutableState()->fillGradient(); }
155 
drawLooper()156     SkDrawLooper* drawLooper() const { return immutableState()->drawLooper(); }
157 
158     bool getTransformedClipBounds(FloatRect* bounds) const;
159     SkMatrix getTotalMatrix() const;
160 
setShouldAntialias(bool antialias)161     void setShouldAntialias(bool antialias) { mutableState()->setShouldAntialias(antialias); }
shouldAntialias()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).
disableAntialiasingOptimizationForHairlineImages()168     void disableAntialiasingOptimizationForHairlineImages() { ASSERT(!isRecording()); m_antialiasHairlineImages = true; }
shouldAntialiasHairlineImages()169     bool shouldAntialiasHairlineImages() const { return m_antialiasHairlineImages; }
170 
setShouldClampToSourceRect(bool clampToSourceRect)171     void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->setShouldClampToSourceRect(clampToSourceRect); }
shouldClampToSourceRect()172     bool shouldClampToSourceRect() const { return immutableState()->shouldClampToSourceRect(); }
173 
setShouldSmoothFonts(bool smoothFonts)174     void setShouldSmoothFonts(bool smoothFonts) { mutableState()->setShouldSmoothFonts(smoothFonts); }
shouldSmoothFonts()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 
setTextDrawingMode(TextDrawingModeFlags mode)181     void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->setTextDrawingMode(mode); }
textDrawingMode()182     TextDrawingModeFlags textDrawingMode() const { return immutableState()->textDrawingMode(); }
183 
setAlphaAsFloat(float alpha)184     void setAlphaAsFloat(float alpha) { mutableState()->setAlphaAsFloat(alpha);}
getNormalizedAlpha()185     int getNormalizedAlpha() const
186     {
187         int alpha = immutableState()->alpha();
188         return alpha > 255 ? 255 : alpha;
189     }
190 
setImageInterpolationQuality(InterpolationQuality quality)191     void setImageInterpolationQuality(InterpolationQuality quality) { mutableState()->setInterpolationQuality(quality); }
imageInterpolationQuality()192     InterpolationQuality imageInterpolationQuality() const { return immutableState()->interpolationQuality(); }
193 
194     void setCompositeOperation(CompositeOperator, blink::WebBlendMode = blink::WebBlendModeNormal);
compositeOperation()195     CompositeOperator compositeOperation() const { return immutableState()->compositeOperator(); }
blendModeOperation()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.
setUseHighResMarkers(bool isHighRes)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).
setCertainlyOpaque(bool isOpaque)206     void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; }
isCertainlyOpaque()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.
printing()212     bool printing() const { return m_printing; }
setPrinting(bool printing)213     void setPrinting(bool printing) { m_printing = printing; }
214 
isAccelerated()215     bool isAccelerated() const { return m_accelerated; }
setAccelerated(bool 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.
setTrackOpaqueRegion(bool track)220     void setTrackOpaqueRegion(bool track) { m_trackOpaqueRegion = track; }
opaqueRegion()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.
setTrackTextRegion(bool track)225     void setTrackTextRegion(bool track) { m_trackTextRegion = track; }
textRegion()226     const SkRect& textRegion() const { return m_textRegion; }
227 
updatingControlTints()228     bool updatingControlTints() const { return m_updatingControlTints; }
setUpdatingControlTints(bool updatingTints)229     void setUpdatingControlTints(bool updatingTints) { m_updatingControlTints = updatingTints; }
230 
annotationMode()231     AnnotationModeFlags annotationMode() const { return m_annotationMode; }
setAnnotationMode(const AnnotationModeFlags mode)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.
fillPaint()242     const SkPaint& fillPaint() const { return immutableState()->fillPaint(); }
243 
244     // Get the current stroke style.
strokePaint()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 
clip(const IntRect & rect)308     void clip(const IntRect& rect) { clipRect(rect); }
clip(const FloatRect & rect)309     void clip(const FloatRect& rect) { clipRect(rect); }
310     void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op);
clipOut(const IntRect & rect)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);
clearShadow()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;
concatCTM(const AffineTransform & affine)377     void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); }
setCTM(const AffineTransform & 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.
applyDeviceScaleFactor(float deviceScaleFactor)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&);
supportsURLFragments()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 
405 private:
immutableState()406     const GraphicsContextState* immutableState() const { return m_paintState; }
407 
mutableState()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)
getFocusRingOutset(int offset)420     static inline int getFocusRingOutset(int offset) { return offset + 2; }
421 #else
getFocusRingOutset(int offset)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
realizePaintSave()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
realizeCanvasSave()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