26 #define DOM(aLayer) aLayer._DOMElement
47 to have a transform applied to it.
51 call this in place of its \c -drawInContext:.
53 @param ctx the context to draw on
57 by implementing this method.
69 CGAffineTransform _affineTransform;
70 CGAffineTransform _sublayerTransform;
71 CGAffineTransform _sublayerTransformForSublayers;
73 CGRect _backingStoreFrame;
74 CGRect _standardBackingStoreFrame;
76 BOOL _hasSublayerTransform;
77 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);
154 _DOMElement = document.createElement(
"div");
156 _DOMElement.style.overflow =
"visible";
157 _DOMElement.style.position =
"absolute";
158 _DOMElement.style.visibility =
"visible";
159 _DOMElement.style.top =
"0px";
160 _DOMElement.style.left =
"0px";
161 _DOMElement.style.zIndex = 0;
162 _DOMElement.style.width =
"0px";
163 _DOMElement.style.height =
"0px";
175 - (void)setBounds:(CGRect)aBounds
177 if (CGRectEqualToRect(_bounds, aBounds))
180 var oldOrigin = _bounds.origin;
182 _bounds = CGRectMakeCopy(aBounds);
184 if (_hasSublayerTransform)
185 _CALayerUpdateSublayerTransformForSublayers(
self);
212 - (void)setPosition:(CGPoint)aPosition
214 if (CGPointEqualToPoint(_position, aPosition))
217 _position = CGPointMakeCopy(aPosition);
234 - (void)setZPosition:(
int)aZPosition
236 if (_zPosition == aZPosition)
239 _zPosition = aZPosition;
248 - (void)setAnchorPoint:(CGPoint)anAnchorPoint
250 anAnchorPoint = CGPointMakeCopy(anAnchorPoint);
251 anAnchorPoint.x = MIN(1.0, MAX(0.0, anAnchorPoint.x));
252 anAnchorPoint.y = MIN(1.0, MAX(0.0, anAnchorPoint.y));
254 if (CGPointEqualToPoint(_anchorPoint, anAnchorPoint))
257 _anchorPoint = anAnchorPoint;
259 if (_hasSublayerTransform)
260 _CALayerUpdateSublayerTransformForSublayers(
self);
263 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
280 - (void)setAffineTransform:(CGAffineTransform)anAffineTransform
295 return _affineTransform;
302 - (void)setSublayerTransform:(CGAffineTransform)anAffineTransform
307 var hadSublayerTransform = _hasSublayerTransform;
312 if (_hasSublayerTransform)
314 _CALayerUpdateSublayerTransformForSublayers(
self);
316 var index = _sublayers.length;
329 return _sublayerTransform;
338 return _transformToLayer;
346 - (void)setFrame:(CGRect)aFrame
361 _frame = [
self convertRect:_bounds toLayer:_superlayer];
376 return _backingStoreFrame;
383 - (void)setBackingStoreFrame:(CGRect)aFrame
385 _hasCustomBackingStoreFrame = (aFrame != nil);
388 aFrame = CGRectMakeCopy(_standardBackingStoreFrame);
393 aFrame = [_superlayer convertRect:aFrame toLayer:nil];
396 frame = [_superlayer convertRect:bounds toLayer:nil];
398 aFrame.origin.x -= CGRectGetMinX(
frame);
399 aFrame.origin.y -= CGRectGetMinY(
frame);
402 aFrame = CGRectMakeCopy(aFrame);
405 if (!CGPointEqualToPoint(_backingStoreFrame.origin, aFrame.origin))
408 if (!CGSizeEqualToSize(_backingStoreFrame.size, aFrame.size))
411 _backingStoreFrame = aFrame;
447 CGContextClearRect(_context, CGRectMake(0.0, 0.0, CGRectGetWidth(_backingStoreFrame), CGRectGetHeight(_backingStoreFrame)));
454 var superlayerTransform = _CALayerGetTransform(_superlayer, nil),
459 transform.tx -= superlayerOrigin.x;
460 transform.ty -= superlayerOrigin.y;
467 transform.tx -= CGRectGetMinX(_backingStoreFrame);
468 transform.ty -= CGRectGetMinY(_backingStoreFrame);
477 _context.drawImage(_contents.buffer, CGRectGetMinX(_bounds), CGRectGetMinY(_bounds));
480 [
self drawInContext:_context];
495 _DOMContentsElement = _context.DOMElement;
497 _DOMContentsElement.style.zIndex = -100;
499 _DOMContentsElement.style.overflow =
"hidden";
500 _DOMContentsElement.style.position =
"absolute";
501 _DOMContentsElement.style.visibility =
"visible";
503 _DOMContentsElement.width = ROUND(CGRectGetWidth(_backingStoreFrame));
504 _DOMContentsElement.height = ROUND(CGRectGetHeight(_backingStoreFrame));
506 _DOMContentsElement.style.top =
"0px";
507 _DOMContentsElement.style.left =
"0px";
508 _DOMContentsElement.style.width = ROUND(CGRectGetWidth(_backingStoreFrame)) +
"px";
509 _DOMContentsElement.style.height = ROUND(CGRectGetHeight(_backingStoreFrame)) +
"px";
511 _DOMElement.appendChild(_DOMContentsElement);
516 if (_delegateRespondsToDisplayLayerSelector)
517 return [_delegate displayLayer:
self];
519 if (CGRectGetWidth(_backingStoreFrame) == 0.0 || CGRectGetHeight(_backingStoreFrame) == 0.0)
523 _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 +
")";
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;\
660 [
self insertSublayer:aLayer atIndex:_sublayers.length];
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;
748 [
CPException raise:
"CALayerNotFoundException" reason:
"aSublayer is not a sublayer of this layer"];
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));
784 var
layer = CALayerRegisteredRunLoopUpdates[UID],
785 mask = layer._runLoopUpdateMask;
788 _CALayerUpdateDOM(layer, mask);
795 layer._runLoopUpdateMask = 0;
799 CALayerRegisteredRunLoopUpdates = nil;
805 - (void)registerRunLoopUpdateWithMask:(
unsigned)anUpdateMask
815 _runLoopUpdateMask |= anUpdateMask;
849 return _needsDisplayOnBoundsChange;
856 - (void)setNeedsDisplayInRect:(CGRect)aRect
869 - (CGPoint)convertPoint:(CGPoint)aPoint fromLayer:(
CALayer)aLayer
880 - (CGPoint)convertPoint:(CGPoint)aPoint toLayer:(
CALayer)aLayer
891 - (CGRect)convertRect:(CGRect)aRect fromLayer:(
CALayer)aLayer
902 - (CGRect)convertRect:(CGRect)aRect toLayer:(
CALayer)aLayer
912 - (BOOL)containsPoint:(CGPoint)aPoint
914 return CGRectContainsPoint(_bounds, aPoint);
929 if (!CGRectContainsPoint(_bounds, point))
933 index = _sublayers.length;
937 if (layer = [_sublayers[index] hitTest:point])
948 - (void)setDelegate:(
id)aDelegate
950 if (_delegate == aDelegate)
953 _delegate = aDelegate;
955 _delegateRespondsToDisplayLayerSelector = [_delegate respondsToSelector:
@selector(displayLayer:)];
956 _delegateRespondsToDrawLayerInContextSelector = [_delegate respondsToSelector:
@selector(drawLayer:inContext:)];
958 if (_delegateRespondsToDisplayLayerSelector || _delegateRespondsToDrawLayerInContextSelector)
971 - (void)_setOwningView:(
CPView)anOwningView
973 _owningView = anOwningView;
977 _owningView = anOwningView;
979 _bounds.size = CGSizeMakeCopy([_owningView
bounds].size);
980 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
987 - (void)_owningViewBoundsChanged
989 _bounds.size = CGSizeMakeCopy([_owningView
bounds].size);
990 _position = CGPointMake(CGRectGetWidth(_bounds) * _anchorPoint.x, CGRectGetHeight(_bounds) * _anchorPoint.y);
1000 var mask = _runLoopUpdateMask;
1003 _CALayerUpdateDOM(
self, mask);
1011 _runLoopUpdateMask = 0;
1013 window.loop =
false;
1018 function _CALayerUpdateSublayerTransformForSublayers(aLayer)
1020 var
bounds = aLayer._bounds,
1022 translateX = CGRectGetWidth(bounds) *
anchorPoint.x,
1023 translateY = CGRectGetHeight(bounds) *
anchorPoint.y;
1031 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";
1067 function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
1069 var bounds = aLayer._bounds,
1071 width = CGRectGetWidth(bounds),
1072 height = CGRectGetHeight(bounds),
1076 backingStoreFrameSize = CGSizeMakeCopy(aLayer._backingStoreFrame),
1077 hasCustomBackingStoreFrame = aLayer._hasCustomBackingStoreFrame;
1096 aLayer._frame = nil;
1097 aLayer._standardBackingStoreFrame = [aLayer convertRect:bounds toLayer:nil];
1102 frame = [
superlayer convertRect:bounds toLayer:nil];
1104 aLayer._standardBackingStoreFrame.origin.x -= CGRectGetMinX(frame);
1105 aLayer._standardBackingStoreFrame.origin.y -= CGRectGetMinY(frame);
1113 var origin = aLayer._standardBackingStoreFrame.origin,
1114 size = aLayer._standardBackingStoreFrame.size;
1116 origin.x = FLOOR(origin.x);
1117 origin.y = FLOOR(origin.y);
1118 size.width = CEIL(size.width) + 1.0;
1119 size.height = CEIL(size.height) + 1.0;
1125 if (!hasCustomBackingStoreFrame)
1131 if (ROUND(CGRectGetMinX(backingStoreFrame)) != ROUND(CGRectGetMinX(aLayer._backingStoreFrame)) ||
1132 ROUND(CGRectGetMinY(backingStoreFrame)) != ROUND(CGRectGetMinY(aLayer._backingStoreFrame)))
1136 if ((CGRectGetWidth(backingStoreFrame) != ROUND(CGRectGetWidth(aLayer._backingStoreFrame)) ||
1137 CGRectGetHeight(backingStoreFrame) != ROUND(CGRectGetHeight(aLayer._backingStoreFrame))))
1154 count = sublayers.length;
1156 for (; index < count; ++index)
1157 _CALayerRecalculateGeometry(sublayers[index], aGeometryChange);
1160 function _CALayerGetTransform(fromLayer, toLayer)
1166 var
layer = fromLayer;
1170 while (layer && layer != toLayer)
1172 var transformFromLayer = layer._transformFromLayer;
1177 layer = layer._superlayer;
1181 if (layer == toLayer)
1191 layer = layer._superlayer;
1194 var index = layers.length;