| /* |
| * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| * Copyright (C) 2008-2009 Torch Mobile, Inc. |
| * Copyright (C) 2013 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef SKY_ENGINE_PLATFORM_GRAPHICS_GRAPHICSCONTEXT_H_ |
| #define SKY_ENGINE_PLATFORM_GRAPHICS_GRAPHICSCONTEXT_H_ |
| |
| #include "sky/engine/platform/PlatformExport.h" |
| #include "sky/engine/platform/fonts/Font.h" |
| #include "sky/engine/platform/geometry/FloatRect.h" |
| #include "sky/engine/platform/graphics/DashArray.h" |
| #include "sky/engine/platform/graphics/DrawLooperBuilder.h" |
| #include "sky/engine/platform/graphics/GraphicsContextAnnotation.h" |
| #include "sky/engine/platform/graphics/GraphicsContextState.h" |
| #include "sky/engine/platform/graphics/ImageBufferSurface.h" |
| #include "sky/engine/platform/graphics/ImageFilter.h" |
| #include "sky/engine/platform/graphics/ImageOrientation.h" |
| #include "sky/engine/platform/graphics/RegionTracker.h" |
| #include "sky/engine/platform/graphics/skia/SkiaUtils.h" |
| #include "sky/engine/wtf/FastAllocBase.h" |
| #include "sky/engine/wtf/Forward.h" |
| #include "sky/engine/wtf/Noncopyable.h" |
| #include "sky/engine/wtf/PassOwnPtr.h" |
| |
| class SkBitmap; |
| class SkPaint; |
| class SkPath; |
| class SkRRect; |
| class SkTextBlob; |
| struct SkRect; |
| |
| namespace blink { |
| |
| class DisplayList; |
| class ImageBuffer; |
| class KURL; |
| |
| class PLATFORM_EXPORT GraphicsContext { |
| WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED; |
| public: |
| enum AntiAliasingMode { |
| NotAntiAliased, |
| AntiAliased |
| }; |
| enum AccessMode { |
| ReadOnly, |
| ReadWrite |
| }; |
| |
| enum DisabledMode { |
| NothingDisabled = 0, // Run as normal. |
| FullyDisabled = 1 // Do absolutely minimal work to remove the cost of the context from performance tests. |
| }; |
| |
| explicit GraphicsContext(SkCanvas*, DisabledMode = NothingDisabled); |
| ~GraphicsContext(); |
| |
| // Returns the canvas used for painting. Must not be called if painting is disabled. |
| // Accessing the backing canvas this way flushes all queued save ops, |
| // so it should be avoided. Use the corresponding draw/matrix/clip methods instead. |
| SkCanvas* canvas() |
| { |
| // Flush any pending saves. |
| realizeCanvasSave(); |
| |
| return m_canvas; |
| } |
| const SkCanvas* canvas() const |
| { |
| return m_canvas; |
| } |
| |
| void resetCanvas(SkCanvas*); |
| |
| bool contextDisabled() const { return m_disabledState; } |
| |
| // ---------- State management methods ----------------- |
| void save(); |
| void restore(); |
| unsigned saveCount() { return m_canvasStateStack.size(); } |
| #if ENABLE(ASSERT) |
| void disableDestructionChecks() { m_disableDestructionChecks = true; } |
| #endif |
| |
| void saveLayer(const SkRect* bounds, const SkPaint*); |
| void restoreLayer(); |
| |
| bool hasStroke() const { return strokeStyle() != NoStroke && strokeThickness() > 0; } |
| |
| float strokeThickness() const { return immutableState()->strokeData().thickness(); } |
| void setStrokeThickness(float thickness) { mutableState()->setStrokeThickness(thickness); } |
| |
| StrokeStyle strokeStyle() const { return immutableState()->strokeData().style(); } |
| void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); } |
| |
| Color strokeColor() const { return immutableState()->strokeData().color(); } |
| void setStrokeColor(const Color& color) { mutableState()->setStrokeColor(color); } |
| SkColor effectiveStrokeColor() const { return immutableState()->effectiveStrokeColor(); } |
| |
| Pattern* strokePattern() const { return immutableState()->strokeData().pattern(); } |
| void setStrokePattern(PassRefPtr<Pattern>); |
| |
| Gradient* strokeGradient() const { return immutableState()->strokeData().gradient(); } |
| void setStrokeGradient(PassRefPtr<Gradient>); |
| |
| void setLineCap(LineCap cap) { mutableState()->setLineCap(cap); } |
| void setLineDash(const DashArray& dashes, float dashOffset) { mutableState()->setLineDash(dashes, dashOffset); } |
| void setLineJoin(LineJoin join) { mutableState()->setLineJoin(join); } |
| void setMiterLimit(float limit) { mutableState()->setMiterLimit(limit); } |
| |
| WindRule fillRule() const { return immutableState()->fillRule(); } |
| void setFillRule(WindRule fillRule) { mutableState()->setFillRule(fillRule); } |
| |
| Color fillColor() const { return immutableState()->fillColor(); } |
| void setFillColor(const Color& color) { mutableState()->setFillColor(color); } |
| SkColor effectiveFillColor() const { return immutableState()->effectiveFillColor(); } |
| |
| void setFillPattern(PassRefPtr<Pattern>); |
| Pattern* fillPattern() const { return immutableState()->fillPattern(); } |
| |
| void setFillGradient(PassRefPtr<Gradient>); |
| Gradient* fillGradient() const { return immutableState()->fillGradient(); } |
| |
| SkDrawLooper* drawLooper() const { return immutableState()->drawLooper(); } |
| |
| bool getTransformedClipBounds(FloatRect* bounds) const; |
| SkMatrix getTotalMatrix() const; |
| |
| void setShouldAntialias(bool antialias) { mutableState()->setShouldAntialias(antialias); } |
| bool shouldAntialias() const { return immutableState()->shouldAntialias(); } |
| |
| // Disable the anti-aliasing optimization for scales/multiple-of-90-degrees |
| // rotations of thin ("hairline") images. |
| // Note: This will only be reliable when the device pixel scale/ratio is |
| // fixed (e.g. when drawing to context backed by an ImageBuffer). |
| void disableAntialiasingOptimizationForHairlineImages() { ASSERT(!isRecording()); m_antialiasHairlineImages = true; } |
| bool shouldAntialiasHairlineImages() const { return m_antialiasHairlineImages; } |
| |
| void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->setShouldClampToSourceRect(clampToSourceRect); } |
| bool shouldClampToSourceRect() const { return immutableState()->shouldClampToSourceRect(); } |
| |
| // FIXME: the setter is only used once, at construction time; convert to a constructor param, |
| // and possibly consolidate with other flags (paintDisabled, isPrinting, ...) |
| void setShouldSmoothFonts(bool smoothFonts) { m_shouldSmoothFonts = smoothFonts; } |
| bool shouldSmoothFonts() const { return m_shouldSmoothFonts; } |
| |
| // Turn off LCD text for the paint if not supported on this context. |
| void adjustTextRenderMode(SkPaint*); |
| bool couldUseLCDRenderedText(); |
| |
| void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->setTextDrawingMode(mode); } |
| TextDrawingModeFlags textDrawingMode() const { return immutableState()->textDrawingMode(); } |
| |
| void setAlphaAsFloat(float alpha) { mutableState()->setAlphaAsFloat(alpha);} |
| int getNormalizedAlpha() const |
| { |
| int alpha = immutableState()->alpha(); |
| return alpha > 255 ? 255 : alpha; |
| } |
| |
| void setImageInterpolationQuality(InterpolationQuality quality) { mutableState()->setInterpolationQuality(quality); } |
| InterpolationQuality imageInterpolationQuality() const { return immutableState()->interpolationQuality(); } |
| |
| void setCompositeOperation(CompositeOperator, WebBlendMode = WebBlendModeNormal); |
| CompositeOperator compositeOperation() const { return immutableState()->compositeOperator(); } |
| WebBlendMode blendModeOperation() const { return immutableState()->blendMode(); } |
| |
| // Speicy the device scale factor which may change the way document markers |
| // and fonts are rendered. |
| void setDeviceScaleFactor(float factor) { m_deviceScaleFactor = factor; } |
| float deviceScaleFactor() const { return m_deviceScaleFactor; } |
| |
| // If true we are (most likely) rendering to a web page and the |
| // canvas has been prepared with an opaque background. If false, |
| // the canvas may have transparency (as is the case when rendering |
| // to a canvas object). |
| void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; } |
| bool isCertainlyOpaque() const { return m_isCertainlyOpaque; } |
| |
| bool isAccelerated() const { return m_accelerated; } |
| void setAccelerated(bool accelerated) { m_accelerated = accelerated; } |
| |
| // The opaque region is empty until tracking is turned on. |
| // It is never clerared by the context. |
| enum RegionTrackingMode { |
| RegionTrackingDisabled = 0, |
| RegionTrackingOpaque, |
| RegionTrackingOverwrite |
| }; |
| void setRegionTrackingMode(RegionTrackingMode); |
| bool regionTrackingEnabled() { return m_regionTrackingMode != RegionTrackingDisabled; } |
| const RegionTracker& opaqueRegion() const { return m_trackedRegion; } |
| |
| // The text region is empty until tracking is turned on. |
| // It is never clerared by the context. |
| void setTrackTextRegion(bool track) { m_trackTextRegion = track; } |
| const SkRect& textRegion() const { return m_textRegion; } |
| |
| AnnotationModeFlags annotationMode() const { return m_annotationMode; } |
| void setAnnotationMode(const AnnotationModeFlags mode) { m_annotationMode = mode; } |
| |
| SkColorFilter* colorFilter() const; |
| void setColorFilter(ColorFilter); |
| // ---------- End state management methods ----------------- |
| |
| // Get the contents of the image buffer |
| bool readPixels(const SkImageInfo&, void* pixels, size_t rowBytes, int x, int y); |
| |
| // Get the current fill style. |
| const SkPaint& fillPaint() const { return immutableState()->fillPaint(); } |
| |
| // Get the current stroke style. |
| const SkPaint& strokePaint() const { return immutableState()->strokePaint(); } |
| |
| // These draw methods will do both stroking and filling. |
| // FIXME: ...except drawRect(), which fills properly but always strokes |
| // using a 1-pixel stroke inset from the rect borders (of the correct |
| // stroke color). |
| void drawRect(const IntRect&); |
| void drawLine(const IntPoint&, const IntPoint&); |
| void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false); |
| |
| void fillPath(const Path&); |
| void strokePath(const Path&); |
| |
| void fillEllipse(const FloatRect&); |
| void strokeEllipse(const FloatRect&); |
| |
| void fillRect(const FloatRect&); |
| void fillRect(const FloatRect&, const Color&); |
| void fillRect(const FloatRect&, const Color&, CompositeOperator); |
| void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&); |
| void fillRoundedRect(const RoundedRect&, const Color&); |
| |
| void clearRect(const FloatRect&); |
| |
| void strokeRect(const FloatRect&); |
| void strokeRect(const FloatRect&, float lineWidth); |
| |
| void fillBetweenRoundedRects(const IntRect&, const IntSize& outerTopLeft, const IntSize& outerTopRight, const IntSize& outerBottomLeft, const IntSize& outerBottomRight, |
| const IntRect&, const IntSize& innerTopLeft, const IntSize& innerTopRight, const IntSize& innerBottomLeft, const IntSize& innerBottomRight, const Color&); |
| void fillBetweenRoundedRects(const RoundedRect&, const RoundedRect&, const Color&); |
| |
| void drawDisplayList(DisplayList*); |
| |
| void drawImage(Image*, const IntPoint&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation); |
| void drawImage(Image*, const IntRect&, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation); |
| void drawImage(Image*, const FloatRect& destRect); |
| void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, RespectImageOrientationEnum = DoNotRespectImageOrientation); |
| void drawImage(Image*, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, WebBlendMode, RespectImageOrientationEnum = DoNotRespectImageOrientation); |
| |
| void drawTiledImage(Image*, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize, |
| CompositeOperator = CompositeSourceOver, WebBlendMode = WebBlendModeNormal, const IntSize& repeatSpacing = IntSize()); |
| void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect, |
| const FloatSize& tileScaleFactor, Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile, |
| CompositeOperator = CompositeSourceOver); |
| |
| void drawImageBuffer(ImageBuffer*, const FloatRect& destRect, const FloatRect* srcRect = 0, CompositeOperator = CompositeSourceOver, WebBlendMode = WebBlendModeNormal); |
| |
| void drawPicture(PassRefPtr<SkPicture>, const FloatRect& dest, const FloatRect& src, CompositeOperator, WebBlendMode); |
| |
| // These methods write to the canvas and modify the opaque region, if tracked. |
| // Also drawLine(const IntPoint& point1, const IntPoint& point2) and fillRoundedRect |
| void writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y); |
| void writePixels(const SkBitmap&, int x, int y); |
| void drawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint* = 0); |
| void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint* = 0); |
| void drawOval(const SkRect&, const SkPaint&); |
| void drawPath(const SkPath&, const SkPaint&); |
| // After drawing directly to the context's canvas, use this function to notify the context so |
| // it can track the opaque region. |
| // FIXME: this is still needed only because ImageSkia::paintSkBitmap() may need to notify for a |
| // smaller rect than the one drawn to, due to its clipping logic. |
| void didDrawRect(const SkRect&, const SkPaint&, const SkBitmap* = 0); |
| void drawRect(const SkRect&, const SkPaint&); |
| void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkRect& textRect, const SkPaint&); |
| void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkRect& textRect, const SkPaint&); |
| void drawTextBlob(const SkTextBlob*, const SkPoint& origin, const SkPaint&); |
| |
| void clip(const IntRect& rect) { clipRect(rect); } |
| void clip(const FloatRect& rect) { clipRect(rect); } |
| void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op); |
| void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); } |
| void clipOutRoundedRect(const RoundedRect&); |
| void clipPath(const Path&, WindRule = RULE_EVENODD); |
| void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true); |
| void clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op); |
| |
| void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&); |
| void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&); |
| void drawBidiText(const Font&, const TextRunPaintInfo&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady); |
| void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1); |
| |
| void drawLineForText(const FloatPoint&, float width); |
| enum DocumentMarkerLineStyle { |
| DocumentMarkerSpellingLineStyle, |
| DocumentMarkerGrammarLineStyle |
| }; |
| void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle); |
| |
| void beginTransparencyLayer(float opacity, const FloatRect* = 0); |
| void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone, ImageFilter* = 0); |
| void endLayer(); |
| |
| // Instead of being dispatched to the active canvas, draw commands following beginRecording() |
| // are stored in a display list that can be replayed at a later time. |
| void beginRecording(const FloatRect& bounds); |
| PassRefPtr<DisplayList> endRecording(); |
| |
| bool hasShadow() const; |
| void setShadow(const FloatSize& offset, float blur, const Color&, |
| DrawLooperBuilder::ShadowTransformMode = DrawLooperBuilder::ShadowRespectsTransforms, |
| DrawLooperBuilder::ShadowAlphaMode = DrawLooperBuilder::ShadowRespectsAlpha); |
| void clearShadow() { clearDrawLooper(); } |
| |
| // It is assumed that this draw looper is used only for shadows |
| // (i.e. a draw looper is set if and only if there is a shadow). |
| // The builder passed into this method will be destroyed. |
| void setDrawLooper(PassOwnPtr<DrawLooperBuilder>); |
| void clearDrawLooper(); |
| |
| void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&); |
| void drawFocusRing(const Path&, int width, int offset, const Color&); |
| |
| enum Edge { |
| NoEdge = 0, |
| TopEdge = 1 << 1, |
| RightEdge = 1 << 2, |
| BottomEdge = 1 << 3, |
| LeftEdge = 1 << 4 |
| }; |
| typedef unsigned Edges; |
| void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge); |
| |
| // This clip function is used only by <canvas> code. It allows |
| // implementations to handle clipping on the canvas differently since |
| // the discipline is different. |
| void canvasClip(const Path&, WindRule = RULE_EVENODD); |
| void clipOut(const Path&); |
| |
| // ---------- Transformation methods ----------------- |
| // Note that the getCTM method returns only the current transform from Blink's perspective, |
| // which is not the final transform used to place content on screen. It cannot be relied upon |
| // for testing where a point will appear on screen or how large it will be. |
| AffineTransform getCTM() const; |
| void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); } |
| void setCTM(const AffineTransform& affine) { setMatrix(affineTransformToSkMatrix(affine)); } |
| void setMatrix(const SkMatrix&); |
| |
| void scale(float x, float y); |
| void rotate(float angleInRadians); |
| void translate(float x, float y); |
| |
| // This function applies the device scale factor to the context, making the context capable of |
| // acting as a base-level context for a HiDPI environment. |
| void applyDeviceScaleFactor(float deviceScaleFactor) { scale(deviceScaleFactor, deviceScaleFactor); } |
| // ---------- End transformation methods ----------------- |
| |
| // URL drawing |
| void setURLForRect(const KURL&, const IntRect&); |
| void setURLFragmentForRect(const String& name, const IntRect&); |
| void addURLTargetAtPoint(const String& name, const IntPoint&); |
| |
| // Create an image buffer compatible with this context, with suitable resolution |
| // for drawing into the buffer and then into this context. |
| PassOwnPtr<ImageBuffer> createRasterBuffer(const IntSize&, OpacityMode = NonOpaque) const; |
| |
| static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle); |
| |
| void beginAnnotation(const AnnotationList&); |
| void endAnnotation(); |
| |
| void preparePaintForDrawRectToRect( |
| SkPaint*, |
| const SkRect& srcRect, |
| const SkRect& destRect, |
| CompositeOperator, |
| WebBlendMode, |
| bool isLazyDecoded = false, |
| bool isDataComplete = true) const; |
| |
| static int focusRingOutsetExtent(int offset, int width) |
| { |
| return focusRingOutset(offset) + (focusRingWidth(width) + 1) / 2; |
| } |
| |
| private: |
| const GraphicsContextState* immutableState() const { return m_paintState; } |
| |
| GraphicsContextState* mutableState() |
| { |
| realizePaintSave(); |
| return m_paintState; |
| } |
| |
| static void setPathFromConvexPoints(SkPath*, size_t, const FloatPoint*); |
| static void setRadii(SkVector*, IntSize, IntSize, IntSize, IntSize); |
| |
| static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter); |
| |
| static inline int focusRingOutset(int offset) { return 0; } |
| static inline int focusRingWidth(int width) { return 1; } |
| static SkPMColor lineColors(int); |
| static SkPMColor antiColors1(int); |
| static SkPMColor antiColors2(int); |
| static void draw1xMarker(SkBitmap*, int); |
| static void draw2xMarker(SkBitmap*, int); |
| |
| // Helpers for drawing a focus ring (drawFocusRing) |
| float prepareFocusRingPaint(SkPaint&, const Color&, int width) const; |
| void drawFocusRingPath(const SkPath&, const Color&, int width); |
| void drawFocusRingRect(const SkRect&, const Color&, int width); |
| |
| |
| // SkCanvas wrappers. |
| void clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op); |
| void clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op); |
| void concat(const SkMatrix&); |
| void drawRRect(const SkRRect&, const SkPaint&); |
| |
| // Apply deferred paint state saves |
| void realizePaintSave() |
| { |
| if (contextDisabled()) |
| return; |
| |
| if (m_paintState->saveCount()) { |
| m_paintState->decrementSaveCount(); |
| ++m_paintStateIndex; |
| if (m_paintStateStack.size() == m_paintStateIndex) { |
| m_paintStateStack.append(GraphicsContextState::createAndCopy(*m_paintState)); |
| m_paintState = m_paintStateStack[m_paintStateIndex].get(); |
| } else { |
| GraphicsContextState* priorPaintState = m_paintState; |
| m_paintState = m_paintStateStack[m_paintStateIndex].get(); |
| m_paintState->copy(*priorPaintState); |
| } |
| } |
| } |
| |
| // Apply deferred canvas state saves |
| void realizeCanvasSave() |
| { |
| if (!m_pendingCanvasSave || contextDisabled()) |
| return; |
| |
| m_canvas->save(); |
| m_pendingCanvasSave = false; |
| } |
| |
| void didDrawTextInRect(const SkRect& textRect); |
| |
| void fillRectWithRoundedHole(const IntRect&, const RoundedRect& roundedHoleRect, const Color&); |
| |
| bool isRecording() const; |
| |
| // null indicates painting is contextDisabled. Never delete this object. |
| SkCanvas* m_canvas; |
| |
| // Paint states stack. Enables local drawing state change with save()/restore() calls. |
| // This state controls the appearance of drawn content. |
| // We do not delete from this stack to avoid memory churn. |
| Vector<OwnPtr<GraphicsContextState> > m_paintStateStack; |
| // Current index on the stack. May not be the last thing on the stack. |
| unsigned m_paintStateIndex; |
| // Raw pointer to the current state. |
| GraphicsContextState* m_paintState; |
| |
| // Currently pending save flags for Skia Canvas state. |
| // Canvas state includes the canavs, it's matrix and clips. Think of it as _where_ |
| // the draw operations will happen. |
| struct CanvasSaveState; |
| Vector<CanvasSaveState> m_canvasStateStack; |
| bool m_pendingCanvasSave; |
| |
| AnnotationModeFlags m_annotationMode; |
| |
| struct RecordingState; |
| Vector<RecordingState> m_recordingStateStack; |
| |
| #if ENABLE(ASSERT) |
| unsigned m_annotationCount; |
| unsigned m_layerCount; |
| bool m_disableDestructionChecks; |
| #endif |
| // Tracks the region painted opaque via the GraphicsContext. |
| RegionTracker m_trackedRegion; |
| |
| // Tracks the region where text is painted via the GraphicsContext. |
| SkRect m_textRegion; |
| |
| unsigned m_disabledState; |
| |
| float m_deviceScaleFactor; |
| |
| // Activation for the above region tracking features |
| unsigned m_regionTrackingMode : 2; |
| bool m_trackTextRegion : 1; |
| |
| bool m_accelerated : 1; |
| bool m_isCertainlyOpaque : 1; |
| bool m_antialiasHairlineImages : 1; |
| bool m_shouldSmoothFonts : 1; |
| }; |
| |
| } // namespace blink |
| |
| #endif // SKY_ENGINE_PLATFORM_GRAPHICS_GRAPHICSCONTEXT_H_ |