Fix typo in ConcatenateCTM display list item serialization
[WebKit-https.git] / Source / WebCore / platform / graphics / displaylists / DisplayListItems.cpp
1 /*
2  * Copyright (C) 2015-2022 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 #include "config.h"
27 #include "DisplayListItems.h"
28
29 #include "DisplayListReplayer.h"
30 #include "Filter.h"
31 #include "FontCascade.h"
32 #include "ImageBuffer.h"
33 #include "MediaPlayer.h"
34 #include "SharedBuffer.h"
35 #include <wtf/text/TextStream.h>
36
37 #if USE(CG)
38 #include "GraphicsContextPlatformPrivateCG.h"
39 #endif
40
41 namespace WebCore {
42 namespace DisplayList {
43
44 // Should match RenderTheme::platformFocusRingWidth()
45 static const float platformFocusRingWidth = 3;
46
47 void Save::apply(GraphicsContext& context) const
48 {
49     context.save();
50 }
51
52 void Restore::apply(GraphicsContext& context) const
53 {
54     context.restore();
55 }
56
57 void Translate::apply(GraphicsContext& context) const
58 {
59     context.translate(m_x, m_y);
60 }
61
62 void Rotate::apply(GraphicsContext& context) const
63 {
64     context.rotate(m_angle);
65 }
66
67 void Scale::apply(GraphicsContext& context) const
68 {
69     context.scale(m_size);
70 }
71
72 void SetCTM::apply(GraphicsContext& context) const
73 {
74     context.setCTM(m_transform);
75 }
76
77 void ConcatenateCTM::apply(GraphicsContext& context) const
78 {
79     context.concatCTM(m_transform);
80 }
81
82 void SetInlineFillColor::apply(GraphicsContext& context) const
83 {
84     context.setFillColor(color());
85 }
86
87 void SetInlineStrokeColor::apply(GraphicsContext& context) const
88 {
89     context.setStrokeColor(color());
90 }
91
92 void SetStrokeThickness::apply(GraphicsContext& context) const
93 {
94     context.setStrokeThickness(m_thickness);
95 }
96
97 SetState::SetState(const GraphicsContextState& state)
98     : m_state(state)
99 {
100 }
101
102 void SetState::apply(GraphicsContext& context)
103 {
104     context.updateState(m_state);
105 }
106
107 void SetLineCap::apply(GraphicsContext& context) const
108 {
109     context.setLineCap(m_lineCap);
110 }
111
112 void SetLineDash::apply(GraphicsContext& context) const
113 {
114     context.setLineDash(m_dashArray, m_dashOffset);
115 }
116
117 void SetLineJoin::apply(GraphicsContext& context) const
118 {
119     context.setLineJoin(m_lineJoin);
120 }
121
122 void SetMiterLimit::apply(GraphicsContext& context) const
123 {
124     context.setMiterLimit(m_miterLimit);
125 }
126
127 void ClearShadow::apply(GraphicsContext& context) const
128 {
129     context.clearShadow();
130 }
131
132 void Clip::apply(GraphicsContext& context) const
133 {
134     context.clip(m_rect);
135 }
136
137 void ClipOut::apply(GraphicsContext& context) const
138 {
139     context.clipOut(m_rect);
140 }
141
142 NO_RETURN_DUE_TO_ASSERT void ClipToImageBuffer::apply(GraphicsContext&) const
143 {
144     ASSERT_NOT_REACHED();
145 }
146
147 void ClipToImageBuffer::apply(GraphicsContext& context, WebCore::ImageBuffer& imageBuffer) const
148 {
149     context.clipToImageBuffer(imageBuffer, m_destinationRect);
150 }
151
152 void ClipOutToPath::apply(GraphicsContext& context) const
153 {
154     context.clipOut(m_path);
155 }
156
157 void ClipPath::apply(GraphicsContext& context) const
158 {
159     context.clipPath(m_path, m_windRule);
160 }
161
162 DrawFilteredImageBuffer::DrawFilteredImageBuffer(std::optional<RenderingResourceIdentifier> sourceImageIdentifier, const FloatRect& sourceImageRect, Filter& filter)
163     : m_sourceImageIdentifier(sourceImageIdentifier)
164     , m_sourceImageRect(sourceImageRect)
165     , m_filter(filter)
166 {
167 }
168
169 NO_RETURN_DUE_TO_ASSERT void DrawFilteredImageBuffer::apply(GraphicsContext&) const
170 {
171     ASSERT_NOT_REACHED();
172 }
173
174 void DrawFilteredImageBuffer::apply(GraphicsContext& context, ImageBuffer* sourceImage, FilterResults& results)
175 {
176     context.drawFilteredImageBuffer(sourceImage, m_sourceImageRect, m_filter, results);
177 }
178
179 DrawGlyphs::DrawGlyphs(RenderingResourceIdentifier fontIdentifier, Vector<GlyphBufferGlyph, 128>&& glyphs, Vector<GlyphBufferAdvance, 128>&& advances, const FloatRect& bounds, const FloatPoint& localAnchor, FontSmoothingMode smoothingMode)
180     : m_fontIdentifier(fontIdentifier)
181     , m_glyphs(WTFMove(glyphs))
182     , m_advances(WTFMove(advances))
183     , m_bounds(bounds)
184     , m_localAnchor(localAnchor)
185     , m_smoothingMode(smoothingMode)
186 {
187 }
188
189 DrawGlyphs::DrawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint& localAnchor, FontSmoothingMode smoothingMode)
190     : m_fontIdentifier(font.renderingResourceIdentifier())
191     , m_localAnchor(localAnchor)
192     , m_smoothingMode(smoothingMode)
193 {
194     m_glyphs.reserveInitialCapacity(count);
195     m_advances.reserveInitialCapacity(count);
196     for (unsigned i = 0; i < count; ++i) {
197         m_glyphs.uncheckedAppend(glyphs[i]);
198         m_advances.uncheckedAppend(advances[i]);
199     }
200     computeBounds(font);
201 }
202
203 void DrawGlyphs::apply(GraphicsContext& context, const Font& font) const
204 {
205     context.drawGlyphs(font, m_glyphs.data(), m_advances.data(), m_glyphs.size(), anchorPoint(), m_smoothingMode);
206 }
207
208 void DrawGlyphs::computeBounds(const Font& font)
209 {
210     // FIXME: This code doesn't actually take the extents of the glyphs into consideration. It assumes that
211     // the glyph lies entirely within its [(ascent + descent), advance] rect.
212     float ascent = font.fontMetrics().floatAscent();
213     float descent = font.fontMetrics().floatDescent();
214     FloatPoint current = localAnchor();
215     size_t numGlyphs = m_glyphs.size();
216     for (size_t i = 0; i < numGlyphs; ++i) {
217         GlyphBufferAdvance advance = m_advances[i];
218         FloatRect glyphRect = FloatRect(current.x(), current.y() - ascent, width(advance), ascent + descent);
219         m_bounds.unite(glyphRect);
220
221         current.move(width(advance), height(advance));
222     }
223 }
224
225 NO_RETURN_DUE_TO_ASSERT void DrawImageBuffer::apply(GraphicsContext&) const
226 {
227     ASSERT_NOT_REACHED();
228 }
229
230 void DrawImageBuffer::apply(GraphicsContext& context, WebCore::ImageBuffer& imageBuffer) const
231 {
232     context.drawImageBuffer(imageBuffer, m_destinationRect, m_srcRect, m_options);
233 }
234
235 NO_RETURN_DUE_TO_ASSERT void DrawNativeImage::apply(GraphicsContext&) const
236 {
237     ASSERT_NOT_REACHED();
238 }
239
240 void DrawNativeImage::apply(GraphicsContext& context, NativeImage& image) const
241 {
242     context.drawNativeImage(image, m_imageSize, m_destinationRect, m_srcRect, m_options);
243 }
244
245 void DrawSystemImage::apply(GraphicsContext& context) const
246 {
247     context.drawSystemImage(m_systemImage, m_destinationRect);
248 }
249
250 DrawPattern::DrawPattern(RenderingResourceIdentifier imageIdentifier, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
251     : m_imageIdentifier(imageIdentifier)
252     , m_destination(destRect)
253     , m_tileRect(tileRect)
254     , m_patternTransform(patternTransform)
255     , m_phase(phase)
256     , m_spacing(spacing)
257     , m_options(options)
258 {
259 }
260
261 NO_RETURN_DUE_TO_ASSERT void DrawPattern::apply(GraphicsContext&) const
262 {
263     ASSERT_NOT_REACHED();
264 }
265
266 void DrawPattern::apply(GraphicsContext& context, SourceImage& sourceImage) const
267 {
268     if (auto image = sourceImage.nativeImageIfExists()) {
269         context.drawPattern(*image, m_destination, m_tileRect, m_patternTransform, m_phase, m_spacing, m_options);
270         return;
271     }
272
273     if (auto imageBuffer = sourceImage.imageBufferIfExists()) {
274         context.drawPattern(*imageBuffer, m_destination, m_tileRect, m_patternTransform, m_phase, m_spacing, m_options);
275         return;
276     }
277
278     ASSERT_NOT_REACHED();
279 }
280
281 void DrawRect::apply(GraphicsContext& context) const
282 {
283     context.drawRect(m_rect, m_borderThickness);
284 }
285
286 std::optional<FloatRect> DrawLine::localBounds(const GraphicsContext&) const
287 {
288     FloatRect bounds;
289     bounds.fitToPoints(m_point1, m_point2);
290     return bounds;
291 }
292
293 void DrawLine::apply(GraphicsContext& context) const
294 {
295     context.drawLine(m_point1, m_point2);
296 }
297
298 DrawLinesForText::DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines, StrokeStyle style)
299     : m_blockLocation(blockLocation)
300     , m_localAnchor(localAnchor)
301     , m_widths(widths)
302     , m_thickness(thickness)
303     , m_printing(printing)
304     , m_doubleLines(doubleLines)
305     , m_style(style)
306 {
307 }
308
309 void DrawLinesForText::apply(GraphicsContext& context) const
310 {
311     context.drawLinesForText(point(), m_thickness, m_widths, m_printing, m_doubleLines, m_style);
312 }
313
314 std::optional<FloatRect> DrawLinesForText::localBounds(const GraphicsContext&) const
315 {
316     // This function needs to return a value equal to or enclosing what GraphicsContext::computeLineBoundsAndAntialiasingModeForText() returns.
317
318     if (!m_widths.size())
319         return FloatRect();
320
321     FloatRect result(point(), FloatSize(m_widths.last(), m_thickness));
322     result.inflate(1); // Account for pixel snapping. FIXME: This isn't perfect, as it doesn't take the CTM into account.
323     return result;
324 }
325
326 void DrawDotsForDocumentMarker::apply(GraphicsContext& context) const
327 {
328     context.drawDotsForDocumentMarker(m_rect, {
329         static_cast<DocumentMarkerLineStyle::Mode>(m_styleMode),
330         m_styleShouldUseDarkAppearance,
331     });
332 }
333
334 std::optional<FloatRect> DrawDotsForDocumentMarker::localBounds(const GraphicsContext&) const
335 {
336     return m_rect;
337 }
338
339 void DrawEllipse::apply(GraphicsContext& context) const
340 {
341     context.drawEllipse(m_rect);
342 }
343
344 void DrawPath::apply(GraphicsContext& context) const
345 {
346     context.drawPath(m_path);
347 }
348
349 void DrawFocusRingPath::apply(GraphicsContext& context) const
350 {
351     context.drawFocusRing(m_path, m_width, m_offset, m_color);
352 }
353
354 std::optional<FloatRect> DrawFocusRingPath::localBounds(const GraphicsContext&) const
355 {
356     FloatRect result = m_path.fastBoundingRect();
357     result.inflate(platformFocusRingWidth);
358     return result;
359 }
360
361 DrawFocusRingRects::DrawFocusRingRects(const Vector<FloatRect>& rects, float width, float offset, const Color& color)
362     : m_rects(rects)
363     , m_width(width)
364     , m_offset(offset)
365     , m_color(color)
366 {
367 }
368
369 void DrawFocusRingRects::apply(GraphicsContext& context) const
370 {
371     context.drawFocusRing(m_rects, m_width, m_offset, m_color);
372 }
373
374 std::optional<FloatRect> DrawFocusRingRects::localBounds(const GraphicsContext&) const
375 {
376     FloatRect result;
377     for (auto& rect : m_rects)
378         result.unite(rect);
379     result.inflate(platformFocusRingWidth);
380     return result;
381 }
382
383 void FillRect::apply(GraphicsContext& context) const
384 {
385     context.fillRect(m_rect);
386 }
387
388 void FillRectWithColor::apply(GraphicsContext& context) const
389 {
390     context.fillRect(m_rect, m_color);
391 }
392
393 FillRectWithGradient::FillRectWithGradient(const FloatRect& rect, Gradient& gradient)
394     : m_rect(rect)
395     , m_gradient(gradient)
396 {
397 }
398
399 void FillRectWithGradient::apply(GraphicsContext& context) const
400 {
401     context.fillRect(m_rect, m_gradient.get());
402 }
403
404 void FillCompositedRect::apply(GraphicsContext& context) const
405 {
406     context.fillRect(m_rect, m_color, m_op, m_blendMode);
407 }
408
409 void FillRoundedRect::apply(GraphicsContext& context) const
410 {
411     context.fillRoundedRect(m_rect, m_color, m_blendMode);
412 }
413
414 void FillRectWithRoundedHole::apply(GraphicsContext& context) const
415 {
416     context.fillRectWithRoundedHole(m_rect, m_roundedHoleRect, m_color);
417 }
418
419 #if ENABLE(INLINE_PATH_DATA)
420
421 void FillLine::apply(GraphicsContext& context) const
422 {
423     context.fillPath(path());
424 }
425
426 void FillArc::apply(GraphicsContext& context) const
427 {
428     context.fillPath(path());
429 }
430
431 void FillQuadCurve::apply(GraphicsContext& context) const
432 {
433     context.fillPath(path());
434 }
435
436 void FillBezierCurve::apply(GraphicsContext& context) const
437 {
438     context.fillPath(path());
439 }
440
441 #endif // ENABLE(INLINE_PATH_DATA)
442
443 void FillPath::apply(GraphicsContext& context) const
444 {
445     context.fillPath(m_path);
446 }
447
448 void FillEllipse::apply(GraphicsContext& context) const
449 {
450     context.fillEllipse(m_rect);
451 }
452
453 #if ENABLE(VIDEO)
454 PaintFrameForMedia::PaintFrameForMedia(MediaPlayer& player, const FloatRect& destination)
455     : m_identifier(player.identifier())
456     , m_destination(destination)
457 {
458 }
459
460 NO_RETURN_DUE_TO_ASSERT void PaintFrameForMedia::apply(GraphicsContext&) const
461 {
462     // Should be handled by the delegate.
463     ASSERT_NOT_REACHED();
464 }
465
466 #endif
467
468 std::optional<FloatRect> StrokeRect::localBounds(const GraphicsContext&) const
469 {
470     FloatRect bounds = m_rect;
471     bounds.expand(m_lineWidth, m_lineWidth);
472     return bounds;
473 }
474
475 void StrokeRect::apply(GraphicsContext& context) const
476 {
477     context.strokeRect(m_rect, m_lineWidth);
478 }
479
480 std::optional<FloatRect> StrokePath::localBounds(const GraphicsContext& context) const
481 {
482     // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
483     float strokeThickness = context.strokeThickness();
484
485     FloatRect bounds = m_path.fastBoundingRect();
486     bounds.expand(strokeThickness, strokeThickness);
487     return bounds;
488 }
489
490 void StrokePath::apply(GraphicsContext& context) const
491 {
492     context.strokePath(m_path);
493 }
494
495 std::optional<FloatRect> StrokeEllipse::localBounds(const GraphicsContext& context) const
496 {
497     float strokeThickness = context.strokeThickness();
498
499     FloatRect bounds = m_rect;
500     bounds.expand(strokeThickness, strokeThickness);
501     return bounds;
502 }
503
504 void StrokeEllipse::apply(GraphicsContext& context) const
505 {
506     context.strokeEllipse(m_rect);
507 }
508
509 std::optional<FloatRect> StrokeLine::localBounds(const GraphicsContext& context) const
510 {
511     float strokeThickness = context.strokeThickness();
512
513     FloatRect bounds;
514     bounds.fitToPoints(start(), end());
515     bounds.expand(strokeThickness, strokeThickness);
516     return bounds;
517 }
518
519 void StrokeLine::apply(GraphicsContext& context) const
520 {
521 #if ENABLE(INLINE_PATH_DATA)
522     auto path = Path::from(InlinePathData { LineData { start(), end() } });
523 #else
524     Path path;
525     path.moveTo(start());
526     path.addLineTo(end());
527 #endif
528     context.strokePath(path);
529 }
530
531 #if ENABLE(INLINE_PATH_DATA)
532
533 std::optional<FloatRect> StrokeArc::localBounds(const GraphicsContext& context) const
534 {
535     // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
536     float strokeThickness = context.strokeThickness();
537
538     auto bounds = path().fastBoundingRect();
539     bounds.expand(strokeThickness, strokeThickness);
540     return bounds;
541 }
542
543 void StrokeArc::apply(GraphicsContext& context) const
544 {
545     context.strokePath(path());
546 }
547
548 std::optional<FloatRect> StrokeQuadCurve::localBounds(const GraphicsContext& context) const
549 {
550     // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
551     float strokeThickness = context.strokeThickness();
552
553     auto bounds = path().fastBoundingRect();
554     bounds.expand(strokeThickness, strokeThickness);
555     return bounds;
556 }
557
558 void StrokeQuadCurve::apply(GraphicsContext& context) const
559 {
560     context.strokePath(path());
561 }
562
563 std::optional<FloatRect> StrokeBezierCurve::localBounds(const GraphicsContext& context) const
564 {
565     // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
566     float strokeThickness = context.strokeThickness();
567
568     auto bounds = path().fastBoundingRect();
569     bounds.expand(strokeThickness, strokeThickness);
570     return bounds;
571 }
572
573 void StrokeBezierCurve::apply(GraphicsContext& context) const
574 {
575     context.strokePath(path());
576 }
577
578 #endif // ENABLE(INLINE_PATH_DATA)
579
580 void ClearRect::apply(GraphicsContext& context) const
581 {
582     context.clearRect(m_rect);
583 }
584
585 void BeginTransparencyLayer::apply(GraphicsContext& context) const
586 {
587     context.beginTransparencyLayer(m_opacity);
588 }
589
590 void EndTransparencyLayer::apply(GraphicsContext& context) const
591 {
592     if (context.isInTransparencyLayer())
593         context.endTransparencyLayer();
594 }
595
596 #if USE(CG)
597
598 void ApplyStrokePattern::apply(GraphicsContext& context) const
599 {
600     context.applyStrokePattern();
601 }
602
603 void ApplyFillPattern::apply(GraphicsContext& context) const
604 {
605     context.applyFillPattern();
606 }
607 #endif
608
609 void ApplyDeviceScaleFactor::apply(GraphicsContext& context) const
610 {
611     context.applyDeviceScaleFactor(m_scaleFactor);
612 }
613
614 #if !LOG_DISABLED
615 static TextStream& operator<<(TextStream& ts, ItemType type)
616 {
617     switch (type) {
618     case ItemType::Save: ts << "save"; break;
619     case ItemType::Restore: ts << "restore"; break;
620     case ItemType::Translate: ts << "translate"; break;
621     case ItemType::Rotate: ts << "rotate"; break;
622     case ItemType::Scale: ts << "scale"; break;
623     case ItemType::SetCTM: ts << "set-ctm"; break;
624     case ItemType::ConcatenateCTM: ts << "concatenate-ctm"; break;
625     case ItemType::SetInlineFillColor: ts << "set-inline-fill-color"; break;
626     case ItemType::SetInlineStrokeColor: ts << "set-inline-stroke-color"; break;
627     case ItemType::SetStrokeThickness: ts << "set-stroke-thickness"; break;
628     case ItemType::SetState: ts << "set-state"; break;
629     case ItemType::SetLineCap: ts << "set-line-cap"; break;
630     case ItemType::SetLineDash: ts << "set-line-dash"; break;
631     case ItemType::SetLineJoin: ts << "set-line-join"; break;
632     case ItemType::SetMiterLimit: ts << "set-miter-limit"; break;
633     case ItemType::Clip: ts << "clip"; break;
634     case ItemType::ClipOut: ts << "clip-out"; break;
635     case ItemType::ClipToImageBuffer: ts << "clip-to-image-buffer"; break;
636     case ItemType::ClipOutToPath: ts << "clip-out-to-path"; break;
637     case ItemType::ClipPath: ts << "clip-path"; break;
638     case ItemType::DrawFilteredImageBuffer: ts << "draw-filtered-image-buffer"; break;
639     case ItemType::DrawGlyphs: ts << "draw-glyphs"; break;
640     case ItemType::DrawImageBuffer: ts << "draw-image-buffer"; break;
641     case ItemType::DrawNativeImage: ts << "draw-native-image"; break;
642     case ItemType::DrawSystemImage: ts << "draw-system-image"; break;
643     case ItemType::DrawPattern: ts << "draw-pattern"; break;
644     case ItemType::DrawRect: ts << "draw-rect"; break;
645     case ItemType::DrawLine: ts << "draw-line"; break;
646     case ItemType::DrawLinesForText: ts << "draw-lines-for-text"; break;
647     case ItemType::DrawDotsForDocumentMarker: ts << "draw-dots-for-document-marker"; break;
648     case ItemType::DrawEllipse: ts << "draw-ellipse"; break;
649     case ItemType::DrawPath: ts << "draw-path"; break;
650     case ItemType::DrawFocusRingPath: ts << "draw-focus-ring-path"; break;
651     case ItemType::DrawFocusRingRects: ts << "draw-focus-ring-rects"; break;
652     case ItemType::FillRect: ts << "fill-rect"; break;
653     case ItemType::FillRectWithColor: ts << "fill-rect-with-color"; break;
654     case ItemType::FillRectWithGradient: ts << "fill-rect-with-gradient"; break;
655     case ItemType::FillCompositedRect: ts << "fill-composited-rect"; break;
656     case ItemType::FillRoundedRect: ts << "fill-rounded-rect"; break;
657     case ItemType::FillRectWithRoundedHole: ts << "fill-rect-with-rounded-hole"; break;
658 #if ENABLE(INLINE_PATH_DATA)
659     case ItemType::FillLine: ts << "fill-line"; break;
660     case ItemType::FillArc: ts << "fill-arc"; break;
661     case ItemType::FillQuadCurve: ts << "fill-quad-curve"; break;
662     case ItemType::FillBezierCurve: ts << "fill-bezier-curve"; break;
663 #endif
664     case ItemType::FillPath: ts << "fill-path"; break;
665     case ItemType::FillEllipse: ts << "fill-ellipse"; break;
666 #if ENABLE(VIDEO)
667     case ItemType::PaintFrameForMedia: ts << "paint-frame-for-media"; break;
668 #endif
669     case ItemType::StrokeRect: ts << "stroke-rect"; break;
670     case ItemType::StrokeLine: ts << "stroke-line"; break;
671 #if ENABLE(INLINE_PATH_DATA)
672     case ItemType::StrokeArc: ts << "stroke-arc"; break;
673     case ItemType::StrokeQuadCurve: ts << "stroke-quad-curve"; break;
674     case ItemType::StrokeBezierCurve: ts << "stroke-bezier-curve"; break;
675 #endif
676     case ItemType::StrokePath: ts << "stroke-path"; break;
677     case ItemType::StrokeEllipse: ts << "stroke-ellipse"; break;
678     case ItemType::ClearRect: ts << "clear-rect"; break;
679     case ItemType::BeginTransparencyLayer: ts << "begin-transparency-layer"; break;
680     case ItemType::EndTransparencyLayer: ts << "end-transparency-layer"; break;
681 #if USE(CG)
682     case ItemType::ApplyStrokePattern: ts << "apply-stroke-pattern"; break;
683     case ItemType::ApplyFillPattern: ts << "apply-fill-pattern"; break;
684 #endif
685     case ItemType::ApplyDeviceScaleFactor: ts << "apply-device-scale-factor"; break;
686     case ItemType::ClearShadow: ts << "clear-shadow"; break;
687     }
688     return ts;
689 }
690
691 void dumpItem(TextStream& ts, const Translate& item, OptionSet<AsTextFlag>)
692 {
693     ts.dumpProperty("x", item.x());
694     ts.dumpProperty("y", item.y());
695 }
696
697 void dumpItem(TextStream& ts, const Rotate& item, OptionSet<AsTextFlag>)
698 {
699     ts.dumpProperty("angle", item.angle());
700 }
701
702 void dumpItem(TextStream& ts, const Scale& item, OptionSet<AsTextFlag>)
703 {
704     ts.dumpProperty("size", item.amount());
705 }
706
707 void dumpItem(TextStream& ts, const SetCTM& item, OptionSet<AsTextFlag>)
708 {
709     ts.dumpProperty("set-ctm", item.transform());
710 }
711
712 void dumpItem(TextStream& ts, const ConcatenateCTM& item, OptionSet<AsTextFlag>)
713 {
714     ts.dumpProperty("ctm", item.transform());
715 }
716
717 void dumpItem(TextStream& ts, const SetInlineFillColor& item, OptionSet<AsTextFlag>)
718 {
719     ts.dumpProperty("color", item.color());
720 }
721
722 void dumpItem(TextStream& ts, const SetInlineStrokeColor& item, OptionSet<AsTextFlag>)
723 {
724     ts.dumpProperty("color", item.color());
725 }
726
727 void dumpItem(TextStream& ts, const SetStrokeThickness& item, OptionSet<AsTextFlag>)
728 {
729     ts.dumpProperty("thickness", item.thickness());
730 }
731
732 void dumpItem(TextStream& ts, const SetState& item, OptionSet<AsTextFlag>)
733 {
734     ts << item.state();
735 }
736
737 void dumpItem(TextStream& ts, const SetLineCap& item, OptionSet<AsTextFlag>)
738 {
739     ts.dumpProperty("line-cap", item.lineCap());
740 }
741
742 void dumpItem(TextStream& ts, const SetLineDash& item, OptionSet<AsTextFlag>)
743 {
744     ts.dumpProperty("dash-array", item.dashArray());
745     ts.dumpProperty("dash-offset", item.dashOffset());
746 }
747
748 void dumpItem(TextStream& ts, const SetLineJoin& item, OptionSet<AsTextFlag>)
749 {
750     ts.dumpProperty("line-join", item.lineJoin());
751 }
752
753 void dumpItem(TextStream& ts, const SetMiterLimit& item, OptionSet<AsTextFlag>)
754 {
755     ts.dumpProperty("mitre-limit", item.miterLimit());
756 }
757
758 void dumpItem(TextStream& ts, const Clip& item, OptionSet<AsTextFlag>)
759 {
760     ts.dumpProperty("rect", item.rect());
761 }
762
763 void dumpItem(TextStream& ts, const ClipOut& item, OptionSet<AsTextFlag>)
764 {
765     ts.dumpProperty("rect", item.rect());
766 }
767
768 void dumpItem(TextStream& ts, const ClipToImageBuffer& item, OptionSet<AsTextFlag> flags)
769 {
770     if (!flags.contains(AsTextFlag::IncludesResourceIdentifiers))
771         ts.dumpProperty("image-buffer-identifier", item.imageBufferIdentifier());
772     ts.dumpProperty("dest-rect", item.destinationRect());
773 }
774
775 void dumpItem(TextStream& ts, const ClipOutToPath& item, OptionSet<AsTextFlag>)
776 {
777     ts.dumpProperty("path", item.path());
778 }
779
780 void dumpItem(TextStream& ts, const ClipPath& item, OptionSet<AsTextFlag>)
781 {
782     ts.dumpProperty("path", item.path());
783     ts.dumpProperty("wind-rule", item.windRule());
784 }
785
786 void dumpItem(TextStream& ts, const DrawFilteredImageBuffer& item, OptionSet<AsTextFlag> flags)
787 {
788     if (!flags.contains(AsTextFlag::IncludesResourceIdentifiers))
789         ts.dumpProperty("source-image-identifier", item.sourceImageIdentifier());
790     ts.dumpProperty("source-image-rect", item.sourceImageRect());
791 }
792
793 void dumpItem(TextStream& ts, const DrawGlyphs& item, OptionSet<AsTextFlag>)
794 {
795     // FIXME: dump more stuff.
796     ts.dumpProperty("local-anchor", item.localAnchor());
797     ts.dumpProperty("anchor-point", item.anchorPoint());
798     ts.dumpProperty("length", item.glyphs().size());
799
800 }
801
802 void dumpItem(TextStream& ts, const DrawImageBuffer& item, OptionSet<AsTextFlag> flags)
803 {
804     if (!flags.contains(AsTextFlag::IncludesResourceIdentifiers))
805         ts.dumpProperty("image-buffer-identifier", item.imageBufferIdentifier());
806     ts.dumpProperty("source-rect", item.source());
807     ts.dumpProperty("dest-rect", item.destinationRect());
808 }
809
810 void dumpItem(TextStream& ts, const DrawNativeImage& item, OptionSet<AsTextFlag> flags)
811 {
812     if (!flags.contains(AsTextFlag::IncludesResourceIdentifiers))
813         ts.dumpProperty("image-identifier", item.imageIdentifier());
814     ts.dumpProperty("source-rect", item.source());
815     ts.dumpProperty("dest-rect", item.destinationRect());
816 }
817
818 void dumpItem(TextStream& ts, const DrawSystemImage& item, OptionSet<AsTextFlag>)
819 {
820     // FIXME: dump more stuff.
821     ts.dumpProperty("destination", item.destinationRect());
822 }
823
824 void dumpItem(TextStream& ts, const DrawPattern& item, OptionSet<AsTextFlag> flags)
825 {
826     if (!flags.contains(AsTextFlag::IncludesResourceIdentifiers))
827         ts.dumpProperty("image-identifier", item.imageIdentifier());
828     ts.dumpProperty("pattern-transform", item.patternTransform());
829     ts.dumpProperty("tile-rect", item.tileRect());
830     ts.dumpProperty("dest-rect", item.destRect());
831     ts.dumpProperty("phase", item.phase());
832     ts.dumpProperty("spacing", item.spacing());
833 }
834
835 void dumpItem(TextStream& ts, const DrawRect& item, OptionSet<AsTextFlag>)
836 {
837     ts.dumpProperty("rect", item.rect());
838     ts.dumpProperty("border-thickness", item.borderThickness());
839 }
840
841 void dumpItem(TextStream& ts, const DrawLine& item, OptionSet<AsTextFlag>)
842 {
843     ts.dumpProperty("point-1", item.point1());
844     ts.dumpProperty("point-2", item.point2());
845 }
846
847 void dumpItem(TextStream& ts, const DrawLinesForText& item, OptionSet<AsTextFlag>)
848 {
849     ts.dumpProperty("block-location", item.blockLocation());
850     ts.dumpProperty("local-anchor", item.localAnchor());
851     ts.dumpProperty("point", item.point());
852     ts.dumpProperty("thickness", item.thickness());
853     ts.dumpProperty("double", item.doubleLines());
854     ts.dumpProperty("widths", item.widths());
855     ts.dumpProperty("is-printing", item.isPrinting());
856     ts.dumpProperty("double", item.doubleLines());
857 }
858
859 void dumpItem(TextStream& ts, const DrawDotsForDocumentMarker& item, OptionSet<AsTextFlag>)
860 {
861     ts.dumpProperty("rect", item.rect());
862 }
863
864 void dumpItem(TextStream& ts, const DrawEllipse& item, OptionSet<AsTextFlag>)
865 {
866     ts.dumpProperty("rect", item.rect());
867 }
868
869 void dumpItem(TextStream& ts, const DrawPath& item, OptionSet<AsTextFlag>)
870 {
871     ts.dumpProperty("path", item.path());
872 }
873
874 void dumpItem(TextStream& ts, const DrawFocusRingPath& item, OptionSet<AsTextFlag>)
875 {
876     ts.dumpProperty("path", item.path());
877     ts.dumpProperty("width", item.width());
878     ts.dumpProperty("offset", item.offset());
879     ts.dumpProperty("color", item.color());
880 }
881
882 void dumpItem(TextStream& ts, const DrawFocusRingRects& item, OptionSet<AsTextFlag>)
883 {
884     ts.dumpProperty("rects", item.rects());
885     ts.dumpProperty("width", item.width());
886     ts.dumpProperty("offset", item.offset());
887     ts.dumpProperty("color", item.color());
888 }
889
890 void dumpItem(TextStream& ts, const FillRect& item, OptionSet<AsTextFlag>)
891 {
892     ts.dumpProperty("rect", item.rect());
893 }
894
895 void dumpItem(TextStream& ts, const FillRectWithColor& item, OptionSet<AsTextFlag>)
896 {
897     ts.dumpProperty("rect", item.rect());
898     ts.dumpProperty("color", item.color());
899 }
900
901 void dumpItem(TextStream& ts, const FillRectWithGradient& item, OptionSet<AsTextFlag>)
902 {
903     // FIXME: log gradient.
904     ts.dumpProperty("rect", item.rect());
905 }
906
907 void dumpItem(TextStream& ts, const FillCompositedRect& item, OptionSet<AsTextFlag>)
908 {
909     ts.dumpProperty("rect", item.rect());
910     ts.dumpProperty("color", item.color());
911     ts.dumpProperty("composite-operation", item.compositeOperator());
912     ts.dumpProperty("blend-mode", item.blendMode());
913 }
914
915 void dumpItem(TextStream& ts, const FillRoundedRect& item, OptionSet<AsTextFlag>)
916 {
917     ts.dumpProperty("rect", item.roundedRect());
918     ts.dumpProperty("color", item.color());
919     ts.dumpProperty("blend-mode", item.blendMode());
920 }
921
922 void dumpItem(TextStream& ts, const FillRectWithRoundedHole& item, OptionSet<AsTextFlag>)
923 {
924     ts.dumpProperty("rect", item.rect());
925     ts.dumpProperty("rounded-hole-rect", item.roundedHoleRect());
926     ts.dumpProperty("color", item.color());
927 }
928
929 #if ENABLE(INLINE_PATH_DATA)
930
931 void dumpItem(TextStream& ts, const FillLine& item, OptionSet<AsTextFlag>)
932 {
933     ts.dumpProperty("path", item.path());
934 }
935
936 void dumpItem(TextStream& ts, const FillArc& item, OptionSet<AsTextFlag>)
937 {
938     ts.dumpProperty("path", item.path());
939 }
940
941 void dumpItem(TextStream& ts, const FillQuadCurve& item, OptionSet<AsTextFlag>)
942 {
943     ts.dumpProperty("path", item.path());
944 }
945
946 void dumpItem(TextStream& ts, const FillBezierCurve& item, OptionSet<AsTextFlag>)
947 {
948     ts.dumpProperty("path", item.path());
949 }
950
951 void dumpItem(TextStream& ts, const StrokeArc& item, OptionSet<AsTextFlag>)
952 {
953     ts.dumpProperty("path", item.path());
954 }
955
956 void dumpItem(TextStream& ts, const StrokeQuadCurve& item, OptionSet<AsTextFlag>)
957 {
958     ts.dumpProperty("path", item.path());
959 }
960
961 void dumpItem(TextStream& ts, const StrokeBezierCurve& item, OptionSet<AsTextFlag>)
962 {
963     ts.dumpProperty("path", item.path());
964 }
965
966 #endif // ENABLE(INLINE_PATH_DATA)
967
968 void dumpItem(TextStream& ts, const FillPath& item, OptionSet<AsTextFlag>)
969 {
970     ts.dumpProperty("path", item.path());
971 }
972
973 void dumpItem(TextStream& ts, const FillEllipse& item, OptionSet<AsTextFlag>)
974 {
975     ts.dumpProperty("rect", item.rect());
976 }
977
978 #if ENABLE(VIDEO)
979
980 void dumpItem(TextStream& ts, const PaintFrameForMedia& item, OptionSet<AsTextFlag>)
981 {
982     ts.dumpProperty("destination", item.destination());
983 }
984
985 #endif // ENABLE(VIDEO)
986
987
988 void dumpItem(TextStream& ts, const StrokeRect& item, OptionSet<AsTextFlag>)
989 {
990     ts.dumpProperty("rect", item.rect());
991     ts.dumpProperty("line-width", item.lineWidth());
992 }
993
994 void dumpItem(TextStream& ts, const StrokePath& item, OptionSet<AsTextFlag>)
995 {
996     ts.dumpProperty("path", item.path());
997 }
998
999 void dumpItem(TextStream& ts, const StrokeEllipse& item, OptionSet<AsTextFlag>)
1000 {
1001     ts.dumpProperty("rect", item.rect());
1002 }
1003
1004 void dumpItem(TextStream& ts, const StrokeLine& item, OptionSet<AsTextFlag>)
1005 {
1006     ts.dumpProperty("start", item.start());
1007     ts.dumpProperty("end", item.end());
1008 }
1009
1010 void dumpItem(TextStream& ts, const ClearRect& item, OptionSet<AsTextFlag>)
1011 {
1012     ts.dumpProperty("rect", item.rect());
1013 }
1014
1015 void dumpItem(TextStream& ts, const BeginTransparencyLayer& item, OptionSet<AsTextFlag>)
1016 {
1017     ts.dumpProperty("opacity", item.opacity());
1018 }
1019
1020 void dumpItem(TextStream& ts, const ApplyDeviceScaleFactor& item, OptionSet<AsTextFlag>)
1021 {
1022     ts.dumpProperty("scale-factor", item.scaleFactor());
1023 }
1024
1025 void dumpItemHandle(TextStream& ts, const ItemHandle& item, OptionSet<AsTextFlag> flags)
1026 {
1027     ts << item.type();
1028
1029     switch (item.type()) {
1030     case ItemType::Translate:
1031         dumpItem(ts, item.get<Translate>(), flags);
1032         break;
1033     case ItemType::Rotate:
1034         dumpItem(ts, item.get<Rotate>(), flags);
1035         break;
1036     case ItemType::Scale:
1037         dumpItem(ts, item.get<Scale>(), flags);
1038         break;
1039     case ItemType::SetCTM:
1040         dumpItem(ts, item.get<SetCTM>(), flags);
1041         break;
1042     case ItemType::ConcatenateCTM:
1043         dumpItem(ts, item.get<ConcatenateCTM>(), flags);
1044         break;
1045     case ItemType::SetInlineFillColor:
1046         dumpItem(ts, item.get<SetInlineFillColor>(), flags);
1047         break;
1048     case ItemType::SetInlineStrokeColor:
1049         dumpItem(ts, item.get<SetInlineStrokeColor>(), flags);
1050         break;
1051     case ItemType::SetStrokeThickness:
1052         dumpItem(ts, item.get<SetStrokeThickness>(), flags);
1053         break;
1054     case ItemType::SetState:
1055         dumpItem(ts, item.get<SetState>(), flags);
1056         break;
1057     case ItemType::SetLineCap:
1058         dumpItem(ts, item.get<SetLineCap>(), flags);
1059         break;
1060     case ItemType::SetLineDash:
1061         dumpItem(ts, item.get<SetLineDash>(), flags);
1062         break;
1063     case ItemType::SetLineJoin:
1064         dumpItem(ts, item.get<SetLineJoin>(), flags);
1065         break;
1066     case ItemType::SetMiterLimit:
1067         dumpItem(ts, item.get<SetMiterLimit>(), flags);
1068         break;
1069     case ItemType::Clip:
1070         dumpItem(ts, item.get<Clip>(), flags);
1071         break;
1072     case ItemType::ClipOut:
1073         dumpItem(ts, item.get<ClipOut>(), flags);
1074         break;
1075     case ItemType::ClipToImageBuffer:
1076         dumpItem(ts, item.get<ClipToImageBuffer>(), flags);
1077         break;
1078     case ItemType::ClipOutToPath:
1079         dumpItem(ts, item.get<ClipOutToPath>(), flags);
1080         break;
1081     case ItemType::ClipPath:
1082         dumpItem(ts, item.get<ClipPath>(), flags);
1083         break;
1084     case ItemType::DrawFilteredImageBuffer:
1085         dumpItem(ts, item.get<DrawFilteredImageBuffer>(), flags);
1086         break;
1087     case ItemType::DrawGlyphs:
1088         dumpItem(ts, item.get<DrawGlyphs>(), flags);
1089         break;
1090     case ItemType::DrawImageBuffer:
1091         dumpItem(ts, item.get<DrawImageBuffer>(), flags);
1092         break;
1093     case ItemType::DrawNativeImage:
1094         dumpItem(ts, item.get<DrawNativeImage>(), flags);
1095         break;
1096     case ItemType::DrawSystemImage:
1097         dumpItem(ts, item.get<DrawSystemImage>(), flags);
1098         break;
1099     case ItemType::DrawPattern:
1100         dumpItem(ts, item.get<DrawPattern>(), flags);
1101         break;
1102     case ItemType::DrawRect:
1103         dumpItem(ts, item.get<DrawRect>(), flags);
1104         break;
1105     case ItemType::DrawLine:
1106         dumpItem(ts, item.get<DrawLine>(), flags);
1107         break;
1108     case ItemType::DrawLinesForText:
1109         dumpItem(ts, item.get<DrawLinesForText>(), flags);
1110         break;
1111     case ItemType::DrawDotsForDocumentMarker:
1112         dumpItem(ts, item.get<DrawDotsForDocumentMarker>(), flags);
1113         break;
1114     case ItemType::DrawEllipse:
1115         dumpItem(ts, item.get<DrawEllipse>(), flags);
1116         break;
1117     case ItemType::DrawPath:
1118         dumpItem(ts, item.get<DrawPath>(), flags);
1119         break;
1120     case ItemType::DrawFocusRingPath:
1121         dumpItem(ts, item.get<DrawFocusRingPath>(), flags);
1122         break;
1123     case ItemType::DrawFocusRingRects:
1124         dumpItem(ts, item.get<DrawFocusRingRects>(), flags);
1125         break;
1126     case ItemType::FillRect:
1127         dumpItem(ts, item.get<FillRect>(), flags);
1128         break;
1129     case ItemType::FillRectWithColor:
1130         dumpItem(ts, item.get<FillRectWithColor>(), flags);
1131         break;
1132     case ItemType::FillRectWithGradient:
1133         dumpItem(ts, item.get<FillRectWithGradient>(), flags);
1134         break;
1135     case ItemType::FillCompositedRect:
1136         dumpItem(ts, item.get<FillCompositedRect>(), flags);
1137         break;
1138     case ItemType::FillRoundedRect:
1139         dumpItem(ts, item.get<FillRoundedRect>(), flags);
1140         break;
1141     case ItemType::FillRectWithRoundedHole:
1142         dumpItem(ts, item.get<FillRectWithRoundedHole>(), flags);
1143         break;
1144 #if ENABLE(INLINE_PATH_DATA)
1145     case ItemType::FillLine:
1146         dumpItem(ts, item.get<FillLine>(), flags);
1147         break;
1148     case ItemType::FillArc:
1149         dumpItem(ts, item.get<FillArc>(), flags);
1150         break;
1151     case ItemType::FillQuadCurve:
1152         dumpItem(ts, item.get<FillQuadCurve>(), flags);
1153         break;
1154     case ItemType::FillBezierCurve:
1155         dumpItem(ts, item.get<FillBezierCurve>(), flags);
1156         break;
1157 #endif
1158     case ItemType::FillPath:
1159         dumpItem(ts, item.get<FillPath>(), flags);
1160         break;
1161     case ItemType::FillEllipse:
1162         dumpItem(ts, item.get<FillEllipse>(), flags);
1163         break;
1164 #if ENABLE(VIDEO)
1165     case ItemType::PaintFrameForMedia:
1166         dumpItem(ts, item.get<PaintFrameForMedia>(), flags);
1167         break;
1168 #endif
1169     case ItemType::StrokeRect:
1170         dumpItem(ts, item.get<StrokeRect>(), flags);
1171         break;
1172     case ItemType::StrokeLine:
1173         dumpItem(ts, item.get<StrokeLine>(), flags);
1174         break;
1175 #if ENABLE(INLINE_PATH_DATA)
1176     case ItemType::StrokeArc:
1177         dumpItem(ts, item.get<StrokeArc>(), flags);
1178         break;
1179     case ItemType::StrokeQuadCurve:
1180         dumpItem(ts, item.get<StrokeQuadCurve>(), flags);
1181         break;
1182     case ItemType::StrokeBezierCurve:
1183         dumpItem(ts, item.get<StrokeBezierCurve>(), flags);
1184         break;
1185 #endif
1186     case ItemType::StrokePath:
1187         dumpItem(ts, item.get<StrokePath>(), flags);
1188         break;
1189     case ItemType::StrokeEllipse:
1190         dumpItem(ts, item.get<StrokeEllipse>(), flags);
1191         break;
1192     case ItemType::ClearRect:
1193         dumpItem(ts, item.get<ClearRect>(), flags);
1194         break;
1195     case ItemType::BeginTransparencyLayer:
1196         dumpItem(ts, item.get<BeginTransparencyLayer>(), flags);
1197         break;
1198     case ItemType::ApplyDeviceScaleFactor:
1199         dumpItem(ts, item.get<ApplyDeviceScaleFactor>(), flags);
1200         break;
1201     // Items with no additional data.
1202     case ItemType::Save:
1203     case ItemType::Restore:
1204     case ItemType::EndTransparencyLayer:
1205 #if USE(CG)
1206     case ItemType::ApplyStrokePattern:
1207     case ItemType::ApplyFillPattern:
1208 #endif
1209     case ItemType::ClearShadow:
1210         break;
1211     }
1212 }
1213 #endif
1214
1215 } // namespace DisplayList
1216 } // namespace WebCore