📄 graphicslayerca.mm
字号:
CGColorRef bgColor = createCGColor(color); setBasicAnimation(AnimatedPropertyBackgroundColor, TransformOperation::NONE, 0, fromBackgroundColor, bgColor, true, transition, beginTime); CGColorRelease(bgColor); } else { removeAllAnimationsForProperty(AnimatedPropertyBackgroundColor); setHasContentsLayer(true); setLayerBackgroundColor(m_contentsLayer.get(), m_backgroundColor); } END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::clearBackgroundColor(){ if (!m_contentLayerForImageOrVideo) setHasContentsLayer(false); else clearLayerBackgroundColor(m_contentsLayer.get());}void GraphicsLayerCA::setContentsOpaque(bool opaque){ GraphicsLayer::setContentsOpaque(opaque); BEGIN_BLOCK_OBJC_EXCEPTIONS [m_layer.get() setOpaque:m_contentsOpaque]; END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::setBackfaceVisibility(bool visible){ if (m_backfaceVisibility == visible) return; GraphicsLayer::setBackfaceVisibility(visible); BEGIN_BLOCK_OBJC_EXCEPTIONS [m_layer.get() setDoubleSided:visible]; END_BLOCK_OBJC_EXCEPTIONS}bool GraphicsLayerCA::setOpacity(float opacity, const Animation* transition, double beginTime){ if (forceSoftwareAnimation()) return false; float clampedOpacity = max(0.0f, min(opacity, 1.0f)); bool opacitiesDiffer = (m_opacity != clampedOpacity); GraphicsLayer::setOpacity(clampedOpacity, transition, beginTime); int animIndex = findAnimationEntry(AnimatedPropertyOpacity, 0); // If we don't have a transition just set the opacity if (!transition || transition->isEmptyOrZeroDuration()) { // Three cases: // 1) no existing animation or transition: just set opacity // 2) existing transition: clear it and set opacity // 3) existing animation: just return // if (animIndex < 0 || m_animations[animIndex].isTransition()) { BEGIN_BLOCK_OBJC_EXCEPTIONS [primaryLayer() setOpacity:opacity]; if (animIndex >= 0) { removeAllAnimationsForProperty(AnimatedPropertyOpacity); animIndex = -1; } else { String keyPath = propertyIdToString(AnimatedPropertyOpacity); // FIXME: using hardcoded '0' here. We should be clearing all animations. For now there is only 1. String animName = keyPath + "_0"; [animatedLayer(AnimatedPropertyOpacity) removeAnimationForKey:animName]; } END_BLOCK_OBJC_EXCEPTIONS } else { // We have an animation, so don't set the opacity directly. return false; } } else { // At this point, we know we have a transition. But if it is the same and // the opacity value has not changed, don't do anything. if (!opacitiesDiffer && ((animIndex == -1) || (m_animations[animIndex].isTransition() && *(m_animations[animIndex].animation()) == *transition))) { return false; } } // If an animation is running, ignore this transition, but still save the value. if (animIndex >= 0 && !m_animations[animIndex].isTransition()) return false; bool didAnimate = false; BEGIN_BLOCK_OBJC_EXCEPTIONS NSNumber* fromOpacityValue = nil; NSNumber* toOpacityValue = [NSNumber numberWithFloat:opacity]; if (transition && !transition->isEmptyOrZeroDuration()) { CALayer* presLayer = getPresentationLayer(primaryLayer()); float fromOpacity = [presLayer opacity]; fromOpacityValue = [NSNumber numberWithFloat:fromOpacity]; setBasicAnimation(AnimatedPropertyOpacity, TransformOperation::NONE, 0, fromOpacityValue, toOpacityValue, true, transition, beginTime); didAnimate = true; } END_BLOCK_OBJC_EXCEPTIONS return didAnimate;}void GraphicsLayerCA::setNeedsDisplay(){ BEGIN_BLOCK_OBJC_EXCEPTIONS if (drawsContent()) [m_layer.get() setNeedsDisplay]; END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& rect){ BEGIN_BLOCK_OBJC_EXCEPTIONS if (drawsContent()) [m_layer.get() setNeedsDisplayInRect:rect]; END_BLOCK_OBJC_EXCEPTIONS}bool GraphicsLayerCA::animateTransform(const TransformValueList& valueList, const IntSize& size, const Animation* anim, double beginTime, bool isTransition){ if (forceSoftwareAnimation() || !anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2) return false; TransformValueList::FunctionList functionList; bool isValid, hasBigRotation; valueList.makeFunctionList(functionList, isValid, hasBigRotation); // We need to fall back to software animation if we don't have setValueFunction:, and // we would need to animate each incoming transform function separately. This is the // case if we have a rotation >= 180 or we have more than one transform function. if ((hasBigRotation || functionList.size() > 1) && !caValueFunctionSupported()) return false; BEGIN_BLOCK_OBJC_EXCEPTIONS // Rules for animation: // // 1) If functionList is empty or we don't have a big rotation, we do a matrix animation. We could // use component animation for lists without a big rotation, but there is no need to, and this // is more efficient. // // 2) Otherwise we do a component hardware animation. bool isMatrixAnimation = !isValid || !hasBigRotation; // Set transform to identity since we are animating components and we need the base // to be the identity transform. TransformationMatrix t; CATransform3D toT3D; copyTransform(toT3D, t); [primaryLayer() setTransform:toT3D]; bool isKeyframe = valueList.size() > 2; // Iterate through the transform functions, sending an animation for each one. for (int functionIndex = 0; ; ++functionIndex) { if (functionIndex >= static_cast<int>(functionList.size()) && !isMatrixAnimation) break; TransformOperation::OperationType opType = #if ENABLE(3D_TRANSFORMS) isMatrixAnimation ? TransformOperation::MATRIX_3D : functionList[functionIndex];#else isMatrixAnimation ? TransformOperation::MATRIX : functionList[functionIndex];#endif if (isKeyframe) { NSMutableArray* timesArray = [[NSMutableArray alloc] init]; NSMutableArray* valArray = [[NSMutableArray alloc] init]; NSMutableArray* tfArray = [[NSMutableArray alloc] init]; // Iterate through the keyframes, building arrays for the animation. for (Vector<TransformValue>::const_iterator it = valueList.values().begin(); it != valueList.values().end(); ++it) { const TransformValue& curValue = (*it); // fill in the key time and timing function [timesArray addObject:[NSNumber numberWithFloat:curValue.key()]]; const TimingFunction* tf = 0; if (curValue.timingFunction()) tf = curValue.timingFunction(); else if (anim->isTimingFunctionSet()) tf = &anim->timingFunction(); CAMediaTimingFunction* timingFunction = getCAMediaTimingFunction(tf ? *tf : TimingFunction(LinearTimingFunction)); [tfArray addObject:timingFunction]; // fill in the function if (isMatrixAnimation) { TransformationMatrix t; curValue.value()->apply(size, t); CATransform3D cat; copyTransform(cat, t); [valArray addObject:[NSValue valueWithCATransform3D:cat]]; } else [valArray addObject:getTransformFunctionValue(curValue, functionIndex, size, opType)]; } // We toss the last tfArray value because it has to one shorter than the others. [tfArray removeLastObject]; setKeyframeAnimation(AnimatedPropertyWebkitTransform, opType, functionIndex, timesArray, valArray, tfArray, isTransition, anim, beginTime); [timesArray release]; [valArray release]; [tfArray release]; } else { // Is a transition id fromValue, toValue; if (isMatrixAnimation) { TransformationMatrix fromt, tot; valueList.at(0).value()->apply(size, fromt); valueList.at(1).value()->apply(size, tot); CATransform3D cat; copyTransform(cat, fromt); fromValue = [NSValue valueWithCATransform3D:cat]; copyTransform(cat, tot); toValue = [NSValue valueWithCATransform3D:cat]; } else { fromValue = getTransformFunctionValue(valueList.at(0), functionIndex, size, opType); toValue = getTransformFunctionValue(valueList.at(1), functionIndex, size, opType); } setBasicAnimation(AnimatedPropertyWebkitTransform, opType, functionIndex, fromValue, toValue, isTransition, anim, beginTime); } if (isMatrixAnimation) break; } END_BLOCK_OBJC_EXCEPTIONS return true;}bool GraphicsLayerCA::animateFloat(AnimatedPropertyID property, const FloatValueList& valueList, const Animation* animation, double beginTime){ if (forceSoftwareAnimation() || valueList.size() < 2) return false; // if there is already is an animation for this property and it hasn't changed, ignore it. int i = findAnimationEntry(property, 0); if (i >= 0 && *m_animations[i].animation() == *animation) { m_animations[i].setIsCurrent(); return false; } if (valueList.size() == 2) { float fromVal = valueList.at(0).value(); float toVal = valueList.at(1).value(); if (isnan(toVal) && isnan(fromVal)) return false; // initialize the property to 0 [animatedLayer(property) setValue:0 forKeyPath:propertyIdToString(property)]; setBasicAnimation(property, TransformOperation::NONE, 0, isnan(fromVal) ? nil : [NSNumber numberWithFloat:fromVal], isnan(toVal) ? nil : [NSNumber numberWithFloat:toVal], false, animation, beginTime); return true; } BEGIN_BLOCK_OBJC_EXCEPTIONS NSMutableArray* timesArray = [[NSMutableArray alloc] init]; NSMutableArray* valArray = [[NSMutableArray alloc] init]; NSMutableArray* tfArray = [[NSMutableArray alloc] init]; for (unsigned i = 0; i < valueList.values().size(); ++i) { const FloatValue& curValue = valueList.values()[i]; [timesArray addObject:[NSNumber numberWithFloat:curValue.key()]]; [valArray addObject:[NSNumber numberWithFloat:curValue.value()]]; const TimingFunction* tf = 0; if (curValue.timingFunction()) tf = curValue.timingFunction(); else if (animation->isTimingFunctionSet()) tf = &animation->timingFunction(); CAMediaTimingFunction* timingFunction = getCAMediaTimingFunction(tf ? *tf : TimingFunction()); [tfArray addObject:timingFunction]; } // We toss the last tfArray value because it has to one shorter than the others. [tfArray removeLastObject]; // Initialize the property to 0. [animatedLayer(property) setValue:0 forKeyPath:propertyIdToString(property)]; // Then set the animation. setKeyframeAnimation(property, TransformOperation::NONE, 0, timesArray, valArray, tfArray, false, animation, beginTime); [timesArray release]; [valArray release]; [tfArray release]; END_BLOCK_OBJC_EXCEPTIONS return true;}void GraphicsLayerCA::setContentsToImage(Image* image){ if (image) { setHasContentsLayer(true); // FIXME: is image flipping really a property of the graphics context? bool needToFlip = GraphicsLayer::graphicsContextsFlipped(); CGPoint anchorPoint = needToFlip ? CGPointMake(0.0f, 1.0f) : CGPointZero; BEGIN_BLOCK_OBJC_EXCEPTIONS { CGImageRef theImage = image->nativeImageForCurrentFrame(); // FIXME: maybe only do trilinear if the image is being scaled down, // but then what if the layer size changes?#if HAVE_MODERN_QUARTZCORE [m_contentsLayer.get() setMinificationFilter:kCAFilterTrilinear];#endif if (needToFlip) { CATransform3D flipper = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; [m_contentsLayer.get() setTransform:flipper]; } [m_contentsLayer.get() setAnchorPoint:anchorPoint]; [m_contentsLayer.get() setContents:(id)theImage]; } END_BLOCK_OBJC_EXCEPTIONS } else setHasContentsLayer(false); m_contentLayerForImageOrVideo = (image != 0);}void GraphicsLayerCA::setContentsToVideo(PlatformLayer* videoLayer){ setContentsLayer(videoLayer); m_contentLayerForImageOrVideo = (videoLayer != 0);}void GraphicsLayerCA::clearContents(){ if (m_contentLayerForImageOrVideo) { setHasContentsLayer(false); m_contentLayerForImageOrVideo = false; }}void GraphicsLayerCA::updateContentsRect(){ if (m_client && m_contentsLayer) { IntRect contentRect = m_client->contentsBox(this); CGPoint point = CGPointMake(contentRect.x(), contentRect.y()); CGRect rect = CGRectMake(0.0f, 0.0f, contentRect.width(), contentRect.height()); BEGIN_BLOCK_OBJC_EXCEPTIONS [m_contentsLayer.get() setPosition:point]; [m_contentsLayer.get() setBounds:rect]; END_BLOCK_OBJC_EXCEPTIONS }}void GraphicsLayerCA::setBasicAnimation(AnimatedPropertyID property, TransformOperation::OperationType operationType, short index, void* fromVal, void* toVal, bool isTransition, const Animation* transition, double beginTime){ ASSERT(fromVal || toVal); WebLayer* layer = animatedLayer(property);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -