00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <Foundation/CPObject.j>
00024
00025 @import <AppKit/CABackingStore.j>
00026
00027 @import <AppKit/CGContext.j>
00028 @import <AppKit/CGGeometry.j>
00029
00030 #include "../CoreGraphics/CGGeometry.h"
00031 #include "../CoreGraphics/CGAffineTransform.j"
00032
00033
00034 #define DOM(aLayer) aLayer._DOMElement
00035
00036 var CALayerGeometryBoundsMask = 1,
00037 CALayerGeometryPositionMask = 2,
00038 CALayerGeometryAnchorPointMask = 4,
00039 CALayerGeometryAffineTransformMask = 8,
00040 CALayerGeometryParentSublayerTransformMask = 16;
00041 var USE_BUFFER = NO;
00042
00043 var CALayerFrameOriginUpdateMask = 1,
00044 CALayerFrameSizeUpdateMask = 2,
00045 CALayerZPositionUpdateMask = 4,
00046 CALayerDisplayUpdateMask = 8,
00047 CALayerCompositeUpdateMask = 16,
00048 CALayerDOMUpdateMask = CALayerZPositionUpdateMask | CALayerFrameOriginUpdateMask | CALayerFrameSizeUpdateMask;
00049
00050 var CALayerRegisteredRunLoopUpdates = nil;
00051
00067 @implementation CALayer : CPObject
00068 {
00069
00070
00071 CGRect _frame;
00072 CGRect _bounds;
00073 CGPoint _position;
00074 unsigned _zPosition;
00075 CGPoint _anchorPoint;
00076
00077 CGAffineTransform _affineTransform;
00078 CGAffineTransform _sublayerTransform;
00079 CGAffineTransform _sublayerTransformForSublayers;
00080
00081 CGRect _backingStoreFrame;
00082 CGRect _standardBackingStoreFrame;
00083
00084 BOOL _hasSublayerTransform;
00085 BOOL _hasCustomBackingStoreFrame;
00086
00087
00088
00089 float _opacity;
00090 BOOL _isHidden;
00091 CPColor _backgroundColor;
00092
00093
00094
00095 CALayer _superlayer;
00096 CPMutableArray _sublayers;
00097
00098
00099
00100 unsigned _runLoopUpdateMask;
00101 BOOL _needsDisplayOnBoundsChange;
00102
00103
00104
00105 id _delegate;
00106
00107 BOOL _delegateRespondsToDisplayLayerSelector;
00108 BOOL _delegateRespondsToDrawLayerInContextSelector;
00109
00110
00111
00112 DOMElement _DOMElement;
00113 DOMElement _DOMContentsElement;
00114 id _contents;
00115 CGContext _context;
00116 CPView _owningView;
00117
00118 CGAffineTransform _transformToLayer;
00119 CGAffineTransform _transformFromLayer;
00120 }
00121
00125 + (CALayer)layer
00126 {
00127 return [[[self class] alloc] init];
00128 }
00129
00133 - (id)init
00134 {
00135 self = [super init];
00136
00137 if (self)
00138 {
00139 _frame = CGRectMakeZero();
00140
00141 _backingStoreFrame = CGRectMakeZero();
00142 _standardBackingStoreFrame = CGRectMakeZero();
00143
00144 _bounds = CGRectMakeZero();
00145 _position = CGPointMakeZero();
00146 _zPosition = 0.0;
00147 _anchorPoint = CGPointMake(0.5, 0.5);
00148 _affineTransform = CGAffineTransformMakeIdentity();
00149 _sublayerTransform = CGAffineTransformMakeIdentity();
00150
00151 _transformToLayer = CGAffineTransformMakeIdentity();
00152 _transformFromLayer = CGAffineTransformMakeIdentity();
00153
00154 _opacity = 1.0;
00155 _isHidden = NO;
00156 _masksToBounds = NO;
00157
00158 _sublayers = [];
00159
00160 _DOMElement = document.createElement("div");
00161
00162 _DOMElement.style.overflow = "visible";
00163 _DOMElement.style.position = "absolute";
00164 _DOMElement.style.visibility = "visible";
00165 _DOMElement.style.top = "0px";
00166 _DOMElement.style.left = "0px";
00167 _DOMElement.style.zIndex = 0;
00168 _DOMElement.style.width = "0px";
00169 _DOMElement.style.height = "0px";
00170 }
00171
00172 return self;
00173 }
00174
00175
00180 - (void)setBounds:(CGRect)aBounds
00181 {
00182 if (CGRectEqualToRect(_bounds, aBounds))
00183 return;
00184
00185 var oldOrigin = _bounds.origin;
00186
00187 _bounds = _CGRectMakeCopy(aBounds);
00188
00189 if (_hasSublayerTransform)
00190 _CALayerUpdateSublayerTransformForSublayers(self);
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 _CALayerRecalculateGeometry(self, CALayerGeometryBoundsMask);
00203 }
00204
00208 - (CGRect)bounds
00209 {
00210 return _bounds;
00211 }
00212
00217 - (void)setPosition:(CGPoint)aPosition
00218 {
00219 if (CGPointEqualToPoint(_position, aPosition))
00220 return;
00221
00222 _position = _CGPointMakeCopy(aPosition);
00223
00224 _CALayerRecalculateGeometry(self, CALayerGeometryPositionMask);
00225 }
00226
00230 - (CGPoint)position
00231 {
00232 return _position;
00233 }
00234
00239 - (void)setZPosition:(int)aZPosition
00240 {
00241 if (_zPosition == aZPosition)
00242 return;
00243
00244 _zPosition = aZPosition;
00245
00246 [self registerRunLoopUpdateWithMask:CALayerZPositionUpdateMask];
00247 }
00248
00253 - (void)setAnchorPoint:(CGPoint)anAnchorPoint
00254 {
00255 anAnchorPoint = _CGPointMakeCopy(anAnchorPoint);
00256 anAnchorPoint.x = MIN(1.0, MAX(0.0, anAnchorPoint.x));
00257 anAnchorPoint.y = MIN(1.0, MAX(0.0, anAnchorPoint.y));
00258
00259 if (CGPointEqualToPoint(_anchorPoint, anAnchorPoint))
00260 return;
00261
00262 _anchorPoint = anAnchorPoint;
00263
00264 if (_hasSublayerTransform)
00265 _CALayerUpdateSublayerTransformForSublayers(self);
00266
00267 if (_owningView)
00268 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
00269
00270 _CALayerRecalculateGeometry(self, CALayerGeometryAnchorPointMask);
00271 }
00272
00276 - (CGPoint)anchorPoint
00277 {
00278 return _anchorPoint;
00279 }
00280
00285 - (void)setAffineTransform:(CGAffineTransform)anAffineTransform
00286 {
00287 if (CGAffineTransformEqualToTransform(_affineTransform, anAffineTransform))
00288 return;
00289
00290 _affineTransform = _CGAffineTransformMakeCopy(anAffineTransform);
00291
00292 _CALayerRecalculateGeometry(self, CALayerGeometryAffineTransformMask);
00293 }
00294
00298 - (CGAffineTransform)affineTransform
00299 {
00300 return _affineTransform;
00301 }
00302
00307 - (void)setSublayerTransform:(CGAffineTransform)anAffineTransform
00308 {
00309 if (CGAffineTransformEqualToTransform(_sublayerTransform, anAffineTransform))
00310 return;
00311
00312 var hadSublayerTransform = _hasSublayerTransform;
00313
00314 _sublayerTransform = _CGAffineTransformMakeCopy(anAffineTransform);
00315 _hasSublayerTransform = !_CGAffineTransformIsIdentity(_sublayerTransform);
00316
00317 if (_hasSublayerTransform)
00318 {
00319 _CALayerUpdateSublayerTransformForSublayers(self);
00320
00321 var index = _sublayers.length;
00322
00323
00324 while (index--)
00325 _CALayerRecalculateGeometry(_sublayers[index], CALayerGeometryParentSublayerTransformMask);
00326 }
00327 }
00328
00332 - (CGAffineTransform)sublayerTransform
00333 {
00334 return _sublayerTransform;
00335 }
00336
00337
00338
00339
00340
00341 - (CGAffineTransform)transformToLayer
00342 {
00343 return _transformToLayer;
00344 }
00345
00351 - (void)setFrame:(CGRect)aFrame
00352 {
00353 alert("FIXME IMPLEMENT");
00354 }
00355
00363 - (CGRect)frame
00364 {
00365 if (!_frame)
00366 _frame = [self convertRect:_bounds toLayer:_superlayer];
00367
00368 return _frame;
00369 }
00370
00379 - (CGRect)backingStoreFrame
00380 {
00381 return _backingStoreFrame;
00382 }
00383
00388 - (void)setBackingStoreFrame:(CGRect)aFrame
00389 {
00390 _hasCustomBackingStoreFrame = (aFrame != nil);
00391
00392 if (aFrame == nil)
00393 aFrame = CGRectMakeCopy(_standardBackingStoreFrame);
00394 else
00395 {
00396 if (_superlayer)
00397 {
00398 aFrame = [_superlayer convertRect:aFrame toLayer:nil];
00399
00400 var bounds = [_superlayer bounds],
00401 frame = [_superlayer convertRect:bounds toLayer:nil];
00402
00403 aFrame.origin.x -= _CGRectGetMinX(frame);
00404 aFrame.origin.y -= _CGRectGetMinY(frame);
00405 }
00406 else
00407 aFrame = CGRectMakeCopy(aFrame);
00408 }
00409
00410 if (!CGPointEqualToPoint(_backingStoreFrame.origin, aFrame.origin))
00411 [self registerRunLoopUpdateWithMask:CALayerFrameOriginUpdateMask];
00412
00413 if (!CGSizeEqualToSize(_backingStoreFrame.size, aFrame.size))
00414 [self registerRunLoopUpdateWithMask:CALayerFrameSizeUpdateMask];
00415
00416 _backingStoreFrame = aFrame;
00417 }
00418
00419
00424 - (CGImage)contents
00425 {
00426 return _contents;
00427 }
00428
00433 - (void)setContents:(CGImage)contents
00434 {
00435 if (_contents == contents)
00436 return;
00437
00438 _contents = contents;
00439
00440 [self composite];
00441 }
00442
00443
00444
00445
00446
00447 - (void)composite
00448 {
00449 if (USE_BUFFER && !_contents || !_context)
00450 return;
00451
00452 CGContextClearRect(_context, _CGRectMake(0.0, 0.0, _CGRectGetWidth(_backingStoreFrame), _CGRectGetHeight(_backingStoreFrame)));
00453
00454
00455 var transform = _transformFromLayer;
00456
00457 if (_superlayer)
00458 {
00459 var superlayerTransform = _CALayerGetTransform(_superlayer, nil),
00460 superlayerOrigin = CGPointApplyAffineTransform(_superlayer._bounds.origin, superlayerTransform);
00461
00462 transform = CGAffineTransformConcat(transform, superlayerTransform);
00463
00464 transform.tx -= superlayerOrigin.x;
00465 transform.ty -= superlayerOrigin.y;
00466 }
00467
00468 transform.tx -= _CGRectGetMinX(_backingStoreFrame);
00469 transform.ty -= _CGRectGetMinY(_backingStoreFrame);
00470
00471 CGContextSaveGState(_context);
00472 CGContextConcatCTM(_context, transform);
00473 if (USE_BUFFER)
00474 {
00475
00476 _context.drawImage(_contents.buffer, _CGRectGetMinX(_bounds), _CGRectGetMinY(_bounds));
00477 }
00478 else
00479 [self drawInContext:_context];
00480 CGContextRestoreGState(_context);
00481 }
00482
00486 - (void)display
00487 {
00488 if (!_context)
00489 {
00490 _context = CGBitmapGraphicsContextCreate();
00491
00492 _DOMContentsElement = _context.DOMElement;
00493
00494 _DOMContentsElement.style.zIndex = -100;
00495
00496 _DOMContentsElement.style.overflow = "hidden";
00497 _DOMContentsElement.style.position = "absolute";
00498 _DOMContentsElement.style.visibility = "visible";
00499
00500 _DOMContentsElement.width = ROUND(_CGRectGetWidth(_backingStoreFrame));
00501 _DOMContentsElement.height = ROUND(_CGRectGetHeight(_backingStoreFrame));
00502
00503 _DOMContentsElement.style.top = "0px";
00504 _DOMContentsElement.style.left = "0px";
00505 _DOMContentsElement.style.width = ROUND(_CGRectGetWidth(_backingStoreFrame)) + "px";
00506 _DOMContentsElement.style.height = ROUND(_CGRectGetHeight(_backingStoreFrame)) + "px";
00507
00508 _DOMElement.appendChild(_DOMContentsElement);
00509 }
00510
00511 if (USE_BUFFER)
00512 {
00513 if (_delegateRespondsToDisplayLayerSelector)
00514 return [_delegate displayInLayer:self];
00515
00516 if (_CGRectGetWidth(_backingStoreFrame) == 0.0 || _CGRectGetHeight(_backingStoreFrame) == 0.0)
00517 return;
00518
00519 if (!_contents)
00520 _contents = CABackingStoreCreate();
00521
00522 CABackingStoreSetSize(_contents, _bounds.size);
00523
00524 [self drawInContext:CABackingStoreGetContext(_contents)];
00525 }
00526
00527 [self composite];
00528 }
00529
00534 - (void)drawInContext:(CGContext)aContext
00535 {
00536 if (_backgroundColor)
00537 {
00538 CGContextSetFillColor(aContext, _backgroundColor);
00539 CGContextFillRect(aContext, _bounds);
00540 }
00541
00542 if (_delegateRespondsToDrawLayerInContextSelector)
00543 [_delegate drawLayer:self inContext:aContext];
00544 }
00545
00546
00547
00552 - (float)opacity
00553 {
00554 return _opacity;
00555 }
00556
00561 - (void)setOpacity:(float)anOpacity
00562 {
00563 if (_opacity == anOpacity)
00564 return;
00565
00566 _opacity = anOpacity;
00567
00568 _DOMElement.style.opacity = anOpacity;
00569 _DOMElement.style.filter = "alpha(opacity=" + anOpacity * 100 + ")";
00570 }
00571
00576 - (void)setHidden:(BOOL)isHidden
00577 {
00578 _isHidden = isHidden;
00579 _DOMElement.style.display = isHidden ? "none" : "block";
00580 }
00581
00585 - (BOOL)hidden
00586 {
00587 return _isHidden;
00588 }
00589
00593 - (BOOL)isHidden
00594 {
00595 return _isHidden;
00596 }
00597
00602 - (void)setMasksToBounds:(BOOL)masksToBounds
00603 {
00604 if (_masksToBounds == masksToBounds)
00605 return;
00606
00607 _masksToBounds = masksToBounds;
00608 _DOMElement.style.overflow = _masksToBounds ? "hidden" : "visible";
00609 }
00610
00615 - (void)setBackgroundColor:(CPColor)aColor
00616 {
00617 _backgroundColor = aColor;
00618
00619 [self setNeedsDisplay];
00620 }
00621
00625 - (CPColor)backgroundColor
00626 {
00627 return _backgroundColor;
00628 }
00629
00630
00634 - (CPArray)sublayers
00635 {
00636 return _sublayers;
00637 }
00638
00642 - (CALayer)superlayer
00643 {
00644 return _superlayer;
00645 }
00646
00647 #define ADJUST_CONTENTS_ZINDEX(aLayer)\
00648 if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)\
00649 _DOMContentsElement.style.zIndex -= 100.0;\
00650
00651
00654 - (void)addSublayer:(CALayer)aLayer
00655 {
00656 [self insertSublayer:aLayer atIndex:_sublayers.length];
00657 return;
00658 ADJUST_CONTENTS_ZINDEX(aLayer);
00659
00660 [_sublayers addObject:aLayer];
00661 _DOMElement.appendChild(DOM(aLayer));
00662 }
00663
00667 - (void)removeFromSuperlayer
00668 {
00669 if (_owningView)
00670 [_owningView setLayer:nil];
00671
00672 if (!_superlayer)
00673 return;
00674
00675 _superlayer._DOMElement.removeChild(_DOMElement);
00676 [_superlayer._sublayers removeObject:self];
00677
00678 _superlayer = nil;
00679 }
00680
00686 - (void)insertSublayer:(CALayer)aLayer atIndex:(unsigned)anIndex
00687 {
00688 if (!aLayer)
00689 return;
00690
00691 var superlayer = [aLayer superlayer];
00692
00693 if (superlayer == self)
00694 {
00695 var index = [_sublayers indexOfObjectIdenticalTo:aLayer];
00696
00697 if (index == anIndex)
00698 return;
00699
00700 [_sublayers removeObjectAtIndex:index];
00701
00702 if (index < anIndex)
00703 --anIndex;
00704 }
00705 else if (superlayer != nil)
00706 [aLayer removeFromSuperlayer];
00707
00708 ADJUST_CONTENTS_ZINDEX(aLayer);
00709
00710 [_sublayers insertObject:aLayer atIndex:anIndex];
00711
00712 if (anIndex >= _sublayers.length - 1)
00713 _DOMElement.appendChild(DOM(aLayer));
00714 else
00715 _DOMElement.insertBefore(DOM(aLayer), _sublayers[anIndex + 1]._DOMElement);
00716
00717 aLayer._superlayer = self;
00718
00719 if (self != superlayer)
00720 _CALayerRecalculateGeometry(aLayer, 0xFFFFFFF);
00721 }
00722
00729 - (void)insertSublayer:(CALayer)aLayer below:(CALayer)aSublayer
00730 {
00731 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : 0;
00732
00733 [self insertSublayer:aLayer atIndex:index == CPNotFound ? _sublayers.length : index];
00734 }
00735
00742 - (void)insertSublayer:(CALayer)aLayer above:(CALayer)aSublayer
00743 {
00744 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : _sublayers.length;
00745 if (index == CPNotFound)
00746 [CPException raise:"CALayerNotFoundException" reason:"aSublayer is not a sublayer of this layer"];
00747
00748 [_sublayers insertObject:aLayer atIndex:index == CPNotFound ? _sublayers.length : index + 1];
00749 }
00750
00756 - (void)replaceSublayer:(CALayer)aSublayer with:(CALayer)aLayer
00757 {
00758 if (aSublayer == aLayer)
00759 return;
00760
00761
00762 if (aSublayer._superlayer != self)
00763 {
00764 alert("EXCEPTION");
00765 return;
00766 }
00767
00768 ADJUST_CONTENTS_ZINDEX(aLayer);
00769
00770 [_sublayers replaceObjectAtIndex:[_sublayers indexOfObjectIdenticalTo:aSublayer] withObject:aLayer];
00771 _DOMElement.replaceChild(DOM(aSublayer), DOM(aLayer));
00772 }
00773
00774
00775
00776
00777
00778
00779 + (void)runLoopUpdateLayers
00780 {if (window.oops) {alert(window.latest); objj_debug_print_backtrace();}
00781 window.loop = true;
00782 for (hash in CALayerRegisteredRunLoopUpdates)
00783 {
00784 var layer = CALayerRegisteredRunLoopUpdates[hash],
00785 mask = layer._runLoopUpdateMask;
00786
00787 if (mask & CALayerDOMUpdateMask)
00788 _CALayerUpdateDOM(layer, mask);
00789
00790 if (mask & CALayerDisplayUpdateMask)
00791 [layer display];
00792
00793 else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
00794 [layer composite];
00795
00796 layer._runLoopUpdateMask = 0;
00797 }
00798 window.loop= false;
00799 CALayerRegisteredRunLoopUpdates = nil;
00800 }
00801
00802
00803
00804
00805 - (void)registerRunLoopUpdateWithMask:(unsigned)anUpdateMask
00806 {
00807 if (CALayerRegisteredRunLoopUpdates == nil)
00808 {
00809 CALayerRegisteredRunLoopUpdates = {};
00810
00811 [[CPRunLoop currentRunLoop] performSelector:@selector(runLoopUpdateLayers)
00812 target:CALayer argument:nil order:0 modes:[CPDefaultRunLoopMode]];
00813 }
00814
00815 _runLoopUpdateMask |= anUpdateMask;
00816 CALayerRegisteredRunLoopUpdates[[self hash]] = self;
00817 }
00818
00819
00820
00821
00822 - (void)setNeedsComposite
00823 {
00824 [self registerRunLoopUpdateWithMask:CALayerCompositeUpdateMask];
00825 }
00826
00830 - (void)setNeedsDisplay
00831 {
00832 [self registerRunLoopUpdateWithMask:CALayerDisplayUpdateMask];
00833 }
00834
00839 - (void)setNeedsDisplayOnBoundsChange:(BOOL)needsDisplayOnBoundsChange
00840 {
00841 _needsDisplayOnBoundsChange = needsDisplayOnBoundsChange;
00842 }
00843
00847 - (BOOL)needsDisplayOnBoundsChange
00848 {
00849 return _needsDisplayOnBoundsChange;
00850 }
00851
00856 - (void)setNeedsDisplayInRect:(CGRect)aRect
00857 {
00858 _dirtyRect = aRect;
00859 [self display];
00860 }
00861
00862
00869 - (CGPoint)convertPoint:(CGPoint)aPoint fromLayer:(CALayer)aLayer
00870 {
00871 return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(aLayer, self));
00872 }
00873
00880 - (CGPoint)convertPoint:(CGPoint)aPoint toLayer:(CALayer)aLayer
00881 {
00882 return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(self, aLayer));
00883 }
00884
00891 - (CGRect)convertRect:(CGRect)aRect fromLayer:(CALayer)aLayer
00892 {
00893 return CGRectApplyAffineTransform(aRect, _CALayerGetTransform(aLayer, self));
00894 }
00895
00902 - (CGRect)convertRect:(CGRect)aRect toLayer:(CALayer)aLayer
00903 {
00904 return CGRectApplyAffineTransform(aRect, _CALayerGetTransform(self, aLayer));
00905 }
00906
00907
00912 - (BOOL)containsPoint:(CGPoint)aPoint
00913 {
00914 return _CGRectContainsPoint(_bounds, aPoint);
00915 }
00916
00922 - (CALayer)hitTest:(CGPoint)aPoint
00923 {
00924 if (_isHidden)
00925 return nil;
00926
00927 var point = CGPointApplyAffineTransform(aPoint, _transformToLayer);
00928
00929
00930 if (!_CGRectContainsPoint(_bounds, point))
00931 return nil;
00932
00933 var layer = nil,
00934 index = _sublayers.length;
00935
00936
00937 while (index--)
00938 if (layer = [_sublayers[index] hitTest:point])
00939 return layer;
00940
00941 return self;
00942 }
00943
00944
00949 - (void)setDelegate:(id)aDelegate
00950 {
00951 if (_delegate == aDelegate)
00952 return;
00953
00954 _delegate = aDelegate;
00955
00956 _delegateRespondsToDisplayLayerSelector = [_delegate respondsToSelector:@selector(displayLayer:)];
00957 _delegateRespondsToDrawLayerInContextSelector = [_delegate respondsToSelector:@selector(drawLayer:inContext:)];
00958
00959 if (_delegateRespondsToDisplayLayerSelector || _delegateRespondsToDrawLayerInContextSelector)
00960 [self setNeedsDisplay];
00961 }
00962
00966 - (id)delegate
00967 {
00968 return _delegate;
00969 }
00970
00971
00972 - (void)_setOwningView:(CPView)anOwningView
00973 {
00974 _owningView = anOwningView;
00975
00976 if (_owningView)
00977 {
00978 _owningView = anOwningView;
00979
00980 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
00981 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
00982 }
00983
00984 _CALayerRecalculateGeometry(self, CALayerGeometryPositionMask | CALayerGeometryBoundsMask);
00985 }
00986
00987
00988 - (void)_owningViewBoundsChanged
00989 {
00990 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
00991 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
00992
00993 _CALayerRecalculateGeometry(self, CALayerGeometryPositionMask | CALayerGeometryBoundsMask);
00994 }
00995
00996
00997 - (void)_update
00998 {
00999 window.loop = true;
01000
01001 var mask = _runLoopUpdateMask;
01002
01003 if (mask & CALayerDOMUpdateMask)
01004 _CALayerUpdateDOM(self, mask);
01005
01006 if (mask & CALayerDisplayUpdateMask)
01007 [self display];
01008
01009 else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
01010 [self composite];
01011
01012 _runLoopUpdateMask = 0;
01013
01014 window.loop = false;
01015 }
01016
01017 @end
01018
01019 function _CALayerUpdateSublayerTransformForSublayers(aLayer)
01020 {
01021 var bounds = aLayer._bounds,
01022 anchorPoint = aLayer._anchorPoint,
01023 translateX = _CGRectGetWidth(bounds) * anchorPoint.x,
01024 translateY = _CGRectGetHeight(bounds) * anchorPoint.y;
01025
01026 aLayer._sublayerTransformForSublayers = CGAffineTransformConcat(
01027 CGAffineTransformMakeTranslation(-translateX, -translateY),
01028 CGAffineTransformConcat(aLayer._sublayerTransform,
01029 CGAffineTransformMakeTranslation(translateX, translateY)));
01030 }
01031
01032 function _CALayerUpdateDOM(aLayer, aMask)
01033 {
01034 var DOMElementStyle = aLayer._DOMElement.style;
01035
01036 if (aMask & CALayerZPositionUpdateMask)
01037 DOMElementStyle.zIndex = aLayer._zPosition;
01038
01039 var frame = aLayer._backingStoreFrame;
01040
01041 if (aMask & CALayerFrameOriginUpdateMask)
01042 {
01043 DOMElementStyle.top = ROUND(_CGRectGetMinY(frame)) + "px";
01044 DOMElementStyle.left = ROUND(_CGRectGetMinX(frame)) + "px";
01045 }
01046
01047 if (aMask & CALayerFrameSizeUpdateMask)
01048 {
01049 var width = MAX(0.0, ROUND(_CGRectGetWidth(frame))),
01050 height = MAX(0.0, ROUND(_CGRectGetHeight(frame))),
01051 DOMContentsElement = aLayer._DOMContentsElement;
01052
01053 DOMElementStyle.width = width + "px";
01054 DOMElementStyle.height = height + "px";
01055
01056 if (DOMContentsElement)
01057 {
01058 DOMContentsElement.width = width;
01059 DOMContentsElement.height = height;
01060 DOMContentsElement.style.width = width + "px";
01061 DOMContentsElement.style.height = height + "px";
01062 }
01063 }
01064 }
01065
01066 function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
01067 {
01068 var bounds = aLayer._bounds,
01069 superlayer = aLayer._superlayer,
01070 width = _CGRectGetWidth(bounds),
01071 height = _CGRectGetHeight(bounds),
01072 position = aLayer._position,
01073 anchorPoint = aLayer._anchorPoint,
01074 affineTransform = aLayer._affineTransform,
01075 backingStoreFrameSize = _CGSizeMakeCopy(aLayer._backingStoreFrame),
01076 hasCustomBackingStoreFrame = aLayer._hasCustomBackingStoreFrame;
01077
01078
01079 aLayer._transformFromLayer = CGAffineTransformConcat(
01080 CGAffineTransformMakeTranslation(-width * anchorPoint.x - _CGRectGetMinX(aLayer._bounds), -height * anchorPoint.y - _CGRectGetMinY(aLayer._bounds)),
01081 CGAffineTransformConcat(affineTransform,
01082 CGAffineTransformMakeTranslation(position.x, position.y)));
01083
01084 if (superlayer && superlayer._hasSublayerTransform)
01085 {
01086
01087 _CGAffineTransformConcatTo(aLayer._transformFromLayer, superlayer._sublayerTransformForSublayers, aLayer._transformFromLayer);
01088 }
01089
01090 aLayer._transformToLayer = CGAffineTransformInvert(aLayer._transformFromLayer);
01091
01092
01093
01094
01095 aLayer._frame = nil;
01096 aLayer._standardBackingStoreFrame = [aLayer convertRect:bounds toLayer:nil];
01097
01098 if (superlayer)
01099 {
01100 var bounds = [superlayer bounds],
01101 frame = [superlayer convertRect:bounds toLayer:nil];
01102
01103 aLayer._standardBackingStoreFrame.origin.x -= _CGRectGetMinX(frame);
01104 aLayer._standardBackingStoreFrame.origin.y -= _CGRectGetMinY(frame);
01105 }
01106
01107
01108
01109
01110
01111
01112 var origin = aLayer._standardBackingStoreFrame.origin,
01113 size = aLayer._standardBackingStoreFrame.size;
01114
01115 origin.x = FLOOR(origin.x);
01116 origin.y = FLOOR(origin.y);
01117 size.width = CEIL(size.width) + 1.0;
01118 size.height = CEIL(size.height) + 1.0;
01119
01120
01121
01122
01123
01124 if (!hasCustomBackingStoreFrame)
01125 {
01126 var backingStoreFrame = CGRectMakeCopy(aLayer._standardBackingStoreFrame);
01127
01128
01129
01130 if (ROUND(_CGRectGetMinX(backingStoreFrame)) != ROUND(_CGRectGetMinX(aLayer._backingStoreFrame)) ||
01131 ROUND(_CGRectGetMinY(backingStoreFrame)) != ROUND(_CGRectGetMinY(aLayer._backingStoreFrame)))
01132 [aLayer registerRunLoopUpdateWithMask:CALayerFrameOriginUpdateMask];
01133
01134
01135 if ((_CGRectGetWidth(backingStoreFrame) != ROUND(_CGRectGetWidth(aLayer._backingStoreFrame)) ||
01136 _CGRectGetHeight(backingStoreFrame) != ROUND(_CGRectGetHeight(aLayer._backingStoreFrame))))
01137 [aLayer registerRunLoopUpdateWithMask:CALayerFrameSizeUpdateMask];
01138
01139 aLayer._backingStoreFrame = backingStoreFrame;
01140 }
01141
01142 if (aGeometryChange & CALayerGeometryBoundsMask && aLayer._needsDisplayOnBoundsChange)
01143 [aLayer setNeedsDisplay];
01144
01145
01146
01147
01148 else if (hasCustomBackingStoreFrame || (aGeometryChange & ~(CALayerGeometryPositionMask | CALayerGeometryAnchorPointMask)))
01149 [aLayer setNeedsComposite];
01150
01151 var sublayers = aLayer._sublayers,
01152 index = 0,
01153 count = sublayers.length;
01154
01155 for (; index < count; ++index)
01156 _CALayerRecalculateGeometry(sublayers[index], aGeometryChange);
01157 }
01158
01159 function _CALayerGetTransform(fromLayer, toLayer)
01160 {
01161 var transform = CGAffineTransformMakeIdentity();
01162
01163 if (fromLayer)
01164 {
01165 var layer = fromLayer;
01166
01167
01168
01169 while (layer && layer != toLayer)
01170 {
01171 var transformFromLayer = layer._transformFromLayer;
01172
01173
01174 _CGAffineTransformConcatTo(transform, transformFromLayer, transform);
01175
01176 layer = layer._superlayer;
01177 }
01178
01179
01180 if (layer == toLayer)
01181 return transform;
01182 }
01183
01184 var layers = [],
01185 layer = toLayer;
01186
01187 while (layer)
01188 {
01189 layers.push(layer);
01190 layer = layer._superlayer;
01191 }
01192
01193 var index = layers.length;
01194
01195 while (index--)
01196 {
01197 var transformToLayer = layers[index]._transformToLayer;
01198
01199 _CGAffineTransformConcatTo(transform, transformToLayer, transform);
01200 }
01201
01202 return transform;
01203 }