Host GraphicsContext's CTM inside GraphicsContextState
[WebKit-https.git] / Source / WebCore / platform / graphics / GraphicsContext.h
1 /*
2  * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2013 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 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 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 "FontCascade.h"
34 #include "Gradient.h"
35 #include "GraphicsTypes.h"
36 #include "Image.h"
37 #include "ImageOrientation.h"
38 #include "Path.h"
39 #include "Pattern.h"
40 #include <wtf/Noncopyable.h>
41
42 #if USE(CG)
43 typedef struct CGContext PlatformGraphicsContext;
44 #elif USE(CAIRO)
45 namespace WebCore {
46 class PlatformContextCairo;
47 }
48 typedef WebCore::PlatformContextCairo PlatformGraphicsContext;
49 #elif USE(WINGDI)
50 typedef struct HDC__ PlatformGraphicsContext;
51 #else
52 typedef void PlatformGraphicsContext;
53 #endif
54
55 #if PLATFORM(WIN)
56 #include "DIBPixelData.h"
57 typedef struct HDC__* HDC;
58 #if !USE(CG)
59 // UInt8 is defined in CoreFoundation/CFBase.h
60 typedef unsigned char UInt8;
61 #endif
62 #endif
63
64 namespace WebCore {
65
66 #if USE(WINGDI)
67 class SharedBitmap;
68 class Font;
69 class GlyphBuffer;
70 #endif
71
72 const int cMisspellingLineThickness = 3;
73 const int cMisspellingLinePatternWidth = 4;
74 const int cMisspellingLinePatternGapWidth = 1;
75
76 class AffineTransform;
77 class FloatRoundedRect;
78 class Gradient;
79 class GraphicsContextPlatformPrivate;
80 class ImageBuffer;
81 class IntRect;
82 class RoundedRect;
83 class URL;
84 class GraphicsContext3D;
85 class TextRun;
86 class TransformationMatrix;
87
88 enum TextDrawingMode {
89     TextModeFill = 1 << 0,
90     TextModeStroke = 1 << 1,
91 #if ENABLE(LETTERPRESS)
92     TextModeLetterpress = 1 << 2,
93 #endif
94 };
95 typedef unsigned TextDrawingModeFlags;
96
97 enum StrokeStyle {
98     NoStroke,
99     SolidStroke,
100     DottedStroke,
101     DashedStroke,
102     DoubleStroke,
103     WavyStroke,
104 };
105
106 enum InterpolationQuality {
107     InterpolationDefault,
108     InterpolationNone,
109     InterpolationLow,
110     InterpolationMedium,
111     InterpolationHigh
112 };
113
114 struct GraphicsContextState {
115     GraphicsContextState()
116         : shouldAntialias(true)
117         , shouldSmoothFonts(true)
118         , antialiasedFontDilationEnabled(true)
119         , shouldSubpixelQuantizeFonts(true)
120         , paintingDisabled(false)
121         , shadowsIgnoreTransforms(false)
122 #if USE(CG)
123         // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
124         // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
125         , shadowsUseLegacyRadius(false)
126 #endif
127         , drawLuminanceMask(false)
128     {
129     }
130
131     RefPtr<Gradient> strokeGradient;
132     RefPtr<Pattern> strokePattern;
133     
134     RefPtr<Gradient> fillGradient;
135     RefPtr<Pattern> fillPattern;
136
137     FloatSize shadowOffset;
138
139     float strokeThickness { 0 };
140     float shadowBlur { 0 };
141
142     TextDrawingModeFlags textDrawingMode { TextModeFill };
143
144     Color strokeColor { Color::black };
145     Color fillColor { Color::black };
146     Color shadowColor;
147
148     StrokeStyle strokeStyle { SolidStroke };
149     WindRule fillRule { RULE_NONZERO };
150
151     ColorSpace strokeColorSpace { ColorSpaceDeviceRGB };
152     ColorSpace fillColorSpace { ColorSpaceDeviceRGB };
153     ColorSpace shadowColorSpace { ColorSpaceDeviceRGB };
154
155     float alpha { 1 };
156     CompositeOperator compositeOperator { CompositeSourceOver };
157     BlendMode blendMode { BlendModeNormal };
158
159     AffineTransform userToDeviceSpaceCTM;
160     AffineTransform ctm;
161
162     bool shouldAntialias : 1;
163     bool shouldSmoothFonts : 1;
164     bool antialiasedFontDilationEnabled : 1;
165     bool shouldSubpixelQuantizeFonts : 1;
166     bool paintingDisabled : 1;
167     bool shadowsIgnoreTransforms : 1;
168 #if USE(CG)
169     bool shadowsUseLegacyRadius : 1;
170 #endif
171     bool drawLuminanceMask : 1;
172 };
173
174 struct ImagePaintingOptions {
175     ImagePaintingOptions(CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), bool useLowQualityScale = false)
176         : m_compositeOperator(compositeOperator)
177         , m_blendMode(blendMode)
178         , m_orientationDescription(orientationDescription)
179         , m_useLowQualityScale(useLowQualityScale)
180     {
181     }
182
183     ImagePaintingOptions(ImageOrientationDescription orientationDescription, bool useLowQualityScale = false, CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal)
184         : m_compositeOperator(compositeOperator)
185         , m_blendMode(blendMode)
186         , m_orientationDescription(orientationDescription)
187         , m_useLowQualityScale(useLowQualityScale)
188     {
189     }
190
191     ImagePaintingOptions(bool useLowQualityScale, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal)
192         : m_compositeOperator(compositeOperator)
193         , m_blendMode(blendMode)
194         , m_orientationDescription(orientationDescription)
195         , m_useLowQualityScale(useLowQualityScale)
196     {
197     }
198
199     CompositeOperator m_compositeOperator;
200     BlendMode m_blendMode;
201     ImageOrientationDescription m_orientationDescription;
202     bool m_useLowQualityScale;
203 };
204
205 class GraphicsContext {
206     WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
207 public:
208     WEBCORE_EXPORT GraphicsContext(PlatformGraphicsContext*);
209     WEBCORE_EXPORT ~GraphicsContext();
210
211     WEBCORE_EXPORT PlatformGraphicsContext* platformContext() const;
212
213     void setStrokeThickness(float);
214     float strokeThickness() const { return m_state.strokeThickness; }
215
216     void setStrokeStyle(StrokeStyle);
217     StrokeStyle strokeStyle() const { return m_state.strokeStyle; }
218
219     WEBCORE_EXPORT void setStrokeColor(const Color&, ColorSpace);
220     Color strokeColor() const { return m_state.strokeColor; }
221     ColorSpace strokeColorSpace() const { return m_state.strokeColorSpace; }
222
223     void setStrokePattern(Ref<Pattern>&&);
224     Pattern* strokePattern() const { return m_state.strokePattern.get(); }
225
226     void setStrokeGradient(Ref<Gradient>&&);
227     Gradient* strokeGradient() const { return m_state.strokeGradient.get(); }
228
229     void setFillRule(WindRule fillRule) { m_state.fillRule = fillRule; }
230     WindRule fillRule() const { return m_state.fillRule; }
231
232     WEBCORE_EXPORT void setFillColor(const Color&, ColorSpace);
233     Color fillColor() const { return m_state.fillColor; }
234     ColorSpace fillColorSpace() const { return m_state.fillColorSpace; }
235
236     void setFillPattern(Ref<Pattern>&&);
237     Pattern* fillPattern() const { return m_state.fillPattern.get(); }
238
239     WEBCORE_EXPORT void setFillGradient(Ref<Gradient>&&);
240     Gradient* fillGradient() const { return m_state.fillGradient.get(); }
241
242     void setShadowsIgnoreTransforms(bool shadowsIgnoreTransforms) { m_state.shadowsIgnoreTransforms = shadowsIgnoreTransforms; }
243     bool shadowsIgnoreTransforms() const { return m_state.shadowsIgnoreTransforms; }
244
245     WEBCORE_EXPORT void setShouldAntialias(bool);
246     bool shouldAntialias() const { return m_state.shouldAntialias; }
247
248     WEBCORE_EXPORT void setAntialiasedFontDilationEnabled(bool);
249     bool antialiasedFontDilationEnabled() const { return m_state.antialiasedFontDilationEnabled; }
250
251     WEBCORE_EXPORT void setShouldSmoothFonts(bool);
252     bool shouldSmoothFonts() const { return m_state.shouldSmoothFonts; }
253
254     // Normally CG enables subpixel-quantization because it improves the performance of aligning glyphs.
255     // In some cases we have to disable to to ensure a high-quality output of the glyphs.
256     void setShouldSubpixelQuantizeFonts(bool shouldSubpixelQuantizeFonts) { m_state.shouldSubpixelQuantizeFonts = shouldSubpixelQuantizeFonts; }
257     bool shouldSubpixelQuantizeFonts() const { return m_state.shouldSubpixelQuantizeFonts; }
258
259     const GraphicsContextState& state() const { return m_state; }
260
261 #if USE(CG)
262     void applyStrokePattern();
263     void applyFillPattern();
264     void drawPath(const Path&);
265
266     WEBCORE_EXPORT void drawNativeImage(PassNativeImagePtr, const FloatSize& selfSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, ImageOrientation = DefaultImageOrientation);
267
268     void clipToNativeImage(PassNativeImagePtr, const FloatRect& destRect, const FloatSize& bufferSize);
269     
270     WEBCORE_EXPORT void setIsCALayerContext(bool);
271     bool isCALayerContext() const;
272
273     WEBCORE_EXPORT void setIsAcceleratedContext(bool);
274 #endif
275     bool isAcceleratedContext() const;
276     RenderingMode renderingMode() const { return isAcceleratedContext() ? Accelerated : Unaccelerated; }
277
278     WEBCORE_EXPORT void save();
279     WEBCORE_EXPORT void restore();
280
281     // These draw methods will do both stroking and filling.
282     // FIXME: ...except drawRect(), which fills properly but always strokes
283     // using a 1-pixel stroke inset from the rect borders (of the correct
284     // stroke color).
285     void drawRect(const FloatRect&, float borderThickness = 1);
286     void drawLine(const FloatPoint&, const FloatPoint&);
287
288 #if PLATFORM(IOS)
289     void drawJoinedLines(CGPoint points[], unsigned count, bool antialias, CGLineCap = kCGLineCapButt);
290 #endif
291
292     void drawEllipse(const FloatRect&);
293     void drawRaisedEllipse(const FloatRect&, const Color& ellipseColor, ColorSpace ellipseColorSpace, const Color& shadowColor, ColorSpace shadowColorSpace);
294     void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false);
295
296     WEBCORE_EXPORT void fillPath(const Path&);
297     void strokePath(const Path&);
298
299     void fillEllipse(const FloatRect&);
300     void strokeEllipse(const FloatRect&);
301
302     WEBCORE_EXPORT void fillRect(const FloatRect&);
303     WEBCORE_EXPORT void fillRect(const FloatRect&, const Color&, ColorSpace);
304     void fillRect(const FloatRect&, Gradient&);
305     void fillRect(const FloatRect&, const Color&, ColorSpace, CompositeOperator, BlendMode = BlendModeNormal);
306     void fillRoundedRect(const FloatRoundedRect&, const Color&, ColorSpace, BlendMode = BlendModeNormal);
307     void fillRectWithRoundedHole(const FloatRect&, const FloatRoundedRect& roundedHoleRect, const Color&, ColorSpace);
308
309     WEBCORE_EXPORT void clearRect(const FloatRect&);
310
311     WEBCORE_EXPORT void strokeRect(const FloatRect&, float lineWidth);
312
313     WEBCORE_EXPORT void drawImage(Image&, ColorSpace, const FloatPoint& destination, const ImagePaintingOptions& = ImagePaintingOptions());
314     WEBCORE_EXPORT void drawImage(Image&, ColorSpace, const FloatRect& destination, const ImagePaintingOptions& = ImagePaintingOptions());
315     void drawImage(Image&, ColorSpace, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = ImagePaintingOptions());
316
317     void drawTiledImage(Image&, ColorSpace, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& = ImagePaintingOptions());
318     void drawTiledImage(Image&, ColorSpace, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor,
319         Image::TileRule, Image::TileRule, const ImagePaintingOptions& = ImagePaintingOptions());
320
321     WEBCORE_EXPORT void drawImageBuffer(ImageBuffer&, ColorSpace, const FloatPoint& destination, const ImagePaintingOptions& = ImagePaintingOptions());
322     void drawImageBuffer(ImageBuffer&, ColorSpace, const FloatRect& destination, const ImagePaintingOptions& = ImagePaintingOptions());
323     void drawImageBuffer(ImageBuffer&, ColorSpace, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = ImagePaintingOptions());
324
325     void drawPattern(Image&, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, ColorSpace, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal);
326
327     WEBCORE_EXPORT void setImageInterpolationQuality(InterpolationQuality);
328     InterpolationQuality imageInterpolationQuality() const;
329
330     WEBCORE_EXPORT void clip(const IntRect&);
331     WEBCORE_EXPORT void clip(const FloatRect&);
332     void clipRoundedRect(const FloatRoundedRect&);
333
334     void clipOut(const FloatRect&);
335     void clipOutRoundedRect(const FloatRoundedRect&);
336     void clipPath(const Path&, WindRule);
337     void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
338     void clipToImageBuffer(ImageBuffer&, const FloatRect&);
339     
340     IntRect clipBounds() const;
341
342     void setTextDrawingMode(TextDrawingModeFlags);
343     TextDrawingModeFlags textDrawingMode() const { return m_state.textDrawingMode; }
344
345     float drawText(const FontCascade&, const TextRun&, const FloatPoint&, int from = 0, int to = -1);
346     void drawGlyphs(const FontCascade&, const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint&);
347     void drawEmphasisMarks(const FontCascade&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1);
348     void drawBidiText(const FontCascade&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction = FontCascade::DoNotPaintIfFontNotReady);
349
350     enum RoundingMode {
351         RoundAllSides,
352         RoundOriginAndDimensions
353     };
354     FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides);
355
356     FloatRect computeLineBoundsForText(const FloatPoint&, float width, bool printing);
357     WEBCORE_EXPORT void drawLineForText(const FloatPoint&, float width, bool printing, bool doubleLines = false);
358     void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines = false);
359     enum DocumentMarkerLineStyle {
360 #if PLATFORM(IOS)
361         TextCheckingDictationPhraseWithAlternativesLineStyle,
362 #endif
363         DocumentMarkerSpellingLineStyle,
364         DocumentMarkerGrammarLineStyle,
365         DocumentMarkerAutocorrectionReplacementLineStyle,
366         DocumentMarkerDictationAlternativesLineStyle
367     };
368     static void updateDocumentMarkerResources();
369     void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
370
371     void setPaintingDisabled(bool paintingDisabled) { m_state.paintingDisabled = paintingDisabled; }
372     bool paintingDisabled() const { return m_state.paintingDisabled; }
373
374     void setUpdatingControlTints(bool);
375     bool updatingControlTints() const { return m_updatingControlTints; }
376
377     WEBCORE_EXPORT void beginTransparencyLayer(float opacity);
378     WEBCORE_EXPORT void endTransparencyLayer();
379     bool isInTransparencyLayer() const { return (m_transparencyCount > 0) && supportsTransparencyLayers(); }
380
381     WEBCORE_EXPORT void setShadow(const FloatSize&, float blur, const Color&, ColorSpace);
382     // Legacy shadow blur radius is used for canvas, and -webkit-box-shadow.
383     // It has different treatment of radii > 8px.
384     void setLegacyShadow(const FloatSize&, float blur, const Color&, ColorSpace);
385
386     WEBCORE_EXPORT void clearShadow();
387     bool getShadow(FloatSize&, float&, Color&, ColorSpace&) const;
388
389     bool hasVisibleShadow() const { return m_state.shadowColor.isValid() && m_state.shadowColor.alpha(); }
390     bool hasShadow() const { return hasVisibleShadow() && (m_state.shadowBlur || m_state.shadowOffset.width() || m_state.shadowOffset.height()); }
391     bool hasBlurredShadow() const { return hasVisibleShadow() && m_state.shadowBlur; }
392
393 #if USE(CAIRO)
394     bool mustUseShadowBlur() const;
395 #endif
396
397     void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
398     void drawFocusRing(const Path&, int width, int offset, const Color&);
399 #if PLATFORM(MAC)
400     void drawFocusRing(const Vector<IntRect>&, int width, int offset, double timeOffset, bool& needsRedraw);
401 #endif
402
403     void setLineCap(LineCap);
404     void setLineDash(const DashArray&, float dashOffset);
405     void setLineJoin(LineJoin);
406     void setMiterLimit(float);
407
408     void setAlpha(float);
409     float alpha() const { return m_state.alpha; }
410
411     WEBCORE_EXPORT void setCompositeOperation(CompositeOperator, BlendMode = BlendModeNormal);
412     CompositeOperator compositeOperation() const { return m_state.compositeOperator; }
413     BlendMode blendModeOperation() const { return m_state.blendMode; }
414
415     void setDrawLuminanceMask(bool drawLuminanceMask) { m_state.drawLuminanceMask = drawLuminanceMask; }
416     bool drawLuminanceMask() const { return m_state.drawLuminanceMask; }
417
418     WEBCORE_EXPORT void clip(const Path&, WindRule = RULE_EVENODD);
419
420     // This clip function is used only by <canvas> code. It allows
421     // implementations to handle clipping on the canvas differently since
422     // the discipline is different.
423     void canvasClip(const Path&, WindRule = RULE_EVENODD);
424     void clipOut(const Path&);
425
426     WEBCORE_EXPORT void scale(const FloatSize& size) { scale(size.width(), size.height()); }
427     void rotate(float angleInRadians);
428     void translate(const FloatSize& size) { translate(size.width(), size.height()); }
429     WEBCORE_EXPORT void scale(float x, float y);
430     WEBCORE_EXPORT void translate(float x, float y);
431
432     void setURLForRect(const URL&, const IntRect&);
433
434     void checkCTMInvariants() const
435     {
436         ASSERT(getCTM(DefinitelyIncludeDeviceScale).isEssentiallyEqualTo(getPlatformCTM(DefinitelyIncludeDeviceScale)));
437         ASSERT(getCTM(PossiblyIncludeDeviceScale).isEssentiallyEqualTo(getPlatformCTM(PossiblyIncludeDeviceScale)));
438     }
439     void concatCTM(const AffineTransform&);
440     void setCTM(const AffineTransform&);
441     void resetPlatformCTM();
442
443     enum IncludeDeviceScale { DefinitelyIncludeDeviceScale, PossiblyIncludeDeviceScale };
444     AffineTransform getCTM(IncludeDeviceScale = PossiblyIncludeDeviceScale) const;
445
446 #if ENABLE(3D_TRANSFORMS) && USE(TEXTURE_MAPPER)
447     // This is needed when using accelerated-compositing in software mode, like in TextureMapper.
448     void concat3DTransform(const TransformationMatrix&);
449     void set3DTransform(const TransformationMatrix&);
450     TransformationMatrix get3DTransform() const;
451 #endif
452     // Create an image buffer compatible with this context, with suitable resolution
453     // for drawing into the buffer and then into this context.
454     std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, bool hasAlpha = true) const;
455     bool isCompatibleWithBuffer(ImageBuffer&) const;
456
457     // This function applies the device scale factor to the context, making the context capable of
458     // acting as a base-level context for a HiDPI environment.
459     WEBCORE_EXPORT void applyDeviceScaleFactor(float);
460     void platformApplyDeviceScaleFactor(float);
461
462 #if OS(WINDOWS)
463     HDC getWindowsContext(const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
464     void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap); // The passed in HDC should be the one handed back by getWindowsContext.
465     HDC hdc() const;
466 #if PLATFORM(WIN)
467 #if USE(WINGDI)
468     void setBitmap(PassRefPtr<SharedBitmap>);
469     const AffineTransform& affineTransform() const;
470     AffineTransform& affineTransform();
471     void resetAffineTransform();
472     void fillRect(const FloatRect&, const Gradient*);
473     void drawText(const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint&);
474     void drawFrameControl(const IntRect& rect, unsigned type, unsigned state);
475     void drawFocusRect(const IntRect& rect);
476     void paintTextField(const IntRect& rect, unsigned state);
477     void drawBitmap(SharedBitmap*, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp, BlendMode blendMode);
478     void drawBitmapPattern(SharedBitmap*, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize);
479     void drawIcon(HICON icon, const IntRect& dstRect, UINT flags);
480     void drawRoundCorner(bool newClip, RECT clipRect, RECT rectWin, HDC dc, int width, int height);
481 #else
482     GraphicsContext(HDC, bool hasAlpha = false); // FIXME: To be removed.
483
484     // When set to true, child windows should be rendered into this context
485     // rather than allowing them just to render to the screen. Defaults to
486     // false.
487     // FIXME: This is a layering violation. GraphicsContext shouldn't know
488     // what a "window" is. It would be much more appropriate for this flag
489     // to be passed as a parameter alongside the GraphicsContext, but doing
490     // that would require lots of changes in cross-platform code that we
491     // aren't sure we want to make.
492     void setShouldIncludeChildWindows(bool);
493     bool shouldIncludeChildWindows() const;
494
495     class WindowsBitmap {
496         WTF_MAKE_NONCOPYABLE(WindowsBitmap);
497     public:
498         WindowsBitmap(HDC, const IntSize&);
499         ~WindowsBitmap();
500
501         HDC hdc() const { return m_hdc; }
502         UInt8* buffer() const { return m_pixelData.buffer(); }
503         unsigned bufferLength() const { return m_pixelData.bufferLength(); }
504         const IntSize& size() const { return m_pixelData.size(); }
505         unsigned bytesPerRow() const { return m_pixelData.bytesPerRow(); }
506         unsigned short bitsPerPixel() const { return m_pixelData.bitsPerPixel(); }
507         const DIBPixelData& windowsDIB() const { return m_pixelData; }
508
509     private:
510         HDC m_hdc;
511         HBITMAP m_bitmap;
512         DIBPixelData m_pixelData;
513     };
514
515     std::unique_ptr<WindowsBitmap> createWindowsBitmap(const IntSize&);
516     // The bitmap should be non-premultiplied.
517     void drawWindowsBitmap(WindowsBitmap*, const IntPoint&);
518 #endif
519 #else // PLATFORM(WIN)
520     bool shouldIncludeChildWindows() const { return false; }
521 #endif // PLATFORM(WIN)
522 #endif // OS(WINDOWS)
523
524 #if USE(CAIRO)
525     GraphicsContext(cairo_t*);
526 #endif
527
528     static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
529
530 private:
531     void platformInit(PlatformGraphicsContext*);
532     void platformDestroy();
533
534 #if PLATFORM(WIN) && !USE(WINGDI)
535     void platformInit(HDC, bool hasAlpha = false);
536 #endif
537
538     void savePlatformState();
539     void restorePlatformState();
540
541     void setPlatformTextDrawingMode(TextDrawingModeFlags);
542
543     void setPlatformStrokeColor(const Color&, ColorSpace);
544     void setPlatformStrokeStyle(StrokeStyle);
545     void setPlatformStrokeThickness(float);
546
547     void setPlatformFillColor(const Color&, ColorSpace);
548
549     void setPlatformShouldAntialias(bool);
550     void setPlatformShouldSmoothFonts(bool);
551
552     void setPlatformShadow(const FloatSize&, float blur, const Color&, ColorSpace);
553     void clearPlatformShadow();
554
555     void setPlatformAlpha(float);
556     void setPlatformCompositeOperation(CompositeOperator, BlendMode = BlendModeNormal);
557
558     void concatPlatformCTM(const AffineTransform&);
559     void scalePlatformCTM(float x, float y);
560     void rotatePlatformCTM(float);
561     void translatePlatformCTM(float, float);
562     void setPlatformCTM(const AffineTransform&);
563     AffineTransform getPlatformCTM(IncludeDeviceScale = PossiblyIncludeDeviceScale) const; // This is only computed to ASSERT() that the GraphicsContextState agrees with the underlying platform.
564
565     void beginPlatformTransparencyLayer(float opacity);
566     void endPlatformTransparencyLayer();
567     static bool supportsTransparencyLayers();
568
569     void fillEllipseAsPath(const FloatRect&);
570     void strokeEllipseAsPath(const FloatRect&);
571
572     void platformFillEllipse(const FloatRect&);
573     void platformStrokeEllipse(const FloatRect&);
574
575     void platformFillRoundedRect(const FloatRoundedRect&, const Color&, ColorSpace);
576
577     FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatPoint&, float width, bool printing, bool& shouldAntialias, Color&);
578
579     GraphicsContextPlatformPrivate* m_data;
580
581     GraphicsContextState m_state;
582     Vector<GraphicsContextState, 1> m_stack;
583     bool m_updatingControlTints;
584     unsigned m_transparencyCount;
585 };
586
587 class GraphicsContextStateSaver {
588     WTF_MAKE_FAST_ALLOCATED;
589 public:
590     GraphicsContextStateSaver(GraphicsContext& context, bool saveAndRestore = true)
591     : m_context(context)
592     , m_saveAndRestore(saveAndRestore)
593     {
594         if (m_saveAndRestore)
595             m_context.save();
596     }
597     
598     ~GraphicsContextStateSaver()
599     {
600         if (m_saveAndRestore)
601             m_context.restore();
602     }
603     
604     void save()
605     {
606         ASSERT(!m_saveAndRestore);
607         m_context.save();
608         m_saveAndRestore = true;
609     }
610
611     void restore()
612     {
613         ASSERT(m_saveAndRestore);
614         m_context.restore();
615         m_saveAndRestore = false;
616     }
617     
618     GraphicsContext* context() const { return &m_context; }
619
620 private:
621     GraphicsContext& m_context;
622     bool m_saveAndRestore;
623 };
624
625 } // namespace WebCore
626
627 #endif // GraphicsContext_h