• 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/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 
50 class SkBitmap;
51 class SkPaint;
52 class SkPath;
53 class SkRRect;
54 struct SkRect;
55 
56 namespace WebCore {
57 
58 class DisplayList;
59 class ImageBuffer;
60 class KURL;
61 
62 class PLATFORM_EXPORT GraphicsContext {
63     WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
64 public:
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.
canvas()80     SkCanvas* canvas()
81     {
82         // Flush any pending saves.
83         realizeSave(SkCanvas::kMatrixClip_SaveFlag);
84 
85         return m_canvas;
86     }
canvas()87     const SkCanvas* canvas() const { return m_canvas; }
paintingDisabled()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 
strokeThickness()100     float strokeThickness() const { return m_state->m_strokeData.thickness(); }
setStrokeThickness(float thickness)101     void setStrokeThickness(float thickness) { m_state->m_strokeData.setThickness(thickness); }
102 
strokeStyle()103     StrokeStyle strokeStyle() const { return m_state->m_strokeData.style(); }
setStrokeStyle(StrokeStyle style)104     void setStrokeStyle(StrokeStyle style) { m_state->m_strokeData.setStyle(style); }
105 
strokeColor()106     Color strokeColor() const { return m_state->m_strokeData.color(); }
107     void setStrokeColor(const Color&);
108 
strokePattern()109     Pattern* strokePattern() const { return m_state->m_strokeData.pattern(); }
110     void setStrokePattern(PassRefPtr<Pattern>);
111 
strokeGradient()112     Gradient* strokeGradient() const { return m_state->m_strokeData.gradient(); }
113     void setStrokeGradient(PassRefPtr<Gradient>);
114 
setLineCap(LineCap cap)115     void setLineCap(LineCap cap) { m_state->m_strokeData.setLineCap(cap); }
setLineDash(const DashArray & dashes,float dashOffset)116     void setLineDash(const DashArray& dashes, float dashOffset) { m_state->m_strokeData.setLineDash(dashes, dashOffset); }
setLineJoin(LineJoin join)117     void setLineJoin(LineJoin join) { m_state->m_strokeData.setLineJoin(join); }
setMiterLimit(float limit)118     void setMiterLimit(float limit) { m_state->m_strokeData.setMiterLimit(limit); }
119 
fillRule()120     WindRule fillRule() const { return m_state->m_fillRule; }
setFillRule(WindRule fillRule)121     void setFillRule(WindRule fillRule) { m_state->m_fillRule = fillRule; }
122 
fillColor()123     Color fillColor() const { return m_state->m_fillColor; }
124     void setFillColor(const Color&);
effectiveFillColor()125     SkColor effectiveFillColor() const { return m_state->applyAlpha(m_state->m_fillColor.rgb()); }
126 
127     void setFillPattern(PassRefPtr<Pattern>);
fillPattern()128     Pattern* fillPattern() const { return m_state->m_fillPattern.get(); }
129 
130     void setFillGradient(PassRefPtr<Gradient>);
fillGradient()131     Gradient* fillGradient() const { return m_state->m_fillGradient.get(); }
132 
drawLooper()133     SkDrawLooper* drawLooper() const { return m_state->m_looper.get(); }
effectiveStrokeColor()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 
setShouldAntialias(bool antialias)143     void setShouldAntialias(bool antialias) { m_state->m_shouldAntialias = antialias; }
shouldAntialias()144     bool shouldAntialias() const { return m_state->m_shouldAntialias; }
145 
setShouldClampToSourceRect(bool clampToSourceRect)146     void setShouldClampToSourceRect(bool clampToSourceRect) { m_state->m_shouldClampToSourceRect = clampToSourceRect; }
shouldClampToSourceRect()147     bool shouldClampToSourceRect() const { return m_state->m_shouldClampToSourceRect; }
148 
setShouldSmoothFonts(bool smoothFonts)149     void setShouldSmoothFonts(bool smoothFonts) { m_state->m_shouldSmoothFonts = smoothFonts; }
shouldSmoothFonts()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 
textDrawingMode()156     TextDrawingModeFlags textDrawingMode() const { return m_state->m_textDrawingMode; }
setTextDrawingMode(TextDrawingModeFlags mode)157     void setTextDrawingMode(TextDrawingModeFlags mode) { m_state->m_textDrawingMode = mode; }
158 
setAlpha(float alpha)159     void setAlpha(float alpha) { m_state->m_alpha = alpha; }
160 
setImageInterpolationQuality(InterpolationQuality quality)161     void setImageInterpolationQuality(InterpolationQuality quality) { m_state->m_interpolationQuality = quality; }
imageInterpolationQuality()162     InterpolationQuality imageInterpolationQuality() const { return m_state->m_interpolationQuality; }
163 
164     void setCompositeOperation(CompositeOperator, blink::WebBlendMode = blink::WebBlendModeNormal);
compositeOperation()165     CompositeOperator compositeOperation() const { return m_state->m_compositeOperator; }
blendModeOperation()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.
setUseHighResMarkers(bool isHighRes)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).
setCertainlyOpaque(bool isOpaque)176     void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; }
isCertainlyOpaque()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.
printing()182     bool printing() const { return m_printing; }
setPrinting(bool printing)183     void setPrinting(bool printing) { m_printing = printing; }
184 
isAccelerated()185     bool isAccelerated() const { return m_accelerated; }
setAccelerated(bool 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.
setTrackOpaqueRegion(bool track)190     void setTrackOpaqueRegion(bool track) { m_trackOpaqueRegion = track; }
opaqueRegion()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.
setTrackTextRegion(bool track)195     void setTrackTextRegion(bool track) { m_trackTextRegion = track; }
textRegion()196     const SkRect& textRegion() const { return m_textRegion; }
197 
updatingControlTints()198     bool updatingControlTints() const { return m_updatingControlTints; }
setUpdatingControlTints(bool updatingTints)199     void setUpdatingControlTints(bool updatingTints) { m_updatingControlTints = updatingTints; }
200 
annotationMode()201     AnnotationModeFlags annotationMode() const { return m_annotationMode; }
setAnnotationMode(const AnnotationModeFlags mode)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 
clip(const IntRect & rect)284     void clip(const IntRect& rect) { clip(FloatRect(rect)); }
clip(const FloatRect & rect)285     void clip(const FloatRect& rect) { clipRect(rect); }
286     void clipRoundedRect(const RoundedRect&);
clipOut(const IntRect & rect)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);
clearShadow()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;
concatCTM(const AffineTransform & affine)347     void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); }
setCTM(const AffineTransform & 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);
translate(const FloatSize & size)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.
applyDeviceScaleFactor(float deviceScaleFactor)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&);
supportsURLFragments()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 
376 private:
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)
getFocusRingOutset(int offset)384     static inline int getFocusRingOutset(int offset) { return offset + 2; }
385 #else
getFocusRingOutset(int offset)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.
fastMod(int value,int max)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.
isDrawingToLayer()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
realizeSave(SkCanvas::SaveFlags flags)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