1 /* 2 * Copyright (C) 2010 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 COMPUTER, 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 #if USE(ACCELERATED_COMPOSITING) 29 30 #import "PlatformCALayer.h" 31 32 #import "BlockExceptions.h" 33 #import "FloatConversion.h" 34 #import "GraphicsContext.h" 35 #import "GraphicsLayerCA.h" 36 #import "WebLayer.h" 37 #import "WebTiledLayer.h" 38 #import <objc/objc-auto.h> 39 #import <objc/objc-runtime.h> 40 #import <QuartzCore/QuartzCore.h> 41 #import <wtf/CurrentTime.h> 42 #import <wtf/UnusedParam.h> 43 44 #define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)) 45 46 using namespace WebCore; 47 48 // This value must be the same as in PlatformCAAnimationMac.mm 49 static NSString * const WKNonZeroBeginTimeFlag = @"WKPlatformCAAnimationNonZeroBeginTimeFlag"; 50 51 static double mediaTimeToCurrentTime(CFTimeInterval t) 52 { 53 return WTF::currentTime() + t - CACurrentMediaTime(); 54 } 55 56 // Delegate for animationDidStart callback 57 @interface WebAnimationDelegate : NSObject { 58 PlatformCALayer* m_owner; 59 } 60 61 - (void)animationDidStart:(CAAnimation *)anim; 62 - (void)setOwner:(PlatformCALayer*)owner; 63 64 @end 65 66 @implementation WebAnimationDelegate 67 68 - (void)animationDidStart:(CAAnimation *)animation 69 { 70 // hasNonZeroBeginTime is stored in a key in the animation 71 bool hasNonZeroBeginTime = [[animation valueForKey:WKNonZeroBeginTimeFlag] boolValue]; 72 CFTimeInterval startTime; 73 74 if (hasNonZeroBeginTime) { 75 // We don't know what time CA used to commit the animation, so just use the current time 76 // (even though this will be slightly off). 77 startTime = mediaTimeToCurrentTime(CACurrentMediaTime()); 78 } else 79 startTime = mediaTimeToCurrentTime([animation beginTime]); 80 81 if (m_owner) 82 m_owner->animationStarted(startTime); 83 } 84 85 - (void)setOwner:(PlatformCALayer*)owner 86 { 87 m_owner = owner; 88 } 89 90 @end 91 92 @interface CALayer(Private) 93 - (void)setContentsChanged; 94 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 95 - (void)setAcceleratesDrawing:(BOOL)flag; 96 - (BOOL)acceleratesDrawing; 97 #endif 98 @end 99 100 static NSString * const platformCALayerPointer = @"WKPlatformCALayer"; 101 102 bool PlatformCALayer::isValueFunctionSupported() 103 { 104 static bool sHaveValueFunction = [CAPropertyAnimation instancesRespondToSelector:@selector(setValueFunction:)]; 105 return sHaveValueFunction; 106 } 107 108 void PlatformCALayer::setOwner(PlatformCALayerClient* owner) 109 { 110 m_owner = owner; 111 112 // Change the delegate's owner if needed 113 if (m_delegate) 114 [static_cast<WebAnimationDelegate*>(m_delegate.get()) setOwner:this]; 115 } 116 117 static NSDictionary* nullActionsDictionary() 118 { 119 NSNull* nullValue = [NSNull null]; 120 NSDictionary* actions = [NSDictionary dictionaryWithObjectsAndKeys: 121 nullValue, @"anchorPoint", 122 nullValue, @"bounds", 123 nullValue, @"contents", 124 nullValue, @"contentsRect", 125 nullValue, @"opacity", 126 nullValue, @"position", 127 nullValue, @"shadowColor", 128 nullValue, @"sublayerTransform", 129 nullValue, @"sublayers", 130 nullValue, @"transform", 131 nullValue, @"zPosition", 132 nil]; 133 return actions; 134 } 135 136 #if HAVE_MODERN_QUARTZCORE 137 static NSString* toCAFilterType(PlatformCALayer::FilterType type) 138 { 139 switch (type) { 140 case PlatformCALayer::Linear: return kCAFilterLinear; 141 case PlatformCALayer::Nearest: return kCAFilterNearest; 142 case PlatformCALayer::Trilinear: return kCAFilterTrilinear; 143 default: return 0; 144 } 145 } 146 #endif 147 148 PassRefPtr<PlatformCALayer> PlatformCALayer::create(LayerType layerType, PlatformCALayerClient* owner) 149 { 150 return adoptRef(new PlatformCALayer(layerType, 0, owner)); 151 } 152 153 PassRefPtr<PlatformCALayer> PlatformCALayer::create(void* platformLayer, PlatformCALayerClient* owner) 154 { 155 return adoptRef(new PlatformCALayer(LayerTypeCustom, static_cast<PlatformLayer*>(platformLayer), owner)); 156 } 157 158 PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformLayer* layer, PlatformCALayerClient* owner) 159 : m_owner(owner) 160 { 161 BEGIN_BLOCK_OBJC_EXCEPTIONS 162 if (layer) { 163 m_layerType = LayerTypeCustom; 164 m_layer = layer; 165 } else { 166 m_layerType = layerType; 167 168 Class layerClass = Nil; 169 switch(layerType) { 170 case LayerTypeLayer: 171 case LayerTypeRootLayer: 172 layerClass = [CALayer class]; 173 break; 174 case LayerTypeWebLayer: 175 layerClass = [WebLayer class]; 176 break; 177 case LayerTypeTransformLayer: 178 layerClass = NSClassFromString(@"CATransformLayer"); 179 break; 180 case LayerTypeWebTiledLayer: 181 layerClass = [WebTiledLayer class]; 182 break; 183 case LayerTypeCustom: 184 break; 185 } 186 187 if (layerClass) 188 m_layer.adoptNS([[layerClass alloc] init]); 189 } 190 191 // Save a pointer to 'this' in the CALayer 192 [m_layer.get() setValue:[NSValue valueWithPointer:this] forKey:platformCALayerPointer]; 193 194 // Clear all the implicit animations on the CALayer 195 [m_layer.get() setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]]; 196 197 // If this is a TiledLayer, set some initial values 198 if (m_layerType == LayerTypeWebTiledLayer) { 199 WebTiledLayer* tiledLayer = static_cast<WebTiledLayer*>(m_layer.get()); 200 [tiledLayer setTileSize:CGSizeMake(GraphicsLayerCA::kTiledLayerTileSize, GraphicsLayerCA::kTiledLayerTileSize)]; 201 [tiledLayer setLevelsOfDetail:1]; 202 [tiledLayer setLevelsOfDetailBias:0]; 203 [tiledLayer setContentsGravity:@"bottomLeft"]; 204 } 205 206 END_BLOCK_OBJC_EXCEPTIONS 207 } 208 209 PlatformCALayer::~PlatformCALayer() 210 { 211 [m_layer.get() setValue:nil forKey:platformCALayerPointer]; 212 213 // Clear the owner, which also clears it in the delegate to prevent attempts 214 // to use the GraphicsLayerCA after it has been destroyed. 215 setOwner(0); 216 217 // Remove the owner pointer from the delegate in case there is a pending animationStarted event. 218 [static_cast<WebAnimationDelegate*>(m_delegate.get()) setOwner:nil]; 219 } 220 221 PlatformCALayer* PlatformCALayer::platformCALayer(void* platformLayer) 222 { 223 if (!platformLayer) 224 return 0; 225 226 // Pointer to PlatformCALayer is kept in a key of the CALayer 227 PlatformCALayer* platformCALayer = nil; 228 BEGIN_BLOCK_OBJC_EXCEPTIONS 229 platformCALayer = static_cast<PlatformCALayer*>([[static_cast<CALayer*>(platformLayer) valueForKey:platformCALayerPointer] pointerValue]); 230 END_BLOCK_OBJC_EXCEPTIONS 231 return platformCALayer; 232 } 233 234 PlatformLayer* PlatformCALayer::platformLayer() const 235 { 236 return m_layer.get(); 237 } 238 239 void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect) 240 { 241 BEGIN_BLOCK_OBJC_EXCEPTIONS 242 if (dirtyRect) 243 [m_layer.get() setNeedsDisplayInRect:*dirtyRect]; 244 else 245 [m_layer.get() setNeedsDisplay]; 246 END_BLOCK_OBJC_EXCEPTIONS 247 } 248 249 void PlatformCALayer::setContentsChanged() 250 { 251 BEGIN_BLOCK_OBJC_EXCEPTIONS 252 [m_layer.get() setContentsChanged]; 253 END_BLOCK_OBJC_EXCEPTIONS 254 } 255 256 PlatformCALayer* PlatformCALayer::superlayer() const 257 { 258 return platformCALayer([m_layer.get() superlayer]); 259 } 260 261 void PlatformCALayer::removeFromSuperlayer() 262 { 263 BEGIN_BLOCK_OBJC_EXCEPTIONS 264 [m_layer.get() removeFromSuperlayer]; 265 END_BLOCK_OBJC_EXCEPTIONS 266 } 267 268 void PlatformCALayer::setSublayers(const PlatformCALayerList& list) 269 { 270 // Short circuiting here not only avoids the allocation of sublayers, but avoids <rdar://problem/7390716> (see below) 271 if (list.size() == 0) { 272 removeAllSublayers(); 273 return; 274 } 275 276 BEGIN_BLOCK_OBJC_EXCEPTIONS 277 NSMutableArray* sublayers = [[NSMutableArray alloc] init]; 278 for (size_t i = 0; i < list.size(); ++i) 279 [sublayers addObject:list[i]->m_layer.get()]; 280 281 [m_layer.get() setSublayers:sublayers]; 282 [sublayers release]; 283 END_BLOCK_OBJC_EXCEPTIONS 284 } 285 286 void PlatformCALayer::removeAllSublayers() 287 { 288 // Workaround for <rdar://problem/7390716>: -[CALayer setSublayers:] crashes if sublayers is an empty array, or nil, under GC. 289 BEGIN_BLOCK_OBJC_EXCEPTIONS 290 if (objc_collectingEnabled()) 291 while ([[m_layer.get() sublayers] count]) 292 [[[m_layer.get() sublayers] objectAtIndex:0] removeFromSuperlayer]; 293 else 294 [m_layer.get() setSublayers:nil]; 295 END_BLOCK_OBJC_EXCEPTIONS 296 } 297 298 void PlatformCALayer::appendSublayer(PlatformCALayer* layer) 299 { 300 BEGIN_BLOCK_OBJC_EXCEPTIONS 301 [m_layer.get() addSublayer:layer->m_layer.get()]; 302 END_BLOCK_OBJC_EXCEPTIONS 303 } 304 305 void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index) 306 { 307 BEGIN_BLOCK_OBJC_EXCEPTIONS 308 [m_layer.get() insertSublayer:layer->m_layer.get() atIndex:index]; 309 END_BLOCK_OBJC_EXCEPTIONS 310 } 311 312 void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* layer) 313 { 314 BEGIN_BLOCK_OBJC_EXCEPTIONS 315 [m_layer.get() replaceSublayer:reference->m_layer.get() with:layer->m_layer.get()]; 316 END_BLOCK_OBJC_EXCEPTIONS 317 } 318 319 size_t PlatformCALayer::sublayerCount() const 320 { 321 return [[m_layer.get() sublayers] count]; 322 } 323 324 void PlatformCALayer::adoptSublayers(PlatformCALayer* source) 325 { 326 // Workaround for <rdar://problem/7390716>: -[CALayer setSublayers:] crashes if sublayers is an empty array, or nil, under GC. 327 NSArray* sublayers = [source->m_layer.get() sublayers]; 328 329 if (objc_collectingEnabled() && ![sublayers count]) { 330 BEGIN_BLOCK_OBJC_EXCEPTIONS 331 while ([[m_layer.get() sublayers] count]) 332 [[[m_layer.get() sublayers] objectAtIndex:0] removeFromSuperlayer]; 333 END_BLOCK_OBJC_EXCEPTIONS 334 return; 335 } 336 337 BEGIN_BLOCK_OBJC_EXCEPTIONS 338 [m_layer.get() setSublayers:sublayers]; 339 END_BLOCK_OBJC_EXCEPTIONS 340 } 341 342 void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation) 343 { 344 // Add the delegate 345 if (!m_delegate) { 346 WebAnimationDelegate* webAnimationDelegate = [[WebAnimationDelegate alloc] init]; 347 m_delegate.adoptNS(webAnimationDelegate); 348 [webAnimationDelegate setOwner:this]; 349 } 350 351 CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>(animation->platformAnimation()); 352 353 if (![propertyAnimation delegate]) 354 [propertyAnimation setDelegate:static_cast<id>(m_delegate.get())]; 355 356 BEGIN_BLOCK_OBJC_EXCEPTIONS 357 [m_layer.get() addAnimation:animation->m_animation.get() forKey:key]; 358 END_BLOCK_OBJC_EXCEPTIONS 359 } 360 361 void PlatformCALayer::removeAnimationForKey(const String& key) 362 { 363 BEGIN_BLOCK_OBJC_EXCEPTIONS 364 [m_layer.get() removeAnimationForKey:key]; 365 END_BLOCK_OBJC_EXCEPTIONS 366 } 367 368 PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key) 369 { 370 CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>([m_layer.get() animationForKey:key]); 371 if (!propertyAnimation) 372 return 0; 373 return PlatformCAAnimation::create(propertyAnimation); 374 } 375 376 PlatformCALayer* PlatformCALayer::mask() const 377 { 378 return platformCALayer([m_layer.get() mask]); 379 } 380 381 void PlatformCALayer::setMask(PlatformCALayer* layer) 382 { 383 BEGIN_BLOCK_OBJC_EXCEPTIONS 384 [m_layer.get() setMask:layer ? layer->platformLayer() : 0]; 385 END_BLOCK_OBJC_EXCEPTIONS 386 } 387 388 bool PlatformCALayer::isOpaque() const 389 { 390 return [m_layer.get() isOpaque]; 391 } 392 393 void PlatformCALayer::setOpaque(bool value) 394 { 395 BEGIN_BLOCK_OBJC_EXCEPTIONS 396 [m_layer.get() setOpaque:value]; 397 END_BLOCK_OBJC_EXCEPTIONS 398 } 399 400 FloatRect PlatformCALayer::bounds() const 401 { 402 return [m_layer.get() bounds]; 403 } 404 405 void PlatformCALayer::setBounds(const FloatRect& value) 406 { 407 BEGIN_BLOCK_OBJC_EXCEPTIONS 408 [m_layer.get() setBounds:value]; 409 END_BLOCK_OBJC_EXCEPTIONS 410 } 411 412 FloatPoint3D PlatformCALayer::position() const 413 { 414 CGPoint point = [m_layer.get() position]; 415 return FloatPoint3D(point.x, point.y, [m_layer.get() zPosition]); 416 } 417 418 void PlatformCALayer::setPosition(const FloatPoint3D& value) 419 { 420 BEGIN_BLOCK_OBJC_EXCEPTIONS 421 [m_layer.get() setPosition:CGPointMake(value.x(), value.y())]; 422 [m_layer.get() setZPosition:value.z()]; 423 END_BLOCK_OBJC_EXCEPTIONS 424 } 425 426 FloatPoint3D PlatformCALayer::anchorPoint() const 427 { 428 CGPoint point = [m_layer.get() anchorPoint]; 429 float z = 0; 430 #if HAVE_MODERN_QUARTZCORE 431 z = [m_layer.get() anchorPointZ]; 432 #endif 433 return FloatPoint3D(point.x, point.y, z); 434 } 435 436 void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value) 437 { 438 BEGIN_BLOCK_OBJC_EXCEPTIONS 439 [m_layer.get() setAnchorPoint:CGPointMake(value.x(), value.y())]; 440 #if HAVE_MODERN_QUARTZCORE 441 [m_layer.get() setAnchorPointZ:value.z()]; 442 #endif 443 END_BLOCK_OBJC_EXCEPTIONS 444 } 445 446 TransformationMatrix PlatformCALayer::transform() const 447 { 448 return [m_layer.get() transform]; 449 } 450 451 void PlatformCALayer::setTransform(const TransformationMatrix& value) 452 { 453 BEGIN_BLOCK_OBJC_EXCEPTIONS 454 [m_layer.get() setTransform:value]; 455 END_BLOCK_OBJC_EXCEPTIONS 456 } 457 458 TransformationMatrix PlatformCALayer::sublayerTransform() const 459 { 460 return [m_layer.get() sublayerTransform]; 461 } 462 463 void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value) 464 { 465 BEGIN_BLOCK_OBJC_EXCEPTIONS 466 [m_layer.get() setSublayerTransform:value]; 467 END_BLOCK_OBJC_EXCEPTIONS 468 } 469 470 TransformationMatrix PlatformCALayer::contentsTransform() const 471 { 472 #if !HAVE_MODERN_QUARTZCORE 473 if (m_layerType != LayerTypeWebLayer) 474 return TransformationMatrix(); 475 476 return [static_cast<WebLayer*>(m_layer.get()) contentsTransform]; 477 #else 478 return TransformationMatrix(); 479 #endif 480 } 481 482 void PlatformCALayer::setContentsTransform(const TransformationMatrix& value) 483 { 484 #if !HAVE_MODERN_QUARTZCORE 485 if (m_layerType != LayerTypeWebLayer) 486 return; 487 488 BEGIN_BLOCK_OBJC_EXCEPTIONS 489 [m_layer.get() setContentsTransform:value]; 490 END_BLOCK_OBJC_EXCEPTIONS 491 #else 492 UNUSED_PARAM(value); 493 #endif 494 } 495 496 bool PlatformCALayer::isHidden() const 497 { 498 return [m_layer.get() isHidden]; 499 } 500 501 void PlatformCALayer::setHidden(bool value) 502 { 503 BEGIN_BLOCK_OBJC_EXCEPTIONS 504 [m_layer.get() setHidden:value]; 505 END_BLOCK_OBJC_EXCEPTIONS 506 } 507 508 bool PlatformCALayer::isGeometryFlipped() const 509 { 510 #if HAVE_MODERN_QUARTZCORE 511 return [m_layer.get() isGeometryFlipped]; 512 #else 513 return false; 514 #endif 515 } 516 517 void PlatformCALayer::setGeometryFlipped(bool value) 518 { 519 #if HAVE_MODERN_QUARTZCORE 520 BEGIN_BLOCK_OBJC_EXCEPTIONS 521 [m_layer.get() setGeometryFlipped:value]; 522 END_BLOCK_OBJC_EXCEPTIONS 523 #else 524 UNUSED_PARAM(value); 525 #endif 526 } 527 528 bool PlatformCALayer::isDoubleSided() const 529 { 530 return [m_layer.get() isDoubleSided]; 531 } 532 533 void PlatformCALayer::setDoubleSided(bool value) 534 { 535 BEGIN_BLOCK_OBJC_EXCEPTIONS 536 [m_layer.get() setDoubleSided:value]; 537 END_BLOCK_OBJC_EXCEPTIONS 538 } 539 540 bool PlatformCALayer::masksToBounds() const 541 { 542 return [m_layer.get() masksToBounds]; 543 } 544 545 void PlatformCALayer::setMasksToBounds(bool value) 546 { 547 BEGIN_BLOCK_OBJC_EXCEPTIONS 548 [m_layer.get() setMasksToBounds:value]; 549 END_BLOCK_OBJC_EXCEPTIONS 550 } 551 552 bool PlatformCALayer::acceleratesDrawing() const 553 { 554 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 555 return [m_layer.get() acceleratesDrawing]; 556 #else 557 return false; 558 #endif 559 } 560 561 void PlatformCALayer::setAcceleratesDrawing(bool acceleratesDrawing) 562 { 563 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 564 BEGIN_BLOCK_OBJC_EXCEPTIONS 565 [m_layer.get() setAcceleratesDrawing:acceleratesDrawing]; 566 END_BLOCK_OBJC_EXCEPTIONS 567 #else 568 UNUSED_PARAM(acceleratesDrawing); 569 #endif 570 } 571 572 CFTypeRef PlatformCALayer::contents() const 573 { 574 return [m_layer.get() contents]; 575 } 576 577 void PlatformCALayer::setContents(CFTypeRef value) 578 { 579 BEGIN_BLOCK_OBJC_EXCEPTIONS 580 [m_layer.get() setContents:static_cast<id>(const_cast<void*>(value))]; 581 END_BLOCK_OBJC_EXCEPTIONS 582 } 583 584 FloatRect PlatformCALayer::contentsRect() const 585 { 586 return [m_layer.get() contentsRect]; 587 } 588 589 void PlatformCALayer::setContentsRect(const FloatRect& value) 590 { 591 BEGIN_BLOCK_OBJC_EXCEPTIONS 592 [m_layer.get() setContentsRect:value]; 593 END_BLOCK_OBJC_EXCEPTIONS 594 } 595 596 void PlatformCALayer::setMinificationFilter(FilterType value) 597 { 598 #if HAVE_MODERN_QUARTZCORE 599 BEGIN_BLOCK_OBJC_EXCEPTIONS 600 [m_layer.get() setMinificationFilter:toCAFilterType(value)]; 601 END_BLOCK_OBJC_EXCEPTIONS 602 #else 603 UNUSED_PARAM(value); 604 #endif 605 } 606 607 void PlatformCALayer::setMagnificationFilter(FilterType value) 608 { 609 #if HAVE_MODERN_QUARTZCORE 610 BEGIN_BLOCK_OBJC_EXCEPTIONS 611 [m_layer.get() setMagnificationFilter:toCAFilterType(value)]; 612 END_BLOCK_OBJC_EXCEPTIONS 613 #else 614 UNUSED_PARAM(value); 615 #endif 616 } 617 618 Color PlatformCALayer::backgroundColor() const 619 { 620 return [m_layer.get() backgroundColor]; 621 } 622 623 void PlatformCALayer::setBackgroundColor(const Color& value) 624 { 625 CGFloat components[4]; 626 value.getRGBA(components[0], components[1], components[2], components[3]); 627 628 RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); 629 RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components)); 630 631 BEGIN_BLOCK_OBJC_EXCEPTIONS 632 [m_layer.get() setBackgroundColor:color.get()]; 633 END_BLOCK_OBJC_EXCEPTIONS 634 } 635 636 float PlatformCALayer::borderWidth() const 637 { 638 return [m_layer.get() borderWidth]; 639 } 640 641 void PlatformCALayer::setBorderWidth(float value) 642 { 643 BEGIN_BLOCK_OBJC_EXCEPTIONS 644 [m_layer.get() setBorderWidth:value]; 645 END_BLOCK_OBJC_EXCEPTIONS 646 } 647 648 Color PlatformCALayer::borderColor() const 649 { 650 return [m_layer.get() borderColor]; 651 } 652 653 void PlatformCALayer::setBorderColor(const Color& value) 654 { 655 CGFloat components[4]; 656 value.getRGBA(components[0], components[1], components[2], components[3]); 657 658 RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); 659 RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components)); 660 661 BEGIN_BLOCK_OBJC_EXCEPTIONS 662 [m_layer.get() setBorderColor:color.get()]; 663 END_BLOCK_OBJC_EXCEPTIONS 664 } 665 666 float PlatformCALayer::opacity() const 667 { 668 return [m_layer.get() opacity]; 669 } 670 671 void PlatformCALayer::setOpacity(float value) 672 { 673 BEGIN_BLOCK_OBJC_EXCEPTIONS 674 [m_layer.get() setOpacity:value]; 675 END_BLOCK_OBJC_EXCEPTIONS 676 } 677 678 String PlatformCALayer::name() const 679 { 680 return [m_layer.get() name]; 681 } 682 683 void PlatformCALayer::setName(const String& value) 684 { 685 BEGIN_BLOCK_OBJC_EXCEPTIONS 686 [m_layer.get() setName:value]; 687 END_BLOCK_OBJC_EXCEPTIONS 688 } 689 690 FloatRect PlatformCALayer::frame() const 691 { 692 return [m_layer.get() frame]; 693 } 694 695 void PlatformCALayer::setFrame(const FloatRect& value) 696 { 697 BEGIN_BLOCK_OBJC_EXCEPTIONS 698 [m_layer.get() setFrame:value]; 699 END_BLOCK_OBJC_EXCEPTIONS 700 } 701 702 float PlatformCALayer::speed() const 703 { 704 return [m_layer.get() speed]; 705 } 706 707 void PlatformCALayer::setSpeed(float value) 708 { 709 BEGIN_BLOCK_OBJC_EXCEPTIONS 710 [m_layer.get() setSpeed:value]; 711 END_BLOCK_OBJC_EXCEPTIONS 712 } 713 714 CFTimeInterval PlatformCALayer::timeOffset() const 715 { 716 return [m_layer.get() timeOffset]; 717 } 718 719 void PlatformCALayer::setTimeOffset(CFTimeInterval value) 720 { 721 BEGIN_BLOCK_OBJC_EXCEPTIONS 722 [m_layer.get() setTimeOffset:value]; 723 END_BLOCK_OBJC_EXCEPTIONS 724 } 725 726 float PlatformCALayer::contentsScale() const 727 { 728 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 729 return [m_layer.get() contentsScale]; 730 #else 731 return 1; 732 #endif 733 } 734 735 void PlatformCALayer::setContentsScale(float value) 736 { 737 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 738 BEGIN_BLOCK_OBJC_EXCEPTIONS 739 [m_layer.get() setContentsScale:value]; 740 END_BLOCK_OBJC_EXCEPTIONS 741 #else 742 UNUSED_PARAM(value); 743 #endif 744 } 745 746 #endif // USE(ACCELERATED_COMPOSITING) 747