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