27 #define DOM(aLayer) aLayer._DOMElement
48 to have a transform applied to it.
52 call this in place of its \c -drawInContext:.
54 @param ctx the context to draw on
58 by implementing this method.
70 CGAffineTransform _affineTransform;
71 CGAffineTransform _sublayerTransform;
72 CGAffineTransform _sublayerTransformForSublayers;
74 CGRect _backingStoreFrame;
75 CGRect _standardBackingStoreFrame;
77 BOOL _hasSublayerTransform;
78 BOOL _hasCustomBackingStoreFrame;
94 unsigned _runLoopUpdateMask;
95 BOOL _needsDisplayOnBoundsChange;
101 BOOL _delegateRespondsToDisplayLayerSelector;
102 BOOL _delegateRespondsToDrawLayerInContextSelector;
106 DOMElement _DOMElement;
107 DOMElement _DOMContentsElement;
112 CGAffineTransform _transformToLayer;
113 CGAffineTransform _transformFromLayer;
121 return [[[
self class] alloc]
init];
133 _frame = CGRectMakeZero();
135 _backingStoreFrame = CGRectMakeZero();
136 _standardBackingStoreFrame = CGRectMakeZero();
138 _bounds = CGRectMakeZero();
139 _position = CGPointMakeZero();
141 _anchorPoint = CGPointMake(0.5, 0.5);
155 _DOMElement = document.createElement(
"div");
157 _DOMElement.style.overflow =
"visible";
158 _DOMElement.style.position =
"absolute";
159 _DOMElement.style.visibility =
"visible";
160 _DOMElement.style.top =
"0px";
161 _DOMElement.style.left =
"0px";
162 _DOMElement.style.zIndex = 0;
163 _DOMElement.style.width =
"0px";
164 _DOMElement.style.height =
"0px";
176 - (void)setBounds:(CGRect)aBounds
178 if (CGRectEqualToRect(_bounds, aBounds))
181 var oldOrigin = _bounds.origin;
183 _bounds = CGRectMakeCopy(aBounds);
185 if (_hasSublayerTransform)
186 _CALayerUpdateSublayerTransformForSublayers(
self);
213 - (void)setPosition:(CGPoint)aPosition
215 if (CGPointEqualToPoint(_position, aPosition))
218 _position = CGPointMakeCopy(aPosition);
235 - (void)setZPosition:(
int)aZPosition
237 if (_zPosition == aZPosition)
240 _zPosition = aZPosition;
249 - (void)setAnchorPoint:(CGPoint)anAnchorPoint
251 anAnchorPoint = CGPointMakeCopy(anAnchorPoint);
252 anAnchorPoint.x = MIN(1.0, MAX(0.0, anAnchorPoint.x));
253 anAnchorPoint.y = MIN(1.0, MAX(0.0, anAnchorPoint.y));
255 if (CGPointEqualToPoint(_anchorPoint, anAnchorPoint))
258 _anchorPoint = anAnchorPoint;
260 if (_hasSublayerTransform)
261 _CALayerUpdateSublayerTransformForSublayers(
self);
264 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
281 - (void)setAffineTransform:(CGAffineTransform)anAffineTransform
296 return _affineTransform;
303 - (void)setSublayerTransform:(CGAffineTransform)anAffineTransform
308 var hadSublayerTransform = _hasSublayerTransform;
313 if (_hasSublayerTransform)
315 _CALayerUpdateSublayerTransformForSublayers(
self);
317 var index = _sublayers.length;
330 return _sublayerTransform;
339 return _transformToLayer;
347 - (void)setFrame:(CGRect)aFrame
362 _frame = [
self convertRect:_bounds toLayer:_superlayer];
377 return _backingStoreFrame;
384 - (void)setBackingStoreFrame:(CGRect)aFrame
386 _hasCustomBackingStoreFrame = (aFrame != nil);
389 aFrame = CGRectMakeCopy(_standardBackingStoreFrame);
394 aFrame = [_superlayer convertRect:aFrame toLayer:nil];
397 frame = [_superlayer convertRect:bounds toLayer:nil];
399 aFrame.origin.x -= CGRectGetMinX(
frame);
400 aFrame.origin.y -= CGRectGetMinY(
frame);
403 aFrame = CGRectMakeCopy(aFrame);
406 if (!CGPointEqualToPoint(_backingStoreFrame.origin, aFrame.origin))
409 if (!CGSizeEqualToSize(_backingStoreFrame.size, aFrame.size))
412 _backingStoreFrame = aFrame;
448 CGContextClearRect(_context, CGRectMake(0.0, 0.0, CGRectGetWidth(_backingStoreFrame), CGRectGetHeight(_backingStoreFrame)));
455 var superlayerTransform = _CALayerGetTransform(_superlayer, nil),
460 transform.tx -= superlayerOrigin.x;
461 transform.ty -= superlayerOrigin.y;
468 transform.tx -= CGRectGetMinX(_backingStoreFrame);
469 transform.ty -= CGRectGetMinY(_backingStoreFrame);
478 _context.drawImage(_contents.buffer, CGRectGetMinX(_bounds), CGRectGetMinY(_bounds));
481 [
self drawInContext:_context];
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);
518 if (_delegateRespondsToDisplayLayerSelector)
519 return [_delegate displayInLayer:
self];
521 if (CGRectGetWidth(_backingStoreFrame) == 0.0 || CGRectGetHeight(_backingStoreFrame) == 0.0)
525 _contents = CABackingStoreCreate();
539 - (void)drawInContext:(CGContext)aContext
541 if (_backgroundColor)
547 if (_delegateRespondsToDrawLayerInContextSelector)
548 [_delegate drawLayer:
self inContext:aContext];
566 - (void)setOpacity:(
float)anOpacity
568 if (_opacity == anOpacity)
571 _opacity = anOpacity;
573 _DOMElement.style.opacity = anOpacity;
574 _DOMElement.style.filter =
"alpha(opacity=" + anOpacity * 100 +
")";
584 _DOMElement.style.display =
isHidden ?
"none" :
"block";
607 - (void)setMasksToBounds:(BOOL)masksToBounds
609 if (_masksToBounds == masksToBounds)
612 _masksToBounds = masksToBounds;
613 _DOMElement.style.overflow = _masksToBounds ?
"hidden" :
"visible";
622 _backgroundColor = aColor;
632 return _backgroundColor;
652 #define ADJUST_CONTENTS_ZINDEX(aLayer)\
653 if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)\
654 _DOMContentsElement.style.zIndex -= 100.0;\
661 [
self insertSublayer:aLayer atIndex:_sublayers.length];
670 [_owningView setLayer:nil];
675 _superlayer._DOMElement.removeChild(_DOMElement);
676 [_superlayer._sublayers removeObject:
self];
686 - (void)insertSublayer:(
CALayer)aLayer atIndex:(CPUInteger)anIndex
693 if (superlayer ==
self)
695 var index = [_sublayers indexOfObjectIdenticalTo:aLayer];
697 if (index == anIndex)
700 [_sublayers removeObjectAtIndex:index];
705 else if (superlayer != nil)
710 [_sublayers insertObject:aLayer atIndex:anIndex];
713 if (anIndex >= _sublayers.length - 1)
714 _DOMElement.appendChild(
DOM(aLayer));
716 _DOMElement.insertBefore(
DOM(aLayer), _sublayers[anIndex + 1]._DOMElement);
719 aLayer._superlayer =
self;
721 if (
self != superlayer)
722 _CALayerRecalculateGeometry(aLayer, 0xFFFFFFF);
733 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : 0;
735 [
self insertSublayer:aLayer atIndex:index ==
CPNotFound ? _sublayers.length : index];
746 var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : _sublayers.length;
749 [
CPException raise:
"CALayerNotFoundException" reason:
"aSublayer is not a sublayer of this layer"];
751 [_sublayers insertObject:aLayer atIndex:index ==
CPNotFound ? _sublayers.length : index + 1];
761 if (aSublayer == aLayer)
764 if (aSublayer._superlayer !=
self)
766 CPLog.warn(
"Attempt to replace a sublayer (%s) which is not in the sublayers of the receiver (%s).", [aSublayer description], [
self description]);
772 [_sublayers replaceObjectAtIndex:[_sublayers indexOfObjectIdenticalTo:aSublayer] withObject:aLayer];
773 _DOMElement.replaceChild(
DOM(aSublayer),
DOM(aLayer));
785 var
layer = CALayerRegisteredRunLoopUpdates[UID],
786 mask = layer._runLoopUpdateMask;
789 _CALayerUpdateDOM(layer, mask);
797 layer._runLoopUpdateMask = 0;
801 CALayerRegisteredRunLoopUpdates = nil;
807 - (void)registerRunLoopUpdateWithMask:(
unsigned)anUpdateMask
817 _runLoopUpdateMask |= anUpdateMask;
851 return _needsDisplayOnBoundsChange;
858 - (void)setNeedsDisplayInRect:(CGRect)aRect
871 - (CGPoint)convertPoint:(CGPoint)aPoint fromLayer:(
CALayer)aLayer
882 - (CGPoint)convertPoint:(CGPoint)aPoint toLayer:(
CALayer)aLayer
893 - (CGRect)convertRect:(CGRect)aRect fromLayer:(
CALayer)aLayer
904 - (CGRect)convertRect:(CGRect)aRect toLayer:(
CALayer)aLayer
914 - (BOOL)containsPoint:(CGPoint)aPoint
916 return CGRectContainsPoint(_bounds, aPoint);
931 if (!CGRectContainsPoint(_bounds, point))
935 index = _sublayers.length;
939 if (layer = [_sublayers[index] hitTest:point])
950 - (void)setDelegate:(
id)aDelegate
952 if (_delegate == aDelegate)
955 _delegate = aDelegate;
957 _delegateRespondsToDisplayLayerSelector = [_delegate respondsToSelector:
@selector(displayLayer:)];
958 _delegateRespondsToDrawLayerInContextSelector = [_delegate respondsToSelector:
@selector(drawLayer:inContext:)];
960 if (_delegateRespondsToDisplayLayerSelector || _delegateRespondsToDrawLayerInContextSelector)
973 - (void)_setOwningView:(
CPView)anOwningView
975 _owningView = anOwningView;
979 _owningView = anOwningView;
981 _bounds.size = CGSizeMakeCopy([_owningView
bounds].size);
982 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
989 - (void)_owningViewBoundsChanged
991 _bounds.size = CGSizeMakeCopy([_owningView
bounds].size);
992 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
1002 var mask = _runLoopUpdateMask;
1005 _CALayerUpdateDOM(
self, mask);
1013 _runLoopUpdateMask = 0;
1015 window.loop =
false;
1020 function _CALayerUpdateSublayerTransformForSublayers(aLayer)
1022 var
bounds = aLayer._bounds,
1024 translateX = CGRectGetWidth(bounds) *
anchorPoint.x,
1025 translateY = CGRectGetHeight(bounds) *
anchorPoint.y;
1033 function _CALayerUpdateDOM(aLayer, aMask)
1036 var DOMElementStyle = aLayer._DOMElement.style;
1039 DOMElementStyle.zIndex = aLayer._zPosition;
1041 var
frame = aLayer._backingStoreFrame;
1045 DOMElementStyle.top = ROUND(CGRectGetMinY(frame)) +
"px";
1046 DOMElementStyle.left = ROUND(CGRectGetMinX(frame)) +
"px";
1051 var
width = MAX(0.0, ROUND(CGRectGetWidth(frame))),
1052 height = MAX(0.0, ROUND(CGRectGetHeight(frame))),
1053 DOMContentsElement = aLayer._DOMContentsElement;
1055 DOMElementStyle.width = width +
"px";
1056 DOMElementStyle.height = height +
"px";
1058 if (DOMContentsElement)
1060 DOMContentsElement.width =
width;
1061 DOMContentsElement.height = height;
1062 DOMContentsElement.style.width = width +
"px";
1063 DOMContentsElement.style.height = height +
"px";
1069 function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
1071 var bounds = aLayer._bounds,
1073 width = CGRectGetWidth(bounds),
1074 height = CGRectGetHeight(bounds),
1078 backingStoreFrameSize = CGSizeMakeCopy(aLayer._backingStoreFrame),
1079 hasCustomBackingStoreFrame = aLayer._hasCustomBackingStoreFrame;
1098 aLayer._frame = nil;
1099 aLayer._standardBackingStoreFrame = [aLayer convertRect:bounds toLayer:nil];
1104 frame = [
superlayer convertRect:bounds toLayer:nil];
1106 aLayer._standardBackingStoreFrame.origin.x -= CGRectGetMinX(frame);
1107 aLayer._standardBackingStoreFrame.origin.y -= CGRectGetMinY(frame);
1115 var origin = aLayer._standardBackingStoreFrame.origin,
1116 size = aLayer._standardBackingStoreFrame.size;
1118 origin.x = FLOOR(origin.x);
1119 origin.y = FLOOR(origin.y);
1120 size.width = CEIL(size.width) + 1.0;
1121 size.height = CEIL(size.height) + 1.0;
1127 if (!hasCustomBackingStoreFrame)
1133 if (ROUND(CGRectGetMinX(backingStoreFrame)) != ROUND(CGRectGetMinX(aLayer._backingStoreFrame)) ||
1134 ROUND(CGRectGetMinY(backingStoreFrame)) != ROUND(CGRectGetMinY(aLayer._backingStoreFrame)))
1138 if ((CGRectGetWidth(backingStoreFrame) != ROUND(CGRectGetWidth(aLayer._backingStoreFrame)) ||
1139 CGRectGetHeight(backingStoreFrame) != ROUND(CGRectGetHeight(aLayer._backingStoreFrame))))
1156 count = sublayers.length;
1158 for (; index < count; ++index)
1159 _CALayerRecalculateGeometry(sublayers[index], aGeometryChange);
1162 function _CALayerGetTransform(fromLayer, toLayer)
1168 var
layer = fromLayer;
1172 while (layer && layer != toLayer)
1174 var transformFromLayer = layer._transformFromLayer;
1179 layer = layer._superlayer;
1183 if (layer == toLayer)
1193 layer = layer._superlayer;
1196 var index = layers.length;