Stop using PassRefPtr in platform/graphics
[WebKit-https.git] / Source / WebCore / platform / graphics / GraphicsContext.h
1 /*
2  * Copyright (C) 2003-2016 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 #pragma once
28
29 #include "DashArray.h"
30 #include "FloatRect.h"
31 #include "FontCascade.h"
32 #include "Gradient.h"
33 #include "GraphicsTypes.h"
34 #include "Image.h"
35 #include "ImageOrientation.h"
36 #include "Pattern.h"
37 #include <wtf/Noncopyable.h>
38
39 #if USE(CG)
40 typedef struct CGContext PlatformGraphicsContext;
41 #elif USE(DIRECT2D)
42 interface ID2D1DCRenderTarget;
43 interface ID2D1RenderTarget;
44 interface ID2D1Factory;
45 interface ID2D1SolidColorBrush;
46 typedef ID2D1RenderTarget PlatformGraphicsContext;
47 #elif USE(CAIRO)
48 namespace WebCore {
49 class PlatformContextCairo;
50 }
51 typedef WebCore::PlatformContextCairo PlatformGraphicsContext;
52 #elif USE(WINGDI)
53 typedef struct HDC__ PlatformGraphicsContext;
54 #else
55 typedef void PlatformGraphicsContext;
56 #endif
57
58 #if PLATFORM(WIN)
59 #include "DIBPixelData.h"
60 typedef struct HDC__* HDC;
61 #if !USE(CG)
62 // UInt8 is defined in CoreFoundation/CFBase.h
63 typedef unsigned char UInt8;
64 #endif
65 #endif
66
67 namespace WebCore {
68
69 #if USE(WINGDI)
70 class SharedBitmap;
71 class Font;
72 class GlyphBuffer;
73 #endif
74
75 const int cMisspellingLineThickness = 3;
76 const int cMisspellingLinePatternWidth = 4;
77 const int cMisspellingLinePatternGapWidth = 1;
78
79 class AffineTransform;
80 class FloatRoundedRect;
81 class Gradient;
82 class GraphicsContextPlatformPrivate;
83 class ImageBuffer;
84 class IntRect;
85 class RoundedRect;
86 class URL;
87 class GraphicsContext3D;
88 class Path;
89 class TextRun;
90 class TransformationMatrix;
91
92 enum TextDrawingMode {
93     TextModeFill = 1 << 0,
94     TextModeStroke = 1 << 1,
95 #if ENABLE(LETTERPRESS)
96     TextModeLetterpress = 1 << 2,
97 #endif
98 };
99 typedef unsigned TextDrawingModeFlags;
100
101 enum StrokeStyle {
102     NoStroke,
103     SolidStroke,
104     DottedStroke,
105     DashedStroke,
106     DoubleStroke,
107     WavyStroke,
108 };
109
110 namespace DisplayList {
111 class Recorder;
112 }
113
114 struct GraphicsContextState {
115     GraphicsContextState()
116         : shouldAntialias(true)
117         , shouldSmoothFonts(true)
118         , shouldSubpixelQuantizeFonts(true)
119         , shadowsIgnoreTransforms(false)
120 #if USE(CG)
121         // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
122         // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
123         , shadowsUseLegacyRadius(false)
124 #endif
125         , drawLuminanceMask(false)
126     {
127     }
128
129     enum Change : uint32_t {
130         NoChange                                = 0,
131         StrokeGradientChange                    = 1 << 1,
132         StrokePatternChange                     = 1 << 2,
133         FillGradientChange                      = 1 << 3,
134         FillPatternChange                       = 1 << 4,
135         StrokeThicknessChange                   = 1 << 5,
136         StrokeColorChange                       = 1 << 6,
137         StrokeStyleChange                       = 1 << 7,
138         FillColorChange                         = 1 << 8,
139         FillRuleChange                          = 1 << 9,
140         ShadowChange                            = 1 << 10,
141         ShadowColorChange                       = 1 << 11,
142         ShadowsIgnoreTransformsChange           = 1 << 12,
143         AlphaChange                             = 1 << 13,
144         CompositeOperationChange                = 1 << 14,
145         BlendModeChange                         = 1 << 15,
146         TextDrawingModeChange                   = 1 << 16,
147         ShouldAntialiasChange                   = 1 << 17,
148         ShouldSmoothFontsChange                 = 1 << 18,
149         ShouldSubpixelQuantizeFontsChange       = 1 << 19,
150         DrawLuminanceMaskChange                 = 1 << 20,
151         ImageInterpolationQualityChange         = 1 << 21,
152     };
153     typedef uint32_t StateChangeFlags;
154
155     RefPtr<Gradient> strokeGradient;
156     RefPtr<Pattern> strokePattern;
157     
158     RefPtr<Gradient> fillGradient;
159     RefPtr<Pattern> fillPattern;
160
161     FloatSize shadowOffset;
162
163     float strokeThickness { 0 };
164     float shadowBlur { 0 };
165
166     TextDrawingModeFlags textDrawingMode { TextModeFill };
167
168     Color strokeColor { Color::black };
169     Color fillColor { Color::black };
170     Color shadowColor;
171
172     StrokeStyle strokeStyle { SolidStroke };
173     WindRule fillRule { RULE_NONZERO };
174
175     float alpha { 1 };
176     CompositeOperator compositeOperator { CompositeSourceOver };
177     BlendMode blendMode { BlendModeNormal };
178     InterpolationQuality imageInterpolationQuality { InterpolationDefault };
179
180     bool shouldAntialias : 1;
181     bool shouldSmoothFonts : 1;
182     bool shouldSubpixelQuantizeFonts : 1;
183     bool shadowsIgnoreTransforms : 1;
184 #if USE(CG)
185     bool shadowsUseLegacyRadius : 1;
186 #endif
187     bool drawLuminanceMask : 1;
188 };
189
190 struct ImagePaintingOptions {
191     ImagePaintingOptions(CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, DecodingMode decodingMode = DecodingMode::Synchronous, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), InterpolationQuality interpolationQuality = InterpolationDefault)
192         : m_compositeOperator(compositeOperator)
193         , m_blendMode(blendMode)
194         , m_decodingMode(decodingMode)
195         , m_orientationDescription(orientationDescription)
196         , m_interpolationQuality(interpolationQuality)
197     {
198     }
199
200     ImagePaintingOptions(ImageOrientationDescription orientationDescription, InterpolationQuality interpolationQuality = InterpolationDefault, CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, DecodingMode decodingMode = DecodingMode::Synchronous)
201         : m_compositeOperator(compositeOperator)
202         , m_blendMode(blendMode)
203         , m_decodingMode(decodingMode)
204         , m_orientationDescription(orientationDescription)
205         , m_interpolationQuality(interpolationQuality)
206     {
207     }
208
209     ImagePaintingOptions(InterpolationQuality interpolationQuality, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, DecodingMode decodingMode = DecodingMode::Synchronous)
210         : m_compositeOperator(compositeOperator)
211         , m_blendMode(blendMode)
212         , m_decodingMode(decodingMode)
213         , m_orientationDescription(orientationDescription)
214         , m_interpolationQuality(interpolationQuality)
215     {
216     }
217     
218     bool usesDefaultInterpolation() const { return m_interpolationQuality == InterpolationDefault; }
219
220     CompositeOperator m_compositeOperator;
221     BlendMode m_blendMode;
222     DecodingMode m_decodingMode;
223     ImageOrientationDescription m_orientationDescription;
224     InterpolationQuality m_interpolationQuality;
225 };
226
227 struct GraphicsContextStateChange {
228     GraphicsContextStateChange() = default;
229     GraphicsContextStateChange(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
230         : m_state(state)
231         , m_changeFlags(flags)
232     {
233     }
234
235     GraphicsContextState::StateChangeFlags changesFromState(const GraphicsContextState&) const;
236
237     void accumulate(const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
238     void apply(GraphicsContext&) const;
239     
240     void dump(TextStream&) const;
241
242     GraphicsContextState m_state;
243     GraphicsContextState::StateChangeFlags m_changeFlags { GraphicsContextState::NoChange };
244 };
245
246 TextStream& operator<<(TextStream&, const GraphicsContextStateChange&);
247
248
249 class GraphicsContext {
250     WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
251 public:
252     WEBCORE_EXPORT GraphicsContext(PlatformGraphicsContext*);
253     GraphicsContext() = default;
254     WEBCORE_EXPORT ~GraphicsContext();
255     
256     enum class NonPaintingReasons {
257         NoReasons,
258         UpdatingControlTints
259     };
260     GraphicsContext(NonPaintingReasons);
261
262     WEBCORE_EXPORT PlatformGraphicsContext* platformContext() const;
263
264     bool paintingDisabled() const { return !m_data && !isRecording(); }
265     bool updatingControlTints() const { return m_nonPaintingReasons == NonPaintingReasons::UpdatingControlTints; }
266
267     void setDisplayListRecorder(DisplayList::Recorder* recorder) { m_displayListRecorder = recorder; }
268     bool isRecording() const { return m_displayListRecorder; }
269
270     void setStrokeThickness(float);
271     float strokeThickness() const { return m_state.strokeThickness; }
272
273     void setStrokeStyle(StrokeStyle);
274     StrokeStyle strokeStyle() const { return m_state.strokeStyle; }
275
276     WEBCORE_EXPORT void setStrokeColor(const Color&);
277     const Color& strokeColor() const { return m_state.strokeColor; }
278
279     void setStrokePattern(Ref<Pattern>&&);
280     Pattern* strokePattern() const { return m_state.strokePattern.get(); }
281
282     void setStrokeGradient(Ref<Gradient>&&);
283     Gradient* strokeGradient() const { return m_state.strokeGradient.get(); }
284
285     void setFillRule(WindRule);
286     WindRule fillRule() const { return m_state.fillRule; }
287
288     WEBCORE_EXPORT void setFillColor(const Color&);
289     const Color& fillColor() const { return m_state.fillColor; }
290
291     void setFillPattern(Ref<Pattern>&&);
292     Pattern* fillPattern() const { return m_state.fillPattern.get(); }
293
294     WEBCORE_EXPORT void setFillGradient(Ref<Gradient>&&);
295     Gradient* fillGradient() const { return m_state.fillGradient.get(); }
296
297     void setShadowsIgnoreTransforms(bool);
298     bool shadowsIgnoreTransforms() const { return m_state.shadowsIgnoreTransforms; }
299
300     WEBCORE_EXPORT void setShouldAntialias(bool);
301     bool shouldAntialias() const { return m_state.shouldAntialias; }
302
303     WEBCORE_EXPORT void setShouldSmoothFonts(bool);
304     bool shouldSmoothFonts() const { return m_state.shouldSmoothFonts; }
305
306     // Normally CG enables subpixel-quantization because it improves the performance of aligning glyphs.
307     // In some cases we have to disable to to ensure a high-quality output of the glyphs.
308     void setShouldSubpixelQuantizeFonts(bool);
309     bool shouldSubpixelQuantizeFonts() const { return m_state.shouldSubpixelQuantizeFonts; }
310
311     const GraphicsContextState& state() const { return m_state; }
312
313 #if USE(CG) || USE(DIRECT2D) || USE(CAIRO)
314     WEBCORE_EXPORT void drawNativeImage(const NativeImagePtr&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, ImageOrientation = ImageOrientation());
315 #endif
316
317 #if USE(CG) || USE(DIRECT2D)
318     void applyStrokePattern();
319     void applyFillPattern();
320     void drawPath(const Path&);
321
322     WEBCORE_EXPORT void setIsCALayerContext(bool);
323     bool isCALayerContext() const;
324
325     WEBCORE_EXPORT void setIsAcceleratedContext(bool);
326 #endif
327     bool isAcceleratedContext() const;
328     RenderingMode renderingMode() const { return isAcceleratedContext() ? Accelerated : Unaccelerated; }
329
330     WEBCORE_EXPORT void save();
331     WEBCORE_EXPORT void restore();
332
333     // These draw methods will do both stroking and filling.
334     // FIXME: ...except drawRect(), which fills properly but always strokes
335     // using a 1-pixel stroke inset from the rect borders (of the correct
336     // stroke color).
337     void drawRect(const FloatRect&, float borderThickness = 1);
338     void drawLine(const FloatPoint&, const FloatPoint&);
339
340     void drawEllipse(const FloatRect&);
341     void drawRaisedEllipse(const FloatRect&, const Color& ellipseColor, const Color& shadowColor);
342
343     WEBCORE_EXPORT void fillPath(const Path&);
344     void strokePath(const Path&);
345
346     void fillEllipse(const FloatRect&);
347     void strokeEllipse(const FloatRect&);
348
349     WEBCORE_EXPORT void fillRect(const FloatRect&);
350     WEBCORE_EXPORT void fillRect(const FloatRect&, const Color&);
351     void fillRect(const FloatRect&, Gradient&);
352     void fillRect(const FloatRect&, const Color&, CompositeOperator, BlendMode = BlendModeNormal);
353     void fillRoundedRect(const FloatRoundedRect&, const Color&, BlendMode = BlendModeNormal);
354     void fillRectWithRoundedHole(const FloatRect&, const FloatRoundedRect& roundedHoleRect, const Color&);
355
356     WEBCORE_EXPORT void clearRect(const FloatRect&);
357
358     WEBCORE_EXPORT void strokeRect(const FloatRect&, float lineWidth);
359
360     WEBCORE_EXPORT void drawImage(Image&, const FloatPoint& destination, const ImagePaintingOptions& = ImagePaintingOptions());
361     WEBCORE_EXPORT void drawImage(Image&, const FloatRect& destination, const ImagePaintingOptions& = ImagePaintingOptions());
362     void drawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = ImagePaintingOptions());
363
364     void drawTiledImage(Image&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& = ImagePaintingOptions());
365     void drawTiledImage(Image&, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor,
366         Image::TileRule, Image::TileRule, const ImagePaintingOptions& = ImagePaintingOptions());
367
368     WEBCORE_EXPORT void drawImageBuffer(ImageBuffer&, const FloatPoint& destination, const ImagePaintingOptions& = ImagePaintingOptions());
369     void drawImageBuffer(ImageBuffer&, const FloatRect& destination, const ImagePaintingOptions& = ImagePaintingOptions());
370     void drawImageBuffer(ImageBuffer&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = ImagePaintingOptions());
371
372     void drawPattern(Image&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode = BlendModeNormal);
373
374     WEBCORE_EXPORT void drawConsumingImageBuffer(std::unique_ptr<ImageBuffer>, const FloatPoint& destination, const ImagePaintingOptions& = ImagePaintingOptions());
375     void drawConsumingImageBuffer(std::unique_ptr<ImageBuffer>, const FloatRect& destination, const ImagePaintingOptions& = ImagePaintingOptions());
376     void drawConsumingImageBuffer(std::unique_ptr<ImageBuffer>, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = ImagePaintingOptions());
377
378     WEBCORE_EXPORT void setImageInterpolationQuality(InterpolationQuality);
379     InterpolationQuality imageInterpolationQuality() const { return m_state.imageInterpolationQuality; }
380
381     WEBCORE_EXPORT void clip(const FloatRect&);
382     void clipRoundedRect(const FloatRoundedRect&);
383
384     void clipOut(const FloatRect&);
385     void clipOutRoundedRect(const FloatRoundedRect&);
386     void clipPath(const Path&, WindRule = RULE_EVENODD);
387     void clipToImageBuffer(ImageBuffer&, const FloatRect&);
388     
389     IntRect clipBounds() const;
390
391     void setTextDrawingMode(TextDrawingModeFlags);
392     TextDrawingModeFlags textDrawingMode() const { return m_state.textDrawingMode; }
393
394     float drawText(const FontCascade&, const TextRun&, const FloatPoint&, unsigned from = 0, std::optional<unsigned> to = std::nullopt);
395     void drawGlyphs(const FontCascade&, const Font&, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint&);
396     void drawEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from = 0, std::optional<unsigned> to = std::nullopt);
397     void drawBidiText(const FontCascade&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction = FontCascade::DoNotPaintIfFontNotReady);
398
399     void applyState(const GraphicsContextState&);
400
401     enum RoundingMode {
402         RoundAllSides,
403         RoundOriginAndDimensions
404     };
405     FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides);
406
407     FloatRect computeUnderlineBoundsForText(const FloatPoint&, float width, bool printing);
408     WEBCORE_EXPORT void drawLineForText(const FloatPoint&, float width, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
409     void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines = false, StrokeStyle = SolidStroke);
410     enum DocumentMarkerLineStyle {
411 #if PLATFORM(IOS)
412         TextCheckingDictationPhraseWithAlternativesLineStyle,
413 #endif
414         DocumentMarkerSpellingLineStyle,
415         DocumentMarkerGrammarLineStyle,
416         DocumentMarkerAutocorrectionReplacementLineStyle,
417         DocumentMarkerDictationAlternativesLineStyle
418     };
419     static void updateDocumentMarkerResources();
420     void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
421
422     WEBCORE_EXPORT void beginTransparencyLayer(float opacity);
423     WEBCORE_EXPORT void endTransparencyLayer();
424     bool isInTransparencyLayer() const { return (m_transparencyCount > 0) && supportsTransparencyLayers(); }
425
426     WEBCORE_EXPORT void setShadow(const FloatSize&, float blur, const Color&);
427     // Legacy shadow blur radius is used for canvas, and -webkit-box-shadow.
428     // It has different treatment of radii > 8px.
429     void setLegacyShadow(const FloatSize&, float blur, const Color&);
430
431     WEBCORE_EXPORT void clearShadow();
432     bool getShadow(FloatSize&, float&, Color&) const;
433
434     bool hasVisibleShadow() const { return m_state.shadowColor.isVisible(); }
435     bool hasShadow() const { return hasVisibleShadow() && (m_state.shadowBlur || m_state.shadowOffset.width() || m_state.shadowOffset.height()); }
436     bool hasBlurredShadow() const { return hasVisibleShadow() && m_state.shadowBlur; }
437
438 #if USE(CAIRO)
439     bool mustUseShadowBlur() const;
440 #endif
441
442     void drawFocusRing(const Vector<FloatRect>&, float width, float offset, const Color&);
443     void drawFocusRing(const Path&, float width, float offset, const Color&);
444 #if PLATFORM(MAC)
445     void drawFocusRing(const Path&, double timeOffset, bool& needsRedraw);
446     void drawFocusRing(const Vector<FloatRect>&, double timeOffset, bool& needsRedraw);
447 #endif
448
449     void setLineCap(LineCap);
450     void setLineDash(const DashArray&, float dashOffset);
451     void setLineJoin(LineJoin);
452     void setMiterLimit(float);
453
454     void setAlpha(float);
455     float alpha() const { return m_state.alpha; }
456
457     WEBCORE_EXPORT void setCompositeOperation(CompositeOperator, BlendMode = BlendModeNormal);
458     CompositeOperator compositeOperation() const { return m_state.compositeOperator; }
459     BlendMode blendModeOperation() const { return m_state.blendMode; }
460
461     void setDrawLuminanceMask(bool);
462     bool drawLuminanceMask() const { return m_state.drawLuminanceMask; }
463
464     // This clip function is used only by <canvas> code. It allows
465     // implementations to handle clipping on the canvas differently since
466     // the discipline is different.
467     void canvasClip(const Path&, WindRule = RULE_EVENODD);
468     void clipOut(const Path&);
469
470     void scale(float s)
471     {
472         scale({ s, s });
473     }
474     WEBCORE_EXPORT void scale(const FloatSize&);
475     void rotate(float angleInRadians);
476     void translate(const FloatSize& size) { translate(size.width(), size.height()); }
477     WEBCORE_EXPORT void translate(float x, float y);
478
479     void setURLForRect(const URL&, const FloatRect&);
480
481     void setDestinationForRect(const String& name, const FloatRect&);
482     void addDestinationAtPoint(const String& name, const FloatPoint&);
483
484     void concatCTM(const AffineTransform&);
485     void setCTM(const AffineTransform&);
486
487     enum IncludeDeviceScale { DefinitelyIncludeDeviceScale, PossiblyIncludeDeviceScale };
488     AffineTransform getCTM(IncludeDeviceScale includeScale = PossiblyIncludeDeviceScale) const;
489
490 #if ENABLE(3D_TRANSFORMS) && USE(TEXTURE_MAPPER)
491     // This is needed when using accelerated-compositing in software mode, like in TextureMapper.
492     void concat3DTransform(const TransformationMatrix&);
493     void set3DTransform(const TransformationMatrix&);
494     TransformationMatrix get3DTransform() const;
495 #endif
496
497     // This function applies the device scale factor to the context, making the context capable of
498     // acting as a base-level context for a HiDPI environment.
499     WEBCORE_EXPORT void applyDeviceScaleFactor(float);
500     void platformApplyDeviceScaleFactor(float);
501     FloatSize scaleFactor() const;
502     FloatSize scaleFactorForDrawing(const FloatRect& destRect, const FloatRect& srcRect) const;
503
504 #if OS(WINDOWS)
505     HDC getWindowsContext(const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
506     void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap); // The passed in HDC should be the one handed back by getWindowsContext.
507     HDC hdc() const;
508 #if PLATFORM(WIN)
509 #if USE(WINGDI)
510     const AffineTransform& affineTransform() const;
511     AffineTransform& affineTransform();
512     void resetAffineTransform();
513     void fillRect(const FloatRect&, const Gradient*);
514     void drawText(const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint&);
515     void drawFrameControl(const IntRect& rect, unsigned type, unsigned state);
516     void drawFocusRect(const IntRect& rect);
517     void paintTextField(const IntRect& rect, unsigned state);
518     void drawBitmap(SharedBitmap*, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator, BlendMode);
519     void drawBitmapPattern(SharedBitmap*, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, CompositeOperator, const FloatRect& destRect, const IntSize& origSourceSize);
520     void drawIcon(HICON icon, const IntRect& dstRect, UINT flags);
521     void drawRoundCorner(bool newClip, RECT clipRect, RECT rectWin, HDC dc, int width, int height);
522 #else
523     GraphicsContext(HDC, bool hasAlpha = false); // FIXME: To be removed.
524
525     // When set to true, child windows should be rendered into this context
526     // rather than allowing them just to render to the screen. Defaults to
527     // false.
528     // FIXME: This is a layering violation. GraphicsContext shouldn't know
529     // what a "window" is. It would be much more appropriate for this flag
530     // to be passed as a parameter alongside the GraphicsContext, but doing
531     // that would require lots of changes in cross-platform code that we
532     // aren't sure we want to make.
533     void setShouldIncludeChildWindows(bool);
534     bool shouldIncludeChildWindows() const;
535
536     class WindowsBitmap {
537         WTF_MAKE_NONCOPYABLE(WindowsBitmap);
538     public:
539         WindowsBitmap(HDC, const IntSize&);
540         ~WindowsBitmap();
541
542         HDC hdc() const { return m_hdc; }
543         UInt8* buffer() const { return m_pixelData.buffer(); }
544         unsigned bufferLength() const { return m_pixelData.bufferLength(); }
545         const IntSize& size() const { return m_pixelData.size(); }
546         unsigned bytesPerRow() const { return m_pixelData.bytesPerRow(); }
547         unsigned short bitsPerPixel() const { return m_pixelData.bitsPerPixel(); }
548         const DIBPixelData& windowsDIB() const { return m_pixelData; }
549
550     private:
551         HDC m_hdc;
552         HBITMAP m_bitmap;
553         DIBPixelData m_pixelData;
554     };
555
556     std::unique_ptr<WindowsBitmap> createWindowsBitmap(const IntSize&);
557     // The bitmap should be non-premultiplied.
558     void drawWindowsBitmap(WindowsBitmap*, const IntPoint&);
559 #endif
560 #if USE(DIRECT2D)
561     GraphicsContext(HDC, ID2D1DCRenderTarget**, RECT, bool hasAlpha = false); // FIXME: To be removed.
562
563     WEBCORE_EXPORT static ID2D1Factory* systemFactory();
564     WEBCORE_EXPORT static ID2D1RenderTarget* defaultRenderTarget();
565
566     WEBCORE_EXPORT void beginDraw();
567     D2D1_COLOR_F colorWithGlobalAlpha(const Color&) const;
568     WEBCORE_EXPORT void endDraw();
569     void flush();
570
571     ID2D1Brush* solidStrokeBrush() const;
572     ID2D1Brush* solidFillBrush() const;
573     ID2D1Brush* patternStrokeBrush() const;
574     ID2D1Brush* patternFillBrush() const;
575     ID2D1StrokeStyle* platformStrokeStyle() const;
576
577     ID2D1SolidColorBrush* brushWithColor(const Color&);
578 #endif
579 #else // PLATFORM(WIN)
580     bool shouldIncludeChildWindows() const { return false; }
581 #endif // PLATFORM(WIN)
582 #endif // OS(WINDOWS)
583
584 #if USE(CAIRO)
585     GraphicsContext(cairo_t*);
586 #endif
587
588     static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle);
589
590     bool supportsInternalLinks() const;
591
592 private:
593     void platformInit(PlatformGraphicsContext*);
594     void platformDestroy();
595
596 #if PLATFORM(WIN) && !USE(WINGDI)
597     void platformInit(HDC, bool hasAlpha = false);
598 #endif
599
600 #if USE(DIRECT2D)
601     void platformInit(HDC, ID2D1RenderTarget**, RECT, bool hasAlpha = false);
602     void drawWithoutShadow(const FloatRect& boundingRect, const std::function<void(ID2D1RenderTarget*)>&);
603     void drawWithShadow(const FloatRect& boundingRect, const std::function<void(ID2D1RenderTarget*)>&);
604 #endif
605
606     void savePlatformState();
607     void restorePlatformState();
608
609     void setPlatformTextDrawingMode(TextDrawingModeFlags);
610
611     void setPlatformStrokeColor(const Color&);
612     void setPlatformStrokeStyle(StrokeStyle);
613     void setPlatformStrokeThickness(float);
614
615     void setPlatformFillColor(const Color&);
616
617     void setPlatformShouldAntialias(bool);
618     void setPlatformShouldSmoothFonts(bool);
619     void setPlatformImageInterpolationQuality(InterpolationQuality);
620
621     void setPlatformShadow(const FloatSize&, float blur, const Color&);
622     void clearPlatformShadow();
623
624     void setPlatformAlpha(float);
625     void setPlatformCompositeOperation(CompositeOperator, BlendMode = BlendModeNormal);
626
627     void beginPlatformTransparencyLayer(float opacity);
628     void endPlatformTransparencyLayer();
629     static bool supportsTransparencyLayers();
630
631     void fillEllipseAsPath(const FloatRect&);
632     void strokeEllipseAsPath(const FloatRect&);
633
634     void platformFillEllipse(const FloatRect&);
635     void platformStrokeEllipse(const FloatRect&);
636
637     void platformFillRoundedRect(const FloatRoundedRect&, const Color&);
638
639     FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatPoint&, float width, bool printing, Color&);
640
641     float dashedLineCornerWidthForStrokeWidth(float) const;
642     float dashedLinePatternWidthForStrokeWidth(float) const;
643     float dashedLinePatternOffsetForPatternAndStrokeWidth(float patternWidth, float strokeWidth) const;
644     Vector<FloatPoint> centerLineAndCutOffCorners(bool isVerticalLine, float cornerWidth, FloatPoint point1, FloatPoint point2) const;
645
646     GraphicsContextPlatformPrivate* m_data { nullptr };
647     DisplayList::Recorder* m_displayListRecorder { nullptr };
648
649     GraphicsContextState m_state;
650     Vector<GraphicsContextState, 1> m_stack;
651
652     const NonPaintingReasons m_nonPaintingReasons { NonPaintingReasons::NoReasons };
653     unsigned m_transparencyCount { 0 };
654 };
655
656 class GraphicsContextStateSaver {
657     WTF_MAKE_FAST_ALLOCATED;
658 public:
659     GraphicsContextStateSaver(GraphicsContext& context, bool saveAndRestore = true)
660     : m_context(context)
661     , m_saveAndRestore(saveAndRestore)
662     {
663         if (m_saveAndRestore)
664             m_context.save();
665     }
666     
667     ~GraphicsContextStateSaver()
668     {
669         if (m_saveAndRestore)
670             m_context.restore();
671     }
672     
673     void save()
674     {
675         ASSERT(!m_saveAndRestore);
676         m_context.save();
677         m_saveAndRestore = true;
678     }
679
680     void restore()
681     {
682         ASSERT(m_saveAndRestore);
683         m_context.restore();
684         m_saveAndRestore = false;
685     }
686     
687     GraphicsContext* context() const { return &m_context; }
688
689 private:
690     GraphicsContext& m_context;
691     bool m_saveAndRestore;
692 };
693
694 class InterpolationQualityMaintainer {
695 public:
696     explicit InterpolationQualityMaintainer(GraphicsContext& graphicsContext, InterpolationQuality interpolationQualityToUse)
697         : m_graphicsContext(graphicsContext)
698         , m_currentInterpolationQuality(graphicsContext.imageInterpolationQuality())
699         , m_interpolationQualityChanged(interpolationQualityToUse != InterpolationDefault && m_currentInterpolationQuality != interpolationQualityToUse)
700     {
701         if (m_interpolationQualityChanged)
702             m_graphicsContext.setImageInterpolationQuality(interpolationQualityToUse);
703     }
704
705     explicit InterpolationQualityMaintainer(GraphicsContext& graphicsContext, std::optional<InterpolationQuality> interpolationQuality)
706         : InterpolationQualityMaintainer(graphicsContext, interpolationQuality ? interpolationQuality.value() : graphicsContext.imageInterpolationQuality())
707     {
708     }
709
710     ~InterpolationQualityMaintainer()
711     {
712         if (m_interpolationQualityChanged)
713             m_graphicsContext.setImageInterpolationQuality(m_currentInterpolationQuality);
714     }
715
716 private:
717     GraphicsContext& m_graphicsContext;
718     InterpolationQuality m_currentInterpolationQuality;
719     bool m_interpolationQualityChanged;
720 };
721
722 } // namespace WebCore