1/*
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "FloatPoint.h"
29#include "FloatRect.h"
30#include "FloatRoundedRect.h"
31#include "Font.h"
32#include "GlyphBuffer.h"
33#include "GraphicsContext.h"
34#include "Image.h"
35#include <wtf/RefCounted.h>
36#include <wtf/TypeCasts.h>
37
38#if USE(CG)
39#include "GraphicsContextPlatformPrivateCG.h"
40#endif
41
42namespace WTF {
43class TextStream;
44}
45
46namespace WebCore {
47
48struct ImagePaintingOptions;
49
50namespace DisplayList {
51
52enum class ItemType {
53 Save,
54 Restore,
55 Translate,
56 Rotate,
57 Scale,
58 ConcatenateCTM,
59 SetState,
60 SetLineCap,
61 SetLineDash,
62 SetLineJoin,
63 SetMiterLimit,
64 ClearShadow,
65 Clip,
66 ClipOut,
67 ClipOutToPath,
68 ClipPath,
69 DrawGlyphs,
70 DrawImage,
71 DrawTiledImage,
72 DrawTiledScaledImage,
73#if USE(CG) || USE(CAIRO)
74 DrawNativeImage,
75#endif
76 DrawPattern,
77 DrawRect,
78 DrawLine,
79 DrawLinesForText,
80 DrawDotsForDocumentMarker,
81 DrawEllipse,
82 DrawPath,
83 DrawFocusRingPath,
84 DrawFocusRingRects,
85 FillRect,
86 FillRectWithColor,
87 FillRectWithGradient,
88 FillCompositedRect,
89 FillRoundedRect,
90 FillRectWithRoundedHole,
91 FillPath,
92 FillEllipse,
93 StrokeRect,
94 StrokePath,
95 StrokeEllipse,
96 ClearRect,
97 BeginTransparencyLayer,
98 EndTransparencyLayer,
99#if USE(CG)
100 ApplyStrokePattern, // FIXME: should not be a recorded item.
101 ApplyFillPattern, // FIXME: should not be a recorded item.
102#endif
103 ApplyDeviceScaleFactor,
104};
105
106class Item : public RefCounted<Item> {
107public:
108 Item() = delete;
109
110 Item(ItemType type)
111 : m_type(type)
112 {
113 }
114
115 virtual ~Item() = default;
116
117 ItemType type() const
118 {
119 return m_type;
120 }
121
122 virtual void apply(GraphicsContext&) const = 0;
123
124 static constexpr bool isDisplayListItem = true;
125
126 virtual bool isDrawingItem() const { return false; }
127
128 // A state item is one preserved by Save/Restore.
129 bool isStateItem() const
130 {
131 return isStateItemType(m_type);
132 }
133
134 static bool isStateItemType(ItemType itemType)
135 {
136 switch (itemType) {
137 case ItemType:: Translate:
138 case ItemType:: Rotate:
139 case ItemType:: Scale:
140 case ItemType:: ConcatenateCTM:
141 case ItemType:: SetState:
142 case ItemType:: SetLineCap:
143 case ItemType:: SetLineDash:
144 case ItemType:: SetLineJoin:
145 case ItemType:: SetMiterLimit:
146 case ItemType:: ClearShadow:
147 return true;
148 default:
149 return false;
150 }
151 return false;
152 }
153
154#if !defined(NDEBUG) || !LOG_DISABLED
155 WTF::CString description() const;
156#endif
157 static size_t sizeInBytes(const Item&);
158
159private:
160 ItemType m_type;
161};
162
163class DrawingItem : public Item {
164public:
165 DrawingItem(ItemType type)
166 : Item(type)
167 {
168 }
169
170 void setExtent(const FloatRect& r) { m_extent = r; }
171 const FloatRect& extent() const { return m_extent.value(); }
172
173 bool extentKnown() const { return static_cast<bool>(m_extent); }
174
175 // Return bounds of this drawing operation in local coordinates.
176 // Does not include effets of transform, shadow etc in the state.
177 virtual Optional<FloatRect> localBounds(const GraphicsContext&) const { return WTF::nullopt; }
178
179private:
180 bool isDrawingItem() const override { return true; }
181
182 Optional<FloatRect> m_extent; // In base coordinates, taking shadows and transforms into account.
183};
184
185class Save : public Item {
186public:
187 static Ref<Save> create()
188 {
189 return adoptRef(*new Save);
190 }
191
192 // Index in the display list of the corresponding Restore item. 0 if unmatched.
193 size_t restoreIndex() const { return m_restoreIndex; }
194 void setRestoreIndex(size_t index) { m_restoreIndex = index; }
195
196private:
197 Save()
198 : Item(ItemType::Save)
199 {
200 }
201
202 void apply(GraphicsContext&) const override;
203
204 size_t m_restoreIndex { 0 };
205};
206
207class Restore : public Item {
208public:
209 static Ref<Restore> create()
210 {
211 return adoptRef(*new Restore);
212 }
213
214private:
215 Restore()
216 : Item(ItemType::Restore)
217 {
218 }
219
220 void apply(GraphicsContext&) const override;
221};
222
223class Translate : public Item {
224public:
225 static Ref<Translate> create(float x, float y)
226 {
227 return adoptRef(*new Translate(x, y));
228 }
229
230 float x() const { return m_x; }
231 float y() const { return m_y; }
232
233private:
234 Translate(float x, float y)
235 : Item(ItemType::Translate)
236 , m_x(x)
237 , m_y(y)
238 {
239 }
240
241 void apply(GraphicsContext&) const override;
242
243 float m_x;
244 float m_y;
245};
246
247class Rotate : public Item {
248public:
249 static Ref<Rotate> create(float angleInRadians)
250 {
251 return adoptRef(*new Rotate(angleInRadians));
252 }
253
254 float angle() const { return m_angle; }
255
256private:
257 Rotate(float angle)
258 : Item(ItemType::Rotate)
259 , m_angle(angle)
260 {
261 }
262
263 void apply(GraphicsContext&) const override;
264
265 float m_angle; // In radians.
266};
267
268class Scale : public Item {
269public:
270 static Ref<Scale> create(const FloatSize& size)
271 {
272 return adoptRef(*new Scale(size));
273 }
274
275 const FloatSize& amount() const { return m_size; }
276
277private:
278 Scale(const FloatSize& size)
279 : Item(ItemType::Scale)
280 , m_size(size)
281 {
282 }
283
284 void apply(GraphicsContext&) const override;
285
286 FloatSize m_size;
287};
288
289class ConcatenateCTM : public Item {
290public:
291 static Ref<ConcatenateCTM> create(const AffineTransform& matrix)
292 {
293 return adoptRef(*new ConcatenateCTM(matrix));
294 }
295
296 const AffineTransform& transform() const { return m_transform; }
297
298private:
299 ConcatenateCTM(const AffineTransform&);
300
301 void apply(GraphicsContext&) const override;
302
303 AffineTransform m_transform;
304};
305
306class SetState : public Item {
307public:
308 static Ref<SetState> create(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
309 {
310 return adoptRef(*new SetState(state, flags));
311 }
312
313 const GraphicsContextStateChange& state() const { return m_state; }
314
315 void accumulate(const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
316
317 void accumulate(GraphicsContextState&) const;
318
319 static void applyState(GraphicsContext&, const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
320
321 static void dumpStateChanges(WTF::TextStream&, const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
322private:
323 SetState(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
324 : Item(ItemType::SetState)
325 , m_state(state, flags)
326 {
327 }
328
329 void apply(GraphicsContext&) const override;
330
331 GraphicsContextStateChange m_state;
332};
333
334class SetLineCap : public Item {
335public:
336 static Ref<SetLineCap> create(LineCap lineCap)
337 {
338 return adoptRef(*new SetLineCap(lineCap));
339 }
340
341 LineCap lineCap() const { return m_lineCap; }
342
343private:
344 SetLineCap(LineCap lineCap)
345 : Item(ItemType::SetLineCap)
346 , m_lineCap(lineCap)
347 {
348 }
349
350 void apply(GraphicsContext&) const override;
351
352 LineCap m_lineCap;
353};
354
355class SetLineDash : public Item {
356public:
357 static Ref<SetLineDash> create(const DashArray& dashArray, float dashOffset)
358 {
359 return adoptRef(*new SetLineDash(dashArray, dashOffset));
360 }
361
362 const DashArray& dashArray() const { return m_dashArray; }
363 float dashOffset() const { return m_dashOffset; }
364
365private:
366 SetLineDash(const DashArray& dashArray, float dashOffset)
367 : Item(ItemType::SetLineDash)
368 , m_dashArray(dashArray)
369 , m_dashOffset(dashOffset)
370 {
371 }
372
373 void apply(GraphicsContext&) const override;
374
375 DashArray m_dashArray;
376 float m_dashOffset;
377};
378
379class SetLineJoin : public Item {
380public:
381 static Ref<SetLineJoin> create(LineJoin lineJoin)
382 {
383 return adoptRef(*new SetLineJoin(lineJoin));
384 }
385
386 LineJoin lineJoin() const { return m_lineJoin; }
387
388private:
389 SetLineJoin(LineJoin lineJoin)
390 : Item(ItemType::SetLineJoin)
391 , m_lineJoin(lineJoin)
392 {
393 }
394
395 void apply(GraphicsContext&) const override;
396
397 LineJoin m_lineJoin;
398};
399
400class SetMiterLimit : public Item {
401public:
402 static Ref<SetMiterLimit> create(float limit)
403 {
404 return adoptRef(*new SetMiterLimit(limit));
405 }
406
407 float miterLimit() const { return m_miterLimit; }
408
409private:
410 SetMiterLimit(float miterLimit)
411 : Item(ItemType::SetMiterLimit)
412 , m_miterLimit(miterLimit)
413 {
414 }
415
416 void apply(GraphicsContext&) const override;
417
418 float m_miterLimit;
419};
420
421class ClearShadow : public Item {
422public:
423 static Ref<ClearShadow> create()
424 {
425 return adoptRef(*new ClearShadow);
426 }
427
428private:
429 ClearShadow()
430 : Item(ItemType::ClearShadow)
431 {
432 }
433
434 void apply(GraphicsContext&) const override;
435};
436
437// FIXME: treat as DrawingItem?
438class Clip : public Item {
439public:
440 static Ref<Clip> create(const FloatRect& rect)
441 {
442 return adoptRef(*new Clip(rect));
443 }
444
445 FloatRect rect() const { return m_rect; }
446
447private:
448 Clip(const FloatRect& rect)
449 : Item(ItemType::Clip)
450 , m_rect(rect)
451 {
452 }
453
454 void apply(GraphicsContext&) const override;
455
456 FloatRect m_rect;
457};
458
459class ClipOut : public Item {
460public:
461 static Ref<ClipOut> create(const FloatRect& rect)
462 {
463 return adoptRef(*new ClipOut(rect));
464 }
465
466 FloatRect rect() const { return m_rect; }
467
468private:
469 ClipOut(const FloatRect& rect)
470 : Item(ItemType::ClipOut)
471 , m_rect(rect)
472 {
473 }
474
475 void apply(GraphicsContext&) const override;
476
477 FloatRect m_rect;
478};
479
480class ClipOutToPath : public Item {
481public:
482 static Ref<ClipOutToPath> create(const Path& path)
483 {
484 return adoptRef(*new ClipOutToPath(path));
485 }
486
487 const Path& path() const { return m_path; }
488
489private:
490 ClipOutToPath(const Path& path)
491 : Item(ItemType::ClipOutToPath)
492 , m_path(path)
493 {
494 }
495
496 void apply(GraphicsContext&) const override;
497
498 const Path m_path;
499};
500
501class ClipPath : public Item {
502public:
503 static Ref<ClipPath> create(const Path& path, WindRule windRule)
504 {
505 return adoptRef(*new ClipPath(path, windRule));
506 }
507
508 const Path& path() const { return m_path; }
509 WindRule windRule() const { return m_windRule; }
510
511private:
512 ClipPath(const Path& path, WindRule windRule)
513 : Item(ItemType::ClipPath)
514 , m_path(path)
515 , m_windRule(windRule)
516 {
517 }
518
519 void apply(GraphicsContext&) const override;
520
521 const Path m_path;
522 WindRule m_windRule;
523};
524
525class DrawGlyphs : public DrawingItem {
526public:
527 static Ref<DrawGlyphs> create(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode smoothingMode)
528 {
529 return adoptRef(*new DrawGlyphs(font, glyphs, advances, count, blockLocation, localAnchor, smoothingMode));
530 }
531
532 const FloatPoint& blockLocation() const { return m_blockLocation; }
533 void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; }
534
535 const FloatSize& localAnchor() const { return m_localAnchor; }
536
537 FloatPoint anchorPoint() const { return m_blockLocation + m_localAnchor; }
538
539 const Vector<GlyphBufferGlyph, 128>& glyphs() const { return m_glyphs; }
540
541private:
542 DrawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode);
543
544 void computeBounds();
545
546 void apply(GraphicsContext&) const override;
547
548 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
549
550 GlyphBuffer generateGlyphBuffer() const;
551
552 Ref<Font> m_font;
553 Vector<GlyphBufferGlyph, 128> m_glyphs;
554 Vector<GlyphBufferAdvance, 128> m_advances;
555 FloatRect m_bounds;
556 FloatPoint m_blockLocation;
557 FloatSize m_localAnchor;
558 FontSmoothingMode m_smoothingMode;
559};
560
561class DrawImage : public DrawingItem {
562public:
563 static Ref<DrawImage> create(Image& image, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& imagePaintingOptions)
564 {
565 return adoptRef(*new DrawImage(image, destination, source, imagePaintingOptions));
566 }
567
568 const Image& image() const { return m_image.get(); }
569 FloatRect source() const { return m_source; }
570 FloatRect destination() const { return m_destination; }
571
572private:
573 DrawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions&);
574
575 void apply(GraphicsContext&) const override;
576
577 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
578
579 mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
580 FloatRect m_destination;
581 FloatRect m_source;
582 ImagePaintingOptions m_imagePaintingOptions;
583};
584
585class DrawTiledImage : public DrawingItem {
586public:
587 static Ref<DrawTiledImage> create(Image& image, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& imagePaintingOptions)
588 {
589 return adoptRef(*new DrawTiledImage(image, destination, source, tileSize, spacing, imagePaintingOptions));
590 }
591
592 const Image& image() const { return m_image.get(); }
593 FloatPoint source() const { return m_source; }
594 FloatRect destination() const { return m_destination; }
595
596 FloatSize tileSize() const { return m_tileSize; }
597 FloatSize spacing() const { return m_spacing; }
598
599private:
600 DrawTiledImage(Image&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions&);
601
602 void apply(GraphicsContext&) const override;
603
604 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
605
606 mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
607 FloatRect m_destination;
608 FloatPoint m_source;
609 FloatSize m_tileSize;
610 FloatSize m_spacing;
611 ImagePaintingOptions m_imagePaintingOptions;
612};
613
614class DrawTiledScaledImage : public DrawingItem {
615public:
616 static Ref<DrawTiledScaledImage> create(Image& image, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions& imagePaintingOptions)
617 {
618 return adoptRef(*new DrawTiledScaledImage(image, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions));
619 }
620
621 const Image& image() const { return m_image.get(); }
622 FloatRect source() const { return m_source; }
623 FloatRect destination() const { return m_destination; }
624
625private:
626 DrawTiledScaledImage(Image&, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&);
627
628 void apply(GraphicsContext&) const override;
629
630 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
631
632 mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
633 FloatRect m_destination;
634 FloatRect m_source;
635 FloatSize m_tileScaleFactor;
636 Image::TileRule m_hRule;
637 Image::TileRule m_vRule;
638 ImagePaintingOptions m_imagePaintingOptions;
639};
640
641#if USE(CG) || USE(CAIRO)
642class DrawNativeImage : public DrawingItem {
643public:
644 static Ref<DrawNativeImage> create(const NativeImagePtr& image, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation)
645 {
646 return adoptRef(*new DrawNativeImage(image, imageSize, destRect, srcRect, op, blendMode, orientation));
647 }
648
649 FloatRect source() const { return m_srcRect; }
650 FloatRect destination() const { return m_destination; }
651
652private:
653 DrawNativeImage(const NativeImagePtr&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientation);
654
655 void apply(GraphicsContext&) const override;
656
657 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
658
659#if USE(CG)
660 RetainPtr<CGImageRef> m_image;
661#endif
662 FloatSize m_imageSize;
663 FloatRect m_destination;
664 FloatRect m_srcRect;
665#if USE(CG)
666 CompositeOperator m_op;
667 BlendMode m_blendMode;
668#endif
669 ImageOrientation m_orientation;
670};
671#endif
672
673class DrawPattern : public DrawingItem {
674public:
675 static Ref<DrawPattern> create(Image& image, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
676 {
677 return adoptRef(*new DrawPattern(image, destRect, tileRect, patternTransform, phase, spacing, op, blendMode));
678 }
679
680 const Image& image() const { return m_image.get(); }
681 const AffineTransform& patternTransform() const { return m_patternTransform; }
682 FloatRect tileRect() const { return m_tileRect; }
683 FloatRect destRect() const { return m_destination; }
684 FloatPoint phase() const { return m_phase; }
685 FloatSize spacing() const { return m_spacing; }
686
687private:
688 DrawPattern(Image&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode = BlendMode::Normal);
689
690 void apply(GraphicsContext&) const override;
691
692 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
693
694 mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
695 AffineTransform m_patternTransform;
696 FloatRect m_tileRect;
697 FloatRect m_destination;
698 FloatPoint m_phase;
699 FloatSize m_spacing;
700 CompositeOperator m_op;
701 BlendMode m_blendMode;
702};
703
704// Is DrawingItem because the size of the transparency layer is implicitly the clip bounds.
705class BeginTransparencyLayer : public DrawingItem {
706public:
707 static Ref<BeginTransparencyLayer> create(float opacity)
708 {
709 return adoptRef(*new BeginTransparencyLayer(opacity));
710 }
711
712 float opacity() const { return m_opacity; }
713
714private:
715 BeginTransparencyLayer(float opacity)
716 : DrawingItem(ItemType::BeginTransparencyLayer)
717 , m_opacity(opacity)
718 {
719 }
720
721 void apply(GraphicsContext&) const override;
722
723 float m_opacity;
724};
725
726class EndTransparencyLayer : public DrawingItem {
727public:
728 static Ref<EndTransparencyLayer> create()
729 {
730 return adoptRef(*new EndTransparencyLayer);
731 }
732
733private:
734 EndTransparencyLayer()
735 : DrawingItem(ItemType::EndTransparencyLayer)
736 {
737 }
738
739 void apply(GraphicsContext&) const override;
740};
741
742class DrawRect : public DrawingItem {
743public:
744 static Ref<DrawRect> create(const FloatRect& rect, float borderThickness)
745 {
746 return adoptRef(*new DrawRect(rect, borderThickness));
747 }
748
749 FloatRect rect() const { return m_rect; }
750 float borderThickness() const { return m_borderThickness; }
751
752private:
753 DrawRect(const FloatRect& rect, float borderThickness)
754 : DrawingItem(ItemType::DrawRect)
755 , m_rect(rect)
756 , m_borderThickness(borderThickness)
757 {
758 }
759
760 void apply(GraphicsContext&) const override;
761 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
762
763 FloatRect m_rect;
764 float m_borderThickness;
765};
766
767class DrawLine : public DrawingItem {
768public:
769 static Ref<DrawLine> create(const FloatPoint& point1, const FloatPoint& point2)
770 {
771 return adoptRef(*new DrawLine(point1, point2));
772 }
773
774 FloatPoint point1() const { return m_point1; }
775 FloatPoint point2() const { return m_point2; }
776
777private:
778 DrawLine(const FloatPoint& point1, const FloatPoint& point2)
779 : DrawingItem(ItemType::DrawLine)
780 , m_point1(point1)
781 , m_point2(point2)
782 {
783 }
784
785 void apply(GraphicsContext&) const override;
786 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
787
788 FloatPoint m_point1;
789 FloatPoint m_point2;
790};
791
792class DrawLinesForText : public DrawingItem {
793public:
794 static Ref<DrawLinesForText> create(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines)
795 {
796 return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, thickness, widths, printing, doubleLines));
797 }
798
799 void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; }
800 const FloatPoint& blockLocation() const { return m_blockLocation; }
801 const FloatSize& localAnchor() const { return m_localAnchor; }
802 FloatPoint point() const { return m_blockLocation + m_localAnchor; }
803 float thickness() const { return m_thickness; }
804 const DashArray& widths() const { return m_widths; }
805 bool isPrinting() const { return m_printing; }
806 bool doubleLines() const { return m_doubleLines; }
807
808private:
809 DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines)
810 : DrawingItem(ItemType::DrawLinesForText)
811 , m_blockLocation(blockLocation)
812 , m_localAnchor(localAnchor)
813 , m_widths(widths)
814 , m_thickness(thickness)
815 , m_printing(printing)
816 , m_doubleLines(doubleLines)
817 {
818 }
819
820 void apply(GraphicsContext&) const override;
821
822 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
823
824 FloatPoint m_blockLocation;
825 FloatSize m_localAnchor;
826 DashArray m_widths;
827 float m_thickness;
828 bool m_printing;
829 bool m_doubleLines;
830};
831
832class DrawDotsForDocumentMarker : public DrawingItem {
833public:
834 static Ref<DrawDotsForDocumentMarker> create(const FloatRect& rect, DocumentMarkerLineStyle style)
835 {
836 return adoptRef(*new DrawDotsForDocumentMarker(rect, style));
837 }
838
839 FloatRect rect() const { return m_rect; }
840
841private:
842 DrawDotsForDocumentMarker(const FloatRect& rect, DocumentMarkerLineStyle style)
843 : DrawingItem(ItemType::DrawDotsForDocumentMarker)
844 , m_rect(rect)
845 , m_style(style)
846 {
847 }
848
849 void apply(GraphicsContext&) const override;
850
851 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
852
853 FloatRect m_rect;
854 DocumentMarkerLineStyle m_style;
855};
856
857class DrawEllipse : public DrawingItem {
858public:
859 static Ref<DrawEllipse> create(const FloatRect& rect)
860 {
861 return adoptRef(*new DrawEllipse(rect));
862 }
863
864 FloatRect rect() const { return m_rect; }
865
866private:
867 DrawEllipse(const FloatRect& rect)
868 : DrawingItem(ItemType::DrawEllipse)
869 , m_rect(rect)
870 {
871 }
872
873 void apply(GraphicsContext&) const override;
874 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
875
876 FloatRect m_rect;
877};
878
879class DrawPath : public DrawingItem {
880public:
881 static Ref<DrawPath> create(const Path& path)
882 {
883 return adoptRef(*new DrawPath(path));
884 }
885
886 const Path& path() const { return m_path; }
887
888private:
889 DrawPath(const Path& path)
890 : DrawingItem(ItemType::DrawPath)
891 , m_path(path)
892 {
893 }
894
895 void apply(GraphicsContext&) const override;
896
897 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_path.fastBoundingRect(); }
898
899 const Path m_path;
900};
901
902class DrawFocusRingPath : public DrawingItem {
903public:
904 static Ref<DrawFocusRingPath> create(const Path& path, float width, float offset, const Color& color)
905 {
906 return adoptRef(*new DrawFocusRingPath(path, width, offset, color));
907 }
908
909 const Path& path() const { return m_path; }
910 float width() const { return m_width; }
911 float offset() const { return m_offset; }
912 const Color& color() const { return m_color; }
913
914private:
915 DrawFocusRingPath(const Path& path, float width, float offset, const Color& color)
916 : DrawingItem(ItemType::DrawFocusRingPath)
917 , m_path(path)
918 , m_width(width)
919 , m_offset(offset)
920 , m_color(color)
921 {
922 }
923
924 void apply(GraphicsContext&) const override;
925
926 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
927
928 const Path m_path;
929 float m_width;
930 float m_offset;
931 Color m_color;
932};
933
934class DrawFocusRingRects : public DrawingItem {
935public:
936 static Ref<DrawFocusRingRects> create(const Vector<FloatRect>& rects, float width, float offset, const Color& color)
937 {
938 return adoptRef(*new DrawFocusRingRects(rects, width, offset, color));
939 }
940
941 const Vector<FloatRect> rects() const { return m_rects; }
942 float width() const { return m_width; }
943 float offset() const { return m_offset; }
944 const Color& color() const { return m_color; }
945
946private:
947 DrawFocusRingRects(const Vector<FloatRect>& rects, float width, float offset, const Color& color)
948 : DrawingItem(ItemType::DrawFocusRingRects)
949 , m_rects(rects)
950 , m_width(width)
951 , m_offset(offset)
952 , m_color(color)
953 {
954 }
955
956 void apply(GraphicsContext&) const override;
957
958 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
959
960 Vector<FloatRect> m_rects;
961 float m_width;
962 float m_offset;
963 Color m_color;
964};
965
966class FillRect : public DrawingItem {
967public:
968 static Ref<FillRect> create(const FloatRect& rect)
969 {
970 return adoptRef(*new FillRect(rect));
971 }
972
973 FloatRect rect() const { return m_rect; }
974
975private:
976 FillRect(const FloatRect& rect)
977 : DrawingItem(ItemType::FillRect)
978 , m_rect(rect)
979 {
980 }
981
982 void apply(GraphicsContext&) const override;
983 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
984
985 FloatRect m_rect;
986};
987
988// FIXME: Make these inherit from FillRect proper.
989class FillRectWithColor : public DrawingItem {
990public:
991 static Ref<FillRectWithColor> create(const FloatRect& rect, const Color& color)
992 {
993 return adoptRef(*new FillRectWithColor(rect, color));
994 }
995
996 FloatRect rect() const { return m_rect; }
997 const Color& color() const { return m_color; }
998
999private:
1000 FillRectWithColor(const FloatRect& rect, const Color& color)
1001 : DrawingItem(ItemType::FillRectWithColor)
1002 , m_rect(rect)
1003 , m_color(color)
1004 {
1005 }
1006
1007 void apply(GraphicsContext&) const override;
1008 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
1009
1010 FloatRect m_rect;
1011 Color m_color;
1012};
1013
1014class FillRectWithGradient : public DrawingItem {
1015public:
1016 static Ref<FillRectWithGradient> create(const FloatRect& rect, Gradient& gradient)
1017 {
1018 return adoptRef(*new FillRectWithGradient(rect, gradient));
1019 }
1020
1021 FloatRect rect() const { return m_rect; }
1022
1023private:
1024 FillRectWithGradient(const FloatRect& rect, Gradient& gradient)
1025 : DrawingItem(ItemType::FillRectWithGradient)
1026 , m_rect(rect)
1027 , m_gradient(gradient)
1028 {
1029 }
1030
1031 void apply(GraphicsContext&) const override;
1032 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
1033
1034 FloatRect m_rect;
1035 mutable Ref<Gradient> m_gradient; // FIXME: Make this not mutable
1036};
1037
1038class FillCompositedRect : public DrawingItem {
1039public:
1040 static Ref<FillCompositedRect> create(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode)
1041 {
1042 return adoptRef(*new FillCompositedRect(rect, color, op, blendMode));
1043 }
1044
1045 FloatRect rect() const { return m_rect; }
1046 const Color& color() const { return m_color; }
1047 CompositeOperator compositeOperator() const { return m_op; }
1048 BlendMode blendMode() const { return m_blendMode; }
1049
1050private:
1051 FillCompositedRect(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode)
1052 : DrawingItem(ItemType::FillCompositedRect)
1053 , m_rect(rect)
1054 , m_color(color)
1055 , m_op(op)
1056 , m_blendMode(blendMode)
1057 {
1058 }
1059
1060 void apply(GraphicsContext&) const override;
1061 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
1062
1063 FloatRect m_rect;
1064 Color m_color;
1065 CompositeOperator m_op;
1066 BlendMode m_blendMode;
1067};
1068
1069class FillRoundedRect : public DrawingItem {
1070public:
1071 static Ref<FillRoundedRect> create(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode)
1072 {
1073 return adoptRef(*new FillRoundedRect(rect, color, blendMode));
1074 }
1075
1076 const FloatRoundedRect& roundedRect() const { return m_rect; }
1077 const Color& color() const { return m_color; }
1078 BlendMode blendMode() const { return m_blendMode; }
1079
1080private:
1081 FillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode)
1082 : DrawingItem(ItemType::FillRoundedRect)
1083 , m_rect(rect)
1084 , m_color(color)
1085 , m_blendMode(blendMode)
1086 {
1087 }
1088
1089 void apply(GraphicsContext&) const override;
1090 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect.rect(); }
1091
1092 FloatRoundedRect m_rect;
1093 Color m_color;
1094 BlendMode m_blendMode;
1095};
1096
1097class FillRectWithRoundedHole : public DrawingItem {
1098public:
1099 static Ref<FillRectWithRoundedHole> create(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
1100 {
1101 return adoptRef(*new FillRectWithRoundedHole(rect, roundedHoleRect, color));
1102 }
1103
1104 const FloatRect& rect() const { return m_rect; }
1105 const FloatRoundedRect& roundedHoleRect() const { return m_roundedHoleRect; }
1106 const Color& color() const { return m_color; }
1107
1108private:
1109 FillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
1110 : DrawingItem(ItemType::FillRectWithRoundedHole)
1111 , m_rect(rect)
1112 , m_roundedHoleRect(roundedHoleRect)
1113 , m_color(color)
1114 {
1115 }
1116
1117 void apply(GraphicsContext&) const override;
1118 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
1119
1120 FloatRect m_rect;
1121 FloatRoundedRect m_roundedHoleRect;
1122 Color m_color;
1123};
1124
1125class FillPath : public DrawingItem {
1126public:
1127 static Ref<FillPath> create(const Path& path)
1128 {
1129 return adoptRef(*new FillPath(path));
1130 }
1131
1132 const Path& path() const { return m_path; }
1133
1134private:
1135 FillPath(const Path& path)
1136 : DrawingItem(ItemType::FillPath)
1137 , m_path(path)
1138 {
1139 }
1140
1141 void apply(GraphicsContext&) const override;
1142 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_path.fastBoundingRect(); }
1143
1144 const Path m_path;
1145};
1146
1147class FillEllipse : public DrawingItem {
1148public:
1149 static Ref<FillEllipse> create(const FloatRect& rect)
1150 {
1151 return adoptRef(*new FillEllipse(rect));
1152 }
1153
1154 FloatRect rect() const { return m_rect; }
1155
1156private:
1157 FillEllipse(const FloatRect& rect)
1158 : DrawingItem(ItemType::FillEllipse)
1159 , m_rect(rect)
1160 {
1161 }
1162
1163 void apply(GraphicsContext&) const override;
1164
1165 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
1166
1167 FloatRect m_rect;
1168};
1169
1170class StrokeRect : public DrawingItem {
1171public:
1172 static Ref<StrokeRect> create(const FloatRect& rect, float lineWidth)
1173 {
1174 return adoptRef(*new StrokeRect(rect, lineWidth));
1175 }
1176
1177 FloatRect rect() const { return m_rect; }
1178 float lineWidth() const { return m_lineWidth; }
1179
1180private:
1181 StrokeRect(const FloatRect& rect, float lineWidth)
1182 : DrawingItem(ItemType::StrokeRect)
1183 , m_rect(rect)
1184 , m_lineWidth(lineWidth)
1185 {
1186 }
1187
1188 void apply(GraphicsContext&) const override;
1189 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
1190
1191 FloatRect m_rect;
1192 float m_lineWidth;
1193};
1194
1195class StrokePath : public DrawingItem {
1196public:
1197 static Ref<StrokePath> create(const Path& path)
1198 {
1199 return adoptRef(*new StrokePath(path));
1200 }
1201
1202 const Path& path() const { return m_path; }
1203
1204private:
1205 StrokePath(const Path& path)
1206 : DrawingItem(ItemType::StrokePath)
1207 , m_path(path)
1208 {
1209 }
1210
1211 void apply(GraphicsContext&) const override;
1212 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
1213
1214 const Path m_path;
1215 FloatPoint m_blockLocation;
1216};
1217
1218class StrokeEllipse : public DrawingItem {
1219public:
1220 static Ref<StrokeEllipse> create(const FloatRect& rect)
1221 {
1222 return adoptRef(*new StrokeEllipse(rect));
1223 }
1224
1225 FloatRect rect() const { return m_rect; }
1226
1227private:
1228 StrokeEllipse(const FloatRect& rect)
1229 : DrawingItem(ItemType::StrokeEllipse)
1230 , m_rect(rect)
1231 {
1232 }
1233
1234 void apply(GraphicsContext&) const override;
1235 Optional<FloatRect> localBounds(const GraphicsContext&) const override;
1236
1237 FloatRect m_rect;
1238};
1239
1240class ClearRect : public DrawingItem {
1241public:
1242 static Ref<ClearRect> create(const FloatRect& rect)
1243 {
1244 return adoptRef(*new ClearRect(rect));
1245 }
1246
1247 FloatRect rect() const { return m_rect; }
1248
1249private:
1250 ClearRect(const FloatRect& rect)
1251 : DrawingItem(ItemType::ClearRect)
1252 , m_rect(rect)
1253 {
1254 }
1255
1256 void apply(GraphicsContext&) const override;
1257 Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
1258
1259 FloatRect m_rect;
1260};
1261
1262#if USE(CG)
1263class ApplyStrokePattern : public Item {
1264public:
1265 static Ref<ApplyStrokePattern> create()
1266 {
1267 return adoptRef(*new ApplyStrokePattern);
1268 }
1269
1270private:
1271 ApplyStrokePattern()
1272 : Item(ItemType::ApplyStrokePattern)
1273 {
1274 }
1275
1276 void apply(GraphicsContext&) const override;
1277};
1278
1279class ApplyFillPattern : public Item {
1280public:
1281 static Ref<ApplyFillPattern> create()
1282 {
1283 return adoptRef(*new ApplyFillPattern);
1284 }
1285
1286private:
1287 ApplyFillPattern()
1288 : Item(ItemType::ApplyFillPattern)
1289 {
1290 }
1291
1292 void apply(GraphicsContext&) const override;
1293};
1294#endif
1295
1296class ApplyDeviceScaleFactor : public Item {
1297public:
1298 static Ref<ApplyDeviceScaleFactor> create(float scaleFactor)
1299 {
1300 return adoptRef(*new ApplyDeviceScaleFactor(scaleFactor));
1301 }
1302
1303 float scaleFactor() const { return m_scaleFactor; }
1304
1305private:
1306 ApplyDeviceScaleFactor(float scaleFactor)
1307 : Item(ItemType::ApplyDeviceScaleFactor)
1308 , m_scaleFactor(scaleFactor)
1309 {
1310 }
1311
1312 void apply(GraphicsContext&) const override;
1313
1314 float m_scaleFactor;
1315};
1316
1317WTF::TextStream& operator<<(WTF::TextStream&, const Item&);
1318
1319} // namespace DisplayList
1320} // namespace WebCore
1321
1322
1323#define SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_DRAWINGITEM(ToValueTypeName, predicate) \
1324SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DisplayList::ToValueTypeName) \
1325 static bool isType(const WebCore::DisplayList::Item& object) { return object.predicate; } \
1326SPECIALIZE_TYPE_TRAITS_END()
1327
1328SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_DRAWINGITEM(DrawingItem, isDrawingItem())
1329
1330#define SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ToValueTypeName) \
1331SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DisplayList::ToValueTypeName) \
1332 static bool isType(const WebCore::DisplayList::Item& item) { return item.type() == WebCore::DisplayList::ItemType::ToValueTypeName; } \
1333SPECIALIZE_TYPE_TRAITS_END()
1334
1335SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Save)
1336SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Restore)
1337SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Translate)
1338SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Rotate)
1339SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Scale)
1340SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ConcatenateCTM)
1341SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetState)
1342SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineCap)
1343SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineDash)
1344SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineJoin)
1345SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetMiterLimit)
1346SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Clip)
1347SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipOut)
1348SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipOutToPath)
1349SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipPath)
1350SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawGlyphs)
1351SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawImage)
1352SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawTiledImage)
1353SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawTiledScaledImage)
1354#if USE(CG) || USE(CAIRO)
1355SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawNativeImage)
1356#endif
1357SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawPattern)
1358SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawRect)
1359SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLine)
1360SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLinesForText)
1361SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawDotsForDocumentMarker)
1362SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawEllipse)
1363SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawPath)
1364SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawFocusRingPath)
1365SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawFocusRingRects)
1366SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRect)
1367SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithColor)
1368SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithGradient)
1369SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillCompositedRect)
1370SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRoundedRect)
1371SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithRoundedHole)
1372SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillPath)
1373SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillEllipse)
1374SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeRect)
1375SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokePath)
1376SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeEllipse)
1377SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClearRect)
1378SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(BeginTransparencyLayer)
1379SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(EndTransparencyLayer)
1380#if USE(CG)
1381SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyStrokePattern)
1382SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyFillPattern)
1383#endif
1384SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyDeviceScaleFactor)
1385SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClearShadow)
1386
1387