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. canvas()88 SkCanvas* canvas() 89 { 90 // Flush any pending saves. 91 realizeCanvasSave(); 92 93 return m_canvas; 94 } canvas()95 const SkCanvas* canvas() const 96 { 97 return m_canvas; 98 } 99 100 void resetCanvas(SkCanvas*); 101 contextDisabled()102 bool contextDisabled() const { return m_disabledState; } 103 104 // ---------- State management methods ----------------- 105 void save(); 106 void restore(); saveCount()107 unsigned saveCount() { return m_canvasStateStack.size(); } 108 #if ENABLE(ASSERT) disableDestructionChecks()109 void disableDestructionChecks() { m_disableDestructionChecks = true; } 110 #endif 111 112 void saveLayer(const SkRect* bounds, const SkPaint*); 113 void restoreLayer(); 114 hasStroke()115 bool hasStroke() const { return strokeStyle() != NoStroke && strokeThickness() > 0; } 116 strokeThickness()117 float strokeThickness() const { return immutableState()->strokeData().thickness(); } setStrokeThickness(float thickness)118 void setStrokeThickness(float thickness) { mutableState()->setStrokeThickness(thickness); } 119 strokeStyle()120 StrokeStyle strokeStyle() const { return immutableState()->strokeData().style(); } setStrokeStyle(StrokeStyle style)121 void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); } 122 strokeColor()123 Color strokeColor() const { return immutableState()->strokeColor(); } setStrokeColor(const Color & color)124 void setStrokeColor(const Color& color) { mutableState()->setStrokeColor(color); } effectiveStrokeColor()125 SkColor effectiveStrokeColor() const { return immutableState()->effectiveStrokeColor(); } 126 strokePattern()127 Pattern* strokePattern() const { return immutableState()->strokePattern(); } 128 void setStrokePattern(PassRefPtr<Pattern>); 129 strokeGradient()130 Gradient* strokeGradient() const { return immutableState()->strokeGradient(); } 131 void setStrokeGradient(PassRefPtr<Gradient>); 132 setLineCap(LineCap cap)133 void setLineCap(LineCap cap) { mutableState()->setLineCap(cap); } setLineDash(const DashArray & dashes,float dashOffset)134 void setLineDash(const DashArray& dashes, float dashOffset) { mutableState()->setLineDash(dashes, dashOffset); } setLineJoin(LineJoin join)135 void setLineJoin(LineJoin join) { mutableState()->setLineJoin(join); } setMiterLimit(float limit)136 void setMiterLimit(float limit) { mutableState()->setMiterLimit(limit); } 137 fillRule()138 WindRule fillRule() const { return immutableState()->fillRule(); } setFillRule(WindRule fillRule)139 void setFillRule(WindRule fillRule) { mutableState()->setFillRule(fillRule); } 140 fillColor()141 Color fillColor() const { return immutableState()->fillColor(); } setFillColor(const Color & color)142 void setFillColor(const Color& color) { mutableState()->setFillColor(color); } effectiveFillColor()143 SkColor effectiveFillColor() const { return immutableState()->effectiveFillColor(); } 144 145 void setFillPattern(PassRefPtr<Pattern>); fillPattern()146 Pattern* fillPattern() const { return immutableState()->fillPattern(); } 147 148 void setFillGradient(PassRefPtr<Gradient>); fillGradient()149 Gradient* fillGradient() const { return immutableState()->fillGradient(); } 150 drawLooper()151 SkDrawLooper* drawLooper() const { return immutableState()->drawLooper(); } 152 153 bool getTransformedClipBounds(FloatRect* bounds) const; 154 SkMatrix getTotalMatrix() const; 155 setShouldAntialias(bool antialias)156 void setShouldAntialias(bool antialias) { mutableState()->setShouldAntialias(antialias); } shouldAntialias()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). disableAntialiasingOptimizationForHairlineImages()163 void disableAntialiasingOptimizationForHairlineImages() { ASSERT(!isRecording()); m_antialiasHairlineImages = true; } shouldAntialiasHairlineImages()164 bool shouldAntialiasHairlineImages() const { return m_antialiasHairlineImages; } 165 setShouldClampToSourceRect(bool clampToSourceRect)166 void setShouldClampToSourceRect(bool clampToSourceRect) { mutableState()->setShouldClampToSourceRect(clampToSourceRect); } shouldClampToSourceRect()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, ...) setShouldSmoothFonts(bool smoothFonts)171 void setShouldSmoothFonts(bool smoothFonts) { m_shouldSmoothFonts = smoothFonts; } shouldSmoothFonts()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 setTextDrawingMode(TextDrawingModeFlags mode)178 void setTextDrawingMode(TextDrawingModeFlags mode) { mutableState()->setTextDrawingMode(mode); } textDrawingMode()179 TextDrawingModeFlags textDrawingMode() const { return immutableState()->textDrawingMode(); } 180 setAlphaAsFloat(float alpha)181 void setAlphaAsFloat(float alpha) { mutableState()->setAlphaAsFloat(alpha);} getNormalizedAlpha()182 int getNormalizedAlpha() const 183 { 184 int alpha = immutableState()->alpha(); 185 return alpha > 255 ? 255 : alpha; 186 } 187 setImageInterpolationQuality(InterpolationQuality quality)188 void setImageInterpolationQuality(InterpolationQuality quality) { mutableState()->setInterpolationQuality(quality); } imageInterpolationQuality()189 InterpolationQuality imageInterpolationQuality() const { return immutableState()->interpolationQuality(); } 190 191 void setCompositeOperation(CompositeOperator, WebBlendMode = WebBlendModeNormal); compositeOperation()192 CompositeOperator compositeOperation() const { return immutableState()->compositeOperator(); } blendModeOperation()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. setDeviceScaleFactor(float factor)197 void setDeviceScaleFactor(float factor) { m_deviceScaleFactor = factor; } deviceScaleFactor()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). setCertainlyOpaque(bool isOpaque)204 void setCertainlyOpaque(bool isOpaque) { m_isCertainlyOpaque = isOpaque; } isCertainlyOpaque()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. printing()210 bool printing() const { return m_printing; } setPrinting(bool printing)211 void setPrinting(bool printing) { m_printing = printing; } 212 isAccelerated()213 bool isAccelerated() const { return m_accelerated; } setAccelerated(bool 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); regionTrackingEnabled()224 bool regionTrackingEnabled() { return m_regionTrackingMode != RegionTrackingDisabled; } opaqueRegion()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. setTrackTextRegion(bool track)229 void setTrackTextRegion(bool track) { m_trackTextRegion = track; } textRegion()230 const SkRect& textRegion() const { return m_textRegion; } 231 annotationMode()232 AnnotationModeFlags annotationMode() const { return m_annotationMode; } setAnnotationMode(const AnnotationModeFlags mode)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. fillPaint()243 const SkPaint& fillPaint() const { return immutableState()->fillPaint(); } 244 245 // Get the current stroke style. strokePaint()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 clip(const IntRect & rect)313 void clip(const IntRect& rect) { clipRect(rect); } clip(const FloatRect & rect)314 void clip(const FloatRect& rect) { clipRect(rect); } 315 void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op); clipOut(const IntRect & rect)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); clearShadow()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; concatCTM(const AffineTransform & affine)382 void concatCTM(const AffineTransform& affine) { concat(affineTransformToSkMatrix(affine)); } setCTM(const AffineTransform & 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. applyDeviceScaleFactor(float deviceScaleFactor)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 focusRingOutsetExtent(int offset,int width)418 static int focusRingOutsetExtent(int offset, int width) 419 { 420 return focusRingOutset(offset) + (focusRingWidth(width) + 1) / 2; 421 } 422 423 private: immutableState()424 const GraphicsContextState* immutableState() const { return m_paintState; } 425 mutableState()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) focusRingOutset(int offset)438 static inline int focusRingOutset(int offset) { return offset + 2; } focusRingWidth(int width)439 static inline int focusRingWidth(int width) { return width; } 440 #else focusRingOutset(int offset)441 static inline int focusRingOutset(int offset) { return 0; } focusRingWidth(int width)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 realizePaintSave()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 realizeCanvasSave()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