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_LEOPARD)) 45 46using namespace WebCore; 47 48// This value must be the same as in PlatformCAAnimationMac.mm 49static NSString * const WKNonZeroBeginTimeFlag = @"WKPlatformCAAnimationNonZeroBeginTimeFlag"; 50 51static 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_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 95- (void)setAcceleratesDrawing:(BOOL)flag; 96- (BOOL)acceleratesDrawing; 97#endif 98@end 99 100static NSString * const platformCALayerPointer = @"WKPlatformCALayer"; 101 102bool PlatformCALayer::isValueFunctionSupported() 103{ 104 static bool sHaveValueFunction = [CAPropertyAnimation instancesRespondToSelector:@selector(setValueFunction:)]; 105 return sHaveValueFunction; 106} 107 108void 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 117static 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 137static 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 148PassRefPtr<PlatformCALayer> PlatformCALayer::create(LayerType layerType, PlatformCALayerClient* owner) 149{ 150 return adoptRef(new PlatformCALayer(layerType, 0, owner)); 151} 152 153PassRefPtr<PlatformCALayer> PlatformCALayer::create(void* platformLayer, PlatformCALayerClient* owner) 154{ 155 return adoptRef(new PlatformCALayer(LayerTypeCustom, static_cast<PlatformLayer*>(platformLayer), owner)); 156} 157 158PlatformCALayer::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 209PlatformCALayer::~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 221PlatformCALayer* 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 234PlatformLayer* PlatformCALayer::platformLayer() const 235{ 236 return m_layer.get(); 237} 238 239void PlatformCALayer::animationStarted(CFTimeInterval beginTime) 240{ 241 if (m_owner) 242 m_owner->platformCALayerAnimationStarted(beginTime); 243} 244 245void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect) 246{ 247 BEGIN_BLOCK_OBJC_EXCEPTIONS 248 if (dirtyRect) 249 [m_layer.get() setNeedsDisplayInRect:*dirtyRect]; 250 else 251 [m_layer.get() setNeedsDisplay]; 252 END_BLOCK_OBJC_EXCEPTIONS 253} 254 255void PlatformCALayer::setContentsChanged() 256{ 257 BEGIN_BLOCK_OBJC_EXCEPTIONS 258 [m_layer.get() setContentsChanged]; 259 END_BLOCK_OBJC_EXCEPTIONS 260} 261 262PlatformCALayer* PlatformCALayer::superlayer() const 263{ 264 return platformCALayer([m_layer.get() superlayer]); 265} 266 267void PlatformCALayer::removeFromSuperlayer() 268{ 269 BEGIN_BLOCK_OBJC_EXCEPTIONS 270 [m_layer.get() removeFromSuperlayer]; 271 END_BLOCK_OBJC_EXCEPTIONS 272} 273 274void PlatformCALayer::setSublayers(const PlatformCALayerList& list) 275{ 276 // Short circuiting here not only avoids the allocation of sublayers, but avoids <rdar://problem/7390716> (see below) 277 if (list.size() == 0) { 278 removeAllSublayers(); 279 return; 280 } 281 282 BEGIN_BLOCK_OBJC_EXCEPTIONS 283 NSMutableArray* sublayers = [[NSMutableArray alloc] init]; 284 for (size_t i = 0; i < list.size(); ++i) 285 [sublayers addObject:list[i]->m_layer.get()]; 286 287 [m_layer.get() setSublayers:sublayers]; 288 [sublayers release]; 289 END_BLOCK_OBJC_EXCEPTIONS 290} 291 292void PlatformCALayer::removeAllSublayers() 293{ 294 // Workaround for <rdar://problem/7390716>: -[CALayer setSublayers:] crashes if sublayers is an empty array, or nil, under GC. 295 BEGIN_BLOCK_OBJC_EXCEPTIONS 296 if (objc_collectingEnabled()) 297 while ([[m_layer.get() sublayers] count]) 298 [[[m_layer.get() sublayers] objectAtIndex:0] removeFromSuperlayer]; 299 else 300 [m_layer.get() setSublayers:nil]; 301 END_BLOCK_OBJC_EXCEPTIONS 302} 303 304void PlatformCALayer::appendSublayer(PlatformCALayer* layer) 305{ 306 BEGIN_BLOCK_OBJC_EXCEPTIONS 307 [m_layer.get() addSublayer:layer->m_layer.get()]; 308 END_BLOCK_OBJC_EXCEPTIONS 309} 310 311void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index) 312{ 313 BEGIN_BLOCK_OBJC_EXCEPTIONS 314 [m_layer.get() insertSublayer:layer->m_layer.get() atIndex:index]; 315 END_BLOCK_OBJC_EXCEPTIONS 316} 317 318void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* layer) 319{ 320 BEGIN_BLOCK_OBJC_EXCEPTIONS 321 [m_layer.get() replaceSublayer:reference->m_layer.get() with:layer->m_layer.get()]; 322 END_BLOCK_OBJC_EXCEPTIONS 323} 324 325size_t PlatformCALayer::sublayerCount() const 326{ 327 return [[m_layer.get() sublayers] count]; 328} 329 330void PlatformCALayer::adoptSublayers(PlatformCALayer* source) 331{ 332 // Workaround for <rdar://problem/7390716>: -[CALayer setSublayers:] crashes if sublayers is an empty array, or nil, under GC. 333 NSArray* sublayers = [source->m_layer.get() sublayers]; 334 335 if (objc_collectingEnabled() && ![sublayers count]) { 336 BEGIN_BLOCK_OBJC_EXCEPTIONS 337 while ([[m_layer.get() sublayers] count]) 338 [[[m_layer.get() sublayers] objectAtIndex:0] removeFromSuperlayer]; 339 END_BLOCK_OBJC_EXCEPTIONS 340 return; 341 } 342 343 BEGIN_BLOCK_OBJC_EXCEPTIONS 344 [m_layer.get() setSublayers:sublayers]; 345 END_BLOCK_OBJC_EXCEPTIONS 346} 347 348void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation) 349{ 350 // Add the delegate 351 if (!m_delegate) { 352 WebAnimationDelegate* webAnimationDelegate = [[WebAnimationDelegate alloc] init]; 353 m_delegate.adoptNS(webAnimationDelegate); 354 [webAnimationDelegate setOwner:this]; 355 } 356 357 CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>(animation->platformAnimation()); 358 359 if (![propertyAnimation delegate]) 360 [propertyAnimation setDelegate:static_cast<id>(m_delegate.get())]; 361 362 BEGIN_BLOCK_OBJC_EXCEPTIONS 363 [m_layer.get() addAnimation:animation->m_animation.get() forKey:key]; 364 END_BLOCK_OBJC_EXCEPTIONS 365} 366 367void PlatformCALayer::removeAnimationForKey(const String& key) 368{ 369 BEGIN_BLOCK_OBJC_EXCEPTIONS 370 [m_layer.get() removeAnimationForKey:key]; 371 END_BLOCK_OBJC_EXCEPTIONS 372} 373 374PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key) 375{ 376 CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>([m_layer.get() animationForKey:key]); 377 if (!propertyAnimation) 378 return 0; 379 return PlatformCAAnimation::create(propertyAnimation); 380} 381 382PlatformCALayer* PlatformCALayer::mask() const 383{ 384 return platformCALayer([m_layer.get() mask]); 385} 386 387void PlatformCALayer::setMask(PlatformCALayer* layer) 388{ 389 BEGIN_BLOCK_OBJC_EXCEPTIONS 390 [m_layer.get() setMask:layer ? layer->platformLayer() : 0]; 391 END_BLOCK_OBJC_EXCEPTIONS 392} 393 394bool PlatformCALayer::isOpaque() const 395{ 396 return [m_layer.get() isOpaque]; 397} 398 399void PlatformCALayer::setOpaque(bool value) 400{ 401 BEGIN_BLOCK_OBJC_EXCEPTIONS 402 [m_layer.get() setOpaque:value]; 403 END_BLOCK_OBJC_EXCEPTIONS 404} 405 406FloatRect PlatformCALayer::bounds() const 407{ 408 return [m_layer.get() bounds]; 409} 410 411void PlatformCALayer::setBounds(const FloatRect& value) 412{ 413 BEGIN_BLOCK_OBJC_EXCEPTIONS 414 [m_layer.get() setBounds:value]; 415 END_BLOCK_OBJC_EXCEPTIONS 416} 417 418FloatPoint3D PlatformCALayer::position() const 419{ 420 CGPoint point = [m_layer.get() position]; 421 return FloatPoint3D(point.x, point.y, [m_layer.get() zPosition]); 422} 423 424void PlatformCALayer::setPosition(const FloatPoint3D& value) 425{ 426 BEGIN_BLOCK_OBJC_EXCEPTIONS 427 [m_layer.get() setPosition:CGPointMake(value.x(), value.y())]; 428 [m_layer.get() setZPosition:value.z()]; 429 END_BLOCK_OBJC_EXCEPTIONS 430} 431 432FloatPoint3D PlatformCALayer::anchorPoint() const 433{ 434 CGPoint point = [m_layer.get() anchorPoint]; 435 float z = 0; 436#if HAVE_MODERN_QUARTZCORE 437 z = [m_layer.get() anchorPointZ]; 438#endif 439 return FloatPoint3D(point.x, point.y, z); 440} 441 442void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value) 443{ 444 BEGIN_BLOCK_OBJC_EXCEPTIONS 445 [m_layer.get() setAnchorPoint:CGPointMake(value.x(), value.y())]; 446#if HAVE_MODERN_QUARTZCORE 447 [m_layer.get() setAnchorPointZ:value.z()]; 448#endif 449 END_BLOCK_OBJC_EXCEPTIONS 450} 451 452TransformationMatrix PlatformCALayer::transform() const 453{ 454 return [m_layer.get() transform]; 455} 456 457void PlatformCALayer::setTransform(const TransformationMatrix& value) 458{ 459 BEGIN_BLOCK_OBJC_EXCEPTIONS 460 [m_layer.get() setTransform:value]; 461 END_BLOCK_OBJC_EXCEPTIONS 462} 463 464TransformationMatrix PlatformCALayer::sublayerTransform() const 465{ 466 return [m_layer.get() sublayerTransform]; 467} 468 469void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value) 470{ 471 BEGIN_BLOCK_OBJC_EXCEPTIONS 472 [m_layer.get() setSublayerTransform:value]; 473 END_BLOCK_OBJC_EXCEPTIONS 474} 475 476TransformationMatrix PlatformCALayer::contentsTransform() const 477{ 478#if !HAVE_MODERN_QUARTZCORE 479 if (m_layerType != LayerTypeWebLayer) 480 return TransformationMatrix(); 481 482 return [static_cast<WebLayer*>(m_layer.get()) contentsTransform]; 483#else 484 return TransformationMatrix(); 485#endif 486} 487 488void PlatformCALayer::setContentsTransform(const TransformationMatrix& value) 489{ 490#if !HAVE_MODERN_QUARTZCORE 491 if (m_layerType != LayerTypeWebLayer) 492 return; 493 494 BEGIN_BLOCK_OBJC_EXCEPTIONS 495 [m_layer.get() setContentsTransform:value]; 496 END_BLOCK_OBJC_EXCEPTIONS 497#else 498 UNUSED_PARAM(value); 499#endif 500} 501 502bool PlatformCALayer::isHidden() const 503{ 504 return [m_layer.get() isHidden]; 505} 506 507void PlatformCALayer::setHidden(bool value) 508{ 509 BEGIN_BLOCK_OBJC_EXCEPTIONS 510 [m_layer.get() setHidden:value]; 511 END_BLOCK_OBJC_EXCEPTIONS 512} 513 514bool PlatformCALayer::isGeometryFlipped() const 515{ 516#if HAVE_MODERN_QUARTZCORE 517 return [m_layer.get() isGeometryFlipped]; 518#else 519 return false; 520#endif 521} 522 523void PlatformCALayer::setGeometryFlipped(bool value) 524{ 525#if HAVE_MODERN_QUARTZCORE 526 BEGIN_BLOCK_OBJC_EXCEPTIONS 527 [m_layer.get() setGeometryFlipped:value]; 528 END_BLOCK_OBJC_EXCEPTIONS 529#else 530 UNUSED_PARAM(value); 531#endif 532} 533 534bool PlatformCALayer::isDoubleSided() const 535{ 536 return [m_layer.get() isDoubleSided]; 537} 538 539void PlatformCALayer::setDoubleSided(bool value) 540{ 541 BEGIN_BLOCK_OBJC_EXCEPTIONS 542 [m_layer.get() setDoubleSided:value]; 543 END_BLOCK_OBJC_EXCEPTIONS 544} 545 546bool PlatformCALayer::masksToBounds() const 547{ 548 return [m_layer.get() masksToBounds]; 549} 550 551void PlatformCALayer::setMasksToBounds(bool value) 552{ 553 BEGIN_BLOCK_OBJC_EXCEPTIONS 554 [m_layer.get() setMasksToBounds:value]; 555 END_BLOCK_OBJC_EXCEPTIONS 556} 557 558bool PlatformCALayer::acceleratesDrawing() const 559{ 560#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 561 return [m_layer.get() acceleratesDrawing]; 562#else 563 return false; 564#endif 565} 566 567void PlatformCALayer::setAcceleratesDrawing(bool acceleratesDrawing) 568{ 569#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 570 BEGIN_BLOCK_OBJC_EXCEPTIONS 571 [m_layer.get() setAcceleratesDrawing:acceleratesDrawing]; 572 END_BLOCK_OBJC_EXCEPTIONS 573#else 574 UNUSED_PARAM(acceleratesDrawing); 575#endif 576} 577 578CFTypeRef PlatformCALayer::contents() const 579{ 580 return [m_layer.get() contents]; 581} 582 583void PlatformCALayer::setContents(CFTypeRef value) 584{ 585 BEGIN_BLOCK_OBJC_EXCEPTIONS 586 [m_layer.get() setContents:static_cast<id>(const_cast<void*>(value))]; 587 END_BLOCK_OBJC_EXCEPTIONS 588} 589 590FloatRect PlatformCALayer::contentsRect() const 591{ 592 return [m_layer.get() contentsRect]; 593} 594 595void PlatformCALayer::setContentsRect(const FloatRect& value) 596{ 597 BEGIN_BLOCK_OBJC_EXCEPTIONS 598 [m_layer.get() setContentsRect:value]; 599 END_BLOCK_OBJC_EXCEPTIONS 600} 601 602void PlatformCALayer::setMinificationFilter(FilterType value) 603{ 604#if HAVE_MODERN_QUARTZCORE 605 BEGIN_BLOCK_OBJC_EXCEPTIONS 606 [m_layer.get() setMinificationFilter:toCAFilterType(value)]; 607 END_BLOCK_OBJC_EXCEPTIONS 608#else 609 UNUSED_PARAM(value); 610#endif 611} 612 613void PlatformCALayer::setMagnificationFilter(FilterType value) 614{ 615#if HAVE_MODERN_QUARTZCORE 616 BEGIN_BLOCK_OBJC_EXCEPTIONS 617 [m_layer.get() setMagnificationFilter:toCAFilterType(value)]; 618 END_BLOCK_OBJC_EXCEPTIONS 619#else 620 UNUSED_PARAM(value); 621#endif 622} 623 624Color PlatformCALayer::backgroundColor() const 625{ 626 return [m_layer.get() backgroundColor]; 627} 628 629void PlatformCALayer::setBackgroundColor(const Color& value) 630{ 631 CGFloat components[4]; 632 value.getRGBA(components[0], components[1], components[2], components[3]); 633 634 RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); 635 RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components)); 636 637 BEGIN_BLOCK_OBJC_EXCEPTIONS 638 [m_layer.get() setBackgroundColor:color.get()]; 639 END_BLOCK_OBJC_EXCEPTIONS 640} 641 642float PlatformCALayer::borderWidth() const 643{ 644 return [m_layer.get() borderWidth]; 645} 646 647void PlatformCALayer::setBorderWidth(float value) 648{ 649 BEGIN_BLOCK_OBJC_EXCEPTIONS 650 [m_layer.get() setBorderWidth:value]; 651 END_BLOCK_OBJC_EXCEPTIONS 652} 653 654Color PlatformCALayer::borderColor() const 655{ 656 return [m_layer.get() borderColor]; 657} 658 659void PlatformCALayer::setBorderColor(const Color& value) 660{ 661 CGFloat components[4]; 662 value.getRGBA(components[0], components[1], components[2], components[3]); 663 664 RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); 665 RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components)); 666 667 BEGIN_BLOCK_OBJC_EXCEPTIONS 668 [m_layer.get() setBorderColor:color.get()]; 669 END_BLOCK_OBJC_EXCEPTIONS 670} 671 672float PlatformCALayer::opacity() const 673{ 674 return [m_layer.get() opacity]; 675} 676 677void PlatformCALayer::setOpacity(float value) 678{ 679 BEGIN_BLOCK_OBJC_EXCEPTIONS 680 [m_layer.get() setOpacity:value]; 681 END_BLOCK_OBJC_EXCEPTIONS 682} 683 684String PlatformCALayer::name() const 685{ 686 return [m_layer.get() name]; 687} 688 689void PlatformCALayer::setName(const String& value) 690{ 691 BEGIN_BLOCK_OBJC_EXCEPTIONS 692 [m_layer.get() setName:value]; 693 END_BLOCK_OBJC_EXCEPTIONS 694} 695 696FloatRect PlatformCALayer::frame() const 697{ 698 return [m_layer.get() frame]; 699} 700 701void PlatformCALayer::setFrame(const FloatRect& value) 702{ 703 BEGIN_BLOCK_OBJC_EXCEPTIONS 704 [m_layer.get() setFrame:value]; 705 END_BLOCK_OBJC_EXCEPTIONS 706} 707 708float PlatformCALayer::speed() const 709{ 710 return [m_layer.get() speed]; 711} 712 713void PlatformCALayer::setSpeed(float value) 714{ 715 BEGIN_BLOCK_OBJC_EXCEPTIONS 716 [m_layer.get() setSpeed:value]; 717 END_BLOCK_OBJC_EXCEPTIONS 718} 719 720CFTimeInterval PlatformCALayer::timeOffset() const 721{ 722 return [m_layer.get() timeOffset]; 723} 724 725void PlatformCALayer::setTimeOffset(CFTimeInterval value) 726{ 727 BEGIN_BLOCK_OBJC_EXCEPTIONS 728 [m_layer.get() setTimeOffset:value]; 729 END_BLOCK_OBJC_EXCEPTIONS 730} 731 732float PlatformCALayer::contentsScale() const 733{ 734#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 735 return [m_layer.get() contentsScale]; 736#else 737 return 1; 738#endif 739} 740 741void PlatformCALayer::setContentsScale(float value) 742{ 743#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 744 BEGIN_BLOCK_OBJC_EXCEPTIONS 745 [m_layer.get() setContentsScale:value]; 746 END_BLOCK_OBJC_EXCEPTIONS 747#else 748 UNUSED_PARAM(value); 749#endif 750} 751 752#endif // USE(ACCELERATED_COMPOSITING) 753