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