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/ImageFilter.h"
     38 #include "platform/graphics/ImageOrientation.h"
     39 #include "platform/graphics/GraphicsContextAnnotation.h"
     40 #include "platform/graphics/GraphicsContextState.h"
     41 #include "platform/graphics/RegionTracker.h"
     42 #include "platform/graphics/skia/SkiaUtils.h"
     43 #include "wtf/FastAllocBase.h"
     44 #include "wtf/Forward.h"
     45 #include "wtf/Noncopyable.h"
     46 #include "wtf/PassOwnPtr.h"
     47 
     48 class SkBitmap;
     49 class SkPaint;
     50 class SkPath;
     51 class SkRRect;
     52 class SkTextBlob;
     53 struct SkRect;
     54 
     55 namespace blink {
     56 
     57 class DisplayList;
     58 class ImageBuffer;
     59 class KURL;
     60 
     61 class PLATFORM_EXPORT GraphicsContext {
     62     WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
     63 public:
     64     enum AntiAliasingMode {
     65         NotAntiAliased,
     66         AntiAliased
     67     };
     68     enum AccessMode {
     69         ReadOnly,
     70         ReadWrite
     71     };
     72 
     73     enum DisabledMode {
     74         NothingDisabled = 0, // Run as normal.
     75         FullyDisabled = 1 // Do absolutely minimal work to remove the cost of the context from performance tests.
     76     };
     77 
     78     // A 0 canvas is allowed, but in such cases the context must only have canvas
     79     // related commands called when within a beginRecording/endRecording block.
     80     // Furthermore, save/restore calls must be balanced any time the canvas is 0.
     81     explicit GraphicsContext(SkCanvas*, DisabledMode = NothingDisabled);
     82 
     83     ~GraphicsContext();
     84 
     85     // Returns the canvas used for painting. Must not be called if painting is disabled.
     86     // Accessing the backing canvas this way flushes all queued save ops,
     87     // so it should be avoided. Use the corresponding draw/matrix/clip methods instead.
     88     SkCanvas* canvas()
     89     {
     90         // Flush any pending saves.
     91         realizeCanvasSave();
     92 
     93         return m_canvas;
     94     }
     95     const SkCanvas* canvas() const
     96     {
     97         return m_canvas;
     98     }
     99 
    100     void resetCanvas(SkCanvas*);
    101 
    102     bool contextDisabled() const { return m_disabledState; }
    103 
    104     // ---------- State management methods -----------------
    105     void save();
    106     void restore();
    107     unsigned saveCount() { return m_canvasStateStack.size(); }
    108 #if ENABLE(ASSERT)
    109     void disableDestructionChecks() { m_disableDestructionChecks = true; }
    110 #endif
    111 
    112     void saveLayer(const SkRect* bounds, const SkPaint*);
    113     void restoreLayer();
    114 
    115     bool hasStroke() const { return strokeStyle() != NoStroke && strokeThickness() > 0; }
    116 
    117     float strokeThickness() const { return immutableState()->strokeData().thickness(); }
    118     void setStrokeThickness(float thickness) { mutableState()->setStrokeThickness(thickness); }
    119 
    120     StrokeStyle strokeStyle() const { return immutableState()->strokeData().style(); }
    121     void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); }
    122 
    123     Color strokeColor() const { return immutableState()->strokeColor(); }
    124     void setStrokeColor(const Color& color) { mutableState()->setStrokeColor(color); }
    125     SkColor effectiveStrokeColor() const { return immutableState()->effectiveStrokeColor(); }
    126 
    127     Pattern* strokePattern() const { return immutableState()->strokePattern(); }
    128     void setStrokePattern(PassRefPtr<Pattern>);
    129 
    130     Gradient* strokeGradient() const { return immutableState()->strokeGradient(); }
    131     void setStrokeGradient(PassRefPtr<Gradient>);
    132 
    133     void setLineCap(LineCap cap) { mutableState()->setLineCap(cap); }
    134     void setLineDash(const DashArray& dashes, float dashOffset) { mutableState()->setLineDash(dashes, dashOffset); }
    135     void setLineJoin(LineJoin join) { mutableState()->setLineJoin(join); }
    136     void setMiterLimit(float limit) { mutableState()->setMiterLimit(limit); }
    137 
    138     WindRule fillRule() const { return immutableState()->fillRule(); }
    139     void setFillRule(WindRule fillRule) { mutableState()->setFillRule(fillRule); }
    140 
    141     Color fillColor() const { return immutableState()->fillColor(); }
    142     void setFillColor(const Color& color) { mutableState()->setFillColor(color); }
    143     SkColor effectiveFillColor() const { return immutableState()->effectiveFillColor(); }
    144 
    145     void setFillPattern(PassRefPtr<Pattern>);
    146     Pattern* fillPattern() const { return immutableState()->fillPattern(); }
    147 
    148     void setFillGradient(PassRefPtr<Gradient>);
    149     Gradient* fillGradient() const { return immutableState()->fillGradient(); }
    150 
    151     SkDrawLooper* drawLooper() const { return immutableState()->drawLooper(); }
    152 
    153     bool getTransformedClipBounds(FloatRect* bounds) const;
    154     SkMatrix getTotalMatrix() const;
    155 
    156     void setShouldAntialias(bool antialias) { mutableState()->setShouldAntialias(antialias); }
    157     bool shouldAntialias() const { return immutableState()->shouldAntialias(); }
    158 
    159     // Disable the anti-aliasing optimization for scales/multiple-of-90-degrees
    160     // rotations of thin ("hairline") images.
    161     // Note: This will only be reliable when the device pixel scale/ratio is
    162     // fixed (e.g. when drawing to context backed by an ImageBuffer).
    163     void disableAntialiasingOptimizationForHairlineImages() { ASSERT(!isRecording()); m_antialiasHairlineImages = true; }
    164     bool shouldAntialiasHairlineImages() const { return m_antialiasHairlineImages; }
    165 
    166     void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->setShouldClampToSourceRect(clampToSourceRect); }
    167     bool shouldClampToSourceRect() const { return immutableState()->shouldClampToSourceRect(); }
    168 
    169     // FIXME: the setter is only used once, at construction time; convert to a constructor param,
    170     // and possibly consolidate with other flags (paintDisabled, isPrinting, ...)
    171     void setShouldSmoothFonts(bool smoothFonts) { m_shouldSmoothFonts = smoothFonts; }
    172     bool shouldSmoothFonts() const { return m_shouldSmoothFonts; }
    173 
    174     // Turn off LCD text for the paint if not supported on this context.
    175     void adjustTextRenderMode(SkPaint*) const;
    176     bool couldUseLCDRenderedText() const;
    177 
    178     void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->setTextDrawingMode(mode); }
    179     TextDrawingModeFlags textDrawingMode() const { return immutableState()->textDrawingMode(); }
    180 
    181     void setAlphaAsFloat(float alpha) { mutableState()->setAlphaAsFloat(alpha);}
    182     int getNormalizedAlpha() const
    183     {
    184         int alpha = immutableState()->alpha();
    185         return alpha > 255 ? 255 : alpha;
    186     }
    187 
    188     void setImageInterpolationQuality(InterpolationQuality quality) { mutableState()->setInterpolationQuality(quality); }
    189     InterpolationQuality imageInterpolationQuality() const { return immutableState()->interpolationQuality(); }
    190 
    191     void setCompositeOperation(CompositeOperator, WebBlendMode = WebBlendModeNormal);
    192     CompositeOperator compositeOperation() const { return immutableState()->compositeOperator(); }
    193     WebBlendMode blendModeOperation() const { return immutableState()->blendMode(); }
    194 
    195     // Speicy the device scale factor which may change the way document markers
    196     // and fonts are rendered.
    197     void setDeviceScaleFactor(float factor) { m_deviceScaleFactor = factor; }
    198     float deviceScaleFactor() const { return m_deviceScaleFactor; }
    199 
    200     // If true we are (most likely) rendering to a web page and the
    201     // canvas has been prepared with an opaque background. If false,
    202     // the canvas may have transparency (as is the case when rendering
    203     // to a canvas object).
    204     void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; }
    205     bool isCertainlyOpaque() const { return m_isCertainlyOpaque; }
    206 
    207     // Returns if the context is a printing context instead of a display
    208     // context. Bitmap shouldn't be resampled when printing to keep the best
    209     // possible quality.
    210     bool printing() const { return m_printing; }
    211     void setPrinting(bool printing) { m_printing = printing; }
    212 
    213     bool isAccelerated() const { return m_accelerated; }
    214     void setAccelerated(bool accelerated) { m_accelerated = accelerated; }
    215 
    216     // The opaque region is empty until tracking is turned on.
    217     // It is never clerared by the context.
    218     enum RegionTrackingMode {
    219         RegionTrackingDisabled = 0,
    220         RegionTrackingOpaque,
    221         RegionTrackingOverwrite
    222     };
    223     void setRegionTrackingMode(RegionTrackingMode);
    224     bool regionTrackingEnabled() { return m_regionTrackingMode != RegionTrackingDisabled; }
    225     const RegionTracker& opaqueRegion() const { return m_trackedRegion; }
    226 
    227     // The text region is empty until tracking is turned on.
    228     // It is never clerared by the context.
    229     void setTrackTextRegion(bool track) { m_trackTextRegion = track; }
    230     const SkRect& textRegion() const { return m_textRegion; }
    231 
    232     AnnotationModeFlags annotationMode() const { return m_annotationMode; }
    233     void setAnnotationMode(const AnnotationModeFlags mode) { m_annotationMode = mode; }
    234 
    235     SkColorFilter* colorFilter() const;
    236     void setColorFilter(ColorFilter);
    237     // ---------- End state management methods -----------------
    238 
    239     // Get the contents of the image buffer
    240     bool readPixels(const SkImageInfo&, void* pixels, size_t rowBytes, int x, int y);
    241 
    242     // Get the current fill style.
    243     const SkPaint& fillPaint() const { return immutableState()->fillPaint(); }
    244 
    245     // Get the current stroke style.
    246     const SkPaint& strokePaint() const { return immutableState()->strokePaint(); }
    247 
    248     // These draw methods will do both stroking and filling.
    249     // FIXME: ...except drawRect(), which fills properly but always strokes
    250     // using a 1-pixel stroke inset from the rect borders (of the correct
    251     // stroke color).
    252     void drawRect(const IntRect&);
    253     void drawLine(const IntPoint&, const IntPoint&);
    254     void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
    255 
    256     void fillPath(const Path&);
    257     void strokePath(const Path&);
    258 
    259     void fillEllipse(const FloatRect&);
    260     void strokeEllipse(const FloatRect&);
    261 
    262     void fillRect(const FloatRect&);
    263     void fillRect(const FloatRect&, const Color&);
    264     void fillRect(const FloatRect&, const Color&, CompositeOperator);
    265     void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&);
    266     void fillRoundedRect(const RoundedRect&, const Color&);
    267 
    268     void clearRect(const FloatRect&);
    269 
    270     void strokeRect(const FloatRect&);
    271     void strokeRect(const FloatRect&, float lineWidth);
    272 
    273     void fillBetweenRoundedRects(const IntRect&, const IntSize& outerTopLeft, const IntSize& outerTopRight, const IntSize& outerBottomLeft, const IntSize& outerBottomRight,
    274         const IntRect&, const IntSize& innerTopLeft, const IntSize& innerTopRight, const IntSize& innerBottomLeft, const IntSize& innerBottomRight, const Color&);
    275     void fillBetweenRoundedRects(const RoundedRect&, const RoundedRect&, const Color&);
    276 
    277     void drawDisplayList(DisplayList*);
    278 
    279     void drawImage(Image*, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
    280     void drawImage(Image*, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
    281     void drawImage(Image*, const FloatRect& destRect);
    282     void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation);
    283     void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, WebBlendMode, RespectImageOrientationEnum = DoNotRespectImageOrientation);
    284 
    285     void drawTiledImage(Image*, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
    286         CompositeOperator = CompositeSourceOver, WebBlendMode = WebBlendModeNormal, const IntSize& repeatSpacing = IntSize());
    287     void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect,
    288         const FloatSize& tileScaleFactor, Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
    289         CompositeOperator = CompositeSourceOver);
    290 
    291     void drawImageBuffer(ImageBuffer*, const FloatRect& destRect, const FloatRect* srcRect = 0, CompositeOperator = CompositeSourceOver, WebBlendMode = WebBlendModeNormal);
    292 
    293     void drawPicture(PassRefPtr<SkPicture>, const FloatRect& dest, const FloatRect& src, CompositeOperator, WebBlendMode);
    294 
    295     // These methods write to the canvas and modify the opaque region, if tracked.
    296     // Also drawLine(const IntPoint& point1, const IntPoint& point2) and fillRoundedRect
    297     void writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
    298     void writePixels(const SkBitmap&, int x, int y);
    299     void drawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint* = 0);
    300     void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint* = 0);
    301     void drawOval(const SkRect&, const SkPaint&);
    302     void drawPath(const SkPath&, const SkPaint&);
    303     // After drawing directly to the context's canvas, use this function to notify the context so
    304     // it can track the opaque region.
    305     // FIXME: this is still needed only because ImageSkia::paintSkBitmap() may need to notify for a
    306     //        smaller rect than the one drawn to, due to its clipping logic.
    307     void didDrawRect(const SkRect&, const SkPaint&, const SkBitmap* = 0);
    308     void drawRect(const SkRect&, const SkPaint&);
    309     void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkRect& textRect, const SkPaint&);
    310     void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkRect& textRect, const SkPaint&);
    311     void drawTextBlob(const SkTextBlob*, const SkPoint& origin, const SkPaint&);
    312 
    313     void clip(const IntRect& rect) { clipRect(rect); }
    314     void clip(const FloatRect& rect) { clipRect(rect); }
    315     void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op);
    316     void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); }
    317     void clipOut(const Path&);
    318     void clipOutRoundedRect(const RoundedRect&);
    319     void clipPath(const Path&, WindRule = RULE_EVENODD);
    320     void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
    321     void clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
    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 
    327     void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
    328     void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&);
    329     void drawBidiText(const Font&, const TextRunPaintInfo&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady);
    330     void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1);
    331 
    332     void drawLineForText(const FloatPoint&, float width, bool printing);
    333     enum DocumentMarkerLineStyle {
    334         DocumentMarkerSpellingLineStyle,
    335         DocumentMarkerGrammarLineStyle
    336     };
    337     void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
    338 
    339     void beginTransparencyLayer(float opacity, const FloatRect* = 0);
    340     void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone, ImageFilter* = 0);
    341     void endLayer();
    342 
    343     void beginCull(const FloatRect&);
    344     void endCull();
    345 
    346     // Instead of being dispatched to the active canvas, draw commands following beginRecording()
    347     // are stored in a display list that can be replayed at a later time. Pass in the bounding
    348     // rectangle for the content in the list.
    349     void beginRecording(const FloatRect&, uint32_t = 0);
    350     PassRefPtr<DisplayList> endRecording();
    351 
    352     bool hasShadow() const;
    353     void setShadow(const FloatSize& offset, float blur, const Color&,
    354         DrawLooperBuilder::ShadowTransformMode = DrawLooperBuilder::ShadowRespectsTransforms,
    355         DrawLooperBuilder::ShadowAlphaMode = DrawLooperBuilder::ShadowRespectsAlpha);
    356     void clearShadow() { clearDrawLooper(); }
    357 
    358     // It is assumed that this draw looper is used only for shadows
    359     // (i.e. a draw looper is set if and only if there is a shadow).
    360     // The builder passed into this method will be destroyed.
    361     void setDrawLooper(PassOwnPtr<DrawLooperBuilder>);
    362     void clearDrawLooper();
    363 
    364     void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
    365     void drawFocusRing(const Path&, int width, int offset, const Color&);
    366 
    367     enum Edge {
    368         NoEdge = 0,
    369         TopEdge = 1 << 1,
    370         RightEdge = 1 << 2,
    371         BottomEdge = 1 << 3,
    372         LeftEdge = 1 << 4
    373     };
    374     typedef unsigned Edges;
    375     void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
    376 
    377     // ---------- Transformation methods -----------------
    378     // Note that the getCTM method returns only the current transform from Blink's perspective,
    379     // which is not the final transform used to place content on screen. It cannot be relied upon
    380     // for testing where a point will appear on screen or how large it will be.
    381     AffineTransform getCTM() const;
    382     void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); }
    383     void setCTM(const AffineTransform& affine) { setMatrix(affineTransformToSkMatrix(affine)); }
    384     void setMatrix(const SkMatrix&);
    385 
    386     void scale(float x, float y);
    387     void rotate(float angleInRadians);
    388     void translate(float x, float y);
    389 
    390     // This function applies the device scale factor to the context, making the context capable of
    391     // acting as a base-level context for a HiDPI environment.
    392     void applyDeviceScaleFactor(float deviceScaleFactor) { scale(deviceScaleFactor, deviceScaleFactor); }
    393     // ---------- End transformation methods -----------------
    394 
    395     // URL drawing
    396     void setURLForRect(const KURL&, const IntRect&);
    397     void setURLFragmentForRect(const String& name, const IntRect&);
    398     void addURLTargetAtPoint(const String& name, const IntPoint&);
    399 
    400     // Create an image buffer compatible with this context, with suitable resolution
    401     // for drawing into the buffer and then into this context.
    402     PassOwnPtr<ImageBuffer> createRasterBuffer(const IntSize&, OpacityMode = NonOpaque) const;
    403 
    404     static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
    405 
    406     void beginAnnotation(const AnnotationList&);
    407     void endAnnotation();
    408 
    409     void preparePaintForDrawRectToRect(
    410         SkPaint*,
    411         const SkRect& srcRect,
    412         const SkRect& destRect,
    413         CompositeOperator,
    414         WebBlendMode,
    415         bool isLazyDecoded = false,
    416         bool isDataComplete = true) const;
    417 
    418     static int focusRingOutsetExtent(int offset, int width)
    419     {
    420         return focusRingOutset(offset) + (focusRingWidth(width) + 1) / 2;
    421     }
    422 
    423 private:
    424     const GraphicsContextState* immutableState() const { return m_paintState; }
    425 
    426     GraphicsContextState* mutableState()
    427     {
    428         realizePaintSave();
    429         return m_paintState;
    430     }
    431 
    432     static void setPathFromConvexPoints(SkPath*, size_t, const FloatPoint*);
    433     static void setRadii(SkVector*, IntSize, IntSize, IntSize, IntSize);
    434 
    435     static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter);
    436 
    437 #if OS(MACOSX)
    438     static inline int focusRingOutset(int offset) { return offset + 2; }
    439     static inline int focusRingWidth(int width) { return width; }
    440 #else
    441     static inline int focusRingOutset(int offset) { return 0; }
    442     static inline int focusRingWidth(int width) { return 1; }
    443     static SkPMColor lineColors(int);
    444     static SkPMColor antiColors1(int);
    445     static SkPMColor antiColors2(int);
    446     static void draw1xMarker(SkBitmap*, int);
    447     static void draw2xMarker(SkBitmap*, int);
    448 #endif
    449 
    450     // Helpers for drawing a focus ring (drawFocusRing)
    451     float prepareFocusRingPaint(SkPaint&, const Color&, int width) const;
    452     void drawFocusRingPath(const SkPath&, const Color&, int width);
    453     void drawFocusRingRect(const SkRect&, const Color&, int width);
    454 
    455     // SkCanvas wrappers.
    456     void clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
    457     void clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
    458     void concat(const SkMatrix&);
    459     void drawRRect(const SkRRect&, const SkPaint&);
    460 
    461     // Apply deferred paint state saves
    462     void realizePaintSave()
    463     {
    464         if (contextDisabled())
    465             return;
    466 
    467         if (m_paintState->saveCount()) {
    468             m_paintState->decrementSaveCount();
    469             ++m_paintStateIndex;
    470             if (m_paintStateStack.size() == m_paintStateIndex) {
    471                 m_paintStateStack.append(GraphicsContextState::createAndCopy(*m_paintState));
    472                 m_paintState = m_paintStateStack[m_paintStateIndex].get();
    473             } else {
    474                 GraphicsContextState* priorPaintState = m_paintState;
    475                 m_paintState = m_paintStateStack[m_paintStateIndex].get();
    476                 m_paintState->copy(*priorPaintState);
    477             }
    478         }
    479     }
    480 
    481     // Apply deferred canvas state saves
    482     void realizeCanvasSave()
    483     {
    484         if (!m_pendingCanvasSave || contextDisabled())
    485             return;
    486 
    487         ASSERT(m_canvas); // m_pendingCanvasSave should never be true when no canvas.
    488         m_canvas->save();
    489         m_pendingCanvasSave = false;
    490     }
    491 
    492     void didDrawTextInRect(const SkRect& textRect);
    493 
    494     void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&);
    495 
    496     bool isRecording() const;
    497 
    498     // null indicates painting is contextDisabled. Never delete this object.
    499     SkCanvas* m_canvas;
    500 
    501     // Paint states stack. Enables local drawing state change with save()/restore() calls.
    502     // This state controls the appearance of drawn content.
    503     // We do not delete from this stack to avoid memory churn.
    504     Vector<OwnPtr<GraphicsContextState> > m_paintStateStack;
    505     // Current index on the stack. May not be the last thing on the stack.
    506     unsigned m_paintStateIndex;
    507     // Raw pointer to the current state.
    508     GraphicsContextState* m_paintState;
    509 
    510     // Currently pending save flags for Skia Canvas state.
    511     // Canvas state includes the canavs, it's matrix and clips. Think of it as _where_
    512     // the draw operations will happen.
    513     struct CanvasSaveState;
    514     Vector<CanvasSaveState> m_canvasStateStack;
    515     bool m_pendingCanvasSave;
    516 
    517     AnnotationModeFlags m_annotationMode;
    518 
    519     struct RecordingState;
    520     Vector<RecordingState> m_recordingStateStack;
    521 
    522 #if ENABLE(ASSERT)
    523     unsigned m_annotationCount;
    524     unsigned m_layerCount;
    525     bool m_disableDestructionChecks;
    526 #endif
    527     // Tracks the region painted opaque via the GraphicsContext.
    528     RegionTracker m_trackedRegion;
    529 
    530     // Tracks the region where text is painted via the GraphicsContext.
    531     SkRect m_textRegion;
    532 
    533     unsigned m_disabledState;
    534 
    535     float m_deviceScaleFactor;
    536 
    537     // Activation for the above region tracking features
    538     unsigned m_regionTrackingMode : 2;
    539     bool m_trackTextRegion : 1;
    540 
    541     bool m_accelerated : 1;
    542     bool m_isCertainlyOpaque : 1;
    543     bool m_printing : 1;
    544     bool m_antialiasHairlineImages : 1;
    545     bool m_shouldSmoothFonts : 1;
    546 };
    547 
    548 } // namespace blink
    549 
    550 #endif // GraphicsContext_h
    551