27 #define DOM(aLayer) aLayer._DOMElement
71 CGAffineTransform _affineTransform;
72 CGAffineTransform _sublayerTransform;
73 CGAffineTransform _sublayerTransformForSublayers;
75 CGRect _backingStoreFrame;
76 CGRect _standardBackingStoreFrame;
78 BOOL _hasSublayerTransform;
79 BOOL _hasCustomBackingStoreFrame;
95 unsigned _runLoopUpdateMask;
96 BOOL _needsDisplayOnBoundsChange;
102 BOOL _delegateRespondsToDisplayLayerSelector;
103 BOOL _delegateRespondsToDrawLayerInContextSelector;
107 DOMElement _DOMElement;
108 DOMElement _DOMContentsElement;
113 CGAffineTransform _transformToLayer;
114 CGAffineTransform _transformFromLayer;
122 return [[[
self class] alloc] init];
134 _frame = CGRectMakeZero();
136 _backingStoreFrame = CGRectMakeZero();
137 _standardBackingStoreFrame = CGRectMakeZero();
139 _bounds = CGRectMakeZero();
140 _position = CGPointMakeZero();
142 _anchorPoint = CGPointMake(0.5, 0.5);
156 _DOMElement = document.createElement(
"div");
158 _DOMElement.style.overflow =
"visible";
159 _DOMElement.style.position =
"absolute";
160 _DOMElement.style.visibility =
"visible";
161 _DOMElement.style.top =
"0px";
162 _DOMElement.style.left =
"0px";
163 _DOMElement.style.zIndex = 0;
164 _DOMElement.style.width =
"0px";
165 _DOMElement.style.height =
"0px";
177 - (void)setBounds:(CGRect)aBounds
179 if (CGRectEqualToRect(_bounds, aBounds))
182 var oldOrigin = _bounds.origin;
184 _bounds = CGRectMakeCopy(aBounds);
186 if (_hasSublayerTransform)
187 _CALayerUpdateSublayerTransformForSublayers(
self);
214 - (void)setPosition:(CGPoint)aPosition
216 if (CGPointEqualToPoint(_position, aPosition))
219 _position = CGPointMakeCopy(aPosition);
236 - (void)setZPosition:(
int)aZPosition
238 if (_zPosition == aZPosition)
241 _zPosition = aZPosition;
250 - (void)setAnchorPoint:(CGPoint)anAnchorPoint
252 anAnchorPoint = CGPointMakeCopy(anAnchorPoint);
253 anAnchorPoint.x = MIN(1.0, MAX(0.0, anAnchorPoint.x));
254 anAnchorPoint.y = MIN(1.0, MAX(0.0, anAnchorPoint.y));
256 if (CGPointEqualToPoint(_anchorPoint, anAnchorPoint))
259 _anchorPoint = anAnchorPoint;
261 if (_hasSublayerTransform)
262 _CALayerUpdateSublayerTransformForSublayers(
self);
265 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
273 - (CGPoint)anchorPoint
282 - (void)setAffineTransform:(CGAffineTransform)anAffineTransform
295 - (CGAffineTransform)affineTransform
297 return _affineTransform;
304 - (void)setSublayerTransform:(CGAffineTransform)anAffineTransform
309 var hadSublayerTransform = _hasSublayerTransform;
314 if (_hasSublayerTransform)
316 _CALayerUpdateSublayerTransformForSublayers(
self);
318 var index = _sublayers.length;
329 - (CGAffineTransform)sublayerTransform
331 return _sublayerTransform;
338 - (CGAffineTransform)transformToLayer
340 return _transformToLayer;
348 - (void)setFrame:(CGRect)aFrame
376 - (CGRect)backingStoreFrame
378 return _backingStoreFrame;
385 - (void)setBackingStoreFrame:(CGRect)aFrame
387 _hasCustomBackingStoreFrame = (aFrame != nil);
390 aFrame = CGRectMakeCopy(_standardBackingStoreFrame);
395 aFrame = [_superlayer convertRect:aFrame toLayer:nil];
397 var bounds = [_superlayer bounds],
398 frame = [_superlayer convertRect:bounds toLayer:nil];
400 aFrame.origin.x -= CGRectGetMinX(
frame);
401 aFrame.origin.y -= CGRectGetMinY(
frame);
404 aFrame = CGRectMakeCopy(aFrame);
407 if (!CGPointEqualToPoint(_backingStoreFrame.origin, aFrame.origin))
410 if (!CGSizeEqualToSize(_backingStoreFrame.size, aFrame.size))
413 _backingStoreFrame = aFrame;
430 - (void)setContents:(CGImage)contents
432 if (_contents == contents)
435 _contents = contents;
449 CGContextClearRect(_context, CGRectMake(0.0, 0.0, CGRectGetWidth(_backingStoreFrame), CGRectGetHeight(_backingStoreFrame)));
456 var superlayerTransform = _CALayerGetTransform(_superlayer, nil),
461 transform.tx -= superlayerOrigin.x;
462 transform.ty -= superlayerOrigin.y;
469 transform.tx -= CGRectGetMinX(_backingStoreFrame);
470 transform.ty -= CGRectGetMinY(_backingStoreFrame);
479 _context.drawImage(_contents.buffer, CGRectGetMinX(_bounds), CGRectGetMinY(_bounds));
496 _DOMContentsElement = _context.DOMElement;
498 _DOMContentsElement.style.zIndex = -100;
500 _DOMContentsElement.style.overflow =
"hidden";
501 _DOMContentsElement.style.position =
"absolute";
502 _DOMContentsElement.style.visibility =
"visible";
504 _DOMContentsElement.width = ROUND(CGRectGetWidth(_backingStoreFrame));
505 _DOMContentsElement.height = ROUND(CGRectGetHeight(_backingStoreFrame));
507 _DOMContentsElement.style.top =
"0px";
508 _DOMContentsElement.style.left =
"0px";
509 _DOMContentsElement.style.width = ROUND(CGRectGetWidth(_backingStoreFrame)) +
"px";
510 _DOMContentsElement.style.height = ROUND(CGRectGetHeight(_backingStoreFrame)) +
"px";
512 _DOMElement.appendChild(_DOMContentsElement);
517 if (_delegateRespondsToDisplayLayerSelector)
518 return [_delegate displayInLayer:self];
520 if (CGRectGetWidth(_backingStoreFrame) == 0.0 || CGRectGetHeight(_backingStoreFrame) == 0.0)
524 _contents = CABackingStoreCreate();
538 - (void)drawInContext:(CGContext)aContext
540 if (_backgroundColor)
546 if (_delegateRespondsToDrawLayerInContextSelector)
547 [_delegate drawLayer:self inContext:aContext];
565 - (void)setOpacity:(
float)anOpacity
567 if (_opacity == anOpacity)
570 _opacity = anOpacity;
572 _DOMElement.style.opacity = anOpacity;
573 _DOMElement.style.filter =
"alpha(opacity=" + anOpacity * 100 +
")";
580 - (void)setHidden:(BOOL)isHidden
582 _isHidden = isHidden;
583 _DOMElement.style.display = isHidden ?
"none" :
"block";
606 - (void)setMasksToBounds:(BOOL)masksToBounds
608 if (_masksToBounds == masksToBounds)
611 _masksToBounds = masksToBounds;
612 _DOMElement.style.overflow = _masksToBounds ?
"hidden" :
"visible";
621 _backgroundColor = aColor;
631 return _backgroundColor;
651 #define ADJUST_CONTENTS_ZINDEX(aLayer)\
652 if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)\
653 _DOMContentsElement.style.zIndex -= 100.0;\
666 - (void)removeFromSuperlayer
669 [_owningView setLayer:nil];
674 _superlayer._DOMElement.removeChild(_DOMElement);
675 [_superlayer._sublayers removeObject:self];
685 - (void)insertSublayer:(
CALayer)aLayer atIndex:(CPUInteger)anIndex
692 if (superlayer ==
self)
694 var index = [_sublayers indexOfObjectIdenticalTo:aLayer];
696 if (index == anIndex)
699 [_sublayers removeObjectAtIndex:index];
704 else if (superlayer != nil)
709 [_sublayers insertObject:aLayer atIndex:anIndex];
712 if (anIndex >= _sublayers.length - 1)
713 _DOMElement.appendChild(
DOM(aLayer));
715 _DOMElement.insertBefore(
DOM(aLayer), _sublayers[anIndex + 1]._DOMElement);
718 aLayer._superlayer =
self;
720 if (
self != superlayer)
721 _CALayerRecalculateGeometry(aLayer, 0xFFFFFFF);
732 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : 0;
734 [
self insertSublayer:aLayer atIndex:index == CPNotFound ? _sublayers.length : index];
745 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : _sublayers.length;
750 [_sublayers insertObject:aLayer atIndex:index == CPNotFound ? _sublayers.length : index + 1];
760 if (aSublayer == aLayer)
763 if (aSublayer._superlayer !=
self)
765 CPLog.warn(
"Attempt to replace a sublayer (%s) which is not in the sublayers of the receiver (%s).", [aSublayer description], [
self description]);
771 [_sublayers replaceObjectAtIndex:[_sublayers indexOfObjectIdenticalTo:aSublayer] withObject:aLayer];
772 _DOMElement.replaceChild(
DOM(aSublayer),
DOM(aLayer));
780 + (void)runLoopUpdateLayers
785 mask = layer._runLoopUpdateMask;
788 _CALayerUpdateDOM(layer, mask);
796 layer._runLoopUpdateMask = 0;
806 - (void)registerRunLoopUpdateWithMask:(
unsigned)anUpdateMask
816 _runLoopUpdateMask |= anUpdateMask;
823 - (void)setNeedsComposite
831 - (void)setNeedsDisplay
840 - (void)setNeedsDisplayOnBoundsChange:(BOOL)needsDisplayOnBoundsChange
842 _needsDisplayOnBoundsChange = needsDisplayOnBoundsChange;
848 - (BOOL)needsDisplayOnBoundsChange
850 return _needsDisplayOnBoundsChange;
857 - (void)setNeedsDisplayInRect:(CGRect)aRect
870 - (CGPoint)convertPoint:(CGPoint)aPoint fromLayer:(
CALayer)aLayer
881 - (CGPoint)convertPoint:(CGPoint)aPoint toLayer:(
CALayer)aLayer
892 - (CGRect)convertRect:(CGRect)aRect fromLayer:(
CALayer)aLayer
903 - (CGRect)convertRect:(CGRect)aRect toLayer:(
CALayer)aLayer
913 - (BOOL)containsPoint:(CGPoint)aPoint
915 return CGRectContainsPoint(_bounds, aPoint);
930 if (!CGRectContainsPoint(_bounds, point))
934 index = _sublayers.length;
938 if (layer = [_sublayers[index] hitTest:point])
949 - (void)setDelegate:(
id)aDelegate
951 if (_delegate == aDelegate)
954 _delegate = aDelegate;
956 _delegateRespondsToDisplayLayerSelector = [_delegate respondsToSelector:@selector(displayLayer:)];
957 _delegateRespondsToDrawLayerInContextSelector = [_delegate respondsToSelector:@selector(drawLayer:inContext:)];
959 if (_delegateRespondsToDisplayLayerSelector || _delegateRespondsToDrawLayerInContextSelector)
972 - (void)_setOwningView:(
CPView)anOwningView
974 _owningView = anOwningView;
978 _owningView = anOwningView;
980 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
981 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
988 - (void)_owningViewBoundsChanged
990 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
991 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
1001 var mask = _runLoopUpdateMask;
1004 _CALayerUpdateDOM(
self, mask);
1012 _runLoopUpdateMask = 0;
1014 window.loop =
false;
1019 function _CALayerUpdateSublayerTransformForSublayers(aLayer)
1021 var bounds = aLayer._bounds,
1022 anchorPoint = aLayer._anchorPoint,
1023 translateX = CGRectGetWidth(bounds) * anchorPoint.x,
1024 translateY = CGRectGetHeight(bounds) * anchorPoint.y;
1032 function _CALayerUpdateDOM(aLayer, aMask)
1034 var DOMElementStyle = aLayer._DOMElement.style;
1037 DOMElementStyle.zIndex = aLayer._zPosition;
1039 var
frame = aLayer._backingStoreFrame;
1043 DOMElementStyle.top = ROUND(CGRectGetMinY(frame)) + "px";
1044 DOMElementStyle.left = ROUND(CGRectGetMinX(frame)) + "px";
1049 var
width = MAX(0.0, ROUND(CGRectGetWidth(frame))),
1050 height = MAX(0.0, ROUND(CGRectGetHeight(frame))),
1051 DOMContentsElement = aLayer._DOMContentsElement;
1053 DOMElementStyle.width = width + "px";
1054 DOMElementStyle.height = height + "px";
1056 if (DOMContentsElement)
1058 DOMContentsElement.width =
width;
1059 DOMContentsElement.height = height;
1060 DOMContentsElement.style.width = width + "px";
1061 DOMContentsElement.style.height = height + "px";
1066 function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
1068 var bounds = aLayer._bounds,
1069 superlayer = aLayer._superlayer,
1070 width = CGRectGetWidth(bounds),
1071 height = CGRectGetHeight(bounds),
1072 position = aLayer._position,
1073 anchorPoint = aLayer._anchorPoint,
1074 affineTransform = aLayer._affineTransform,
1075 backingStoreFrameSize = CGSizeMakeCopy(aLayer._backingStoreFrame),
1076 hasCustomBackingStoreFrame = aLayer._hasCustomBackingStoreFrame;
1084 if (superlayer && superlayer._hasSublayerTransform)
1087 CGAffineTransformConcatTo(aLayer._transformFromLayer, superlayer._sublayerTransformForSublayers, aLayer._transformFromLayer);
1095 aLayer._frame = nil;
1100 var bounds = [superlayer bounds],
1101 frame = [superlayer convertRect:bounds toLayer:nil];
1103 aLayer._standardBackingStoreFrame.origin.x -= CGRectGetMinX(frame);
1104 aLayer._standardBackingStoreFrame.origin.y -= CGRectGetMinY(frame);
1112 var origin = aLayer._standardBackingStoreFrame.origin,
1113 size = aLayer._standardBackingStoreFrame.size;
1115 origin.x = FLOOR(origin.x);
1116 origin.y = FLOOR(origin.y);
1117 size.width = CEIL(size.width) + 1.0;
1118 size.height = CEIL(size.height) + 1.0;
1124 if (!hasCustomBackingStoreFrame)
1126 var backingStoreFrame = CGRectMakeCopy(aLayer._standardBackingStoreFrame);
1130 if (ROUND(CGRectGetMinX(backingStoreFrame)) != ROUND(CGRectGetMinX(aLayer._backingStoreFrame)) ||
1131 ROUND(CGRectGetMinY(backingStoreFrame)) != ROUND(CGRectGetMinY(aLayer._backingStoreFrame)))
1135 if ((CGRectGetWidth(backingStoreFrame) != ROUND(CGRectGetWidth(aLayer._backingStoreFrame)) ||
1136 CGRectGetHeight(backingStoreFrame) != ROUND(CGRectGetHeight(aLayer._backingStoreFrame))))
1139 aLayer._backingStoreFrame = backingStoreFrame;
1151 var sublayers = aLayer._sublayers,
1153 count = sublayers.length;
1155 for (; index < count; ++index)
1156 _CALayerRecalculateGeometry(sublayers[index], aGeometryChange);
1159 function _CALayerGetTransform(fromLayer, toLayer)
1165 var layer = fromLayer;
1169 while (layer && layer != toLayer)
1171 var transformFromLayer = layer._transformFromLayer;
1176 layer = layer._superlayer;
1180 if (layer == toLayer)
1190 layer = layer._superlayer;
1193 var index = layers.length;
1197 var transformToLayer = layers[index]._transformToLayer;