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