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)
41typedef struct CGContext PlatformGraphicsContext;
42#elif USE(DIRECT2D)
43interface ID2D1DCRenderTarget;
44interface ID2D1RenderTarget;
45interface ID2D1Factory;
46interface ID2D1SolidColorBrush;
47typedef ID2D1RenderTarget PlatformGraphicsContext;
48#elif USE(CAIRO)
49namespace WebCore {
50class PlatformContextCairo;
51}
52typedef WebCore::PlatformContextCairo PlatformGraphicsContext;
53#elif USE(WINGDI)
54typedef struct HDC__ PlatformGraphicsContext;
55#else
56typedef void PlatformGraphicsContext;
57#endif
58
59#if PLATFORM(WIN)
60#include "DIBPixelData.h"
61typedef struct HDC__* HDC;
62#if !USE(CG)
63// UInt8 is defined in CoreFoundation/CFBase.h
64typedef 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
74namespace WebCore {
75
76#if USE(WINGDI)
77class SharedBitmap;
78class Font;
79class GlyphBuffer;
80#endif
81
82class AffineTransform;
83class FloatRoundedRect;
84class Gradient;
85class GraphicsContextImpl;
86class GraphicsContextPlatformPrivate;
87class ImageBuffer;
88class IntRect;
89class RoundedRect;
90class GraphicsContext3D;
91class Path;
92class TextRun;
93class TransformationMatrix;
94
95enum TextDrawingMode {
96 TextModeFill = 1 << 0,
97 TextModeStroke = 1 << 1,
98#if ENABLE(LETTERPRESS)
99 TextModeLetterpress = 1 << 2,
100#endif
101};
102typedef unsigned TextDrawingModeFlags;
103
104enum StrokeStyle {
105 NoStroke,
106 SolidStroke,
107 DottedStroke,
108 DashedStroke,
109 DoubleStroke,
110 WavyStroke,
111};
112
113struct 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
124namespace DisplayList {
125class Recorder;
126}
127
128struct 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
204struct 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
241struct 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
260WTF::TextStream& operator<<(WTF::TextStream&, const GraphicsContextStateChange&);
261
262
263class GraphicsContext {
264 WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
265public:
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, Optional<unsigned> to = WTF::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, Optional<unsigned> to = WTF::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
587private:
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
651class GraphicsContextStateSaver {
652 WTF_MAKE_FAST_ALLOCATED;
653public:
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
684private:
685 GraphicsContext& m_context;
686 bool m_saveAndRestore;
687};
688
689class InterpolationQualityMaintainer {
690public:
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, 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
711private:
712 GraphicsContext& m_graphicsContext;
713 InterpolationQuality m_currentInterpolationQuality;
714 bool m_interpolationQualityChanged;
715};
716
717} // namespace WebCore
718