[Win] Provide a means for viewing the layer tree
[WebKit-https.git] / Source / WebCore / platform / graphics / ca / win / PlatformCALayerWin.cpp
1 /*
2  * Copyright (C) 2011, 2014-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 #include "config.h"
27
28 #include "PlatformCALayerWin.h"
29
30 #include "AbstractCACFLayerTreeHost.h"
31 #include "FontCascade.h"
32 #include "GraphicsContext.h"
33 #include "PlatformCAAnimationWin.h"
34 #include "PlatformCALayerWinInternal.h"
35 #include "TextRun.h"
36 #include "TileController.h"
37 #include "WebCoreHeaderDetection.h"
38 #include "WebTiledBackingLayerWin.h"
39 #include <QuartzCore/CoreAnimationCF.h>
40 #include <WebKitSystemInterface/WebKitSystemInterface.h>
41 #include <wtf/CurrentTime.h>
42 #include <wtf/text/CString.h>
43 #include <wtf/text/StringBuilder.h>
44
45 using namespace WebCore;
46
47 PassRefPtr<PlatformCALayer> PlatformCALayerWin::create(LayerType layerType, PlatformCALayerClient* owner)
48 {
49     return adoptRef(new PlatformCALayerWin(layerType, 0, owner));
50 }
51
52 PassRefPtr<PlatformCALayer> PlatformCALayerWin::create(PlatformLayer* platformLayer, PlatformCALayerClient* owner)
53 {
54     return adoptRef(new PlatformCALayerWin(LayerTypeCustom, platformLayer, owner));
55 }
56
57 static CFStringRef toCACFLayerType(PlatformCALayer::LayerType type)
58 {
59     return (type == PlatformCALayer::LayerTypeTransformLayer) ? kCACFTransformLayer : kCACFLayer;
60 }
61
62 static CFStringRef toCACFFilterType(PlatformCALayer::FilterType type)
63 {
64     switch (type) {
65     case PlatformCALayer::Linear: return kCACFFilterLinear;
66     case PlatformCALayer::Nearest: return kCACFFilterNearest;
67     case PlatformCALayer::Trilinear: return kCACFFilterTrilinear;
68     default: return 0;
69     }
70 }
71
72 static AbstractCACFLayerTreeHost* layerTreeHostForLayer(const PlatformCALayer* layer)
73 {
74     // We need the AbstractCACFLayerTreeHost associated with this layer, which is stored in the UserData of the CACFContext
75     void* userData = wkCACFLayerGetContextUserData(layer->platformLayer());
76     if (!userData)
77         return 0;
78
79     return static_cast<AbstractCACFLayerTreeHost*>(userData);
80 }
81
82 static PlatformCALayerWinInternal* intern(const PlatformCALayer* layer)
83 {
84     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(layer->platformLayer()));
85 }
86
87 static PlatformCALayerWinInternal* intern(void* layer)
88 {
89     return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(static_cast<CACFLayerRef>(layer)));
90 }
91
92 PlatformCALayer* PlatformCALayer::platformCALayer(void* platformLayer)
93 {
94     if (!platformLayer)
95         return 0;
96     
97     PlatformCALayerWinInternal* layerIntern = intern(platformLayer);
98     return layerIntern ? layerIntern->owner() : 0;
99 }
100
101 PlatformCALayer::RepaintRectList PlatformCALayer::collectRectsToPaint(CGContextRef, PlatformCALayer*)
102 {
103     // FIXME: We should actually collect rects to use instead of defaulting to Windows'
104     // normal drawing path.
105     PlatformCALayer::RepaintRectList dirtyRects;
106     return dirtyRects;
107 }
108
109 void PlatformCALayer::drawLayerContents(CGContextRef context, WebCore::PlatformCALayer* platformCALayer, RepaintRectList&)
110 {
111     intern(platformCALayer)->displayCallback(platformCALayer->platformLayer(), context);
112 }
113
114 CGRect PlatformCALayer::frameForLayer(const PlatformLayer* tileLayer)
115 {
116     return CACFLayerGetFrame(static_cast<CACFLayerRef>(const_cast<PlatformLayer*>(tileLayer)));
117 }
118
119 static void displayCallback(CACFLayerRef caLayer, CGContextRef context)
120 {
121     ASSERT_ARG(caLayer, CACFLayerGetUserData(caLayer));
122     intern(caLayer)->displayCallback(caLayer, context);
123 }
124
125 static void layoutSublayersProc(CACFLayerRef caLayer) 
126 {
127     PlatformCALayer* layer = PlatformCALayer::platformCALayer(caLayer);
128     if (layer && layer->owner())
129         layer->owner()->platformCALayerLayoutSublayersOfLayer(layer);
130 }
131
132 PlatformCALayerWin::PlatformCALayerWin(LayerType layerType, PlatformLayer* layer, PlatformCALayerClient* owner)
133     : PlatformCALayer(layer ? LayerTypeCustom : layerType, owner)
134     , m_customAppearance(GraphicsLayer::NoCustomAppearance)
135 {
136     if (layer) {
137         m_layer = layer;
138         return;
139     }
140
141     m_layer = adoptCF(CACFLayerCreate(toCACFLayerType(layerType)));
142
143 #if HAVE(CACFLAYER_SETCONTENTSSCALE)
144     CACFLayerSetContentsScale(m_layer.get(), owner ? owner->platformCALayerDeviceScaleFactor() : 1.0f);
145 #endif
146
147     // Create the PlatformCALayerWinInternal object and point to it in the userdata.
148     PlatformCALayerWinInternal* intern = nullptr;
149
150     if (usesTiledBackingLayer()) {
151         intern = new WebTiledBackingLayerWin(this);
152         TileController* tileController = reinterpret_cast<WebTiledBackingLayerWin*>(intern)->createTileController(this);
153         m_customSublayers = std::make_unique<PlatformCALayerList>(tileController->containerLayers());
154     } else
155         intern = new PlatformCALayerWinInternal(this);
156
157     CACFLayerSetUserData(m_layer.get(), intern);
158
159     // Set the display callback
160     CACFLayerSetDisplayCallback(m_layer.get(), displayCallback);
161     CACFLayerSetLayoutCallback(m_layer.get(), layoutSublayersProc);
162 }
163
164 PlatformCALayerWin::~PlatformCALayerWin()
165 {
166     // Toss all the kids
167     removeAllSublayers();
168
169     PlatformCALayerWinInternal* layerIntern = intern(this);
170     if (usesTiledBackingLayer())
171         reinterpret_cast<WebTiledBackingLayerWin*>(layerIntern)->invalidate();
172
173     // Get rid of the user data
174     CACFLayerSetUserData(m_layer.get(), nullptr);
175
176     CACFLayerRemoveFromSuperlayer(m_layer.get());
177
178     delete layerIntern;
179 }
180
181 PassRefPtr<PlatformCALayer> PlatformCALayerWin::clone(PlatformCALayerClient* owner) const
182 {
183     PlatformCALayer::LayerType type = (layerType() == PlatformCALayer::LayerTypeTransformLayer) ?
184         PlatformCALayer::LayerTypeTransformLayer : PlatformCALayer::LayerTypeLayer;
185     RefPtr<PlatformCALayer> newLayer = PlatformCALayerWin::create(type, owner);
186
187     newLayer->setPosition(position());
188     newLayer->setBounds(bounds());
189     newLayer->setAnchorPoint(anchorPoint());
190     newLayer->setTransform(transform());
191     newLayer->setSublayerTransform(sublayerTransform());
192     newLayer->setContents(contents());
193     newLayer->setMasksToBounds(masksToBounds());
194     newLayer->setDoubleSided(isDoubleSided());
195     newLayer->setOpaque(isOpaque());
196     newLayer->setBackgroundColor(backgroundColor());
197     newLayer->setContentsScale(contentsScale());
198     newLayer->copyFiltersFrom(*this);
199
200     return newLayer;
201 }
202
203 PlatformCALayer* PlatformCALayerWin::rootLayer() const
204 {
205     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
206     return host ? host->rootLayer() : nullptr;
207 }
208
209 void PlatformCALayerWin::animationStarted(const String& animationKey, CFTimeInterval beginTime)
210 {
211     // Update start time for any animation not yet started
212     CFTimeInterval cacfBeginTime = currentTimeToMediaTime(beginTime);
213
214     HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = m_animations.end();
215     for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = m_animations.begin(); it != end; ++it)
216         it->value->setActualStartTimeIfNeeded(cacfBeginTime);
217
218     if (m_owner)
219         m_owner->platformCALayerAnimationStarted(animationKey, beginTime);
220 }
221
222 void PlatformCALayerWin::animationEnded(const String& animationKey)
223 {
224     if (m_owner)
225         m_owner->platformCALayerAnimationEnded(animationKey);
226 }
227
228 void PlatformCALayerWin::setNeedsDisplayInRect(const FloatRect& dirtyRect)
229 {
230     intern(this)->setNeedsDisplayInRect(dirtyRect);
231 }
232
233 void PlatformCALayerWin::setNeedsDisplay()
234 {
235     intern(this)->setNeedsDisplay();
236 }
237
238 void PlatformCALayerWin::setNeedsCommit()
239 {
240     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
241     if (host)
242         host->layerTreeDidChange();
243 }
244
245 void PlatformCALayerWin::copyContentsFromLayer(PlatformCALayer* source)
246 {
247     if (source) {
248         RetainPtr<CFTypeRef> contents = CACFLayerGetContents(source->platformLayer());
249         CACFLayerSetContents(m_layer.get(), contents.get());
250     } else
251         CACFLayerSetContents(m_layer.get(), nullptr);
252
253     setNeedsCommit();
254 }
255
256 void PlatformCALayerWin::setNeedsLayout()
257 {
258     if (!m_owner || !m_owner->platformCALayerRespondsToLayoutChanges())
259         return;
260
261     CACFLayerSetNeedsLayout(m_layer.get());
262     setNeedsCommit();
263 }
264
265 PlatformCALayer* PlatformCALayerWin::superlayer() const
266 {
267     return platformCALayer(CACFLayerGetSuperlayer(m_layer.get()));
268 }
269
270 void PlatformCALayerWin::removeFromSuperlayer()
271 {
272     CACFLayerRemoveFromSuperlayer(m_layer.get());
273     setNeedsCommit();
274 }
275
276 void PlatformCALayerWin::setSublayers(const PlatformCALayerList& list)
277 {
278     intern(this)->setSublayers(list);
279 }
280
281 void PlatformCALayerWin::removeAllSublayers()
282 {
283     intern(this)->removeAllSublayers();
284 }
285
286 void PlatformCALayerWin::appendSublayer(PlatformCALayer& layer)
287 {
288     // This must be in terms of insertSublayer instead of a direct call so PlatformCALayerInternal can override.
289     insertSublayer(layer, intern(this)->sublayerCount());
290 }
291
292 void PlatformCALayerWin::insertSublayer(PlatformCALayer& layer, size_t index)
293 {
294     intern(this)->insertSublayer(layer, index);
295 }
296
297 void PlatformCALayerWin::replaceSublayer(PlatformCALayer& reference, PlatformCALayer& newLayer)
298 {
299     // This must not use direct calls to allow PlatformCALayerInternal to override.
300     ASSERT_ARG(reference, reference.superlayer() == this);
301
302     if (&reference == &newLayer)
303         return;
304
305     int referenceIndex = intern(this)->indexOfSublayer(&reference);
306     ASSERT(referenceIndex != -1);
307     if (referenceIndex == -1)
308         return;
309
310     reference.removeFromSuperlayer();
311
312     newLayer.removeFromSuperlayer();
313     insertSublayer(newLayer, referenceIndex);
314 }
315
316 void PlatformCALayerWin::adoptSublayers(PlatformCALayer& source)
317 {
318     PlatformCALayerList sublayers;
319     intern(&source)->getSublayers(sublayers);
320
321     // Use setSublayers() because it properly nulls out the superlayer pointers.
322     setSublayers(sublayers);
323 }
324
325 void PlatformCALayerWin::addAnimationForKey(const String& key, PlatformCAAnimation& animation)
326 {
327     // Add it to the animation list
328     m_animations.add(key, &animation);
329
330     CACFLayerAddAnimation(m_layer.get(), key.createCFString().get(), downcast<PlatformCAAnimationWin>(animation).platformAnimation());
331     setNeedsCommit();
332
333     // Tell the host about it so we can fire the start animation event
334     AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
335     if (host)
336         host->addPendingAnimatedLayer(this);
337 }
338
339 void PlatformCALayerWin::removeAnimationForKey(const String& key)
340 {
341     // Remove it from the animation list
342     m_animations.remove(key);
343
344     CACFLayerRemoveAnimation(m_layer.get(), key.createCFString().get());
345
346     // We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
347     // There may be other active animations on the layer and if an animation
348     // callback is fired on a layer without any animations no harm is done.
349
350     setNeedsCommit();
351 }
352
353 PassRefPtr<PlatformCAAnimation> PlatformCALayerWin::animationForKey(const String& key)
354 {
355     HashMap<String, RefPtr<PlatformCAAnimation> >::iterator it = m_animations.find(key);
356     if (it == m_animations.end())
357         return 0;
358
359     return it->value;
360 }
361
362 void PlatformCALayerWin::setMask(PlatformCALayer* layer)
363 {
364     CACFLayerSetMask(m_layer.get(), layer ? layer->platformLayer() : 0);
365     setNeedsCommit();
366 }
367
368 bool PlatformCALayerWin::isOpaque() const
369 {
370     return intern(this)->isOpaque();
371 }
372
373 void PlatformCALayerWin::setOpaque(bool value)
374 {
375     intern(this)->setOpaque(value);
376     setNeedsCommit();
377 }
378
379 FloatRect PlatformCALayerWin::bounds() const
380 {
381     return CACFLayerGetBounds(m_layer.get());
382 }
383
384 void PlatformCALayerWin::setBounds(const FloatRect& value)
385 {
386     intern(this)->setBounds(value);
387     setNeedsLayout();
388 }
389
390 FloatPoint3D PlatformCALayerWin::position() const
391 {
392     CGPoint point = CACFLayerGetPosition(m_layer.get());
393     return FloatPoint3D(point.x, point.y, CACFLayerGetZPosition(m_layer.get()));
394 }
395
396 void PlatformCALayerWin::setPosition(const FloatPoint3D& value)
397 {
398     CACFLayerSetPosition(m_layer.get(), CGPointMake(value.x(), value.y()));
399     CACFLayerSetZPosition(m_layer.get(), value.z());
400     setNeedsCommit();
401 }
402
403 FloatPoint3D PlatformCALayerWin::anchorPoint() const
404 {
405     CGPoint point = CACFLayerGetAnchorPoint(m_layer.get());
406     float z = CACFLayerGetAnchorPointZ(m_layer.get());
407     return FloatPoint3D(point.x, point.y, z);
408 }
409
410 void PlatformCALayerWin::setAnchorPoint(const FloatPoint3D& value)
411 {
412     CACFLayerSetAnchorPoint(m_layer.get(), CGPointMake(value.x(), value.y()));
413     CACFLayerSetAnchorPointZ(m_layer.get(), value.z());
414     setNeedsCommit();
415 }
416
417 TransformationMatrix PlatformCALayerWin::transform() const
418 {
419     return CACFLayerGetTransform(m_layer.get());
420 }
421
422 void PlatformCALayerWin::setTransform(const TransformationMatrix& value)
423 {
424     CACFLayerSetTransform(m_layer.get(), value);
425     setNeedsCommit();
426 }
427
428 TransformationMatrix PlatformCALayerWin::sublayerTransform() const
429 {
430     return CACFLayerGetSublayerTransform(m_layer.get());
431 }
432
433 void PlatformCALayerWin::setSublayerTransform(const TransformationMatrix& value)
434 {
435     CACFLayerSetSublayerTransform(m_layer.get(), value);
436     setNeedsCommit();
437 }
438
439 void PlatformCALayerWin::setHidden(bool value)
440 {
441     CACFLayerSetHidden(m_layer.get(), value);
442     setNeedsCommit();
443 }
444
445 void PlatformCALayerWin::setBackingStoreAttached(bool)
446 {
447 }
448
449 bool PlatformCALayerWin::backingStoreAttached() const
450 {
451     return true;
452 }
453
454 void PlatformCALayerWin::setGeometryFlipped(bool value)
455 {
456     CACFLayerSetGeometryFlipped(m_layer.get(), value);
457     setNeedsCommit();
458 }
459
460 bool PlatformCALayerWin::isDoubleSided() const
461 {
462     return CACFLayerIsDoubleSided(m_layer.get());
463 }
464
465 void PlatformCALayerWin::setDoubleSided(bool value)
466 {
467     CACFLayerSetDoubleSided(m_layer.get(), value);
468     setNeedsCommit();
469 }
470
471 bool PlatformCALayerWin::masksToBounds() const
472 {
473     return CACFLayerGetMasksToBounds(m_layer.get());
474 }
475
476 void PlatformCALayerWin::setMasksToBounds(bool value)
477 {
478     CACFLayerSetMasksToBounds(m_layer.get(), value);
479     setNeedsCommit();
480 }
481
482 bool PlatformCALayerWin::acceleratesDrawing() const
483 {
484     return false;
485 }
486
487 void PlatformCALayerWin::setAcceleratesDrawing(bool)
488 {
489 }
490
491 CFTypeRef PlatformCALayerWin::contents() const
492 {
493     return CACFLayerGetContents(m_layer.get());
494 }
495
496 void PlatformCALayerWin::setContents(CFTypeRef value)
497 {
498     CACFLayerSetContents(m_layer.get(), value);
499     setNeedsCommit();
500 }
501
502 void PlatformCALayerWin::setContentsRect(const FloatRect& value)
503 {
504     CACFLayerSetContentsRect(m_layer.get(), value);
505     setNeedsCommit();
506 }
507
508 void PlatformCALayerWin::setMinificationFilter(FilterType value)
509 {
510     CACFLayerSetMinificationFilter(m_layer.get(), toCACFFilterType(value));
511 }
512
513 void PlatformCALayerWin::setMagnificationFilter(FilterType value)
514 {
515     CACFLayerSetMagnificationFilter(m_layer.get(), toCACFFilterType(value));
516     setNeedsCommit();
517 }
518
519 Color PlatformCALayerWin::backgroundColor() const
520 {
521     return CACFLayerGetBackgroundColor(m_layer.get());
522 }
523
524 void PlatformCALayerWin::setBackgroundColor(const Color& value)
525 {
526     CGFloat components[4];
527     value.getRGBA(components[0], components[1], components[2], components[3]);
528
529     RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
530     RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components));
531
532     CACFLayerSetBackgroundColor(m_layer.get(), color.get());
533     setNeedsCommit();
534 }
535
536 void PlatformCALayerWin::setBorderWidth(float value)
537 {
538     intern(this)->setBorderWidth(value);
539     setNeedsCommit();
540 }
541
542 void PlatformCALayerWin::setBorderColor(const Color& value)
543 {
544     intern(this)->setBorderColor(value);
545     setNeedsCommit();
546 }
547
548 float PlatformCALayerWin::opacity() const
549 {
550     return CACFLayerGetOpacity(m_layer.get());
551 }
552
553 void PlatformCALayerWin::setOpacity(float value)
554 {
555     CACFLayerSetOpacity(m_layer.get(), value);
556     setNeedsCommit();
557 }
558
559 void PlatformCALayerWin::setFilters(const FilterOperations&)
560 {
561 }
562
563 void PlatformCALayerWin::copyFiltersFrom(const PlatformCALayer&)
564 {
565 }
566
567 void PlatformCALayerWin::setName(const String& value)
568 {
569     CACFLayerSetName(m_layer.get(), value.createCFString().get());
570     setNeedsCommit();
571 }
572
573 void PlatformCALayerWin::setSpeed(float value)
574 {
575     CACFLayerSetSpeed(m_layer.get(), value);
576     setNeedsCommit();
577 }
578
579 void PlatformCALayerWin::setTimeOffset(CFTimeInterval value)
580 {
581     CACFLayerSetTimeOffset(m_layer.get(), value);
582     setNeedsCommit();
583 }
584
585 void PlatformCALayerWin::setEdgeAntialiasingMask(unsigned mask)
586 {
587     CACFLayerSetEdgeAntialiasingMask(m_layer.get(), mask);
588     setNeedsCommit();
589 }
590
591 float PlatformCALayerWin::contentsScale() const
592 {
593     return intern(this)->contentsScale();
594 }
595
596 void PlatformCALayerWin::setContentsScale(float scaleFactor)
597 {
598     intern(this)->setContentsScale(scaleFactor);
599     setNeedsCommit();
600 }
601
602 float PlatformCALayerWin::cornerRadius() const
603 {
604     return 0; // FIXME: implement.
605 }
606
607 void PlatformCALayerWin::setCornerRadius(float value)
608 {
609     // FIXME: implement.
610 }
611
612 FloatRoundedRect PlatformCALayerWin::shapeRoundedRect() const
613 {
614     // FIXME: implement.
615     return FloatRoundedRect();
616 }
617
618 void PlatformCALayerWin::setShapeRoundedRect(const FloatRoundedRect&)
619 {
620     // FIXME: implement.
621 }
622
623 WindRule PlatformCALayerWin::shapeWindRule() const
624 {
625     // FIXME: implement.
626     return RULE_NONZERO;
627 }
628
629 void PlatformCALayerWin::setShapeWindRule(WindRule)
630 {
631     // FIXME: implement.
632 }
633
634 Path PlatformCALayerWin::shapePath() const
635 {
636     // FIXME: implement.
637     return Path();
638 }
639
640 void PlatformCALayerWin::setShapePath(const Path&)
641 {
642     // FIXME: implement.
643 }
644
645 static void printIndent(StringBuilder& builder, int indent)
646 {
647     for ( ; indent > 0; --indent)
648         builder.append("  ");
649 }
650
651 static void printTransform(StringBuilder& builder, const CATransform3D& transform)
652 {
653     builder.append('[');
654     builder.appendNumber(transform.m11);
655     builder.append(' ');
656     builder.appendNumber(transform.m12);
657     builder.append(' ');
658     builder.appendNumber(transform.m13);
659     builder.append(' ');
660     builder.appendNumber(transform.m14);
661     builder.append("; ");
662     builder.appendNumber(transform.m21);
663     builder.append(' ');
664     builder.appendNumber(transform.m22);
665     builder.append(' ');
666     builder.appendNumber(transform.m23);
667     builder.append(' ');
668     builder.appendNumber(transform.m24);
669     builder.append("; ");
670     builder.appendNumber(transform.m31);
671     builder.append(' ');
672     builder.appendNumber(transform.m32);
673     builder.append(' ');
674     builder.appendNumber(transform.m33);
675     builder.append(' ');
676     builder.appendNumber(transform.m34);
677     builder.append("; ");
678     builder.appendNumber(transform.m41);
679     builder.append(' ');
680     builder.appendNumber(transform.m42);
681     builder.append(' ');
682     builder.appendNumber(transform.m43);
683     builder.append(' ');
684     builder.appendNumber(transform.m44);
685     builder.append(']');
686 }
687
688 static void printColor(StringBuilder& builder, int indent, const String& label, CGColorRef color)
689 {
690     Color layerColor(color);
691     if (!layerColor.isValid())
692         return;
693
694     builder.append('\n');
695     printIndent(builder, indent);
696     builder.append('(');
697     builder.append(label);
698     builder.append(' ');
699     builder.append(layerColor.nameForRenderTreeAsText());
700     builder.append(')');
701 }
702
703 static void printLayer(StringBuilder& builder, const PlatformCALayer* layer, int indent)
704 {
705     FloatPoint3D layerPosition = layer->position();
706     FloatPoint3D layerAnchorPoint = layer->anchorPoint();
707     FloatRect layerBounds = layer->bounds();
708     builder.append('\n');
709     printIndent(builder, indent);
710
711     char* layerTypeName = nullptr;
712     switch (layer->layerType()) {
713     case PlatformCALayer::LayerTypeLayer: layerTypeName = "layer"; break;
714     case PlatformCALayer::LayerTypeWebLayer: layerTypeName = "web-layer"; break;
715     case PlatformCALayer::LayerTypeSimpleLayer: layerTypeName = "simple-layer"; break;
716     case PlatformCALayer::LayerTypeTransformLayer: layerTypeName = "transform-layer"; break;
717     case PlatformCALayer::LayerTypeWebTiledLayer: layerTypeName = "web-tiled-layer"; break;
718     case PlatformCALayer::LayerTypeTiledBackingLayer: layerTypeName = "tiled-backing-layer"; break;
719     case PlatformCALayer::LayerTypePageTiledBackingLayer: layerTypeName = "page-tiled-backing-layer"; break;
720     case PlatformCALayer::LayerTypeTiledBackingTileLayer: layerTypeName = "tiled-backing-tile-layer"; break;
721     case PlatformCALayer::LayerTypeRootLayer: layerTypeName = "root-layer"; break;
722     case PlatformCALayer::LayerTypeAVPlayerLayer: layerTypeName = "avplayer-layer"; break;
723     case PlatformCALayer::LayerTypeWebGLLayer: layerTypeName = "webgl-layer"; break;
724     case PlatformCALayer::LayerTypeBackdropLayer: layerTypeName = "backdrop-layer"; break;
725     case PlatformCALayer::LayerTypeShapeLayer: layerTypeName = "shape-layer"; break;
726     case PlatformCALayer::LayerTypeLightSystemBackdropLayer: layerTypeName = "light-system-backdrop-layer"; break;
727     case PlatformCALayer::LayerTypeDarkSystemBackdropLayer: layerTypeName = "dark-system-backdrop-layer"; break;
728     case PlatformCALayer::LayerTypeScrollingLayer: layerTypeName = "scrolling-layer"; break;
729     case PlatformCALayer::LayerTypeCustom: layerTypeName = "custom-layer"; break;
730     }
731
732     builder.append("(");
733     builder.append(layerTypeName);
734     builder.append(" [");
735     builder.appendNumber(layerPosition.x());
736     builder.append(' ');
737     builder.appendNumber(layerPosition.y());
738     builder.append(' ');
739     builder.appendNumber(layerPosition.z());
740     builder.append("] [");
741     builder.appendNumber(layerBounds.x());
742     builder.append(' ');
743     builder.appendNumber(layerBounds.y());
744     builder.append(' ');
745     builder.appendNumber(layerBounds.width());
746     builder.append(' ');
747     builder.appendNumber(layerBounds.height());
748     builder.append("] [");
749     builder.appendNumber(layerAnchorPoint.x());
750     builder.append(' ');
751     builder.appendNumber(layerAnchorPoint.y());
752     builder.append(' ');
753     builder.appendNumber(layerAnchorPoint.z());
754     builder.append("] superlayer=");
755     builder.appendNumber(reinterpret_cast<unsigned long long>(layer->superlayer()));
756
757     // Print name if needed
758     String layerName = CACFLayerGetName(layer->platformLayer());
759     if (!layerName.isEmpty()) {
760         builder.append('\n');
761         printIndent(builder, indent + 1);
762         builder.append("(name \"");
763         builder.append(layerName);
764         builder.append("\")");
765     }
766
767     // Print borderWidth if needed
768     if (CGFloat borderWidth = CACFLayerGetBorderWidth(layer->platformLayer())) {
769         builder.append('\n');
770         printIndent(builder, indent + 1);
771         builder.append("(borderWidth ");
772         builder.appendNumber(borderWidth);
773         builder.append(')');
774     }
775
776     // Print backgroundColor if needed
777     printColor(builder, indent + 1, "backgroundColor", CACFLayerGetBackgroundColor(layer->platformLayer()));
778
779     // Print borderColor if needed
780     printColor(builder, indent + 1, "borderColor", CACFLayerGetBorderColor(layer->platformLayer()));
781
782     // Print masksToBounds if needed
783     if (bool layerMasksToBounds = layer->masksToBounds()) {
784         builder.append('\n');
785         printIndent(builder, indent + 1);
786         builder.append("(masksToBounds true)");
787     }
788
789     // Print opacity if needed
790     float layerOpacity = layer->opacity();
791     if (layerOpacity != 1) {
792         builder.append('\n');
793         printIndent(builder, indent + 1);
794         builder.append("(opacity ");
795         builder.appendNumber(layerOpacity);
796         builder.append(')');
797     }
798
799     // Print sublayerTransform if needed
800     TransformationMatrix layerTransform = layer->sublayerTransform();
801     if (!layerTransform.isIdentity()) {
802         builder.append('\n');
803         printIndent(builder, indent + 1);
804         builder.append("(sublayerTransform ");
805         printTransform(builder, layerTransform);
806         builder.append(')');
807     }
808
809     // Print transform if needed
810     layerTransform = layer->transform();
811     if (!layerTransform.isIdentity()) {
812         builder.append('\n');
813         printIndent(builder, indent + 1);
814         builder.append("(transform ");
815         printTransform(builder, layerTransform);
816         builder.append(')');
817     }
818
819     // Print contents if needed
820     if (CFTypeRef layerContents = layer->contents()) {
821         if (CFGetTypeID(layerContents) == CGImageGetTypeID()) {
822             CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents));
823             builder.append('\n');
824             printIndent(builder, indent + 1);
825             builder.append("(contents (image [");
826             builder.appendNumber(CGImageGetWidth(imageContents));
827             builder.append(' ');
828             builder.appendNumber(CGImageGetHeight(imageContents));
829             builder.append("]))");
830         }
831
832         if (CFGetTypeID(layerContents) == CABackingStoreGetTypeID()) {
833             CABackingStoreRef backingStore = static_cast<CABackingStoreRef>(const_cast<void*>(layerContents));
834             CGImageRef imageContents = CABackingStoreGetCGImage(backingStore);
835             builder.append('\n');
836             printIndent(builder, indent + 1);
837             builder.append("(contents (backing-store [");
838             builder.appendNumber(CGImageGetWidth(imageContents));
839             builder.append(' ');
840             builder.appendNumber(CGImageGetHeight(imageContents));
841             builder.append("]))");
842         }
843     }
844
845     // Print sublayers if needed
846     int n = intern(layer)->sublayerCount();
847     if (n > 0) {
848         builder.append('\n');
849         printIndent(builder, indent + 1);
850         builder.append("(sublayers");
851
852         PlatformCALayerList sublayers;
853         intern(layer)->getSublayers(sublayers);
854         ASSERT(n == sublayers.size());
855         for (int i = 0; i < n; ++i)
856             printLayer(builder, sublayers[i].get(), indent + 2);
857
858         builder.append(')');
859     }
860
861     builder.append(')');
862 }
863
864 String PlatformCALayerWin::layerTreeAsString() const
865 {
866     // Print heading info
867     CGRect rootBounds = bounds();
868
869     StringBuilder builder;
870     builder.append("\n\n** Render tree at time ");
871     builder.appendNumber(monotonicallyIncreasingTime());
872     builder.append(" (bounds ");
873     builder.appendNumber(rootBounds.origin.x);
874     builder.append(", ");
875     builder.appendNumber(rootBounds.origin.y);
876     builder.append(' ');
877     builder.appendNumber(rootBounds.size.width);
878     builder.append('x');
879     builder.appendNumber(rootBounds.size.height);
880     builder.append(") **\n\n");
881
882     // Print layer tree from the root
883     printLayer(builder, this, 0);
884
885     return builder.toString();
886 }
887
888 PassRefPtr<PlatformCALayer> PlatformCALayerWin::createCompatibleLayer(PlatformCALayer::LayerType layerType, PlatformCALayerClient* client) const
889 {
890     return PlatformCALayerWin::create(layerType, client);
891 }
892
893 TiledBacking* PlatformCALayerWin::tiledBacking()
894 {
895     if (!usesTiledBackingLayer())
896         return nullptr;
897
898     return reinterpret_cast<WebTiledBackingLayerWin*>(intern(this))->tiledBacking();
899 }
900
901 void PlatformCALayerWin::drawTextAtPoint(CGContextRef context, CGFloat x, CGFloat y, const char* message, size_t length) const
902 {
903     String text(message, length);
904
905     FontCascadeDescription desc;
906
907     NONCLIENTMETRICS metrics;
908     metrics.cbSize = sizeof(metrics);
909     SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
910     desc.setOneFamily(metrics.lfSmCaptionFont.lfFaceName);
911
912     desc.setComputedSize(18);
913
914     FontCascade font = FontCascade(desc, 0, 0);
915     font.update(nullptr);
916
917     GraphicsContext cg(context);
918     cg.setFillColor(Color::black, ColorSpaceDeviceRGB);
919     cg.drawText(font, TextRun(text), IntPoint(x, y));
920 }