1 /* 2 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2008-2009 Torch Mobile, Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef GraphicsContext_h 28 #define GraphicsContext_h 29 30 #include "ColorSpace.h" 31 #include "DashArray.h" 32 #include "FloatRect.h" 33 #include "Gradient.h" 34 #include "Image.h" 35 #include "Path.h" 36 #include "Pattern.h" 37 #include <wtf/Noncopyable.h> 38 #include <wtf/PassOwnPtr.h> 39 40 #if USE(CG) 41 typedef struct CGContext PlatformGraphicsContext; 42 #elif USE(CAIRO) 43 namespace WebCore { 44 class ContextShadow; 45 class PlatformContextCairo; 46 } 47 typedef WebCore::PlatformContextCairo PlatformGraphicsContext; 48 #elif PLATFORM(OPENVG) 49 namespace WebCore { 50 class SurfaceOpenVG; 51 } 52 typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext; 53 #elif PLATFORM(QT) 54 #include <QPainter> 55 namespace WebCore { 56 class ContextShadow; 57 } 58 typedef QPainter PlatformGraphicsContext; 59 #elif PLATFORM(WX) 60 class wxGCDC; 61 class wxWindowDC; 62 63 // wxGraphicsContext allows us to support Path, etc. 64 // but on some platforms, e.g. Linux, it requires fairly 65 // new software. 66 #if USE(WXGC) 67 // On OS X, wxGCDC is just a typedef for wxDC, so use wxDC explicitly to make 68 // the linker happy. 69 #ifdef __APPLE__ 70 class wxDC; 71 typedef wxDC PlatformGraphicsContext; 72 #else 73 typedef wxGCDC PlatformGraphicsContext; 74 #endif 75 #else 76 typedef wxWindowDC PlatformGraphicsContext; 77 #endif 78 #elif USE(SKIA) 79 namespace WebCore { 80 class PlatformContextSkia; 81 } 82 typedef WebCore::PlatformContextSkia PlatformGraphicsContext; 83 #elif PLATFORM(HAIKU) 84 class BView; 85 typedef BView PlatformGraphicsContext; 86 struct pattern; 87 #elif OS(WINCE) 88 typedef struct HDC__ PlatformGraphicsContext; 89 #else 90 typedef void PlatformGraphicsContext; 91 #endif 92 93 #if PLATFORM(WIN) 94 #include "DIBPixelData.h" 95 typedef struct HDC__* HDC; 96 #if !USE(CG) 97 // UInt8 is defined in CoreFoundation/CFBase.h 98 typedef unsigned char UInt8; 99 #endif 100 #endif 101 102 #if PLATFORM(QT) && defined(Q_WS_WIN) 103 #include <windows.h> 104 #endif 105 106 namespace WebCore { 107 108 #if OS(WINCE) && !PLATFORM(QT) 109 class SharedBitmap; 110 class SimpleFontData; 111 class GlyphBuffer; 112 #endif 113 114 const int cMisspellingLineThickness = 3; 115 const int cMisspellingLinePatternWidth = 4; 116 const int cMisspellingLinePatternGapWidth = 1; 117 118 class AffineTransform; 119 class DrawingBuffer; 120 class Font; 121 class Generator; 122 class GraphicsContextPlatformPrivate; 123 class ImageBuffer; 124 class IntRect; 125 class RoundedIntRect; 126 class KURL; 127 class SharedGraphicsContext3D; 128 class TextRun; 129 130 enum TextDrawingMode { 131 TextModeInvisible = 0, 132 TextModeFill = 1 << 0, 133 TextModeStroke = 1 << 1, 134 TextModeClip = 1 << 2 135 }; 136 typedef unsigned TextDrawingModeFlags; 137 138 enum StrokeStyle { 139 NoStroke, 140 SolidStroke, 141 DottedStroke, 142 DashedStroke 143 }; 144 145 enum InterpolationQuality { 146 InterpolationDefault, 147 InterpolationNone, 148 InterpolationLow, 149 InterpolationMedium, 150 InterpolationHigh 151 }; 152 153 struct GraphicsContextState { GraphicsContextStateGraphicsContextState154 GraphicsContextState() 155 : strokeThickness(0) 156 , shadowBlur(0) 157 #if USE(CAIRO) 158 , globalAlpha(1) 159 #endif 160 , textDrawingMode(TextModeFill) 161 , strokeColor(Color::black) 162 , fillColor(Color::black) 163 , strokeStyle(SolidStroke) 164 , fillRule(RULE_NONZERO) 165 , strokeColorSpace(ColorSpaceDeviceRGB) 166 , fillColorSpace(ColorSpaceDeviceRGB) 167 , shadowColorSpace(ColorSpaceDeviceRGB) 168 , compositeOperator(CompositeSourceOver) 169 , shouldAntialias(true) 170 , shouldSmoothFonts(true) 171 , paintingDisabled(false) 172 , shadowsIgnoreTransforms(false) 173 #if USE(CG) 174 // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>), 175 // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow. 176 , shadowsUseLegacyRadius(false) 177 #endif 178 { 179 } 180 181 RefPtr<Gradient> strokeGradient; 182 RefPtr<Pattern> strokePattern; 183 184 RefPtr<Gradient> fillGradient; 185 RefPtr<Pattern> fillPattern; 186 187 FloatSize shadowOffset; 188 189 float strokeThickness; 190 float shadowBlur; 191 192 #if USE(CAIRO) 193 float globalAlpha; 194 #endif 195 TextDrawingModeFlags textDrawingMode; 196 197 Color strokeColor; 198 Color fillColor; 199 Color shadowColor; 200 201 StrokeStyle strokeStyle; 202 WindRule fillRule; 203 204 ColorSpace strokeColorSpace; 205 ColorSpace fillColorSpace; 206 ColorSpace shadowColorSpace; 207 208 CompositeOperator compositeOperator; 209 210 bool shouldAntialias : 1; 211 bool shouldSmoothFonts : 1; 212 bool paintingDisabled : 1; 213 bool shadowsIgnoreTransforms : 1; 214 #if USE(CG) 215 bool shadowsUseLegacyRadius : 1; 216 #endif 217 }; 218 219 class GraphicsContext { 220 WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED; 221 public: 222 GraphicsContext(PlatformGraphicsContext*); 223 ~GraphicsContext(); 224 225 #if !OS(WINCE) || PLATFORM(QT) 226 PlatformGraphicsContext* platformContext() const; 227 #endif 228 229 float strokeThickness() const; 230 void setStrokeThickness(float); 231 StrokeStyle strokeStyle() const; 232 void setStrokeStyle(StrokeStyle); 233 Color strokeColor() const; 234 ColorSpace strokeColorSpace() const; 235 void setStrokeColor(const Color&, ColorSpace); 236 237 void setStrokePattern(PassRefPtr<Pattern>); 238 Pattern* strokePattern() const; 239 240 void setStrokeGradient(PassRefPtr<Gradient>); 241 Gradient* strokeGradient() const; 242 243 WindRule fillRule() const; 244 void setFillRule(WindRule); 245 Color fillColor() const; 246 ColorSpace fillColorSpace() const; 247 void setFillColor(const Color&, ColorSpace); 248 249 void setFillPattern(PassRefPtr<Pattern>); 250 Pattern* fillPattern() const; 251 252 void setFillGradient(PassRefPtr<Gradient>); 253 Gradient* fillGradient() const; 254 255 void setShadowsIgnoreTransforms(bool); 256 bool shadowsIgnoreTransforms() const; 257 258 void setShouldAntialias(bool); 259 bool shouldAntialias() const; 260 261 void setShouldSmoothFonts(bool); 262 bool shouldSmoothFonts() const; 263 264 const GraphicsContextState& state() const; 265 266 #if USE(CG) 267 void applyStrokePattern(); 268 void applyFillPattern(); 269 void drawPath(const Path&); 270 271 // Allow font smoothing (LCD antialiasing). Not part of the graphics state. 272 void setAllowsFontSmoothing(bool); 273 274 void setIsCALayerContext(bool); 275 bool isCALayerContext() const; 276 277 void setIsAcceleratedContext(bool); 278 bool isAcceleratedContext() const; 279 #endif 280 281 void save(); 282 void restore(); 283 284 // These draw methods will do both stroking and filling. 285 // FIXME: ...except drawRect(), which fills properly but always strokes 286 // using a 1-pixel stroke inset from the rect borders (of the correct 287 // stroke color). 288 void drawRect(const IntRect&); 289 void drawLine(const IntPoint&, const IntPoint&); 290 void drawEllipse(const IntRect&); 291 void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false); 292 293 void fillPath(const Path&); 294 void strokePath(const Path&); 295 296 // Arc drawing (used by border-radius in CSS) just supports stroking at the moment. 297 void strokeArc(const IntRect&, int startAngle, int angleSpan); 298 299 void fillRect(const FloatRect&); 300 void fillRect(const FloatRect&, const Color&, ColorSpace); 301 void fillRect(const FloatRect&, Generator&); 302 void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&, ColorSpace); 303 void fillRoundedRect(const RoundedIntRect&, const Color&, ColorSpace); 304 void fillRectWithRoundedHole(const IntRect&, const RoundedIntRect& roundedHoleRect, const Color&, ColorSpace); 305 306 void clearRect(const FloatRect&); 307 308 void strokeRect(const FloatRect&, float lineWidth); 309 310 void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver); 311 void drawImage(Image*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 312 void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver); 313 void drawImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 314 void drawImage(Image*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), 315 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 316 void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize, 317 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 318 void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, 319 Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile, 320 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 321 322 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver); 323 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 324 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver); 325 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 326 void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), 327 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 328 329 void setImageInterpolationQuality(InterpolationQuality); 330 InterpolationQuality imageInterpolationQuality() const; 331 332 void clip(const IntRect&); 333 void clip(const FloatRect&); 334 void addRoundedRectClip(const RoundedIntRect&); 335 void addInnerRoundedRectClip(const IntRect&, int thickness); 336 void clipOut(const IntRect&); 337 void clipOutRoundedRect(const RoundedIntRect&); 338 void clipPath(const Path&, WindRule); 339 void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true); 340 void clipToImageBuffer(ImageBuffer*, const FloatRect&); 341 342 IntRect clipBounds() const; 343 344 TextDrawingModeFlags textDrawingMode() const; 345 void setTextDrawingMode(TextDrawingModeFlags); 346 347 void drawText(const Font&, const TextRun&, const FloatPoint&, int from = 0, int to = -1); 348 void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1); 349 void drawBidiText(const Font&, const TextRun&, const FloatPoint&); 350 void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1); 351 352 enum RoundingMode { 353 RoundAllSides, 354 RoundOriginAndDimensions 355 }; 356 FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides); 357 358 void drawLineForText(const FloatPoint&, float width, bool printing); 359 enum TextCheckingLineStyle { 360 TextCheckingSpellingLineStyle, 361 TextCheckingGrammarLineStyle, 362 TextCheckingReplacementLineStyle 363 }; 364 void drawLineForTextChecking(const FloatPoint&, float width, TextCheckingLineStyle); 365 366 bool paintingDisabled() const; 367 void setPaintingDisabled(bool); 368 369 bool updatingControlTints() const; 370 void setUpdatingControlTints(bool); 371 372 void beginTransparencyLayer(float opacity); 373 void endTransparencyLayer(); 374 375 bool hasShadow() const; 376 void setShadow(const FloatSize&, float blur, const Color&, ColorSpace); 377 // Legacy shadow blur radius is used for canvas, and -webkit-box-shadow. 378 // It has different treatment of radii > 8px. 379 void setLegacyShadow(const FloatSize&, float blur, const Color&, ColorSpace); 380 381 bool getShadow(FloatSize&, float&, Color&, ColorSpace&) const; 382 void clearShadow(); 383 384 void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&); 385 void drawFocusRing(const Path&, int width, int offset, const Color&); 386 387 void setLineCap(LineCap); 388 void setLineDash(const DashArray&, float dashOffset); 389 void setLineJoin(LineJoin); 390 void setMiterLimit(float); 391 392 void setAlpha(float); 393 #if USE(CAIRO) 394 float getAlpha(); 395 #endif 396 397 void setCompositeOperation(CompositeOperator); 398 CompositeOperator compositeOperation() const; 399 400 void clip(const Path&); 401 402 // This clip function is used only by <canvas> code. It allows 403 // implementations to handle clipping on the canvas differently since 404 // the discipline is different. 405 void canvasClip(const Path&); 406 void clipOut(const Path&); 407 408 void scale(const FloatSize&); 409 void rotate(float angleInRadians); translate(const FloatSize & size)410 void translate(const FloatSize& size) { translate(size.width(), size.height()); } 411 void translate(float x, float y); 412 413 void setURLForRect(const KURL&, const IntRect&); 414 415 void concatCTM(const AffineTransform&); 416 void setCTM(const AffineTransform&); 417 AffineTransform getCTM() const; 418 419 #if OS(WINCE) && !PLATFORM(QT) 420 void setBitmap(PassRefPtr<SharedBitmap>); 421 const AffineTransform& affineTransform() const; 422 AffineTransform& affineTransform(); 423 void resetAffineTransform(); 424 void fillRect(const FloatRect&, const Gradient*); 425 void drawText(const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point); 426 void drawFrameControl(const IntRect& rect, unsigned type, unsigned state); 427 void drawFocusRect(const IntRect& rect); 428 void paintTextField(const IntRect& rect, unsigned state); 429 void drawBitmap(SharedBitmap*, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp); 430 void drawBitmapPattern(SharedBitmap*, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize); 431 void drawIcon(HICON icon, const IntRect& dstRect, UINT flags); 432 HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = false, bool mayCreateBitmap = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers. 433 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = false, bool mayCreateBitmap = true); // The passed in HDC should be the one handed back by getWindowsContext. 434 void drawRoundCorner(bool newClip, RECT clipRect, RECT rectWin, HDC dc, int width, int height); 435 #elif PLATFORM(WIN) 436 GraphicsContext(HDC, bool hasAlpha = false); // FIXME: To be removed. 437 bool inTransparencyLayer() const; 438 HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers. 439 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); // The passed in HDC should be the one handed back by getWindowsContext. 440 441 // When set to true, child windows should be rendered into this context 442 // rather than allowing them just to render to the screen. Defaults to 443 // false. 444 // FIXME: This is a layering violation. GraphicsContext shouldn't know 445 // what a "window" is. It would be much more appropriate for this flag 446 // to be passed as a parameter alongside the GraphicsContext, but doing 447 // that would require lots of changes in cross-platform code that we 448 // aren't sure we want to make. 449 void setShouldIncludeChildWindows(bool); 450 bool shouldIncludeChildWindows() const; 451 452 class WindowsBitmap { 453 WTF_MAKE_NONCOPYABLE(WindowsBitmap); 454 public: 455 WindowsBitmap(HDC, const IntSize&); 456 ~WindowsBitmap(); 457 hdc()458 HDC hdc() const { return m_hdc; } buffer()459 UInt8* buffer() const { return m_pixelData.buffer(); } bufferLength()460 unsigned bufferLength() const { return m_pixelData.bufferLength(); } size()461 const IntSize& size() const { return m_pixelData.size(); } bytesPerRow()462 unsigned bytesPerRow() const { return m_pixelData.bytesPerRow(); } bitsPerPixel()463 unsigned short bitsPerPixel() const { return m_pixelData.bitsPerPixel(); } windowsDIB()464 const DIBPixelData& windowsDIB() const { return m_pixelData; } 465 466 private: 467 HDC m_hdc; 468 HBITMAP m_bitmap; 469 DIBPixelData m_pixelData; 470 }; 471 472 PassOwnPtr<WindowsBitmap> createWindowsBitmap(const IntSize&); 473 // The bitmap should be non-premultiplied. 474 void drawWindowsBitmap(WindowsBitmap*, const IntPoint&); 475 #endif 476 477 #if (PLATFORM(QT) && defined(Q_WS_WIN)) || (PLATFORM(WX) && OS(WINDOWS)) 478 HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); 479 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); shouldIncludeChildWindows()480 bool shouldIncludeChildWindows() const { return false; } 481 #endif 482 483 #if PLATFORM(WX) inTransparencyLayer()484 bool inTransparencyLayer() const { return false; } 485 #endif 486 487 #if PLATFORM(QT) 488 bool inTransparencyLayer() const; 489 void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask); 490 void takeOwnershipOfPlatformContext(); 491 #endif 492 493 #if PLATFORM(QT) || USE(CAIRO) 494 ContextShadow* contextShadow(); 495 #endif 496 497 #if USE(CAIRO) 498 GraphicsContext(cairo_t*); 499 #endif 500 501 #if PLATFORM(GTK) 502 void setGdkExposeEvent(GdkEventExpose*); 503 GdkWindow* gdkWindow() const; 504 GdkEventExpose* gdkExposeEvent() const; 505 #endif 506 507 #if PLATFORM(HAIKU) 508 pattern getHaikuStrokeStyle(); 509 #endif 510 511 void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&); 512 void syncSoftwareCanvas(); 513 void markDirtyRect(const IntRect&); // Hints that a portion of the backing store is dirty. 514 515 static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle); 516 517 private: 518 void platformInit(PlatformGraphicsContext*); 519 void platformDestroy(); 520 521 #if PLATFORM(WIN) && !OS(WINCE) 522 void platformInit(HDC, bool hasAlpha = false); 523 #endif 524 525 void savePlatformState(); 526 void restorePlatformState(); 527 528 void setPlatformTextDrawingMode(TextDrawingModeFlags); 529 void setPlatformFont(const Font& font); 530 531 void setPlatformStrokeColor(const Color&, ColorSpace); 532 void setPlatformStrokeStyle(StrokeStyle); 533 void setPlatformStrokeThickness(float); 534 void setPlatformStrokeGradient(Gradient*); 535 void setPlatformStrokePattern(Pattern*); 536 537 void setPlatformFillColor(const Color&, ColorSpace); 538 void setPlatformFillGradient(Gradient*); 539 void setPlatformFillPattern(Pattern*); 540 541 void setPlatformShouldAntialias(bool); 542 void setPlatformShouldSmoothFonts(bool); 543 544 void setPlatformShadow(const FloatSize&, float blur, const Color&, ColorSpace); 545 void clearPlatformShadow(); 546 547 void setPlatformCompositeOperation(CompositeOperator); 548 549 GraphicsContextPlatformPrivate* m_data; 550 551 GraphicsContextState m_state; 552 Vector<GraphicsContextState> m_stack; 553 bool m_updatingControlTints; 554 }; 555 556 class GraphicsContextStateSaver { 557 public: 558 GraphicsContextStateSaver(GraphicsContext& context, bool saveAndRestore = true) m_context(context)559 : m_context(context) 560 , m_saveAndRestore(saveAndRestore) 561 { 562 if (m_saveAndRestore) 563 m_context.save(); 564 } 565 ~GraphicsContextStateSaver()566 ~GraphicsContextStateSaver() 567 { 568 if (m_saveAndRestore) 569 m_context.restore(); 570 } 571 save()572 void save() 573 { 574 ASSERT(!m_saveAndRestore); 575 m_context.save(); 576 m_saveAndRestore = true; 577 } 578 restore()579 void restore() 580 { 581 ASSERT(m_saveAndRestore); 582 m_context.restore(); 583 m_saveAndRestore = false; 584 } 585 586 private: 587 GraphicsContext& m_context; 588 bool m_saveAndRestore; 589 }; 590 591 } // namespace WebCore 592 593 #endif // GraphicsContext_h 594 595