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