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