27 #define DOM(aLayer) aLayer._DOMElement
70 CGAffineTransform _affineTransform;
71 CGAffineTransform _sublayerTransform;
72 CGAffineTransform _sublayerTransformForSublayers;
74 CGRect _backingStoreFrame;
75 CGRect _standardBackingStoreFrame;
77 BOOL _hasSublayerTransform;
78 BOOL _hasCustomBackingStoreFrame;
93 unsigned _runLoopUpdateMask;
94 BOOL _needsDisplayOnBoundsChange;
100 BOOL _delegateRespondsToDisplayLayerSelector;
101 BOOL _delegateRespondsToDrawLayerInContextSelector;
105 DOMElement _DOMElement;
106 DOMElement _DOMContentsElement;
111 CGAffineTransform _transformToLayer;
112 CGAffineTransform _transformFromLayer;
120 return [[[
self class] alloc] init];
132 _frame = CGRectMakeZero();
134 _backingStoreFrame = CGRectMakeZero();
135 _standardBackingStoreFrame = CGRectMakeZero();
137 _bounds = CGRectMakeZero();
138 _position = CGPointMakeZero();
140 _anchorPoint = CGPointMake(0.5, 0.5);
141 _affineTransform = CGAffineTransformMakeIdentity();
142 _sublayerTransform = CGAffineTransformMakeIdentity();
144 _transformToLayer = CGAffineTransformMakeIdentity();
145 _transformFromLayer = CGAffineTransformMakeIdentity();
153 _DOMElement = document.createElement(
"div");
155 _DOMElement.style.overflow =
"visible";
156 _DOMElement.style.position =
"absolute";
157 _DOMElement.style.visibility =
"visible";
158 _DOMElement.style.top =
"0px";
159 _DOMElement.style.left =
"0px";
160 _DOMElement.style.zIndex = 0;
161 _DOMElement.style.width =
"0px";
162 _DOMElement.style.height =
"0px";
173 - (void)setBounds:(CGRect)aBounds
175 if (CGRectEqualToRect(_bounds, aBounds))
178 var oldOrigin = _bounds.origin;
180 _bounds = _CGRectMakeCopy(aBounds);
182 if (_hasSublayerTransform)
183 _CALayerUpdateSublayerTransformForSublayers(
self);
210 - (void)setPosition:(CGPoint)aPosition
212 if (CGPointEqualToPoint(_position, aPosition))
215 _position = _CGPointMakeCopy(aPosition);
232 - (void)setZPosition:(
int)aZPosition
234 if (_zPosition == aZPosition)
237 _zPosition = aZPosition;
246 - (void)setAnchorPoint:(CGPoint)anAnchorPoint
248 anAnchorPoint = _CGPointMakeCopy(anAnchorPoint);
249 anAnchorPoint.x = MIN(1.0, MAX(0.0, anAnchorPoint.x));
250 anAnchorPoint.y = MIN(1.0, MAX(0.0, anAnchorPoint.y));
252 if (CGPointEqualToPoint(_anchorPoint, anAnchorPoint))
255 _anchorPoint = anAnchorPoint;
257 if (_hasSublayerTransform)
258 _CALayerUpdateSublayerTransformForSublayers(
self);
261 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
269 - (CGPoint)anchorPoint
278 - (void)setAffineTransform:(CGAffineTransform)anAffineTransform
280 if (CGAffineTransformEqualToTransform(_affineTransform, anAffineTransform))
283 _affineTransform = _CGAffineTransformMakeCopy(anAffineTransform);
291 - (CGAffineTransform)affineTransform
293 return _affineTransform;
300 - (void)setSublayerTransform:(CGAffineTransform)anAffineTransform
302 if (CGAffineTransformEqualToTransform(_sublayerTransform, anAffineTransform))
305 var hadSublayerTransform = _hasSublayerTransform;
307 _sublayerTransform = _CGAffineTransformMakeCopy(anAffineTransform);
308 _hasSublayerTransform = !_CGAffineTransformIsIdentity(_sublayerTransform);
310 if (_hasSublayerTransform)
312 _CALayerUpdateSublayerTransformForSublayers(
self);
314 var index = _sublayers.length;
325 - (CGAffineTransform)sublayerTransform
327 return _sublayerTransform;
334 - (CGAffineTransform)transformToLayer
336 return _transformToLayer;
344 - (void)setFrame:(CGRect)aFrame
346 alert(
"FIXME IMPLEMENT");
372 - (CGRect)backingStoreFrame
374 return _backingStoreFrame;
381 - (void)setBackingStoreFrame:(CGRect)aFrame
383 _hasCustomBackingStoreFrame = (aFrame != nil);
386 aFrame = CGRectMakeCopy(_standardBackingStoreFrame);
391 aFrame = [_superlayer convertRect:aFrame toLayer:nil];
393 var bounds = [_superlayer bounds],
394 frame = [_superlayer convertRect:bounds toLayer:nil];
396 aFrame.origin.x -= _CGRectGetMinX(
frame);
397 aFrame.origin.y -= _CGRectGetMinY(
frame);
400 aFrame = CGRectMakeCopy(aFrame);
403 if (!CGPointEqualToPoint(_backingStoreFrame.origin, aFrame.origin))
406 if (!CGSizeEqualToSize(_backingStoreFrame.size, aFrame.size))
409 _backingStoreFrame = aFrame;
426 - (void)setContents:(CGImage)contents
428 if (_contents == contents)
431 _contents = contents;
445 CGContextClearRect(_context, _CGRectMake(0.0, 0.0, _CGRectGetWidth(_backingStoreFrame), _CGRectGetHeight(_backingStoreFrame)));
452 var superlayerTransform = _CALayerGetTransform(_superlayer, nil),
453 superlayerOrigin = CGPointApplyAffineTransform(_superlayer._bounds.origin, superlayerTransform);
455 transform = CGAffineTransformConcat(_transformFromLayer, superlayerTransform);
457 transform.tx -= superlayerOrigin.x;
458 transform.ty -= superlayerOrigin.y;
463 transform = CGAffineTransformCreateCopy(_transformFromLayer);
465 transform.tx -= _CGRectGetMinX(_backingStoreFrame);
466 transform.ty -= _CGRectGetMinY(_backingStoreFrame);
474 _context.drawImage(_contents.buffer, _CGRectGetMinX(_bounds), _CGRectGetMinY(_bounds));
490 _DOMContentsElement = _context.DOMElement;
492 _DOMContentsElement.style.zIndex = -100;
494 _DOMContentsElement.style.overflow =
"hidden";
495 _DOMContentsElement.style.position =
"absolute";
496 _DOMContentsElement.style.visibility =
"visible";
498 _DOMContentsElement.width = ROUND(_CGRectGetWidth(_backingStoreFrame));
499 _DOMContentsElement.height = ROUND(_CGRectGetHeight(_backingStoreFrame));
501 _DOMContentsElement.style.top =
"0px";
502 _DOMContentsElement.style.left =
"0px";
503 _DOMContentsElement.style.width = ROUND(_CGRectGetWidth(_backingStoreFrame)) +
"px";
504 _DOMContentsElement.style.height = ROUND(_CGRectGetHeight(_backingStoreFrame)) +
"px";
506 _DOMElement.appendChild(_DOMContentsElement);
511 if (_delegateRespondsToDisplayLayerSelector)
512 return [_delegate displayInLayer:self];
514 if (_CGRectGetWidth(_backingStoreFrame) == 0.0 || _CGRectGetHeight(_backingStoreFrame) == 0.0)
518 _contents = CABackingStoreCreate();
532 - (void)drawInContext:(CGContext)aContext
534 if (_backgroundColor)
540 if (_delegateRespondsToDrawLayerInContextSelector)
541 [_delegate drawLayer:self inContext:aContext];
559 - (void)setOpacity:(
float)anOpacity
561 if (_opacity == anOpacity)
564 _opacity = anOpacity;
566 _DOMElement.style.opacity = anOpacity;
567 _DOMElement.style.filter =
"alpha(opacity=" + anOpacity * 100 +
")";
574 - (void)setHidden:(BOOL)isHidden
576 _isHidden = isHidden;
577 _DOMElement.style.display = isHidden ?
"none" :
"block";
600 - (void)setMasksToBounds:(BOOL)masksToBounds
602 if (_masksToBounds == masksToBounds)
605 _masksToBounds = masksToBounds;
606 _DOMElement.style.overflow = _masksToBounds ?
"hidden" :
"visible";
615 _backgroundColor = aColor;
625 return _backgroundColor;
645 #define ADJUST_CONTENTS_ZINDEX(aLayer)\
646 if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)\
647 _DOMContentsElement.style.zIndex -= 100.0;\
658 [_sublayers addObject:aLayer];
659 _DOMElement.appendChild(
DOM(aLayer));
665 - (void)removeFromSuperlayer
668 [_owningView setLayer:nil];
673 _superlayer._DOMElement.removeChild(_DOMElement);
674 [_superlayer._sublayers removeObject:self];
684 - (void)insertSublayer:(
CALayer)aLayer atIndex:(
unsigned)anIndex
691 if (superlayer ==
self)
693 var index = [_sublayers indexOfObjectIdenticalTo:aLayer];
695 if (index == anIndex)
698 [_sublayers removeObjectAtIndex:index];
703 else if (superlayer != nil)
708 [_sublayers insertObject:aLayer atIndex:anIndex];
710 if (anIndex >= _sublayers.length - 1)
711 _DOMElement.appendChild(
DOM(aLayer));
713 _DOMElement.insertBefore(
DOM(aLayer), _sublayers[anIndex + 1]._DOMElement);
715 aLayer._superlayer =
self;
717 if (
self != superlayer)
718 _CALayerRecalculateGeometry(aLayer, 0xFFFFFFF);
729 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : 0;
731 [
self insertSublayer:aLayer atIndex:index == CPNotFound ? _sublayers.length : index];
742 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : _sublayers.length;
746 [_sublayers insertObject:aLayer atIndex:index == CPNotFound ? _sublayers.length : index + 1];
756 if (aSublayer == aLayer)
760 if (aSublayer._superlayer !=
self)
768 [_sublayers replaceObjectAtIndex:[_sublayers indexOfObjectIdenticalTo:aSublayer] withObject:aLayer];
769 _DOMElement.replaceChild(
DOM(aSublayer),
DOM(aLayer));
777 + (void)runLoopUpdateLayers
782 mask = layer._runLoopUpdateMask;
785 _CALayerUpdateDOM(layer, mask);
793 layer._runLoopUpdateMask = 0;
802 - (void)registerRunLoopUpdateWithMask:(
unsigned)anUpdateMask
812 _runLoopUpdateMask |= anUpdateMask;
819 - (void)setNeedsComposite
827 - (void)setNeedsDisplay
836 - (void)setNeedsDisplayOnBoundsChange:(BOOL)needsDisplayOnBoundsChange
838 _needsDisplayOnBoundsChange = needsDisplayOnBoundsChange;
844 - (BOOL)needsDisplayOnBoundsChange
846 return _needsDisplayOnBoundsChange;
853 - (void)setNeedsDisplayInRect:(CGRect)aRect
866 - (CGPoint)convertPoint:(CGPoint)aPoint fromLayer:(
CALayer)aLayer
868 return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(aLayer,
self));
877 - (CGPoint)convertPoint:(CGPoint)aPoint toLayer:(
CALayer)aLayer
879 return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(
self, aLayer));
888 - (CGRect)convertRect:(CGRect)aRect fromLayer:(
CALayer)aLayer
899 - (CGRect)convertRect:(CGRect)aRect toLayer:(
CALayer)aLayer
909 - (BOOL)containsPoint:(CGPoint)aPoint
911 return _CGRectContainsPoint(_bounds, aPoint);
924 var point = CGPointApplyAffineTransform(aPoint, _transformToLayer);
927 if (!_CGRectContainsPoint(_bounds, point))
931 index = _sublayers.length;
935 if (layer = [_sublayers[index] hitTest:point])
946 - (void)setDelegate:(
id)aDelegate
948 if (_delegate == aDelegate)
951 _delegate = aDelegate;
953 _delegateRespondsToDisplayLayerSelector = [_delegate respondsToSelector:@selector(displayLayer:)];
954 _delegateRespondsToDrawLayerInContextSelector = [_delegate respondsToSelector:@selector(drawLayer:inContext:)];
956 if (_delegateRespondsToDisplayLayerSelector || _delegateRespondsToDrawLayerInContextSelector)
969 - (void)_setOwningView:(
CPView)anOwningView
971 _owningView = anOwningView;
975 _owningView = anOwningView;
977 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
978 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
985 - (void)_owningViewBoundsChanged
987 _bounds.size = CGSizeMakeCopy([_owningView bounds].size);
988 _position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
998 var mask = _runLoopUpdateMask;
1001 _CALayerUpdateDOM(
self, mask);
1009 _runLoopUpdateMask = 0;
1011 window.loop =
false;
1016 function _CALayerUpdateSublayerTransformForSublayers(aLayer)
1018 var bounds = aLayer._bounds,
1019 anchorPoint = aLayer._anchorPoint,
1020 translateX = _CGRectGetWidth(bounds) * anchorPoint.x,
1021 translateY = _CGRectGetHeight(bounds) * anchorPoint.y;
1023 aLayer._sublayerTransformForSublayers = CGAffineTransformConcat(
1024 CGAffineTransformMakeTranslation(-translateX, -translateY),
1025 CGAffineTransformConcat(aLayer._sublayerTransform,
1026 CGAffineTransformMakeTranslation(translateX, translateY)));
1029 function _CALayerUpdateDOM(aLayer, aMask)
1031 var DOMElementStyle = aLayer._DOMElement.style;
1034 DOMElementStyle.zIndex = aLayer._zPosition;
1036 var
frame = aLayer._backingStoreFrame;
1040 DOMElementStyle.top = ROUND(_CGRectGetMinY(frame)) + "px";
1041 DOMElementStyle.left = ROUND(_CGRectGetMinX(frame)) + "px";
1046 var
width = MAX(0.0, ROUND(_CGRectGetWidth(frame))),
1047 height = MAX(0.0, ROUND(_CGRectGetHeight(frame))),
1048 DOMContentsElement = aLayer._DOMContentsElement;
1050 DOMElementStyle.width = width + "px";
1051 DOMElementStyle.height = height + "px";
1053 if (DOMContentsElement)
1055 DOMContentsElement.width =
width;
1056 DOMContentsElement.height = height;
1057 DOMContentsElement.style.width = width + "px";
1058 DOMContentsElement.style.height = height + "px";
1063 function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
1065 var bounds = aLayer._bounds,
1066 superlayer = aLayer._superlayer,
1067 width = _CGRectGetWidth(bounds),
1068 height = _CGRectGetHeight(bounds),
1069 position = aLayer._position,
1070 anchorPoint = aLayer._anchorPoint,
1071 affineTransform = aLayer._affineTransform,
1072 backingStoreFrameSize = _CGSizeMakeCopy(aLayer._backingStoreFrame),
1073 hasCustomBackingStoreFrame = aLayer._hasCustomBackingStoreFrame;
1076 aLayer._transformFromLayer = CGAffineTransformConcat(
1077 CGAffineTransformMakeTranslation(-width * anchorPoint.x - _CGRectGetMinX(aLayer._bounds), -height * anchorPoint.y - _CGRectGetMinY(aLayer._bounds)),
1078 CGAffineTransformConcat(affineTransform,
1079 CGAffineTransformMakeTranslation(position.x, position.y)));
1081 if (superlayer && superlayer._hasSublayerTransform)
1084 _CGAffineTransformConcatTo(aLayer._transformFromLayer, superlayer._sublayerTransformForSublayers, aLayer._transformFromLayer);
1092 aLayer._frame = nil;
1097 var bounds = [superlayer bounds],
1098 frame = [superlayer convertRect:bounds toLayer:nil];
1100 aLayer._standardBackingStoreFrame.origin.x -= _CGRectGetMinX(frame);
1101 aLayer._standardBackingStoreFrame.origin.y -= _CGRectGetMinY(frame);
1109 var origin = aLayer._standardBackingStoreFrame.origin,
1110 size = aLayer._standardBackingStoreFrame.size;
1112 origin.x = FLOOR(origin.x);
1113 origin.y = FLOOR(origin.y);
1114 size.width = CEIL(size.width) + 1.0;
1115 size.height = CEIL(size.height) + 1.0;
1121 if (!hasCustomBackingStoreFrame)
1123 var backingStoreFrame = CGRectMakeCopy(aLayer._standardBackingStoreFrame);
1127 if (ROUND(_CGRectGetMinX(backingStoreFrame)) != ROUND(_CGRectGetMinX(aLayer._backingStoreFrame)) ||
1128 ROUND(_CGRectGetMinY(backingStoreFrame)) != ROUND(_CGRectGetMinY(aLayer._backingStoreFrame)))
1132 if ((_CGRectGetWidth(backingStoreFrame) != ROUND(_CGRectGetWidth(aLayer._backingStoreFrame)) ||
1133 _CGRectGetHeight(backingStoreFrame) != ROUND(_CGRectGetHeight(aLayer._backingStoreFrame))))
1136 aLayer._backingStoreFrame = backingStoreFrame;
1148 var sublayers = aLayer._sublayers,
1150 count = sublayers.length;
1152 for (; index < count; ++index)
1153 _CALayerRecalculateGeometry(sublayers[index], aGeometryChange);
1156 function _CALayerGetTransform(fromLayer, toLayer)
1158 var transform = CGAffineTransformMakeIdentity();
1162 var layer = fromLayer;
1166 while (layer && layer != toLayer)
1168 var transformFromLayer = layer._transformFromLayer;
1171 _CGAffineTransformConcatTo(transform, transformFromLayer, transform);
1173 layer = layer._superlayer;
1177 if (layer == toLayer)
1187 layer = layer._superlayer;
1190 var index = layers.length;
1194 var transformToLayer = layers[index]._transformToLayer;
1196 _CGAffineTransformConcatTo(transform, transformToLayer, transform);