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 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_TIGER) && !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::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 249void PlatformCALayer::setContentsChanged() 250{ 251 BEGIN_BLOCK_OBJC_EXCEPTIONS 252 [m_layer.get() setContentsChanged]; 253 END_BLOCK_OBJC_EXCEPTIONS 254} 255 256PlatformCALayer* PlatformCALayer::superlayer() const 257{ 258 return platformCALayer([m_layer.get() superlayer]); 259} 260 261void PlatformCALayer::removeFromSuperlayer() 262{ 263 BEGIN_BLOCK_OBJC_EXCEPTIONS 264 [m_layer.get() removeFromSuperlayer]; 265 END_BLOCK_OBJC_EXCEPTIONS 266} 267 268void 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 286void 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 298void 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 305void 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 312void 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 319size_t PlatformCALayer::sublayerCount() const 320{ 321 return [[m_layer.get() sublayers] count]; 322} 323 324void 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 342void 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 361void PlatformCALayer::removeAnimationForKey(const String& key) 362{ 363 BEGIN_BLOCK_OBJC_EXCEPTIONS 364 [m_layer.get() removeAnimationForKey:key]; 365 END_BLOCK_OBJC_EXCEPTIONS 366} 367 368PassRefPtr<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 376PlatformCALayer* PlatformCALayer::mask() const 377{ 378 return platformCALayer([m_layer.get() mask]); 379} 380 381void 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 388bool PlatformCALayer::isOpaque() const 389{ 390 return [m_layer.get() isOpaque]; 391} 392 393void PlatformCALayer::setOpaque(bool value) 394{ 395 BEGIN_BLOCK_OBJC_EXCEPTIONS 396 [m_layer.get() setOpaque:value]; 397 END_BLOCK_OBJC_EXCEPTIONS 398} 399 400FloatRect PlatformCALayer::bounds() const 401{ 402 return [m_layer.get() bounds]; 403} 404 405void PlatformCALayer::setBounds(const FloatRect& value) 406{ 407 BEGIN_BLOCK_OBJC_EXCEPTIONS 408 [m_layer.get() setBounds:value]; 409 END_BLOCK_OBJC_EXCEPTIONS 410} 411 412FloatPoint3D PlatformCALayer::position() const 413{ 414 CGPoint point = [m_layer.get() position]; 415 return FloatPoint3D(point.x, point.y, [m_layer.get() zPosition]); 416} 417 418void 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 426FloatPoint3D 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 436void 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 446TransformationMatrix PlatformCALayer::transform() const 447{ 448 return [m_layer.get() transform]; 449} 450 451void PlatformCALayer::setTransform(const TransformationMatrix& value) 452{ 453 BEGIN_BLOCK_OBJC_EXCEPTIONS 454 [m_layer.get() setTransform:value]; 455 END_BLOCK_OBJC_EXCEPTIONS 456} 457 458TransformationMatrix PlatformCALayer::sublayerTransform() const 459{ 460 return [m_layer.get() sublayerTransform]; 461} 462 463void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value) 464{ 465 BEGIN_BLOCK_OBJC_EXCEPTIONS 466 [m_layer.get() setSublayerTransform:value]; 467 END_BLOCK_OBJC_EXCEPTIONS 468} 469 470TransformationMatrix 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 482void 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 496bool PlatformCALayer::isHidden() const 497{ 498 return [m_layer.get() isHidden]; 499} 500 501void PlatformCALayer::setHidden(bool value) 502{ 503 BEGIN_BLOCK_OBJC_EXCEPTIONS 504 [m_layer.get() setHidden:value]; 505 END_BLOCK_OBJC_EXCEPTIONS 506} 507 508bool PlatformCALayer::isGeometryFlipped() const 509{ 510#if HAVE_MODERN_QUARTZCORE 511 return [m_layer.get() isGeometryFlipped]; 512#else 513 return false; 514#endif 515} 516 517void 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 528bool PlatformCALayer::isDoubleSided() const 529{ 530 return [m_layer.get() isDoubleSided]; 531} 532 533void PlatformCALayer::setDoubleSided(bool value) 534{ 535 BEGIN_BLOCK_OBJC_EXCEPTIONS 536 [m_layer.get() setDoubleSided:value]; 537 END_BLOCK_OBJC_EXCEPTIONS 538} 539 540bool PlatformCALayer::masksToBounds() const 541{ 542 return [m_layer.get() masksToBounds]; 543} 544 545void PlatformCALayer::setMasksToBounds(bool value) 546{ 547 BEGIN_BLOCK_OBJC_EXCEPTIONS 548 [m_layer.get() setMasksToBounds:value]; 549 END_BLOCK_OBJC_EXCEPTIONS 550} 551 552bool 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 561void 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 572CFTypeRef PlatformCALayer::contents() const 573{ 574 return [m_layer.get() contents]; 575} 576 577void 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 584FloatRect PlatformCALayer::contentsRect() const 585{ 586 return [m_layer.get() contentsRect]; 587} 588 589void PlatformCALayer::setContentsRect(const FloatRect& value) 590{ 591 BEGIN_BLOCK_OBJC_EXCEPTIONS 592 [m_layer.get() setContentsRect:value]; 593 END_BLOCK_OBJC_EXCEPTIONS 594} 595 596void 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 607void 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 618Color PlatformCALayer::backgroundColor() const 619{ 620 return [m_layer.get() backgroundColor]; 621} 622 623void 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 636float PlatformCALayer::borderWidth() const 637{ 638 return [m_layer.get() borderWidth]; 639} 640 641void PlatformCALayer::setBorderWidth(float value) 642{ 643 BEGIN_BLOCK_OBJC_EXCEPTIONS 644 [m_layer.get() setBorderWidth:value]; 645 END_BLOCK_OBJC_EXCEPTIONS 646} 647 648Color PlatformCALayer::borderColor() const 649{ 650 return [m_layer.get() borderColor]; 651} 652 653void 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 666float PlatformCALayer::opacity() const 667{ 668 return [m_layer.get() opacity]; 669} 670 671void PlatformCALayer::setOpacity(float value) 672{ 673 BEGIN_BLOCK_OBJC_EXCEPTIONS 674 [m_layer.get() setOpacity:value]; 675 END_BLOCK_OBJC_EXCEPTIONS 676} 677 678String PlatformCALayer::name() const 679{ 680 return [m_layer.get() name]; 681} 682 683void PlatformCALayer::setName(const String& value) 684{ 685 BEGIN_BLOCK_OBJC_EXCEPTIONS 686 [m_layer.get() setName:value]; 687 END_BLOCK_OBJC_EXCEPTIONS 688} 689 690FloatRect PlatformCALayer::frame() const 691{ 692 return [m_layer.get() frame]; 693} 694 695void PlatformCALayer::setFrame(const FloatRect& value) 696{ 697 BEGIN_BLOCK_OBJC_EXCEPTIONS 698 [m_layer.get() setFrame:value]; 699 END_BLOCK_OBJC_EXCEPTIONS 700} 701 702float PlatformCALayer::speed() const 703{ 704 return [m_layer.get() speed]; 705} 706 707void PlatformCALayer::setSpeed(float value) 708{ 709 BEGIN_BLOCK_OBJC_EXCEPTIONS 710 [m_layer.get() setSpeed:value]; 711 END_BLOCK_OBJC_EXCEPTIONS 712} 713 714CFTimeInterval PlatformCALayer::timeOffset() const 715{ 716 return [m_layer.get() timeOffset]; 717} 718 719void PlatformCALayer::setTimeOffset(CFTimeInterval value) 720{ 721 BEGIN_BLOCK_OBJC_EXCEPTIONS 722 [m_layer.get() setTimeOffset:value]; 723 END_BLOCK_OBJC_EXCEPTIONS 724} 725 726float 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 735void 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