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 {
00781 for (UID in CALayerRegisteredRunLoopUpdates)
00782 {
00783 var layer = CALayerRegisteredRunLoopUpdates[UID],
00784 mask = layer._runLoopUpdateMask;
00785
00786 if (mask & CALayerDOMUpdateMask)
00787 _CALayerUpdateDOM(layer, mask);
00788
00789 if (mask & CALayerDisplayUpdateMask)
00790 [layer display];
00791
00792 else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
00793 [layer composite];
00794
00795 layer._runLoopUpdateMask = 0;
00796 }
00797 window.loop= false;
00798 CALayerRegisteredRunLoopUpdates = nil;
00799 }
00800
00801
00802
00803
00804 - (void)registerRunLoopUpdateWithMask:(unsigned)anUpdateMask
00805 {
00806 if (CALayerRegisteredRunLoopUpdates == nil)
00807 {
00808 CALayerRegisteredRunLoopUpdates = {};
00809
00810 [[CPRunLoop currentRunLoop] performSelector:@selector(runLoopUpdateLayers)
00811 target:CALayer argument:nil order:0 modes:[CPDefaultRunLoopMode]];
00812 }
00813
00814 _runLoopUpdateMask |= anUpdateMask;
00815 CALayerRegisteredRunLoopUpdates[[self UID]] = self;
00816 }
00817
00818
00819
00820
00821 - (void)setNeedsComposite
00822 {
00823 [self registerRunLoopUpdateWithMask:CALayerCompositeUpdateMask];
00824 }
00825
00829 - (void)setNeedsDisplay
00830 {
00831 [self registerRunLoopUpdateWithMask:CALayerDisplayUpdateMask];
00832 }
00833
00838 - (void)setNeedsDisplayOnBoundsChange:(BOOL)needsDisplayOnBoundsChange
00839 {
00840 _needsDisplayOnBoundsChange = needsDisplayOnBoundsChange;
00841 }
00842
00846 - (BOOL)needsDisplayOnBoundsChange
00847 {
00848 return _needsDisplayOnBoundsChange;
00849 }
00850
00855 - (void)setNeedsDisplayInRect:(CGRect)aRect
00856 {
00857 _dirtyRect = aRect;
00858 [self display];
00859 }
00860
00861
00868 - (CGPoint)convertPoint:(CGPoint)aPoint fromLayer:(CALayer)aLayer
00869 {
00870 return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(aLayer, self));
00871 }
00872
00879 - (CGPoint)convertPoint:(CGPoint)aPoint toLayer:(CALayer)aLayer
00880 {
00881 return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(self, aLayer));
00882 }
00883
00890 - (CGRect)convertRect:(CGRect)aRect fromLayer:(CALayer)aLayer
00891 {
00892 return CGRectApplyAffineTransform(aRect, _CALayerGetTransform(aLayer, self));
00893 }
00894
00901 - (CGRect)convertRect:(CGRect)aRect toLayer:(CALayer)aLayer
00902 {
00903 return CGRectApplyAffineTransform(aRect, _CALayerGetTransform(self, aLayer));
00904 }
00905
00906
00911 - (BOOL)containsPoint:(CGPoint)aPoint
00912 {
00913 return _CGRectContainsPoint(_bounds, aPoint);
00914 }
00915
00921 - (CALayer)hitTest:(CGPoint)aPoint
00922 {
00923 if (_isHidden)
00924 return nil;
00925
00926 var point = CGPointApplyAffineTransform(aPoint, _transformToLayer);
00927
00928
00929 if (!_CGRectContainsPoint(_bounds, point))
00930 return nil;
00931
00932 var layer = nil,
00933 index = _sublayers.length;
00934
00935
00936 while (index--)
00937 if (layer = [_sublayers[index] hitTest:point])
00938 return layer;
00939
00940 return self;
00941 }
00942
00943
00948 - (void)setDelegate:(id)aDelegate
00949 {
00950 if (_delegate == aDelegate)
00951 return;
00952
00953 _delegate = aDelegate;
00954
00955 _delegateRespondsToDisplayLayerSelector = [_delegate respondsToSelector:@selector(displayLayer:)];
00956 _delegateRespondsToDrawLayerInContextSelector = [_delegate respondsToSelector:@selector(drawLayer:inContext:)];
00957
00958 if (_delegateRespondsToDisplayLayerSelector || _delegateRespondsToDrawLayerInContextSelector)
00959 [self setNeedsDisplay];
00960 }
00961
00965 - (id)delegate
00966 {
00967 return _delegate;
00968 }
00969
00970
00971 - (void)_setOwningView:(CPView)anOwningView
00972 {
00973 _owningView = anOwningView;
00974
00975 if (_owningView)
00976 {
00977 _owningView = anOwningView;
00978
00979 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
00980 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
00981 }
00982
00983 _CALayerRecalculateGeometry(self, CALayerGeometryPositionMask | CALayerGeometryBoundsMask);
00984 }
00985
00986
00987 - (void)_owningViewBoundsChanged
00988 {
00989 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
00990 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
00991
00992 _CALayerRecalculateGeometry(self, CALayerGeometryPositionMask | CALayerGeometryBoundsMask);
00993 }
00994
00995
00996 - (void)_update
00997 {
00998 window.loop = true;
00999
01000 var mask = _runLoopUpdateMask;
01001
01002 if (mask & CALayerDOMUpdateMask)
01003 _CALayerUpdateDOM(self, mask);
01004
01005 if (mask & CALayerDisplayUpdateMask)
01006 [self display];
01007
01008 else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
01009 [self composite];
01010
01011 _runLoopUpdateMask = 0;
01012
01013 window.loop = false;
01014 }
01015
01016 @end
01017
01018 function _CALayerUpdateSublayerTransformForSublayers(aLayer)
01019 {
01020 var bounds = aLayer._bounds,
01021 anchorPoint = aLayer._anchorPoint,
01022 translateX = _CGRectGetWidth(bounds) * anchorPoint.x,
01023 translateY = _CGRectGetHeight(bounds) * anchorPoint.y;
01024
01025 aLayer._sublayerTransformForSublayers = CGAffineTransformConcat(
01026 CGAffineTransformMakeTranslation(-translateX, -translateY),
01027 CGAffineTransformConcat(aLayer._sublayerTransform,
01028 CGAffineTransformMakeTranslation(translateX, translateY)));
01029 }
01030
01031 function _CALayerUpdateDOM(aLayer, aMask)
01032 {
01033 var DOMElementStyle = aLayer._DOMElement.style;
01034
01035 if (aMask & CALayerZPositionUpdateMask)
01036 DOMElementStyle.zIndex = aLayer._zPosition;
01037
01038 var frame = aLayer._backingStoreFrame;
01039
01040 if (aMask & CALayerFrameOriginUpdateMask)
01041 {
01042 DOMElementStyle.top = ROUND(_CGRectGetMinY(frame)) + "px";
01043 DOMElementStyle.left = ROUND(_CGRectGetMinX(frame)) + "px";
01044 }
01045
01046 if (aMask & CALayerFrameSizeUpdateMask)
01047 {
01048 var width = MAX(0.0, ROUND(_CGRectGetWidth(frame))),
01049 height = MAX(0.0, ROUND(_CGRectGetHeight(frame))),
01050 DOMContentsElement = aLayer._DOMContentsElement;
01051
01052 DOMElementStyle.width = width + "px";
01053 DOMElementStyle.height = height + "px";
01054
01055 if (DOMContentsElement)
01056 {
01057 DOMContentsElement.width = width;
01058 DOMContentsElement.height = height;
01059 DOMContentsElement.style.width = width + "px";
01060 DOMContentsElement.style.height = height + "px";
01061 }
01062 }
01063 }
01064
01065 function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
01066 {
01067 var bounds = aLayer._bounds,
01068 superlayer = aLayer._superlayer,
01069 width = _CGRectGetWidth(bounds),
01070 height = _CGRectGetHeight(bounds),
01071 position = aLayer._position,
01072 anchorPoint = aLayer._anchorPoint,
01073 affineTransform = aLayer._affineTransform,
01074 backingStoreFrameSize = _CGSizeMakeCopy(aLayer._backingStoreFrame),
01075 hasCustomBackingStoreFrame = aLayer._hasCustomBackingStoreFrame;
01076
01077
01078 aLayer._transformFromLayer = CGAffineTransformConcat(
01079 CGAffineTransformMakeTranslation(-width * anchorPoint.x - _CGRectGetMinX(aLayer._bounds), -height * anchorPoint.y - _CGRectGetMinY(aLayer._bounds)),
01080 CGAffineTransformConcat(affineTransform,
01081 CGAffineTransformMakeTranslation(position.x, position.y)));
01082
01083 if (superlayer && superlayer._hasSublayerTransform)
01084 {
01085
01086 _CGAffineTransformConcatTo(aLayer._transformFromLayer, superlayer._sublayerTransformForSublayers, aLayer._transformFromLayer);
01087 }
01088
01089 aLayer._transformToLayer = CGAffineTransformInvert(aLayer._transformFromLayer);
01090
01091
01092
01093
01094 aLayer._frame = nil;
01095 aLayer._standardBackingStoreFrame = [aLayer convertRect:bounds toLayer:nil];
01096
01097 if (superlayer)
01098 {
01099 var bounds = [superlayer bounds],
01100 frame = [superlayer convertRect:bounds toLayer:nil];
01101
01102 aLayer._standardBackingStoreFrame.origin.x -= _CGRectGetMinX(frame);
01103 aLayer._standardBackingStoreFrame.origin.y -= _CGRectGetMinY(frame);
01104 }
01105
01106
01107
01108
01109
01110
01111 var origin = aLayer._standardBackingStoreFrame.origin,
01112 size = aLayer._standardBackingStoreFrame.size;
01113
01114 origin.x = FLOOR(origin.x);
01115 origin.y = FLOOR(origin.y);
01116 size.width = CEIL(size.width) + 1.0;
01117 size.height = CEIL(size.height) + 1.0;
01118
01119
01120
01121
01122
01123 if (!hasCustomBackingStoreFrame)
01124 {
01125 var backingStoreFrame = CGRectMakeCopy(aLayer._standardBackingStoreFrame);
01126
01127
01128
01129 if (ROUND(_CGRectGetMinX(backingStoreFrame)) != ROUND(_CGRectGetMinX(aLayer._backingStoreFrame)) ||
01130 ROUND(_CGRectGetMinY(backingStoreFrame)) != ROUND(_CGRectGetMinY(aLayer._backingStoreFrame)))
01131 [aLayer registerRunLoopUpdateWithMask:CALayerFrameOriginUpdateMask];
01132
01133
01134 if ((_CGRectGetWidth(backingStoreFrame) != ROUND(_CGRectGetWidth(aLayer._backingStoreFrame)) ||
01135 _CGRectGetHeight(backingStoreFrame) != ROUND(_CGRectGetHeight(aLayer._backingStoreFrame))))
01136 [aLayer registerRunLoopUpdateWithMask:CALayerFrameSizeUpdateMask];
01137
01138 aLayer._backingStoreFrame = backingStoreFrame;
01139 }
01140
01141 if (aGeometryChange & CALayerGeometryBoundsMask && aLayer._needsDisplayOnBoundsChange)
01142 [aLayer setNeedsDisplay];
01143
01144
01145
01146
01147 else if (hasCustomBackingStoreFrame || (aGeometryChange & ~(CALayerGeometryPositionMask | CALayerGeometryAnchorPointMask)))
01148 [aLayer setNeedsComposite];
01149
01150 var sublayers = aLayer._sublayers,
01151 index = 0,
01152 count = sublayers.length;
01153
01154 for (; index < count; ++index)
01155 _CALayerRecalculateGeometry(sublayers[index], aGeometryChange);
01156 }
01157
01158 function _CALayerGetTransform(fromLayer, toLayer)
01159 {
01160 var transform = CGAffineTransformMakeIdentity();
01161
01162 if (fromLayer)
01163 {
01164 var layer = fromLayer;
01165
01166
01167
01168 while (layer && layer != toLayer)
01169 {
01170 var transformFromLayer = layer._transformFromLayer;
01171
01172
01173 _CGAffineTransformConcatTo(transform, transformFromLayer, transform);
01174
01175 layer = layer._superlayer;
01176 }
01177
01178
01179 if (layer == toLayer)
01180 return transform;
01181 }
01182
01183 var layers = [],
01184 layer = toLayer;
01185
01186 while (layer)
01187 {
01188 layers.push(layer);
01189 layer = layer._superlayer;
01190 }
01191
01192 var index = layers.length;
01193
01194 while (index--)
01195 {
01196 var transformToLayer = layers[index]._transformToLayer;
01197
01198 _CGAffineTransformConcatTo(transform, transformToLayer, transform);
01199 }
01200
01201 return transform;
01202 }