summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/mac
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/mac')
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.cpp13
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.h3
-rw-r--r--WebCore/platform/graphics/mac/FontComplexTextMac.cpp47
-rw-r--r--WebCore/platform/graphics/mac/FontMac.mm46
-rw-r--r--WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp18
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContextMac.mm4
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerMac.h388
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerMac.mm2514
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm4
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm95
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.h9
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.mm49
-rw-r--r--WebCore/platform/graphics/mac/WebTiledLayer.h1
-rw-r--r--WebCore/platform/graphics/mac/WebTiledLayer.mm44
14 files changed, 187 insertions, 3048 deletions
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp
index e6a7bef..206fd5f 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -56,10 +56,11 @@ static inline CGFloat ceilCGFloat(CGFloat f)
return static_cast<CGFloat>(ceil(f));
}
-ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts)
+ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts, bool forTextEmphasis)
: m_font(*font)
, m_run(run)
, m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection)
+ , m_forTextEmphasis(forTextEmphasis)
, m_currentCharacter(0)
, m_end(run.length())
, m_totalWidth(0)
@@ -240,7 +241,7 @@ void ComplexTextController::collectComplexTextRuns()
nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[-1], curr[0]), false);
}
} else
- nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps);
+ nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps ? SmallCapsVariant : AutoVariant);
if (!isSurrogate && m_font.isSmallCaps()) {
nextIsSmallCaps = forceSmallCaps || (newC = u_toupper(c)) != c;
@@ -462,7 +463,7 @@ void ComplexTextController::adjustGlyphsAndAdvances()
if (ch == '\t' && m_run.allowTabs()) {
float tabWidth = m_font.tabWidth(*fontData);
advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastRounding, tabWidth);
- } else if (ch == zeroWidthSpace || Font::treatAsZeroWidthSpace(ch) && !treatAsSpace) {
+ } else if (ch == zeroWidthSpace || (Font::treatAsZeroWidthSpace(ch) && !treatAsSpace)) {
advance.width = 0;
glyph = fontData->spaceGlyph();
}
@@ -518,7 +519,7 @@ void ComplexTextController::adjustGlyphsAndAdvances()
// Check to see if the next character is a "rounding hack character", if so, adjust the
// width so that the total run width will be on an integer boundary.
- if (m_run.applyWordRounding() && !lastGlyph && Font::isRoundingHackCharacter(nextCh) || m_run.applyRunRounding() && lastGlyph) {
+ if ((m_run.applyWordRounding() && !lastGlyph && Font::isRoundingHackCharacter(nextCh)) || (m_run.applyRunRounding() && lastGlyph)) {
CGFloat totalWidth = widthSinceLastRounding + advance.width;
widthSinceLastRounding = ceilCGFloat(totalWidth);
CGFloat extraWidth = widthSinceLastRounding - totalWidth;
@@ -536,6 +537,10 @@ void ComplexTextController::adjustGlyphsAndAdvances()
} else
widthSinceLastRounding += advance.width;
+ // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space.
+ if (m_forTextEmphasis && (!Font::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK)))
+ glyph = 0;
+
advance.height *= -1;
m_adjustedAdvances.append(advance);
m_adjustedGlyphs.append(glyph);
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.h b/WebCore/platform/graphics/mac/ComplexTextController.h
index 85407c7..9cf80a6 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -47,7 +47,7 @@ class TextRun;
// OS Versions >= 10.6, ATSUI is used otherwise.
class ComplexTextController {
public:
- ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0);
+ ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool forTextEmphasis = false);
// Advance and emit glyphs up to the specified character.
void advance(unsigned to, GlyphBuffer* = 0);
@@ -156,6 +156,7 @@ private:
const Font& m_font;
const TextRun& m_run;
bool m_mayUseNaturalWritingDirection;
+ bool m_forTextEmphasis;
Vector<UChar, 256> m_smallCapsBuffer;
diff --git a/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
index 05eae03..ca006d9 100644
--- a/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
+++ b/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
@@ -55,34 +55,55 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint
return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
}
-void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
- int from, int to) const
+float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
{
- // This glyph buffer holds our glyphs + advances + font data for each glyph.
- GlyphBuffer glyphBuffer;
+ float initialAdvance;
- float startX = point.x();
- ComplexTextController controller(this, run);
+ ComplexTextController controller(this, run, false, 0, forTextEmphasis);
controller.advance(from);
float beforeWidth = controller.runWidthSoFar();
controller.advance(to, &glyphBuffer);
-
- // We couldn't generate any glyphs for the run. Give up.
+
if (glyphBuffer.isEmpty())
- return;
-
+ return 0;
+
float afterWidth = controller.runWidthSoFar();
if (run.rtl()) {
- startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
+ initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
glyphBuffer.swap(i, end);
} else
- startX += beforeWidth;
+ initialAdvance = beforeWidth;
+
+ return initialAdvance;
+}
+
+void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+{
+ // This glyph buffer holds our glyphs + advances + font data for each glyph.
+ GlyphBuffer glyphBuffer;
+
+ float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
+
+ // We couldn't generate any glyphs for the run. Give up.
+ if (glyphBuffer.isEmpty())
+ return;
// Draw the glyph buffer now at the starting point returned in startX.
FloatPoint startPoint(startX, point.y());
- drawGlyphBuffer(context, glyphBuffer, run, startPoint);
+ drawGlyphBuffer(context, glyphBuffer, startPoint);
+}
+
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+{
+ GlyphBuffer glyphBuffer;
+ float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
+
+ if (glyphBuffer.isEmpty())
+ return;
+
+ drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
}
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm
index 8dc741b..8519667 100644
--- a/WebCore/platform/graphics/mac/FontMac.mm
+++ b/WebCore/platform/graphics/mac/FontMac.mm
@@ -91,22 +91,27 @@ static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef cont
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = context->platformContext();
- bool newShouldUseFontSmoothing = shouldUseSmoothing();
+ bool shouldSmoothFonts = true;
+ bool changeFontSmoothing = false;
+
switch(fontDescription().fontSmoothing()) {
case Antialiased: {
context->setShouldAntialias(true);
- newShouldUseFontSmoothing = false;
+ shouldSmoothFonts = false;
+ changeFontSmoothing = true;
break;
}
case SubpixelAntialiased: {
context->setShouldAntialias(true);
- newShouldUseFontSmoothing = true;
+ shouldSmoothFonts = true;
+ changeFontSmoothing = true;
break;
}
case NoSmoothing: {
context->setShouldAntialias(false);
- newShouldUseFontSmoothing = false;
+ shouldSmoothFonts = false;
+ changeFontSmoothing = true;
break;
}
case AutoSmoothing: {
@@ -116,11 +121,18 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
default:
ASSERT_NOT_REACHED();
}
-
- bool originalShouldUseFontSmoothing = wkCGContextGetShouldSmoothFonts(cgContext);
- if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing)
- CGContextSetShouldSmoothFonts(cgContext, newShouldUseFontSmoothing);
+ if (!shouldUseSmoothing()) {
+ shouldSmoothFonts = false;
+ changeFontSmoothing = true;
+ }
+
+ bool originalShouldUseFontSmoothing = false;
+ if (changeFontSmoothing) {
+ originalShouldUseFontSmoothing = wkCGContextGetShouldSmoothFonts(cgContext);
+ CGContextSetShouldSmoothFonts(cgContext, shouldSmoothFonts);
+ }
+
const FontPlatformData& platformData = font->platformData();
NSFont* drawFont;
if (!isPrinterFont()) {
@@ -157,20 +169,24 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
+ ColorSpace shadowColorSpace;
ColorSpace fillColorSpace = context->fillColorSpace();
- context->getShadow(shadowOffset, shadowBlur, shadowColor);
+ context->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
- bool hasSimpleShadow = context->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur && !platformData.isColorBitmapFont();
+ bool hasSimpleShadow = context->textDrawingMode() == TextModeFill && shadowColor.isValid() && !shadowBlur && !platformData.isColorBitmapFont() && (!context->shadowsIgnoreTransforms() || context->getCTM().isIdentityOrTranslationOrFlipped());
if (hasSimpleShadow) {
// Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
context->clearShadow();
Color fillColor = context->fillColor();
Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
- context->setFillColor(shadowFillColor, fillColorSpace);
- CGContextSetTextPosition(cgContext, point.x() + shadowOffset.width(), point.y() + shadowOffset.height());
+ context->setFillColor(shadowFillColor, shadowColorSpace);
+ float shadowTextX = point.x() + shadowOffset.width();
+ // If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
+ float shadowTextY = point.y() + shadowOffset.height() * (context->shadowsIgnoreTransforms() ? -1 : 1);
+ CGContextSetTextPosition(cgContext, shadowTextX, shadowTextY);
showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->syntheticBoldOffset()) {
- CGContextSetTextPosition(cgContext, point.x() + shadowOffset.width() + font->syntheticBoldOffset(), point.y() + shadowOffset.height());
+ CGContextSetTextPosition(cgContext, shadowTextX + font->syntheticBoldOffset(), shadowTextY);
showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
context->setFillColor(fillColor, fillColorSpace);
@@ -184,9 +200,9 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
}
if (hasSimpleShadow)
- context->setShadow(shadowOffset, shadowBlur, shadowColor, fillColorSpace);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
- if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing)
+ if (changeFontSmoothing)
CGContextSetShouldSmoothFonts(cgContext, originalShouldUseFontSmoothing);
}
diff --git a/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
index 9524cd2..5388c24 100644
--- a/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
+++ b/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
@@ -28,6 +28,7 @@
#include "config.h"
#include "GlyphPageTreeNode.h"
+#include "Font.h"
#include "SimpleFontData.h"
#include "WebCoreSystemInterface.h"
@@ -35,12 +36,27 @@
namespace WebCore {
+#ifndef BUILDING_ON_TIGER
+static bool shouldUseCoreText(UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
+{
+ if (fontData->orientation() == Vertical && !fontData->isBrokenIdeographFont()) {
+ // Ideographs don't have a vertical variant.
+ for (unsigned i = 0; i < bufferLength; ++i) {
+ if (!Font::isCJKIdeograph(buffer[i]))
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
+
bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
{
bool haveGlyphs = false;
#ifndef BUILDING_ON_TIGER
- if (fontData->orientation() == Horizontal || fontData->isBrokenIdeographFont()) {
+ if (!shouldUseCoreText(buffer, bufferLength, fontData)) {
Vector<CGGlyph, 512> glyphs(bufferLength);
wkGetGlyphsForCharacters(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength);
for (unsigned i = 0; i < length; ++i) {
diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
index c149d70..6a4fa03 100644
--- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
@@ -87,8 +87,8 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
drawFocusRingToContext(platformContext(), focusRingPath.get(), colorRef, radius);
}
-#ifdef BUILDING_ON_TIGER // Post-Tiger's setCompositeOperation() is defined in GraphicsContextCG.cpp.
-void GraphicsContext::setCompositeOperation(CompositeOperator op)
+#ifdef BUILDING_ON_TIGER // Post-Tiger's setPlatformCompositeOperation() is defined in GraphicsContextCG.cpp.
+void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
{
if (paintingDisabled())
return;
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerMac.h b/WebCore/platform/graphics/mac/GraphicsLayerMac.h
deleted file mode 100644
index 5d4dfe2..0000000
--- a/WebCore/platform/graphics/mac/GraphicsLayerMac.h
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GraphicsLayerMac_h
-#define GraphicsLayerMac_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "GraphicsLayer.h"
-#include "WebLayer.h"
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/RetainPtr.h>
-#include <wtf/text/StringHash.h>
-
-@class CABasicAnimation;
-@class CAKeyframeAnimation;
-@class CAMediaTimingFunction;
-@class CAPropertyAnimation;
-@class WebAnimationDelegate;
-
-namespace WebCore {
-
-class GraphicsLayerMac : public GraphicsLayer {
-public:
-
- GraphicsLayerMac(GraphicsLayerClient*);
- virtual ~GraphicsLayerMac();
-
- virtual void setName(const String&);
-
- // for hosting this GraphicsLayer in a native layer hierarchy
- virtual NativeLayer nativeLayer() const;
-
- virtual bool setChildren(const Vector<GraphicsLayer*>&);
- virtual void addChild(GraphicsLayer*);
- virtual void addChildAtIndex(GraphicsLayer*, int index);
- virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling);
- virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling);
- virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
-
- virtual void removeFromParent();
-
- virtual void setMaskLayer(GraphicsLayer*);
- virtual void setReplicatedLayer(GraphicsLayer*);
-
- virtual void setPosition(const FloatPoint&);
- virtual void setAnchorPoint(const FloatPoint3D&);
- virtual void setSize(const FloatSize&);
-
- virtual void setTransform(const TransformationMatrix&);
-
- virtual void setChildrenTransform(const TransformationMatrix&);
-
- virtual void setPreserves3D(bool);
- virtual void setMasksToBounds(bool);
- virtual void setDrawsContent(bool);
-
- virtual void setBackgroundColor(const Color&);
- virtual void clearBackgroundColor();
-
- virtual void setContentsOpaque(bool);
- virtual void setBackfaceVisibility(bool);
-
- // return true if we started an animation
- virtual void setOpacity(float);
-
- virtual void setNeedsDisplay();
- virtual void setNeedsDisplayInRect(const FloatRect&);
- virtual void setContentsNeedsDisplay();
-
- virtual void setContentsRect(const IntRect&);
-
- virtual void suspendAnimations(double time);
- virtual void resumeAnimations();
-
- virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& animationName, double timeOffset);
- virtual void pauseAnimation(const String& animationName, double timeOffset);
- virtual void removeAnimation(const String& animationName);
-
- virtual void setContentsToImage(Image*);
- virtual void setContentsToMedia(PlatformLayer*);
- virtual void setContentsToCanvas(PlatformLayer*);
-
- virtual bool hasContentsLayer() const { return m_contentsLayer; }
-
- virtual PlatformLayer* platformLayer() const;
-
- virtual void setDebugBackgroundColor(const Color&);
- virtual void setDebugBorder(const Color&, float borderWidth);
-
- virtual void didDisplay(PlatformLayer*);
-
- void recursiveCommitChanges();
-
- virtual void syncCompositingState();
- virtual void syncCompositingStateForThisLayerOnly();
-
- // Should only be called by animationDidStart: callback
- void animationDidStart(CAAnimation*);
-
-protected:
- virtual void setOpacityInternal(float);
-
-private:
- void updateOpacityOnLayer();
-
- CALayer* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); }
- CALayer* hostLayerForSublayers() const;
- CALayer* layerForSuperlayer() const;
- CALayer* animatedLayer(AnimatedPropertyID) const;
-
- typedef String CloneID; // Identifier for a given clone, based on original/replica branching down the tree.
- static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; }
-
- typedef HashMap<CloneID, RetainPtr<CALayer> > LayerMap;
- LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); }
- LayerMap* animatedLayerClones(AnimatedPropertyID) const;
-
- bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
- bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize);
-
- // Return autoreleased animation (use RetainPtr?)
- CABasicAnimation* createBasicAnimation(const Animation*, AnimatedPropertyID, bool additive);
- CAKeyframeAnimation* createKeyframeAnimation(const Animation*, AnimatedPropertyID, bool additive);
- void setupAnimation(CAPropertyAnimation*, const Animation*, bool additive);
-
- CAMediaTimingFunction* timingFunctionForAnimationValue(const AnimationValue*, const Animation*);
-
- bool setAnimationEndpoints(const KeyframeValueList&, const Animation*, CABasicAnimation*);
- bool setAnimationKeyframes(const KeyframeValueList&, const Animation*, CAKeyframeAnimation*);
-
- bool setTransformAnimationEndpoints(const KeyframeValueList&, const Animation*, CABasicAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
- bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, CAKeyframeAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
-
- bool animationIsRunning(const String& animationName) const
- {
- return m_runningAnimations.find(animationName) != m_runningAnimations.end();
- }
-
- void commitLayerChangesBeforeSublayers();
- void commitLayerChangesAfterSublayers();
-
- FloatSize constrainedSize() const;
-
- bool requiresTiledLayer(const FloatSize&) const;
- void swapFromOrToTiledLayer(bool useTiledLayer);
-
- CompositingCoordinatesOrientation defaultContentsOrientation() const;
- void updateContentsTransform();
-
- void setupContentsLayer(CALayer*);
- CALayer* contentsLayer() const { return m_contentsLayer.get(); }
-
- virtual void setReplicatedByLayer(GraphicsLayer*);
-
- // Used to track the path down the tree for replica layers.
- struct ReplicaState {
- static const size_t maxReplicaDepth = 16;
- enum ReplicaBranchType { ChildBranch = 0, ReplicaBranch = 1 };
- ReplicaState(ReplicaBranchType firstBranch)
- : m_replicaDepth(0)
- {
- push(firstBranch);
- }
-
- // Called as we walk down the tree to build replicas.
- void push(ReplicaBranchType branchType)
- {
- m_replicaBranches.append(branchType);
- if (branchType == ReplicaBranch)
- ++m_replicaDepth;
- }
-
- void setBranchType(ReplicaBranchType branchType)
- {
- ASSERT(!m_replicaBranches.isEmpty());
-
- if (m_replicaBranches.last() != branchType) {
- if (branchType == ReplicaBranch)
- ++m_replicaDepth;
- else
- --m_replicaDepth;
- }
-
- m_replicaBranches.last() = branchType;
- }
-
- void pop()
- {
- if (m_replicaBranches.last() == ReplicaBranch)
- --m_replicaDepth;
- m_replicaBranches.removeLast();
- }
-
- size_t depth() const { return m_replicaBranches.size(); }
- size_t replicaDepth() const { return m_replicaDepth; }
-
- CloneID cloneID() const;
-
- private:
- Vector<ReplicaBranchType> m_replicaBranches;
- size_t m_replicaDepth;
- };
- CALayer *replicatedLayerRoot(ReplicaState&);
-
- enum CloneLevel { RootCloneLevel, IntermediateCloneLevel };
- CALayer *fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState&, CloneLevel);
-
- CALayer *cloneLayer(CALayer *, CloneLevel);
- CALayer *findOrMakeClone(CloneID, CALayer *, LayerMap*, CloneLevel);
-
- void ensureCloneLayers(CloneID index, CALayer *& primaryLayer, CALayer *& structuralLayer, CALayer *& contentsLayer, CloneLevel);
-
- bool hasCloneLayers() const { return m_layerClones; }
- void removeCloneLayers();
- FloatPoint positionForCloneRootLayer() const;
-
- void propagateLayerChangeToReplicas();
-
- // All these "update" methods will be called inside a BEGIN_BLOCK_OBJC_EXCEPTIONS/END_BLOCK_OBJC_EXCEPTIONS block.
- void updateLayerNames();
- void updateSublayerList();
- void updateLayerPosition();
- void updateLayerSize();
- void updateAnchorPoint();
- void updateTransform();
- void updateChildrenTransform();
- void updateMasksToBounds();
- void updateContentsOpaque();
- void updateBackfaceVisibility();
- void updateStructuralLayer();
- void updateLayerDrawsContent();
- void updateLayerBackgroundColor();
-
- void updateContentsImage();
- void updateContentsMediaLayer();
- void updateContentsCanvasLayer();
- void updateContentsRect();
- void updateMaskLayer();
- void updateReplicatedLayers();
-
- void updateLayerAnimations();
- void updateContentsNeedsDisplay();
-
- enum StructuralLayerPurpose {
- NoStructuralLayer = 0,
- StructuralLayerForPreserves3D,
- StructuralLayerForReplicaFlattening
- };
- void ensureStructuralLayer(StructuralLayerPurpose);
- StructuralLayerPurpose structuralLayerPurpose() const;
-
- void setCAAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, const String& animationName, int index, double timeOffset);
- bool removeCAAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index);
- void pauseCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, double timeOffset);
-
- enum MoveOrCopy { Move, Copy };
- static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, CALayer *fromLayer, CALayer *toLayer);
- void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID, CALayer * fromLayer, CALayer * toLayer);
-
- enum LayerChange {
- NoChange = 0,
- NameChanged = 1 << 1,
- ChildrenChanged = 1 << 2, // also used for content layer, and preserves-3d, and size if tiling changes?
- PositionChanged = 1 << 3,
- AnchorPointChanged = 1 << 4,
- SizeChanged = 1 << 5,
- TransformChanged = 1 << 6,
- ChildrenTransformChanged = 1 << 7,
- Preserves3DChanged = 1 << 8,
- MasksToBoundsChanged = 1 << 9,
- DrawsContentChanged = 1 << 10, // need this?
- BackgroundColorChanged = 1 << 11,
- ContentsOpaqueChanged = 1 << 12,
- BackfaceVisibilityChanged = 1 << 13,
- OpacityChanged = 1 << 14,
- AnimationChanged = 1 << 15,
- DirtyRectsChanged = 1 << 16,
- ContentsImageChanged = 1 << 17,
- ContentsMediaLayerChanged = 1 << 18,
- ContentsCanvasLayerChanged = 1 << 19,
- ContentsRectChanged = 1 << 20,
- MaskLayerChanged = 1 << 21,
- ReplicatedLayerChanged = 1 << 22,
- ContentsNeedsDisplay = 1 << 23
- };
- typedef unsigned LayerChangeFlags;
- void noteLayerPropertyChanged(LayerChangeFlags flags);
- void noteSublayersChanged();
-
- void repaintLayerDirtyRects();
-
- RetainPtr<WebLayer> m_layer; // The main layer
- RetainPtr<CALayer> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer.
- RetainPtr<CALayer> m_contentsLayer; // A layer used for inner content, like image and video
-
- // References to clones of our layers, for replicated layers.
- OwnPtr<LayerMap> m_layerClones;
- OwnPtr<LayerMap> m_structuralLayerClones;
- OwnPtr<LayerMap> m_contentsLayerClones;
-
- enum ContentsLayerPurpose {
- NoContentsLayer = 0,
- ContentsLayerForImage,
- ContentsLayerForMedia,
- ContentsLayerForCanvas
- };
-
- ContentsLayerPurpose m_contentsLayerPurpose;
- bool m_contentsLayerHasBackgroundColor : 1;
-
- RetainPtr<WebAnimationDelegate> m_animationDelegate;
-
- RetainPtr<CGImageRef> m_uncorrectedContentsImage;
- RetainPtr<CGImageRef> m_pendingContentsImage;
-
- // This represents the animation of a single property. There may be multiple transform animations for
- // a single transition or keyframe animation, so index is used to distinguish these.
- struct LayerPropertyAnimation {
- LayerPropertyAnimation(CAPropertyAnimation* caAnimation, const String& animationName, AnimatedPropertyID property, int index, double timeOffset)
- : m_animation(caAnimation)
- , m_name(animationName)
- , m_property(property)
- , m_index(index)
- , m_timeOffset(timeOffset)
- { }
-
- RetainPtr<CAPropertyAnimation*> m_animation;
- String m_name;
- AnimatedPropertyID m_property;
- int m_index;
- double m_timeOffset;
- };
-
- // Uncommitted transitions and animations.
- Vector<LayerPropertyAnimation> m_uncomittedAnimations;
-
- enum Action { Remove, Pause };
- struct AnimationProcessingAction {
- AnimationProcessingAction(Action action = Remove, double timeOffset = 0)
- : action(action)
- , timeOffset(timeOffset)
- {
- }
- Action action;
- double timeOffset; // only used for pause
- };
- typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
- AnimationsToProcessMap m_animationsToProcess;
-
- // Map of animation names to their associated lists of property animations, so we can remove/pause them.
- typedef HashMap<String, Vector<LayerPropertyAnimation> > AnimationsMap;
- AnimationsMap m_runningAnimations;
-
- Vector<FloatRect> m_dirtyRects;
-
- LayerChangeFlags m_uncommittedChanges;
-};
-
-} // namespace WebCore
-
-
-#endif // USE(ACCELERATED_COMPOSITING)
-
-#endif // GraphicsLayerMac_h
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerMac.mm b/WebCore/platform/graphics/mac/GraphicsLayerMac.mm
deleted file mode 100644
index f9b16a0..0000000
--- a/WebCore/platform/graphics/mac/GraphicsLayerMac.mm
+++ /dev/null
@@ -1,2514 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#import "GraphicsLayerMac.h"
-
-#import "Animation.h"
-#import "BlockExceptions.h"
-#import "FloatConversion.h"
-#import "FloatRect.h"
-#import "Image.h"
-#import "PlatformString.h"
-#import <QuartzCore/QuartzCore.h>
-#import "RotateTransformOperation.h"
-#import "ScaleTransformOperation.h"
-#import "SystemTime.h"
-#import "TranslateTransformOperation.h"
-#import "WebLayer.h"
-#import "WebTiledLayer.h"
-#import <limits.h>
-#import <objc/objc-auto.h>
-#import <wtf/CurrentTime.h>
-#import <wtf/UnusedParam.h>
-#import <wtf/RetainPtr.h>
-#import <wtf/text/StringConcatenate.h>
-
-using namespace std;
-
-#define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD))
-
-namespace WebCore {
-
-static NSString * const WebKitAnimationBeginTimeSetKey = @"WebKitAnimationBeginTimeSet";
-
-// The threshold width or height above which a tiled layer will be used. This should be
-// large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL
-// texture size limit on all supported hardware.
-static const int cMaxPixelDimension = 2000;
-
-// The width and height of a single tile in a tiled layer. Should be large enough to
-// avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough
-// to keep the overall tile cost low.
-static const int cTiledLayerTileSize = 512;
-
-// If we send a duration of 0 to CA, then it will use the default duration
-// of 250ms. So send a very small value instead.
-static const float cAnimationAlmostZeroDuration = 1e-3f;
-
-// CACurrentMediaTime() is a time since boot. These methods convert between that and
-// WebCore time, which is system time (UTC).
-static CFTimeInterval currentTimeToMediaTime(double t)
-{
- return CACurrentMediaTime() + t - WTF::currentTime();
-}
-
-static double mediaTimeToCurrentTime(CFTimeInterval t)
-{
- return WTF::currentTime() + t - CACurrentMediaTime();
-}
-
-} // namespace WebCore
-
-@interface CALayer(Private)
-- (void)setContentsChanged;
-@end
-
-@interface WebAnimationDelegate : NSObject {
- WebCore::GraphicsLayerMac* m_graphicsLayer;
-}
-
-- (void)animationDidStart:(CAAnimation *)anim;
-- (WebCore::GraphicsLayerMac*)graphicsLayer;
-- (void)setLayer:(WebCore::GraphicsLayerMac*)graphicsLayer;
-
-@end
-
-@implementation WebAnimationDelegate
-
-- (void)animationDidStart:(CAAnimation *)animation
-{
- if (m_graphicsLayer)
- m_graphicsLayer->animationDidStart(animation);
-}
-
-- (WebCore::GraphicsLayerMac*)graphicsLayer
-{
- return m_graphicsLayer;
-}
-
-- (void)setLayer:(WebCore::GraphicsLayerMac*)graphicsLayer
-{
- m_graphicsLayer = graphicsLayer;
-}
-
-@end
-
-namespace WebCore {
-
-static inline void copyTransform(CATransform3D& toT3D, const TransformationMatrix& t)
-{
- toT3D.m11 = narrowPrecisionToFloat(t.m11());
- toT3D.m12 = narrowPrecisionToFloat(t.m12());
- toT3D.m13 = narrowPrecisionToFloat(t.m13());
- toT3D.m14 = narrowPrecisionToFloat(t.m14());
- toT3D.m21 = narrowPrecisionToFloat(t.m21());
- toT3D.m22 = narrowPrecisionToFloat(t.m22());
- toT3D.m23 = narrowPrecisionToFloat(t.m23());
- toT3D.m24 = narrowPrecisionToFloat(t.m24());
- toT3D.m31 = narrowPrecisionToFloat(t.m31());
- toT3D.m32 = narrowPrecisionToFloat(t.m32());
- toT3D.m33 = narrowPrecisionToFloat(t.m33());
- toT3D.m34 = narrowPrecisionToFloat(t.m34());
- toT3D.m41 = narrowPrecisionToFloat(t.m41());
- toT3D.m42 = narrowPrecisionToFloat(t.m42());
- toT3D.m43 = narrowPrecisionToFloat(t.m43());
- toT3D.m44 = narrowPrecisionToFloat(t.m44());
-}
-
-static NSValue* getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size)
-{
- switch (transformType) {
- case TransformOperation::ROTATE:
- case TransformOperation::ROTATE_X:
- case TransformOperation::ROTATE_Y:
- return [NSNumber numberWithDouble:transformOp ? deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle()) : 0];
- case TransformOperation::SCALE_X:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->x() : 1];
- case TransformOperation::SCALE_Y:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->y() : 1];
- case TransformOperation::SCALE_Z:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->z() : 1];
- case TransformOperation::TRANSLATE_X:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->x(size) : 0];
- case TransformOperation::TRANSLATE_Y:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->y(size) : 0];
- case TransformOperation::TRANSLATE_Z:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->z(size) : 0];
- case TransformOperation::SCALE:
- case TransformOperation::SCALE_3D:
- return [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->x() : 1],
- [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->y() : 1],
- [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->z() : 1],
- nil];
- case TransformOperation::TRANSLATE:
- case TransformOperation::TRANSLATE_3D:
- return [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->x(size) : 0],
- [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->y(size) : 0],
- [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->z(size) : 0],
- nil];
- case TransformOperation::SKEW_X:
- case TransformOperation::SKEW_Y:
- case TransformOperation::SKEW:
- case TransformOperation::MATRIX:
- case TransformOperation::ROTATE_3D:
- case TransformOperation::MATRIX_3D:
- case TransformOperation::PERSPECTIVE:
- case TransformOperation::IDENTITY:
- case TransformOperation::NONE: {
- TransformationMatrix transform;
- if (transformOp)
- transformOp->apply(transform, size);
- CATransform3D caTransform;
- copyTransform(caTransform, transform);
- return [NSValue valueWithCATransform3D:caTransform];
- }
- }
-
- return 0;
-}
-
-#if HAVE_MODERN_QUARTZCORE
-static NSString *getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
-{
- // Use literal strings to avoid link-time dependency on those symbols.
- switch (transformType) {
- case TransformOperation::ROTATE_X:
- return @"rotateX"; // kCAValueFunctionRotateX;
- case TransformOperation::ROTATE_Y:
- return @"rotateY"; // kCAValueFunctionRotateY;
- case TransformOperation::ROTATE:
- return @"rotateZ"; // kCAValueFunctionRotateZ;
- case TransformOperation::SCALE_X:
- return @"scaleX"; // kCAValueFunctionScaleX;
- case TransformOperation::SCALE_Y:
- return @"scaleY"; // kCAValueFunctionScaleY;
- case TransformOperation::SCALE_Z:
- return @"scaleZ"; // kCAValueFunctionScaleZ;
- case TransformOperation::TRANSLATE_X:
- return @"translateX"; // kCAValueFunctionTranslateX;
- case TransformOperation::TRANSLATE_Y:
- return @"translateY"; // kCAValueFunctionTranslateY;
- case TransformOperation::TRANSLATE_Z:
- return @"translateZ"; // kCAValueFunctionTranslateZ;
- case TransformOperation::SCALE:
- case TransformOperation::SCALE_3D:
- return @"scale"; // kCAValueFunctionScale;
- case TransformOperation::TRANSLATE:
- case TransformOperation::TRANSLATE_3D:
- return @"translate"; // kCAValueFunctionTranslate;
- default:
- return nil;
- }
-}
-#endif
-
-static String propertyIdToString(AnimatedPropertyID property)
-{
- switch (property) {
- case AnimatedPropertyWebkitTransform:
- return "transform";
- case AnimatedPropertyOpacity:
- return "opacity";
- case AnimatedPropertyBackgroundColor:
- return "backgroundColor";
- case AnimatedPropertyInvalid:
- ASSERT_NOT_REACHED();
- }
- ASSERT_NOT_REACHED();
- return "";
-}
-
-static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index)
-{
- return makeString(animationName, '_', String::number(property), '_', String::number(index));
-}
-
-static CAMediaTimingFunction* getCAMediaTimingFunction(const TimingFunction* timingFunction)
-{
- // By this point, timing functions can only be linear or cubic, not steps.
- ASSERT(!timingFunction->isStepsTimingFunction());
- if (timingFunction->isCubicBezierTimingFunction()) {
- const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
- return [CAMediaTimingFunction functionWithControlPoints:static_cast<float>(ctf->x1()) :static_cast<float>(ctf->y1())
- :static_cast<float>(ctf->x2()) :static_cast<float>(ctf->y2())];
- } else
- return [CAMediaTimingFunction functionWithName:@"linear"];
-}
-
-static void setLayerBorderColor(PlatformLayer* layer, const Color& color)
-{
- [layer setBorderColor:cachedCGColor(color, ColorSpaceDeviceRGB)];
-}
-
-static void clearBorderColor(PlatformLayer* layer)
-{
- [layer setBorderColor:nil];
-}
-
-static void setLayerBackgroundColor(PlatformLayer* layer, const Color& color)
-{
- [layer setBackgroundColor:cachedCGColor(color, ColorSpaceDeviceRGB)];
-}
-
-static void clearLayerBackgroundColor(PlatformLayer* layer)
-{
- [layer setBackgroundColor:0];
-}
-
-static void safeSetSublayers(CALayer* layer, NSArray* sublayers)
-{
- // Workaround for <rdar://problem/7390716>: -[CALayer setSublayers:] crashes if sublayers is an empty array, or nil, under GC.
- if (objc_collectingEnabled() && ![sublayers count]) {
- while ([[layer sublayers] count])
- [[[layer sublayers] objectAtIndex:0] removeFromSuperlayer];
- return;
- }
-
- [layer setSublayers:sublayers];
-}
-
-static bool caValueFunctionSupported()
-{
- static bool sHaveValueFunction = [CAPropertyAnimation instancesRespondToSelector:@selector(setValueFunction:)];
- return sHaveValueFunction;
-}
-
-static bool forceSoftwareAnimation()
-{
- static bool forceSoftwareAnimation = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreForceSoftwareAnimation"];
- return forceSoftwareAnimation;
-}
-
-static NSDictionary* nullActionsDictionary()
-{
- NSNull* nullValue = [NSNull null];
- NSDictionary* actions = [NSDictionary dictionaryWithObjectsAndKeys:
- nullValue, @"anchorPoint",
- nullValue, @"bounds",
- nullValue, @"contents",
- nullValue, @"contentsRect",
- nullValue, @"opacity",
- nullValue, @"position",
- nullValue, @"shadowColor",
- nullValue, @"sublayerTransform",
- nullValue, @"sublayers",
- nullValue, @"transform",
- nullValue, @"zPosition",
- nil];
- return actions;
-}
-
-static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
-{
- if (anim->timingFunction()->isStepsTimingFunction())
- return true;
-
- for (unsigned i = 0; i < valueList.size(); ++i) {
- const TimingFunction* timingFunction = valueList.at(i)->timingFunction();
- if (timingFunction && timingFunction->isStepsTimingFunction())
- return true;
- }
-
- return false;
-}
-
-PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
-{
- return new GraphicsLayerMac(client);
-}
-
-GraphicsLayerMac::GraphicsLayerMac(GraphicsLayerClient* client)
- : GraphicsLayer(client)
- , m_contentsLayerPurpose(NoContentsLayer)
- , m_contentsLayerHasBackgroundColor(false)
- , m_uncommittedChanges(NoChange)
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS
- m_layer.adoptNS([[WebLayer alloc] init]);
- [m_layer.get() setLayerOwner:this];
-
-#if !HAVE_MODERN_QUARTZCORE
- setContentsOrientation(defaultContentsOrientation());
-#endif
-
- updateDebugIndicators();
-
- m_animationDelegate.adoptNS([[WebAnimationDelegate alloc] init]);
- [m_animationDelegate.get() setLayer:this];
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-GraphicsLayerMac::~GraphicsLayerMac()
-{
- // We release our references to the CALayers here, but do not actively unparent them,
- // since that will cause a commit and break our batched commit model. The layers will
- // get released when the rootmost modified GraphicsLayerMac rebuilds its child layers.
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- // Clean up the WK layer.
- if (m_layer) {
- WebLayer* layer = m_layer.get();
- [layer setLayerOwner:nil];
- }
-
- if (m_contentsLayer) {
- if ([m_contentsLayer.get() respondsToSelector:@selector(setLayerOwner:)])
- [(id)m_contentsLayer.get() setLayerOwner:nil];
- }
-
- // animationDidStart: can fire after this, so we need to clear out the layer on the delegate.
- [m_animationDelegate.get() setLayer:0];
-
- // Release the clone layers inside the exception-handling block.
- removeCloneLayers();
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-void GraphicsLayerMac::setName(const String& name)
-{
- String longName = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + name;
- GraphicsLayer::setName(longName);
- noteLayerPropertyChanged(NameChanged);
-}
-
-NativeLayer GraphicsLayerMac::nativeLayer() const
-{
- return m_layer.get();
-}
-
-bool GraphicsLayerMac::setChildren(const Vector<GraphicsLayer*>& children)
-{
- bool childrenChanged = GraphicsLayer::setChildren(children);
- if (childrenChanged)
- noteSublayersChanged();
-
- return childrenChanged;
-}
-
-void GraphicsLayerMac::addChild(GraphicsLayer* childLayer)
-{
- GraphicsLayer::addChild(childLayer);
- noteSublayersChanged();
-}
-
-void GraphicsLayerMac::addChildAtIndex(GraphicsLayer* childLayer, int index)
-{
- GraphicsLayer::addChildAtIndex(childLayer, index);
- noteSublayersChanged();
-}
-
-void GraphicsLayerMac::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
-{
- GraphicsLayer::addChildBelow(childLayer, sibling);
- noteSublayersChanged();
-}
-
-void GraphicsLayerMac::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
-{
- GraphicsLayer::addChildAbove(childLayer, sibling);
- noteSublayersChanged();
-}
-
-bool GraphicsLayerMac::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
-{
- if (GraphicsLayer::replaceChild(oldChild, newChild)) {
- noteSublayersChanged();
- return true;
- }
- return false;
-}
-
-void GraphicsLayerMac::removeFromParent()
-{
- if (m_parent)
- static_cast<GraphicsLayerMac*>(m_parent)->noteSublayersChanged();
- GraphicsLayer::removeFromParent();
-}
-
-void GraphicsLayerMac::setMaskLayer(GraphicsLayer* layer)
-{
- if (layer == m_maskLayer)
- return;
-
- GraphicsLayer::setMaskLayer(layer);
- noteLayerPropertyChanged(MaskLayerChanged);
-
- propagateLayerChangeToReplicas();
-
- if (m_replicatedLayer)
- static_cast<GraphicsLayerMac*>(m_replicatedLayer)->propagateLayerChangeToReplicas();
-}
-
-void GraphicsLayerMac::setReplicatedLayer(GraphicsLayer* layer)
-{
- if (layer == m_replicatedLayer)
- return;
-
- GraphicsLayer::setReplicatedLayer(layer);
- noteLayerPropertyChanged(ReplicatedLayerChanged);
-}
-
-void GraphicsLayerMac::setReplicatedByLayer(GraphicsLayer* layer)
-{
- if (layer == m_replicaLayer)
- return;
-
- GraphicsLayer::setReplicatedByLayer(layer);
- noteSublayersChanged();
- noteLayerPropertyChanged(ReplicatedLayerChanged);
-}
-
-void GraphicsLayerMac::setPosition(const FloatPoint& point)
-{
- if (point == m_position)
- return;
-
- GraphicsLayer::setPosition(point);
- noteLayerPropertyChanged(PositionChanged);
-}
-
-void GraphicsLayerMac::setAnchorPoint(const FloatPoint3D& point)
-{
- if (point == m_anchorPoint)
- return;
-
- GraphicsLayer::setAnchorPoint(point);
- noteLayerPropertyChanged(AnchorPointChanged);
-}
-
-void GraphicsLayerMac::setSize(const FloatSize& size)
-{
- if (size == m_size)
- return;
-
- GraphicsLayer::setSize(size);
- noteLayerPropertyChanged(SizeChanged);
-}
-
-void GraphicsLayerMac::setTransform(const TransformationMatrix& t)
-{
- if (t == m_transform)
- return;
-
- GraphicsLayer::setTransform(t);
- noteLayerPropertyChanged(TransformChanged);
-}
-
-void GraphicsLayerMac::setChildrenTransform(const TransformationMatrix& t)
-{
- if (t == m_childrenTransform)
- return;
-
- GraphicsLayer::setChildrenTransform(t);
- noteLayerPropertyChanged(ChildrenTransformChanged);
-}
-
-void GraphicsLayerMac::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, CALayer *fromLayer, CALayer *toLayer)
-{
- NSString *animationID = animationIdentifier;
- CAAnimation *anim = [fromLayer animationForKey:animationID];
- if (!anim)
- return;
-
- switch (operation) {
- case Move:
- [anim retain];
- [fromLayer removeAnimationForKey:animationID];
- [toLayer addAnimation:anim forKey:animationID];
- [anim release];
- break;
-
- case Copy:
- [toLayer addAnimation:anim forKey:animationID];
- break;
- }
-}
-
-void GraphicsLayerMac::moveOrCopyAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, CALayer *fromLayer, CALayer *toLayer)
-{
- // Look for running animations affecting this property.
- AnimationsMap::const_iterator end = m_runningAnimations.end();
- for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
- const Vector<LayerPropertyAnimation>& propertyAnimations = it->second;
- size_t numAnimations = propertyAnimations.size();
- for (size_t i = 0; i < numAnimations; ++i) {
- const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
- if (currAnimation.m_property == property)
- moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index), fromLayer, toLayer);
- }
- }
-}
-
-void GraphicsLayerMac::setPreserves3D(bool preserves3D)
-{
- if (preserves3D == m_preserves3D)
- return;
-
- GraphicsLayer::setPreserves3D(preserves3D);
- noteLayerPropertyChanged(Preserves3DChanged);
-}
-
-void GraphicsLayerMac::setMasksToBounds(bool masksToBounds)
-{
- if (masksToBounds == m_masksToBounds)
- return;
-
- GraphicsLayer::setMasksToBounds(masksToBounds);
- noteLayerPropertyChanged(MasksToBoundsChanged);
-}
-
-void GraphicsLayerMac::setDrawsContent(bool drawsContent)
-{
- if (drawsContent == m_drawsContent)
- return;
-
- GraphicsLayer::setDrawsContent(drawsContent);
- noteLayerPropertyChanged(DrawsContentChanged);
-}
-
-void GraphicsLayerMac::setBackgroundColor(const Color& color)
-{
- if (m_backgroundColorSet && m_backgroundColor == color)
- return;
-
- GraphicsLayer::setBackgroundColor(color);
-
- m_contentsLayerHasBackgroundColor = true;
- noteLayerPropertyChanged(BackgroundColorChanged);
-}
-
-void GraphicsLayerMac::clearBackgroundColor()
-{
- if (!m_backgroundColorSet)
- return;
-
- GraphicsLayer::clearBackgroundColor();
- m_contentsLayerHasBackgroundColor = false;
- noteLayerPropertyChanged(BackgroundColorChanged);
-}
-
-void GraphicsLayerMac::setContentsOpaque(bool opaque)
-{
- if (m_contentsOpaque == opaque)
- return;
-
- GraphicsLayer::setContentsOpaque(opaque);
- noteLayerPropertyChanged(ContentsOpaqueChanged);
-}
-
-void GraphicsLayerMac::setBackfaceVisibility(bool visible)
-{
- if (m_backfaceVisibility == visible)
- return;
-
- GraphicsLayer::setBackfaceVisibility(visible);
- noteLayerPropertyChanged(BackfaceVisibilityChanged);
-}
-
-void GraphicsLayerMac::setOpacity(float opacity)
-{
- float clampedOpacity = max(0.0f, min(opacity, 1.0f));
-
- if (clampedOpacity == m_opacity)
- return;
-
- GraphicsLayer::setOpacity(clampedOpacity);
- noteLayerPropertyChanged(OpacityChanged);
-}
-
-void GraphicsLayerMac::setNeedsDisplay()
-{
- FloatRect hugeRect(-numeric_limits<float>::max() / 2, -numeric_limits<float>::max() / 2,
- numeric_limits<float>::max(), numeric_limits<float>::max());
-
- setNeedsDisplayInRect(hugeRect);
-}
-
-void GraphicsLayerMac::setNeedsDisplayInRect(const FloatRect& rect)
-{
- if (!drawsContent())
- return;
-
- const size_t maxDirtyRects = 32;
-
- for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
- if (m_dirtyRects[i].contains(rect))
- return;
- }
-
- if (m_dirtyRects.size() < maxDirtyRects)
- m_dirtyRects.append(rect);
- else
- m_dirtyRects[0].unite(rect);
-
- noteLayerPropertyChanged(DirtyRectsChanged);
-}
-
-void GraphicsLayerMac::setContentsNeedsDisplay()
-{
- noteLayerPropertyChanged(ContentsNeedsDisplay);
-}
-
-void GraphicsLayerMac::setContentsRect(const IntRect& rect)
-{
- if (rect == m_contentsRect)
- return;
-
- GraphicsLayer::setContentsRect(rect);
- noteLayerPropertyChanged(ContentsRectChanged);
-}
-
-bool GraphicsLayerMac::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
-{
- ASSERT(!animationName.isEmpty());
-
- if (forceSoftwareAnimation() || !anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
- return false;
-
-#if !HAVE_MODERN_QUARTZCORE
- // Older versions of QuartzCore do not handle opacity in transform layers properly, so we will
- // always do software animation in that case.
- if (valueList.property() == AnimatedPropertyOpacity)
- return false;
-#endif
-
- // CoreAnimation does not handle the steps() timing function. Fall back
- // to software animation in that case.
- if (animationHasStepsTimingFunction(valueList, anim))
- return false;
-
- bool createdAnimations = false;
- if (valueList.property() == AnimatedPropertyWebkitTransform)
- createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
- else
- createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
-
- if (createdAnimations)
- noteLayerPropertyChanged(AnimationChanged);
-
- return createdAnimations;
-}
-
-void GraphicsLayerMac::pauseAnimation(const String& animationName, double timeOffset)
-{
- if (!animationIsRunning(animationName))
- return;
-
- AnimationsToProcessMap::iterator it = m_animationsToProcess.find(animationName);
- if (it != m_animationsToProcess.end()) {
- AnimationProcessingAction& processingInfo = it->second;
- // If an animation is scheduled to be removed, don't change the remove to a pause.
- if (processingInfo.action != Remove)
- processingInfo.action = Pause;
- } else
- m_animationsToProcess.add(animationName, AnimationProcessingAction(Pause, timeOffset));
-
- noteLayerPropertyChanged(AnimationChanged);
-}
-
-void GraphicsLayerMac::removeAnimation(const String& animationName)
-{
- if (!animationIsRunning(animationName))
- return;
-
- m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
- noteLayerPropertyChanged(AnimationChanged);
-}
-
-void GraphicsLayerMac::animationDidStart(CAAnimation* caAnimation)
-{
- bool hadNonZeroBeginTime = [[caAnimation valueForKey:WebKitAnimationBeginTimeSetKey] boolValue];
-
- double startTime;
- if (hadNonZeroBeginTime) {
- // We don't know what time CA used to commit the animation, so just use the current time
- // (even though this will be slightly off).
- startTime = WebCore::mediaTimeToCurrentTime(CACurrentMediaTime());
- } else
- startTime = WebCore::mediaTimeToCurrentTime([caAnimation beginTime]);
-
- if (m_client)
- m_client->notifyAnimationStarted(this, startTime);
-}
-
-void GraphicsLayerMac::setContentsToImage(Image* image)
-{
- if (image) {
- CGImageRef newImage = image->nativeImageForCurrentFrame();
- if (!newImage)
- return;
-
- // Check to see if the image changed; we have to do this because the call to
- // CGImageCreateCopyWithColorSpace() below can create a new image every time.
- if (m_uncorrectedContentsImage && m_uncorrectedContentsImage.get() == newImage)
- return;
-
- m_uncorrectedContentsImage = newImage;
- m_pendingContentsImage = newImage;
- CGColorSpaceRef colorSpace = CGImageGetColorSpace(m_pendingContentsImage.get());
-
- static CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
- if (colorSpace && CFEqual(colorSpace, deviceRGB)) {
- // CoreGraphics renders images tagged with DeviceRGB using the color space of the main display. When we hand such
- // images to CA we need to tag them similarly so CA rendering matches CG rendering.
- static CGColorSpaceRef genericRGB = CGDisplayCopyColorSpace(kCGDirectMainDisplay);
- m_pendingContentsImage.adoptCF(CGImageCreateCopyWithColorSpace(m_pendingContentsImage.get(), genericRGB));
- }
- m_contentsLayerPurpose = ContentsLayerForImage;
- if (!m_contentsLayer)
- noteSublayersChanged();
- } else {
- m_uncorrectedContentsImage = 0;
- m_pendingContentsImage = 0;
- m_contentsLayerPurpose = NoContentsLayer;
- if (m_contentsLayer)
- noteSublayersChanged();
- }
-
- noteLayerPropertyChanged(ContentsImageChanged);
-}
-
-void GraphicsLayerMac::setContentsToMedia(PlatformLayer* mediaLayer)
-{
- if (mediaLayer == m_contentsLayer)
- return;
-
- m_contentsLayer = mediaLayer;
- m_contentsLayerPurpose = mediaLayer ? ContentsLayerForMedia : NoContentsLayer;
-
- noteSublayersChanged();
- noteLayerPropertyChanged(ContentsMediaLayerChanged);
-}
-
-void GraphicsLayerMac::didDisplay(PlatformLayer* layer)
-{
- CALayer* sourceLayer;
- LayerMap* layerCloneMap;
-
- if (layer == m_layer) {
- sourceLayer = m_layer.get();
- layerCloneMap = m_layerClones.get();
- } else if (layer == m_contentsLayer) {
- sourceLayer = m_contentsLayer.get();
- layerCloneMap = m_contentsLayerClones.get();
- } else
- return;
-
- if (layerCloneMap) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currClone = it->second.get();
- if (!currClone)
- continue;
-
- if ([currClone contents] != [sourceLayer contents])
- [currClone setContents:[sourceLayer contents]];
- else
- [currClone setContentsChanged];
- }
- }
-}
-
-void GraphicsLayerMac::syncCompositingState()
-{
- recursiveCommitChanges();
-}
-
-void GraphicsLayerMac::syncCompositingStateForThisLayerOnly()
-{
- commitLayerChangesBeforeSublayers();
- commitLayerChangesAfterSublayers();
-}
-
-void GraphicsLayerMac::recursiveCommitChanges()
-{
- commitLayerChangesBeforeSublayers();
-
- if (m_maskLayer)
- static_cast<GraphicsLayerMac*>(m_maskLayer)->commitLayerChangesBeforeSublayers();
-
- const Vector<GraphicsLayer*>& childLayers = children();
- size_t numChildren = childLayers.size();
- for (size_t i = 0; i < numChildren; ++i) {
- GraphicsLayerMac* curChild = static_cast<GraphicsLayerMac*>(childLayers[i]);
- curChild->recursiveCommitChanges();
- }
-
- if (m_replicaLayer)
- static_cast<GraphicsLayerMac*>(m_replicaLayer)->recursiveCommitChanges();
-
- if (m_maskLayer)
- static_cast<GraphicsLayerMac*>(m_maskLayer)->commitLayerChangesAfterSublayers();
-
- commitLayerChangesAfterSublayers();
-}
-
-void GraphicsLayerMac::commitLayerChangesBeforeSublayers()
-{
- if (!m_uncommittedChanges)
- return;
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
- if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
- updateStructuralLayer();
-
- if (m_uncommittedChanges & NameChanged)
- updateLayerNames();
-
- if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
- updateContentsImage();
-
- if (m_uncommittedChanges & ContentsMediaLayerChanged) // Needs to happen before ChildrenChanged
- updateContentsMediaLayer();
-
- if (m_uncommittedChanges & ContentsCanvasLayerChanged) // Needs to happen before ChildrenChanged
- updateContentsCanvasLayer();
-
- if (m_uncommittedChanges & BackgroundColorChanged) // Needs to happen before ChildrenChanged, and after updating image or video
- updateLayerBackgroundColor();
-
- if (m_uncommittedChanges & ChildrenChanged)
- updateSublayerList();
-
- if (m_uncommittedChanges & PositionChanged)
- updateLayerPosition();
-
- if (m_uncommittedChanges & AnchorPointChanged)
- updateAnchorPoint();
-
- if (m_uncommittedChanges & SizeChanged)
- updateLayerSize();
-
- if (m_uncommittedChanges & TransformChanged)
- updateTransform();
-
- if (m_uncommittedChanges & ChildrenTransformChanged)
- updateChildrenTransform();
-
- if (m_uncommittedChanges & MasksToBoundsChanged)
- updateMasksToBounds();
-
- if (m_uncommittedChanges & DrawsContentChanged)
- updateLayerDrawsContent();
-
- if (m_uncommittedChanges & ContentsOpaqueChanged)
- updateContentsOpaque();
-
- if (m_uncommittedChanges & BackfaceVisibilityChanged)
- updateBackfaceVisibility();
-
- if (m_uncommittedChanges & OpacityChanged)
- updateOpacityOnLayer();
-
- if (m_uncommittedChanges & AnimationChanged)
- updateLayerAnimations();
-
- if (m_uncommittedChanges & DirtyRectsChanged)
- repaintLayerDirtyRects();
-
- if (m_uncommittedChanges & ContentsRectChanged)
- updateContentsRect();
-
- if (m_uncommittedChanges & MaskLayerChanged)
- updateMaskLayer();
-
- if (m_uncommittedChanges & ContentsNeedsDisplay)
- updateContentsNeedsDisplay();
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-void GraphicsLayerMac::commitLayerChangesAfterSublayers()
-{
- if (!m_uncommittedChanges)
- return;
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- if (m_uncommittedChanges & ReplicatedLayerChanged)
- updateReplicatedLayers();
-
- m_uncommittedChanges = NoChange;
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-void GraphicsLayerMac::updateLayerNames()
-{
- switch (structuralLayerPurpose()) {
- case StructuralLayerForPreserves3D:
- [m_structuralLayer.get() setName:("Transform layer " + name())];
- break;
- case StructuralLayerForReplicaFlattening:
- [m_structuralLayer.get() setName:("Replica flattening layer " + name())];
- break;
- case NoStructuralLayer:
- break;
- }
- [m_layer.get() setName:name()];
-}
-
-void GraphicsLayerMac::updateSublayerList()
-{
- NSMutableArray* newSublayers = nil;
-
- const Vector<GraphicsLayer*>& childLayers = children();
-
- if (m_structuralLayer || m_contentsLayer || childLayers.size() > 0) {
- newSublayers = [[NSMutableArray alloc] init];
-
- if (m_structuralLayer) {
- // Add the replica layer first.
- if (m_replicaLayer)
- [newSublayers addObject:static_cast<GraphicsLayerMac*>(m_replicaLayer)->primaryLayer()];
- // Add the primary layer. Even if we have negative z-order children, the primary layer always comes behind.
- [newSublayers addObject:m_layer.get()];
- } else if (m_contentsLayer) {
- // FIXME: add the contents layer in the correct order with negative z-order children.
- // This does not cause visible rendering issues because currently contents layers are only used
- // for replaced elements that don't have children.
- [newSublayers addObject:m_contentsLayer.get()];
- }
-
- size_t numChildren = childLayers.size();
- for (size_t i = 0; i < numChildren; ++i) {
- GraphicsLayerMac* curChild = static_cast<GraphicsLayerMac*>(childLayers[i]);
- CALayer *childLayer = curChild->layerForSuperlayer();
- [newSublayers addObject:childLayer];
- }
-
- [newSublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
- }
-
- if (m_structuralLayer) {
- safeSetSublayers(m_structuralLayer.get(), newSublayers);
-
- if (m_contentsLayer) {
- // If we have a transform layer, then the contents layer is parented in the
- // primary layer (which is itself a child of the transform layer).
- safeSetSublayers(m_layer.get(), nil);
- [m_layer.get() addSublayer:m_contentsLayer.get()];
- }
- } else
- safeSetSublayers(m_layer.get(), newSublayers);
-
- [newSublayers release];
-}
-
-void GraphicsLayerMac::updateLayerPosition()
-{
- FloatSize usedSize = m_usingTiledLayer ? constrainedSize() : m_size;
-
- // Position is offset on the layer by the layer anchor point.
- CGPoint posPoint = CGPointMake(m_position.x() + m_anchorPoint.x() * usedSize.width(),
- m_position.y() + m_anchorPoint.y() * usedSize.height());
-
- [primaryLayer() setPosition:posPoint];
-
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CGPoint clonePosition = posPoint;
- if (m_replicaLayer && isReplicatedRootClone(it->first)) {
- // Maintain the special-case position for the root of a clone subtree,
- // which we set up in replicatedLayerRoot().
- clonePosition = positionForCloneRootLayer();
- }
- CALayer *currLayer = it->second.get();
- [currLayer setPosition:clonePosition];
- }
- }
-}
-
-void GraphicsLayerMac::updateLayerSize()
-{
- CGRect rect = CGRectMake(0, 0, m_size.width(), m_size.height());
- if (m_structuralLayer) {
- [m_structuralLayer.get() setBounds:rect];
-
- if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- [it->second.get() setBounds:rect];
- }
-
- // The anchor of the contents layer is always at 0.5, 0.5, so the position is center-relative.
- CGPoint centerPoint = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
- [m_layer.get() setPosition:centerPoint];
-
- if (LayerMap* layerCloneMap = m_layerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- [it->second.get() setPosition:centerPoint];
- }
- }
-
- bool needTiledLayer = requiresTiledLayer(m_size);
- if (needTiledLayer != m_usingTiledLayer)
- swapFromOrToTiledLayer(needTiledLayer);
-
- if (m_usingTiledLayer) {
- FloatSize sizeToUse = constrainedSize();
- rect = CGRectMake(0, 0, sizeToUse.width(), sizeToUse.height());
- }
-
- [m_layer.get() setBounds:rect];
- if (LayerMap* layerCloneMap = m_layerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- [it->second.get() setBounds:rect];
- }
-
- // Contents transform may depend on height.
- updateContentsTransform();
-
- // Note that we don't resize m_contentsLayer. It's up the caller to do that.
-
- // if we've changed the bounds, we need to recalculate the position
- // of the layer, taking anchor point into account.
- updateLayerPosition();
-}
-
-void GraphicsLayerMac::updateAnchorPoint()
-{
- [primaryLayer() setAnchorPoint:FloatPoint(m_anchorPoint.x(), m_anchorPoint.y())];
-#if HAVE_MODERN_QUARTZCORE
- [primaryLayer() setAnchorPointZ:m_anchorPoint.z()];
-#endif
-
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setAnchorPoint:FloatPoint(m_anchorPoint.x(), m_anchorPoint.y())];
-#if HAVE_MODERN_QUARTZCORE
- [currLayer setAnchorPointZ:m_anchorPoint.z()];
-#endif
- }
- }
-
- updateLayerPosition();
-}
-
-void GraphicsLayerMac::updateTransform()
-{
- CATransform3D transform;
- copyTransform(transform, m_transform);
- [primaryLayer() setTransform:transform];
-
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- if (m_replicaLayer && isReplicatedRootClone(it->first)) {
- // Maintain the special-case transform for the root of a clone subtree,
- // which we set up in replicatedLayerRoot().
- [currLayer setTransform:CATransform3DIdentity];
- } else
- [currLayer setTransform:transform];
- }
- }
-}
-
-void GraphicsLayerMac::updateChildrenTransform()
-{
- CATransform3D transform;
- copyTransform(transform, m_childrenTransform);
- [primaryLayer() setSublayerTransform:transform];
-
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setSublayerTransform:transform];
- }
- }
-}
-
-void GraphicsLayerMac::updateMasksToBounds()
-{
- [m_layer.get() setMasksToBounds:m_masksToBounds];
-
- if (LayerMap* layerCloneMap = m_layerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setMasksToBounds:m_masksToBounds];
- }
- }
-
- updateDebugIndicators();
-}
-
-void GraphicsLayerMac::updateContentsOpaque()
-{
- [m_layer.get() setOpaque:m_contentsOpaque];
-
- if (LayerMap* layerCloneMap = m_layerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setOpaque:m_contentsOpaque];
- }
- }
-}
-
-void GraphicsLayerMac::updateBackfaceVisibility()
-{
- if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
- [m_structuralLayer.get() setDoubleSided:m_backfaceVisibility];
-
- if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setDoubleSided:m_backfaceVisibility];
- }
- }
- }
-
- [m_layer.get() setDoubleSided:m_backfaceVisibility];
-
- if (LayerMap* layerCloneMap = m_layerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setDoubleSided:m_backfaceVisibility];
- }
- }
-}
-
-void GraphicsLayerMac::updateStructuralLayer()
-{
- ensureStructuralLayer(structuralLayerPurpose());
-}
-
-void GraphicsLayerMac::ensureStructuralLayer(StructuralLayerPurpose purpose)
-{
- if (purpose == NoStructuralLayer) {
- if (m_structuralLayer) {
- // Replace the transformLayer in the parent with this layer.
- [m_layer.get() removeFromSuperlayer];
- [[m_structuralLayer.get() superlayer] replaceSublayer:m_structuralLayer.get() with:m_layer.get()];
-
- moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_structuralLayer.get(), m_layer.get());
- moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_structuralLayer.get(), m_layer.get());
-
- // Release the structural layer.
- m_structuralLayer = 0;
-
- // Update the properties of m_layer now that we no longer have a structural layer.
- updateLayerPosition();
- updateLayerSize();
- updateAnchorPoint();
- updateTransform();
- updateChildrenTransform();
-
- updateSublayerList();
- updateOpacityOnLayer();
- }
- return;
- }
-
- bool structuralLayerChanged = false;
-
- if (purpose == StructuralLayerForPreserves3D) {
- Class transformLayerClass = NSClassFromString(@"CATransformLayer");
- if (!transformLayerClass)
- return;
-
- if (m_structuralLayer && ![m_structuralLayer.get() isKindOfClass:transformLayerClass])
- m_structuralLayer = 0;
-
- if (!m_structuralLayer) {
- m_structuralLayer.adoptNS([[transformLayerClass alloc] init]);
- structuralLayerChanged = true;
- }
- } else {
- if (m_structuralLayer && ![m_structuralLayer.get() isMemberOfClass:[CALayer self]])
- m_structuralLayer = 0;
-
- if (!m_structuralLayer) {
- m_structuralLayer.adoptNS([[CALayer alloc] init]);
- structuralLayerChanged = true;
- }
- }
-
- if (!structuralLayerChanged)
- return;
-
- // Turn off default animations.
- [m_structuralLayer.get() setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
-
- updateLayerNames();
-
- // Update the properties of the structural layer.
- updateLayerPosition();
- updateLayerSize();
- updateAnchorPoint();
- updateTransform();
- updateChildrenTransform();
- updateBackfaceVisibility();
-
- // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
- CGPoint point = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
- [m_layer.get() setPosition:point];
- [m_layer.get() setAnchorPoint:CGPointMake(0.5f, 0.5f)];
- [m_layer.get() setTransform:CATransform3DIdentity];
- [m_layer.get() setOpacity:1];
-
- // Move this layer to be a child of the transform layer.
- [[m_layer.get() superlayer] replaceSublayer:m_layer.get() with:m_structuralLayer.get()];
- [m_structuralLayer.get() addSublayer:m_layer.get()];
-
- moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_layer.get(), m_structuralLayer.get());
- moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_layer.get(), m_structuralLayer.get());
-
- updateSublayerList();
- updateOpacityOnLayer();
-}
-
-GraphicsLayerMac::StructuralLayerPurpose GraphicsLayerMac::structuralLayerPurpose() const
-{
- if (preserves3D())
- return StructuralLayerForPreserves3D;
-
- if (isReplicated())
- return StructuralLayerForReplicaFlattening;
-
- return NoStructuralLayer;
-}
-
-void GraphicsLayerMac::updateLayerDrawsContent()
-{
- bool needTiledLayer = requiresTiledLayer(m_size);
- if (needTiledLayer != m_usingTiledLayer)
- swapFromOrToTiledLayer(needTiledLayer);
-
- if (m_drawsContent)
- [m_layer.get() setNeedsDisplay];
- else
- [m_layer.get() setContents:nil];
-
- updateDebugIndicators();
-}
-
-void GraphicsLayerMac::updateLayerBackgroundColor()
-{
- if (!m_contentsLayer)
- return;
-
- // We never create the contents layer just for background color yet.
- if (m_backgroundColorSet)
- setLayerBackgroundColor(m_contentsLayer.get(), m_backgroundColor);
- else
- clearLayerBackgroundColor(m_contentsLayer.get());
-}
-
-void GraphicsLayerMac::updateContentsImage()
-{
- if (m_pendingContentsImage) {
- if (!m_contentsLayer.get()) {
- WebLayer* imageLayer = [WebLayer layer];
-#ifndef NDEBUG
- [imageLayer setName:@"Image Layer"];
-#endif
- setupContentsLayer(imageLayer);
- m_contentsLayer.adoptNS([imageLayer retain]);
- // m_contentsLayer will be parented by updateSublayerList
- }
-
- // FIXME: maybe only do trilinear if the image is being scaled down,
- // but then what if the layer size changes?
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
- [m_contentsLayer.get() setMinificationFilter:kCAFilterTrilinear];
-#endif
- [m_contentsLayer.get() setContents:(id)m_pendingContentsImage.get()];
- m_pendingContentsImage = 0;
-
- if (m_contentsLayerClones) {
- LayerMap::const_iterator end = m_contentsLayerClones->end();
- for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
- [it->second.get() setContents:[m_contentsLayer.get() contents]];
- }
-
- updateContentsRect();
- } else {
- // No image.
- // m_contentsLayer will be removed via updateSublayerList.
- m_contentsLayer = 0;
- }
-}
-
-void GraphicsLayerMac::updateContentsMediaLayer()
-{
- // Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
- if (m_contentsLayer) {
- setupContentsLayer(m_contentsLayer.get());
- updateContentsRect();
- }
-}
-
-void GraphicsLayerMac::updateContentsCanvasLayer()
-{
- // CanvasLayer was set as m_contentsLayer, and will get parented in updateSublayerList().
- if (m_contentsLayer) {
- setupContentsLayer(m_contentsLayer.get());
- [m_contentsLayer.get() setNeedsDisplay];
- updateContentsRect();
- }
-}
-
-void GraphicsLayerMac::updateContentsRect()
-{
- if (!m_contentsLayer)
- return;
-
- CGPoint point = CGPointMake(m_contentsRect.x(),
- m_contentsRect.y());
- CGRect rect = CGRectMake(0.0f,
- 0.0f,
- m_contentsRect.width(),
- m_contentsRect.height());
-
- [m_contentsLayer.get() setPosition:point];
- [m_contentsLayer.get() setBounds:rect];
-
- if (m_contentsLayerClones) {
- LayerMap::const_iterator end = m_contentsLayerClones->end();
- for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setPosition:point];
- [currLayer setBounds:rect];
- }
- }
-}
-
-void GraphicsLayerMac::updateMaskLayer()
-{
- CALayer *maskCALayer = m_maskLayer ? m_maskLayer->platformLayer() : 0;
- [m_layer.get() setMask:maskCALayer];
-
- LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerMac*>(m_maskLayer)->primaryLayerClones() : 0;
-
- if (LayerMap* layerCloneMap = m_layerClones.get()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
-
- CALayer *maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->first).get() : 0;
- [currLayer setMask:maskClone];
- }
- }
-}
-
-void GraphicsLayerMac::updateReplicatedLayers()
-{
- // Clone the descendants of the replicated layer, and parent under us.
- ReplicaState replicaState(ReplicaState::ReplicaBranch);
-
- CALayer *replicaRoot = replicatedLayerRoot(replicaState);
- if (!replicaRoot)
- return;
-
- if (m_structuralLayer)
- [m_structuralLayer.get() insertSublayer:replicaRoot atIndex:0];
- else
- [m_layer.get() insertSublayer:replicaRoot atIndex:0];
-}
-
-// For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
-GraphicsLayerMac::CloneID GraphicsLayerMac::ReplicaState::cloneID() const
-{
- size_t depth = m_replicaBranches.size();
-
- const size_t bitsPerUChar = sizeof(UChar) * 8;
- size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
-
- Vector<UChar> result(vectorSize);
- result.fill(0);
-
- // Create a string from the bit sequence which we can use to identify the clone.
- // Note that the string may contain embedded nulls, but that's OK.
- for (size_t i = 0; i < depth; ++i) {
- UChar& currChar = result[i / bitsPerUChar];
- currChar = (currChar << 1) | m_replicaBranches[i];
- }
-
- return String::adopt(result);
-}
-
-CALayer *GraphicsLayerMac::replicatedLayerRoot(ReplicaState& replicaState)
-{
- // Limit replica nesting, to avoid 2^N explosion of replica layers.
- if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
- return nil;
-
- GraphicsLayerMac* replicatedLayer = static_cast<GraphicsLayerMac*>(m_replicatedLayer);
-
- CALayer *clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
- FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
-
- // Replica root has no offset or transform
- [clonedLayerRoot setPosition:cloneRootPosition];
- [clonedLayerRoot setTransform:CATransform3DIdentity];
-
- return clonedLayerRoot;
-}
-
-void GraphicsLayerMac::updateLayerAnimations()
-{
- if (m_animationsToProcess.size()) {
- AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
- for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
- const String& currAnimationName = it->first;
- AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
- if (animationIt == m_runningAnimations.end())
- continue;
-
- const AnimationProcessingAction& processingInfo = it->second;
- const Vector<LayerPropertyAnimation>& animations = animationIt->second;
- for (size_t i = 0; i < animations.size(); ++i) {
- const LayerPropertyAnimation& currAnimation = animations[i];
- switch (processingInfo.action) {
- case Remove:
- removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index);
- break;
- case Pause:
- pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, processingInfo.timeOffset);
- break;
- }
- }
-
- if (processingInfo.action == Remove)
- m_runningAnimations.remove(currAnimationName);
- }
-
- m_animationsToProcess.clear();
- }
-
- size_t numAnimations;
- if ((numAnimations = m_uncomittedAnimations.size())) {
- for (size_t i = 0; i < numAnimations; ++i) {
- const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
- setCAAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
-
- AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
- if (it == m_runningAnimations.end()) {
- Vector<LayerPropertyAnimation> animations;
- animations.append(pendingAnimation);
- m_runningAnimations.add(pendingAnimation.m_name, animations);
- } else {
- Vector<LayerPropertyAnimation>& animations = it->second;
- animations.append(pendingAnimation);
- }
- }
-
- m_uncomittedAnimations.clear();
- }
-}
-
-void GraphicsLayerMac::setCAAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
-{
- PlatformLayer* layer = animatedLayer(property);
-
- if (timeOffset) {
- [caAnim setBeginTime:CACurrentMediaTime() - timeOffset];
- [caAnim setValue:[NSNumber numberWithBool:YES] forKey:WebKitAnimationBeginTimeSetKey];
- }
-
- NSString *animationID = animationIdentifier(animationName, property, index);
-
- [layer removeAnimationForKey:animationID];
- [layer addAnimation:caAnim forKey:animationID];
-
- if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- // Skip immediate replicas, since they move with the original.
- if (m_replicaLayer && isReplicatedRootClone(it->first))
- continue;
- CALayer *currLayer = it->second.get();
- [currLayer removeAnimationForKey:animationID];
- [currLayer addAnimation:caAnim forKey:animationID];
- }
- }
-}
-
-// Workaround for <rdar://problem/7311367>
-static void bug7311367Workaround(CALayer* transformLayer, const TransformationMatrix& transform)
-{
- if (!transformLayer)
- return;
-
- CATransform3D caTransform;
- copyTransform(caTransform, transform);
- caTransform.m41 += 1;
- [transformLayer setTransform:caTransform];
-
- caTransform.m41 -= 1;
- [transformLayer setTransform:caTransform];
-}
-
-bool GraphicsLayerMac::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index)
-{
- PlatformLayer* layer = animatedLayer(property);
-
- NSString *animationID = animationIdentifier(animationName, property, index);
-
- if (![layer animationForKey:animationID])
- return false;
-
- [layer removeAnimationForKey:animationID];
- bug7311367Workaround(m_structuralLayer.get(), m_transform);
-
- if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- // Skip immediate replicas, since they move with the original.
- if (m_replicaLayer && isReplicatedRootClone(it->first))
- continue;
-
- CALayer *currLayer = it->second.get();
- [currLayer removeAnimationForKey:animationID];
- }
- }
- return true;
-}
-
-static void copyAnimationProperties(CAPropertyAnimation* from, CAPropertyAnimation* to)
-{
- [to setBeginTime:[from beginTime]];
- [to setDuration:[from duration]];
- [to setRepeatCount:[from repeatCount]];
- [to setAutoreverses:[from autoreverses]];
- [to setFillMode:[from fillMode]];
- [to setRemovedOnCompletion:[from isRemovedOnCompletion]];
- [to setAdditive:[from isAdditive]];
- [to setTimingFunction:[from timingFunction]];
-
-#if HAVE_MODERN_QUARTZCORE
- [to setValueFunction:[from valueFunction]];
-#endif
-
- if (id object = [from valueForKey:WebKitAnimationBeginTimeSetKey])
- [to setValue:object forKey:WebKitAnimationBeginTimeSetKey];
-}
-
-void GraphicsLayerMac::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
-{
- PlatformLayer* layer = animatedLayer(property);
-
- NSString *animationID = animationIdentifier(animationName, property, index);
-
- CAAnimation *caAnim = [layer animationForKey:animationID];
- if (!caAnim)
- return;
-
- // Animations on the layer are immutable, so we have to clone and modify.
- CAPropertyAnimation* pausedAnim = nil;
- if ([caAnim isKindOfClass:[CAKeyframeAnimation class]]) {
- CAKeyframeAnimation* existingKeyframeAnim = static_cast<CAKeyframeAnimation*>(caAnim);
- CAKeyframeAnimation* newAnim = [CAKeyframeAnimation animationWithKeyPath:[existingKeyframeAnim keyPath]];
- copyAnimationProperties(existingKeyframeAnim, newAnim);
- [newAnim setValues:[existingKeyframeAnim values]];
- [newAnim setKeyTimes:[existingKeyframeAnim keyTimes]];
- [newAnim setTimingFunctions:[existingKeyframeAnim timingFunctions]];
- pausedAnim = newAnim;
- } else if ([caAnim isKindOfClass:[CABasicAnimation class]]) {
- CABasicAnimation* existingPropertyAnim = static_cast<CABasicAnimation*>(caAnim);
- CABasicAnimation* newAnim = [CABasicAnimation animationWithKeyPath:[existingPropertyAnim keyPath]];
- copyAnimationProperties(existingPropertyAnim, newAnim);
- [newAnim setFromValue:[existingPropertyAnim fromValue]];
- [newAnim setToValue:[existingPropertyAnim toValue]];
- pausedAnim = newAnim;
- }
-
- // pausedAnim has the beginTime of caAnim already.
- [pausedAnim setSpeed:0];
- [pausedAnim setTimeOffset:timeOffset];
-
- [layer addAnimation:pausedAnim forKey:animationID]; // This will replace the running animation.
-
- // Pause the animations on the clones too.
- if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- // Skip immediate replicas, since they move with the original.
- if (m_replicaLayer && isReplicatedRootClone(it->first))
- continue;
- CALayer *currLayer = it->second.get();
- [currLayer addAnimation:pausedAnim forKey:animationID];
- }
- }
-}
-
-void GraphicsLayerMac::setContentsToCanvas(PlatformLayer* canvasLayer)
-{
- if (canvasLayer == m_contentsLayer)
- return;
-
- m_contentsLayer = canvasLayer;
- if (m_contentsLayer && [m_contentsLayer.get() respondsToSelector:@selector(setLayerOwner:)])
- [(id)m_contentsLayer.get() setLayerOwner:this];
-
- m_contentsLayerPurpose = canvasLayer ? ContentsLayerForCanvas : NoContentsLayer;
-
- noteSublayersChanged();
- noteLayerPropertyChanged(ContentsCanvasLayerChanged);
-}
-
-void GraphicsLayerMac::repaintLayerDirtyRects()
-{
- if (!m_dirtyRects.size())
- return;
-
- for (size_t i = 0; i < m_dirtyRects.size(); ++i)
- [m_layer.get() setNeedsDisplayInRect:m_dirtyRects[i]];
-
- m_dirtyRects.clear();
-}
-
-void GraphicsLayerMac::updateContentsNeedsDisplay()
-{
- if (m_contentsLayer)
- [m_contentsLayer.get() setNeedsDisplay];
-}
-
-bool GraphicsLayerMac::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
-{
- ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
- bool isKeyframe = valueList.size() > 2;
- bool valuesOK;
-
- bool additive = false;
- int animationIndex = 0;
-
- CAPropertyAnimation* caAnimation;
- if (isKeyframe) {
- CAKeyframeAnimation* keyframeAnim = createKeyframeAnimation(animation, valueList.property(), additive);
- valuesOK = setAnimationKeyframes(valueList, animation, keyframeAnim);
- caAnimation = keyframeAnim;
- } else {
- CABasicAnimation* basicAnim = createBasicAnimation(animation, valueList.property(), additive);
- valuesOK = setAnimationEndpoints(valueList, animation, basicAnim);
- caAnimation = basicAnim;
- }
-
- if (!valuesOK)
- return false;
-
- m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
-
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return true;
-}
-
-bool GraphicsLayerMac::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
-{
- ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
-
- TransformOperationList functionList;
- bool listsMatch, hasBigRotation;
- fetchTransformOperationList(valueList, functionList, listsMatch, 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;
-
- bool validMatrices = true;
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
- // If functionLists don't match we do a matrix animation, otherwise we do a component hardware animation.
- // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
- // if that's not true as well.
- bool isMatrixAnimation = !listsMatch || !caValueFunctionSupported();
-
- size_t numAnimations = isMatrixAnimation ? 1 : functionList.size();
- bool isKeyframe = valueList.size() > 2;
-
- // Iterate through the transform functions, sending an animation for each one.
- for (size_t animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
- TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : functionList[animationIndex];
- CAPropertyAnimation* caAnimation;
-
-#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD)
- // CA applies animations in reverse order (<rdar://problem/7095638>) so we need the last one we add (per property)
- // to be non-additive.
- bool additive = animationIndex < (numAnimations - 1);
-#else
- bool additive = animationIndex > 0;
-#endif
- if (isKeyframe) {
- CAKeyframeAnimation* keyframeAnim = createKeyframeAnimation(animation, valueList.property(), additive);
- validMatrices = setTransformAnimationKeyframes(valueList, animation, keyframeAnim, animationIndex, transformOp, isMatrixAnimation, boxSize);
- caAnimation = keyframeAnim;
- } else {
- CABasicAnimation* basicAnim = createBasicAnimation(animation, valueList.property(), additive);
- validMatrices = setTransformAnimationEndpoints(valueList, animation, basicAnim, animationIndex, transformOp, isMatrixAnimation, boxSize);
- caAnimation = basicAnim;
- }
-
- if (!validMatrices)
- break;
-
- m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
- }
-
- END_BLOCK_OBJC_EXCEPTIONS;
-
- return validMatrices;
-}
-
-CABasicAnimation* GraphicsLayerMac::createBasicAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
-{
- CABasicAnimation* basicAnim = [CABasicAnimation animationWithKeyPath:propertyIdToString(property)];
- setupAnimation(basicAnim, anim, additive);
- return basicAnim;
-}
-
-CAKeyframeAnimation* GraphicsLayerMac::createKeyframeAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
-{
- CAKeyframeAnimation* keyframeAnim = [CAKeyframeAnimation animationWithKeyPath:propertyIdToString(property)];
- setupAnimation(keyframeAnim, anim, additive);
- return keyframeAnim;
-}
-
-void GraphicsLayerMac::setupAnimation(CAPropertyAnimation* propertyAnim, const Animation* anim, bool additive)
-{
- double duration = anim->duration();
- if (duration <= 0)
- duration = cAnimationAlmostZeroDuration;
-
- float repeatCount = anim->iterationCount();
- if (repeatCount == Animation::IterationCountInfinite)
- repeatCount = FLT_MAX;
- else if (anim->direction() == Animation::AnimationDirectionAlternate)
- repeatCount /= 2;
-
- NSString *fillMode = 0;
- switch (anim->fillMode()) {
- case AnimationFillModeNone:
- fillMode = kCAFillModeForwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
- break;
- case AnimationFillModeBackwards:
- fillMode = kCAFillModeBoth; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
- break;
- case AnimationFillModeForwards:
- fillMode = kCAFillModeForwards;
- break;
- case AnimationFillModeBoth:
- fillMode = kCAFillModeBoth;
- break;
- }
-
- [propertyAnim setDuration:duration];
- [propertyAnim setRepeatCount:repeatCount];
- [propertyAnim setAutoreverses:anim->direction()];
- [propertyAnim setRemovedOnCompletion:NO];
- [propertyAnim setAdditive:additive];
- [propertyAnim setFillMode:fillMode];
-
- [propertyAnim setDelegate:m_animationDelegate.get()];
-}
-
-CAMediaTimingFunction* GraphicsLayerMac::timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
-{
- const TimingFunction* tf = 0;
- if (animValue->timingFunction())
- tf = animValue->timingFunction();
- else if (anim->isTimingFunctionSet())
- tf = anim->timingFunction().get();
-
- return getCAMediaTimingFunction(tf ? tf : CubicBezierTimingFunction::create().get());
-}
-
-bool GraphicsLayerMac::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, CABasicAnimation* basicAnim)
-{
- id fromValue = nil;
- id toValue = nil;
-
- switch (valueList.property()) {
- case AnimatedPropertyOpacity: {
- const FloatAnimationValue* startVal = static_cast<const FloatAnimationValue*>(valueList.at(0));
- const FloatAnimationValue* endVal = static_cast<const FloatAnimationValue*>(valueList.at(1));
- fromValue = [NSNumber numberWithFloat:startVal->value()];
- toValue = [NSNumber numberWithFloat:endVal->value()];
- break;
- }
- default:
- ASSERT_NOT_REACHED(); // we don't animate color yet
- break;
- }
-
- // This codepath is used for 2-keyframe animations, so we still need to look in the start
- // for a timing function.
- CAMediaTimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), anim);
- [basicAnim setTimingFunction:timingFunction];
-
- [basicAnim setFromValue:fromValue];
- [basicAnim setToValue:toValue];
-
- return true;
-}
-
-bool GraphicsLayerMac::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* anim, CAKeyframeAnimation* keyframeAnim)
-{
- RetainPtr<NSMutableArray> keyTimes(AdoptNS, [[NSMutableArray alloc] init]);
- RetainPtr<NSMutableArray> values(AdoptNS, [[NSMutableArray alloc] init]);
- RetainPtr<NSMutableArray> timingFunctions(AdoptNS, [[NSMutableArray alloc] init]);
-
- for (unsigned i = 0; i < valueList.size(); ++i) {
- const AnimationValue* curValue = valueList.at(i);
- [keyTimes.get() addObject:[NSNumber numberWithFloat:curValue->keyTime()]];
-
- switch (valueList.property()) {
- case AnimatedPropertyOpacity: {
- const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
- [values.get() addObject:[NSNumber numberWithFloat:floatValue->value()]];
- break;
- }
- default:
- ASSERT_NOT_REACHED(); // we don't animate color yet
- break;
- }
-
- CAMediaTimingFunction* timingFunction = timingFunctionForAnimationValue(curValue, anim);
- [timingFunctions.get() addObject:timingFunction];
- }
-
- // We toss the last tfArray value because it has to one shorter than the others.
- [timingFunctions.get() removeLastObject];
-
- [keyframeAnim setKeyTimes:keyTimes.get()];
- [keyframeAnim setValues:values.get()];
- [keyframeAnim setTimingFunctions:timingFunctions.get()];
-
- return true;
-}
-
-bool GraphicsLayerMac::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, CABasicAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOp, bool isMatrixAnimation, const IntSize& boxSize)
-{
- id fromValue;
- id toValue;
-
- ASSERT(valueList.size() == 2);
- const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(0));
- const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(1));
-
- if (isMatrixAnimation) {
- TransformationMatrix fromTransform, toTransform;
- startValue->value()->apply(boxSize, fromTransform);
- endValue->value()->apply(boxSize, toTransform);
-
- // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
- if (!fromTransform.isInvertible() || !toTransform.isInvertible())
- return false;
-
- CATransform3D caTransform;
- copyTransform(caTransform, fromTransform);
- fromValue = [NSValue valueWithCATransform3D:caTransform];
-
- copyTransform(caTransform, toTransform);
- toValue = [NSValue valueWithCATransform3D:caTransform];
- } else {
- fromValue = getTransformFunctionValue(startValue->value()->at(functionIndex), transformOp, boxSize);
- toValue = getTransformFunctionValue(endValue->value()->at(functionIndex), transformOp, boxSize);
- }
-
- // This codepath is used for 2-keyframe animations, so we still need to look in the start
- // for a timing function.
- CAMediaTimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), anim);
- [basicAnim setTimingFunction:timingFunction];
-
- [basicAnim setFromValue:fromValue];
- [basicAnim setToValue:toValue];
-
-#if HAVE_MODERN_QUARTZCORE
- if (NSString *valueFunctionName = getValueFunctionNameForTransformOperation(transformOp))
- [basicAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
-#endif
-
- return true;
-}
-
-bool GraphicsLayerMac::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, CAKeyframeAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
-{
- RetainPtr<NSMutableArray> keyTimes(AdoptNS, [[NSMutableArray alloc] init]);
- RetainPtr<NSMutableArray> values(AdoptNS, [[NSMutableArray alloc] init]);
- RetainPtr<NSMutableArray> timingFunctions(AdoptNS, [[NSMutableArray alloc] init]);
-
- for (unsigned i = 0; i < valueList.size(); ++i) {
- const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(i));
- [keyTimes.get() addObject:[NSNumber numberWithFloat:curValue->keyTime()]];
-
- if (isMatrixAnimation) {
- TransformationMatrix transform;
- curValue->value()->apply(boxSize, transform);
-
- // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
- if (!transform.isInvertible())
- return false;
-
- CATransform3D caTransform;
- copyTransform(caTransform, transform);
- [values.get() addObject:[NSValue valueWithCATransform3D:caTransform]];
- } else {
- const TransformOperation* transformOp = curValue->value()->at(functionIndex);
- [values.get() addObject:getTransformFunctionValue(transformOp, transformOpType, boxSize)];
- }
-
- CAMediaTimingFunction* timingFunction = timingFunctionForAnimationValue(curValue, animation);
- [timingFunctions.get() addObject:timingFunction];
- }
-
- // We toss the last tfArray value because it has to one shorter than the others.
- [timingFunctions.get() removeLastObject];
-
- [keyframeAnim setKeyTimes:keyTimes.get()];
- [keyframeAnim setValues:values.get()];
- [keyframeAnim setTimingFunctions:timingFunctions.get()];
-
-#if HAVE_MODERN_QUARTZCORE
- if (NSString *valueFunctionName = getValueFunctionNameForTransformOperation(transformOpType))
- [keyframeAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
-#endif
- return true;
-}
-
-void GraphicsLayerMac::suspendAnimations(double time)
-{
- double t = currentTimeToMediaTime(time ? time : currentTime());
- [primaryLayer() setSpeed:0];
- [primaryLayer() setTimeOffset:t];
-
- // Suspend the animations on the clones too.
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setSpeed:0];
- [currLayer setTimeOffset:t];
- }
- }
-}
-
-void GraphicsLayerMac::resumeAnimations()
-{
- [primaryLayer() setSpeed:1];
- [primaryLayer() setTimeOffset:0];
-
- // Resume the animations on the clones too.
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- CALayer *currLayer = it->second.get();
- [currLayer setSpeed:1];
- [currLayer setTimeOffset:0];
- }
- }
-}
-
-CALayer* GraphicsLayerMac::hostLayerForSublayers() const
-{
- return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get();
-}
-
-CALayer* GraphicsLayerMac::layerForSuperlayer() const
-{
- return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
-}
-
-CALayer* GraphicsLayerMac::animatedLayer(AnimatedPropertyID property) const
-{
- return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
-}
-
-GraphicsLayerMac::LayerMap* GraphicsLayerMac::animatedLayerClones(AnimatedPropertyID property) const
-{
- return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
-}
-
-PlatformLayer* GraphicsLayerMac::platformLayer() const
-{
- return primaryLayer();
-}
-
-void GraphicsLayerMac::setDebugBackgroundColor(const Color& color)
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- if (color.isValid())
- setLayerBackgroundColor(m_layer.get(), color);
- else
- clearLayerBackgroundColor(m_layer.get());
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-void GraphicsLayerMac::setDebugBorder(const Color& color, float borderWidth)
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- if (color.isValid()) {
- setLayerBorderColor(m_layer.get(), color);
- [m_layer.get() setBorderWidth:borderWidth];
- } else {
- clearBorderColor(m_layer.get());
- [m_layer.get() setBorderWidth:0];
- }
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-FloatSize GraphicsLayerMac::constrainedSize() const
-{
- float tileColumns = ceilf(m_size.width() / cTiledLayerTileSize);
- float tileRows = ceilf(m_size.height() / cTiledLayerTileSize);
- double numTiles = tileColumns * tileRows;
-
- FloatSize constrainedSize = m_size;
- const unsigned cMaxTileCount = 512;
- while (numTiles > cMaxTileCount) {
- // Constrain the wider dimension.
- if (constrainedSize.width() >= constrainedSize.height()) {
- tileColumns = max(floorf(cMaxTileCount / tileRows), 1.0f);
- constrainedSize.setWidth(tileColumns * cTiledLayerTileSize);
- } else {
- tileRows = max(floorf(cMaxTileCount / tileColumns), 1.0f);
- constrainedSize.setHeight(tileRows * cTiledLayerTileSize);
- }
- numTiles = tileColumns * tileRows;
- }
-
- return constrainedSize;
-}
-
-bool GraphicsLayerMac::requiresTiledLayer(const FloatSize& size) const
-{
- if (!m_drawsContent)
- return false;
-
- // FIXME: catch zero-size height or width here (or earlier)?
- return size.width() > cMaxPixelDimension || size.height() > cMaxPixelDimension;
-}
-
-void GraphicsLayerMac::swapFromOrToTiledLayer(bool useTiledLayer)
-{
- if (useTiledLayer == m_usingTiledLayer)
- return;
-
- CGSize tileSize = CGSizeMake(cTiledLayerTileSize, cTiledLayerTileSize);
-
- RetainPtr<CALayer> oldLayer = m_layer.get();
-
- Class layerClass = useTiledLayer ? [WebTiledLayer self] : [WebLayer self];
- m_layer.adoptNS([[layerClass alloc] init]);
-
- m_usingTiledLayer = useTiledLayer;
-
- if (useTiledLayer) {
- WebTiledLayer* tiledLayer = (WebTiledLayer*)m_layer.get();
- [tiledLayer setTileSize:tileSize];
- [tiledLayer setLevelsOfDetail:1];
- [tiledLayer setLevelsOfDetailBias:0];
- [tiledLayer setContentsGravity:@"bottomLeft"];
-
-#if !HAVE_MODERN_QUARTZCORE
- // Tiled layer has issues with flipped coordinates.
- setContentsOrientation(CompositingCoordinatesTopDown);
-#endif
- } else {
-#if !HAVE_MODERN_QUARTZCORE
- setContentsOrientation(defaultContentsOrientation());
-#endif
- }
-
- [m_layer.get() setLayerOwner:this];
- safeSetSublayers(m_layer.get(), [oldLayer.get() sublayers]);
-
- [[oldLayer.get() superlayer] replaceSublayer:oldLayer.get() with:m_layer.get()];
-
- updateContentsTransform();
-
- updateLayerPosition();
- updateLayerSize();
- updateAnchorPoint();
- updateTransform();
- updateChildrenTransform();
- updateMasksToBounds();
- updateContentsOpaque();
- updateBackfaceVisibility();
- updateLayerBackgroundColor();
-
- updateOpacityOnLayer();
-
-#ifndef NDEBUG
- String name = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + m_name;
- [m_layer.get() setName:name];
-#endif
-
- // move over animations
- moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get());
- moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, oldLayer.get(), m_layer.get());
- moveOrCopyAnimationsForProperty(Move, AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get());
-
- // need to tell new layer to draw itself
- setNeedsDisplay();
-
- updateDebugIndicators();
-}
-
-GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerMac::defaultContentsOrientation() const
-{
-#if !HAVE_MODERN_QUARTZCORE
- // Older QuartzCore does not support -geometryFlipped, so we manually flip the root
- // layer geometry, and then flip the contents of each layer back so that the CTM for CG
- // is unflipped, allowing it to do the correct font auto-hinting.
- return CompositingCoordinatesBottomUp;
-#else
- return CompositingCoordinatesTopDown;
-#endif
-}
-
-void GraphicsLayerMac::updateContentsTransform()
-{
-#if !HAVE_MODERN_QUARTZCORE
- if (contentsOrientation() == CompositingCoordinatesBottomUp) {
- CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
- contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, -[m_layer.get() bounds].size.height);
- [m_layer.get() setContentsTransform:contentsTransform];
- }
-#endif
-}
-
-void GraphicsLayerMac::setupContentsLayer(CALayer* contentsLayer)
-{
- // Turn off implicit animations on the inner layer.
- [contentsLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
- [contentsLayer setMasksToBounds:YES];
-
- if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) {
- 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};
- [contentsLayer setTransform:flipper];
- [contentsLayer setAnchorPoint:CGPointMake(0.0f, 1.0f)];
- } else
- [contentsLayer setAnchorPoint:CGPointZero];
-
- if (showDebugBorders()) {
- setLayerBorderColor(contentsLayer, Color(0, 0, 128, 180));
- [contentsLayer setBorderWidth:1.0f];
- }
-}
-
-CALayer *GraphicsLayerMac::findOrMakeClone(CloneID cloneID, CALayer *sourceLayer, LayerMap* clones, CloneLevel cloneLevel)
-{
- if (!sourceLayer)
- return 0;
-
- CALayer *resultLayer;
-
- // Add with a dummy value to get an iterator for the insertion position, and a boolean that tells
- // us whether there's an item there. This technique avoids two hash lookups.
- RetainPtr<CALayer> dummy;
- pair<LayerMap::iterator, bool> addResult = clones->add(cloneID, dummy);
- if (!addResult.second) {
- // Value was not added, so it exists already.
- resultLayer = addResult.first->second.get();
- } else {
- resultLayer = cloneLayer(sourceLayer, cloneLevel);
-#ifndef NDEBUG
- [resultLayer setName:[NSString stringWithFormat:@"Clone %d of layer %@", cloneID[0U], sourceLayer]];
-#endif
- addResult.first->second = resultLayer;
- }
-
- return resultLayer;
-}
-
-void GraphicsLayerMac::ensureCloneLayers(CloneID cloneID, CALayer *& primaryLayer, CALayer *& structuralLayer, CALayer *& contentsLayer, CloneLevel cloneLevel)
-{
- structuralLayer = nil;
- contentsLayer = nil;
-
- if (!m_layerClones)
- m_layerClones = new LayerMap;
-
- if (!m_structuralLayerClones && m_structuralLayer)
- m_structuralLayerClones = new LayerMap;
-
- if (!m_contentsLayerClones && m_contentsLayer)
- m_contentsLayerClones = new LayerMap;
-
- primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
- structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
- contentsLayer = findOrMakeClone(cloneID, m_contentsLayer.get(), m_contentsLayerClones.get(), cloneLevel);
-}
-
-void GraphicsLayerMac::removeCloneLayers()
-{
- m_layerClones = 0;
- m_structuralLayerClones = 0;
- m_contentsLayerClones = 0;
-}
-
-FloatPoint GraphicsLayerMac::positionForCloneRootLayer() const
-{
- // This can get called during a sync when we've just removed the m_replicaLayer.
- if (!m_replicaLayer)
- return FloatPoint();
-
- FloatPoint replicaPosition = m_replicaLayer->replicatedLayerPosition();
- return FloatPoint(replicaPosition.x() + m_anchorPoint.x() * m_size.width(),
- replicaPosition.y() + m_anchorPoint.y() * m_size.height());
-}
-
-void GraphicsLayerMac::propagateLayerChangeToReplicas()
-{
- for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
- GraphicsLayerMac* currLayerCA = static_cast<GraphicsLayerMac*>(currLayer);
- if (!currLayerCA->hasCloneLayers())
- break;
-
- if (currLayerCA->replicaLayer())
- static_cast<GraphicsLayerMac*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
- }
-}
-
-CALayer *GraphicsLayerMac::fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState& replicaState, CloneLevel cloneLevel)
-{
- CALayer *primaryLayer;
- CALayer *structuralLayer;
- CALayer *contentsLayer;
- ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel);
-
- if (m_maskLayer) {
- CALayer *maskClone = static_cast<GraphicsLayerMac*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
- [primaryLayer setMask:maskClone];
- }
-
- if (m_replicatedLayer) {
- // We are a replica being asked for clones of our layers.
- CALayer *replicaRoot = replicatedLayerRoot(replicaState);
- if (!replicaRoot)
- return nil;
-
- if (structuralLayer) {
- [structuralLayer insertSublayer:replicaRoot atIndex:0];
- return structuralLayer;
- }
-
- [primaryLayer insertSublayer:replicaRoot atIndex:0];
- return primaryLayer;
- }
-
- const Vector<GraphicsLayer*>& childLayers = children();
- NSMutableArray* clonalSublayers = nil;
-
- CALayer *replicaLayer = nil;
- if (m_replicaLayer && m_replicaLayer != replicaRoot) {
- // We have nested replicas. Ask the replica layer for a clone of its contents.
- replicaState.setBranchType(ReplicaState::ReplicaBranch);
- replicaLayer = static_cast<GraphicsLayerMac*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
- replicaState.setBranchType(ReplicaState::ChildBranch);
- }
-
- if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) {
- clonalSublayers = [[NSMutableArray alloc] init];
-
- if (structuralLayer) {
- // Replicas render behind the actual layer content.
- if (replicaLayer)
- [clonalSublayers addObject:replicaLayer];
-
- // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind.
- [clonalSublayers addObject:primaryLayer];
- } else if (contentsLayer) {
- // FIXME: add the contents layer in the correct order with negative z-order children.
- // This does not cause visible rendering issues because currently contents layers are only used
- // for replaced elements that don't have children.
- [clonalSublayers addObject:contentsLayer];
- }
-
- replicaState.push(ReplicaState::ChildBranch);
-
- size_t numChildren = childLayers.size();
- for (size_t i = 0; i < numChildren; ++i) {
- GraphicsLayerMac* curChild = static_cast<GraphicsLayerMac*>(childLayers[i]);
-
- CALayer *childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
- if (childLayer)
- [clonalSublayers addObject:childLayer];
- }
-
- replicaState.pop();
-
- [clonalSublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
- }
-
- CALayer *result;
- if (structuralLayer) {
- [structuralLayer setSublayers:clonalSublayers];
-
- if (contentsLayer) {
- // If we have a transform layer, then the contents layer is parented in the
- // primary layer (which is itself a child of the transform layer).
- [primaryLayer setSublayers:nil];
- [primaryLayer addSublayer:contentsLayer];
- }
-
- result = structuralLayer;
- } else {
- [primaryLayer setSublayers:clonalSublayers];
- result = primaryLayer;
- }
-
- [clonalSublayers release];
- return result;
-}
-
-CALayer *GraphicsLayerMac::cloneLayer(CALayer *layer, CloneLevel cloneLevel)
-{
- static Class transformLayerClass = NSClassFromString(@"CATransformLayer");
- CALayer *newLayer = nil;
- if ([layer isKindOfClass:transformLayerClass])
- newLayer = [transformLayerClass layer];
- else
- newLayer = [CALayer layer];
-
- [newLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
-
- [newLayer setPosition:[layer position]];
- [newLayer setBounds:[layer bounds]];
- [newLayer setAnchorPoint:[layer anchorPoint]];
-#if HAVE_MODERN_QUARTZCORE
- [newLayer setAnchorPointZ:[layer anchorPointZ]];
-#endif
- [newLayer setTransform:[layer transform]];
- [newLayer setSublayerTransform:[layer sublayerTransform]];
- [newLayer setContents:[layer contents]];
- [newLayer setMasksToBounds:[layer masksToBounds]];
- [newLayer setDoubleSided:[layer isDoubleSided]];
- [newLayer setOpaque:[layer isOpaque]];
- [newLayer setBackgroundColor:[layer backgroundColor]];
-
- if (cloneLevel == IntermediateCloneLevel) {
- [newLayer setOpacity:[layer opacity]];
- moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyWebkitTransform, layer, newLayer);
- moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyOpacity, layer, newLayer);
- }
-
- if (showDebugBorders()) {
- setLayerBorderColor(newLayer, Color(255, 122, 251));
- [newLayer setBorderWidth:2];
- }
-
- return newLayer;
-}
-
-void GraphicsLayerMac::setOpacityInternal(float accumulatedOpacity)
-{
- LayerMap* layerCloneMap = 0;
-
- if (preserves3D()) {
- [m_layer.get() setOpacity:accumulatedOpacity];
- layerCloneMap = m_layerClones.get();
- } else {
- [primaryLayer() setOpacity:accumulatedOpacity];
- layerCloneMap = primaryLayerClones();
- }
-
- if (layerCloneMap) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- if (m_replicaLayer && isReplicatedRootClone(it->first))
- continue;
- CALayer *currLayer = it->second.get();
- [currLayer setOpacity:m_opacity];
- }
- }
-}
-
-void GraphicsLayerMac::updateOpacityOnLayer()
-{
-#if !HAVE_MODERN_QUARTZCORE
- // Distribute opacity either to our own layer or to our children. We pass in the
- // contribution from our parent(s).
- distributeOpacity(parent() ? parent()->accumulatedOpacity() : 1);
-#else
- [primaryLayer() setOpacity:m_opacity];
-
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
- LayerMap::const_iterator end = layerCloneMap->end();
- for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- if (m_replicaLayer && isReplicatedRootClone(it->first))
- continue;
-
- CALayer *currLayer = it->second.get();
- [currLayer setOpacity:m_opacity];
- }
-
- }
-#endif
-}
-
-void GraphicsLayerMac::noteSublayersChanged()
-{
- noteLayerPropertyChanged(ChildrenChanged);
- propagateLayerChangeToReplicas();
-}
-
-void GraphicsLayerMac::noteLayerPropertyChanged(LayerChangeFlags flags)
-{
- if (!m_uncommittedChanges && m_client)
- m_client->notifySyncRequired(this);
-
- m_uncommittedChanges |= flags;
-}
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index 1538e07..2361f6a 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -255,7 +255,7 @@ void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
#endif
nil];
-#if defined(BUILDING_ON_SNOW_LEOPARD)
+#if !defined(BUILDING_ON_LEOPARD)
CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
CFArrayRef proxiesForURL = CFNetworkCopyProxiesForURL((CFURLRef)cocoaURL, proxySettings);
BOOL willUseProxy = YES;
@@ -623,7 +623,7 @@ void MediaPlayerPrivateQTKit::resumeLoad()
{
m_delayingLoad = false;
- if (m_movieURL)
+ if (!m_movieURL.isNull())
loadInternal(m_movieURL);
}
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index e1d3f43..92585c6 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -357,9 +357,13 @@ void SimpleFontData::platformCharWidthInit()
void SimpleFontData::platformDestroy()
{
- if (m_smallCapsFontData && !isCustomFont()) {
- fontCache()->releaseFontData(m_smallCapsFontData);
- m_smallCapsFontData = 0;
+ if (!isCustomFont() && m_derivedFontData) {
+ // These come from the cache.
+ if (m_derivedFontData->smallCaps)
+ fontCache()->releaseFontData(m_derivedFontData->smallCaps.leakPtr());
+
+ if (m_derivedFontData->emphasisMark)
+ fontCache()->releaseFontData(m_derivedFontData->emphasisMark.leakPtr());
}
#ifdef BUILDING_ON_TIGER
@@ -373,41 +377,60 @@ void SimpleFontData::platformDestroy()
#endif
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
- if (!m_smallCapsFontData) {
- if (isCustomFont()) {
- FontPlatformData smallCapsFontData(m_platformData);
- smallCapsFontData.m_size = smallCapsFontData.m_size * smallCapsFontSizeMultiplier;
- m_smallCapsFontData = new SimpleFontData(smallCapsFontData, true, false);
- } else {
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- float size = m_platformData.size() * smallCapsFontSizeMultiplier;
- FontPlatformData smallCapsFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
-
- // AppKit resets the type information (screen/printer) when you convert a font to a different size.
- // We have to fix up the font that we're handed back.
- smallCapsFont.setFont(fontDescription.usePrinterFont() ? [smallCapsFont.font() printerFont] : [smallCapsFont.font() screenFont]);
-
- if (smallCapsFont.font()) {
- NSFontManager *fontManager = [NSFontManager sharedFontManager];
- NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()];
-
- if (m_platformData.m_syntheticBold)
- fontTraits |= NSBoldFontMask;
- if (m_platformData.m_syntheticOblique)
- fontTraits |= NSItalicFontMask;
-
- NSFontTraitMask smallCapsFontTraits = [fontManager traitsOfFont:smallCapsFont.font()];
- smallCapsFont.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(smallCapsFontTraits & NSBoldFontMask);
- smallCapsFont.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(smallCapsFontTraits & NSItalicFontMask);
-
- m_smallCapsFontData = fontCache()->getCachedFontData(&smallCapsFont);
- }
- END_BLOCK_OBJC_EXCEPTIONS;
- }
+ if (isCustomFont()) {
+ FontPlatformData scaledFontData(m_platformData);
+ scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
+ return new SimpleFontData(scaledFontData, true, false);
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ float size = m_platformData.size() * scaleFactor;
+ FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
+
+ // AppKit resets the type information (screen/printer) when you convert a font to a different size.
+ // We have to fix up the font that we're handed back.
+ scaledFontData.setFont(fontDescription.usePrinterFont() ? [scaledFontData.font() printerFont] : [scaledFontData.font() screenFont]);
+
+ if (scaledFontData.font()) {
+ NSFontManager *fontManager = [NSFontManager sharedFontManager];
+ NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()];
+
+ if (m_platformData.m_syntheticBold)
+ fontTraits |= NSBoldFontMask;
+ if (m_platformData.m_syntheticOblique)
+ fontTraits |= NSItalicFontMask;
+
+ NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontData.font()];
+ scaledFontData.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(scaledFontTraits & NSBoldFontMask);
+ scaledFontData.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(scaledFontTraits & NSItalicFontMask);
+
+ return fontCache()->getCachedFontData(&scaledFontData);
}
- return m_smallCapsFontData;
+ END_BLOCK_OBJC_EXCEPTIONS;
+
+ return 0;
+}
+
+SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+{
+ if (!m_derivedFontData)
+ m_derivedFontData = DerivedFontData::create(isCustomFont());
+ if (!m_derivedFontData->smallCaps)
+ m_derivedFontData->smallCaps = scaledFontData(fontDescription, smallCapsFontSizeMultiplier);
+
+ return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+ if (!m_derivedFontData)
+ m_derivedFontData = DerivedFontData::create(isCustomFont());
+ if (!m_derivedFontData->emphasisMark)
+ m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5f);
+
+ return m_derivedFontData->emphasisMark.get();
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/mac/WebLayer.h b/WebCore/platform/graphics/mac/WebLayer.h
index 3a91f04..62d69fc 100644
--- a/WebCore/platform/graphics/mac/WebLayer.h
+++ b/WebCore/platform/graphics/mac/WebLayer.h
@@ -34,14 +34,6 @@ namespace WebCore {
class GraphicsLayer;
}
-// Category implemented by WebLayer and WebTiledLayer.
-@interface CALayer(WebLayerAdditions)
-
-- (void)setLayerOwner:(WebCore::GraphicsLayer*)layer;
-- (WebCore::GraphicsLayer*)layerOwner;
-
-@end
-
#if defined(BUILDING_ON_LEOPARD)
@interface CALayer(WebLayerInternal)
- (CGAffineTransform)contentsTransform;
@@ -51,7 +43,6 @@ namespace WebCore {
@interface WebLayer : CALayer
{
- WebCore::GraphicsLayer* m_layerOwner;
}
@end
diff --git a/WebCore/platform/graphics/mac/WebLayer.mm b/WebCore/platform/graphics/mac/WebLayer.mm
index 9bb8212..128e63b 100644
--- a/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/WebCore/platform/graphics/mac/WebLayer.mm
@@ -30,7 +30,8 @@
#import "WebLayer.h"
#import "GraphicsContext.h"
-#import "GraphicsLayer.h"
+#import "GraphicsLayerCA.h"
+#import "PlatformCALayer.h"
#import <objc/objc-runtime.h>
#import <QuartzCore/QuartzCore.h>
#import <wtf/UnusedParam.h>
@@ -62,6 +63,11 @@ void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::GraphicsLa
GraphicsContext graphicsContext(context);
+ if (!layerContents->contentsOpaque()) {
+ // Turn off font smoothing to improve the appearance of text rendered onto a transparent background.
+ graphicsContext.setShouldSmoothFonts(false);
+ }
+
// It's important to get the clip from the context, because it may be significantly
// smaller than the layer bounds (e.g. tiled layers)
CGRect clipBounds = CGContextGetClipBoundingBox(context);
@@ -146,58 +152,39 @@ void setLayerNeedsDisplayInRect(CALayer *layer, WebCore::GraphicsLayer* layerCon
return nil;
}
-// Implement this so presentationLayer can get our custom attributes
-- (id)initWithLayer:(id)layer
-{
- if ((self = [super initWithLayer:layer]))
- m_layerOwner = [(WebLayer*)layer layerOwner];
-
- return self;
-}
-
- (void)setNeedsDisplay
{
- if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent())
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer && layer->owner() && layer->owner()->client() && layer->owner()->drawsContent())
[super setNeedsDisplay];
}
- (void)setNeedsDisplayInRect:(CGRect)dirtyRect
{
- setLayerNeedsDisplayInRect(self, m_layerOwner, dirtyRect);
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer)
+ setLayerNeedsDisplayInRect(self, layer->owner(), dirtyRect);
}
- (void)display
{
[super display];
- if (m_layerOwner)
- m_layerOwner->didDisplay(self);
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer && layer->owner())
+ layer->owner()->didDisplay(self);
}
- (void)drawInContext:(CGContextRef)context
{
- drawLayerContents(context, self, m_layerOwner);
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer)
+ drawLayerContents(context, self, layer->owner());
}
@end // implementation WebLayer
#pragma mark -
-@implementation WebLayer(WebLayerAdditions)
-
-- (void)setLayerOwner:(GraphicsLayer*)aLayer
-{
- m_layerOwner = aLayer;
-}
-
-- (GraphicsLayer*)layerOwner
-{
- return m_layerOwner;
-}
-
-@end
-
-#pragma mark -
-
#ifndef NDEBUG
@implementation CALayer(ExtendedDescription)
diff --git a/WebCore/platform/graphics/mac/WebTiledLayer.h b/WebCore/platform/graphics/mac/WebTiledLayer.h
index 1c9144d..6f559e3 100644
--- a/WebCore/platform/graphics/mac/WebTiledLayer.h
+++ b/WebCore/platform/graphics/mac/WebTiledLayer.h
@@ -32,7 +32,6 @@
@interface WebTiledLayer : CATiledLayer
{
- WebCore::GraphicsLayer* m_layerOwner;
}
// implements WebLayerAdditions
diff --git a/WebCore/platform/graphics/mac/WebTiledLayer.mm b/WebCore/platform/graphics/mac/WebTiledLayer.mm
index 72128ad..bf35431 100644
--- a/WebCore/platform/graphics/mac/WebTiledLayer.mm
+++ b/WebCore/platform/graphics/mac/WebTiledLayer.mm
@@ -30,7 +30,8 @@
#import "WebTiledLayer.h"
#import "GraphicsContext.h"
-#import "GraphicsLayer.h"
+#import "GraphicsLayerCA.h"
+#import "PlatformCALayer.h"
#import <wtf/UnusedParam.h>
using namespace WebCore;
@@ -56,54 +57,35 @@ using namespace WebCore;
return nil;
}
-// Implement this so presentationLayer can get our custom attributes
-- (id)initWithLayer:(id)layer
-{
- if ((self = [super initWithLayer:layer]))
- m_layerOwner = [(WebLayer*)layer layerOwner];
-
- return self;
-}
-
- (void)setNeedsDisplay
{
- if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent())
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer && layer->owner() && layer->owner()->client() && layer->owner()->drawsContent())
[super setNeedsDisplay];
}
- (void)setNeedsDisplayInRect:(CGRect)dirtyRect
{
- setLayerNeedsDisplayInRect(self, m_layerOwner, dirtyRect);
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer)
+ setLayerNeedsDisplayInRect(self, layer->owner(), dirtyRect);
}
- (void)display
{
[super display];
- if (m_layerOwner)
- m_layerOwner->didDisplay(self);
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer && layer->owner())
+ layer->owner()->didDisplay(self);
}
- (void)drawInContext:(CGContextRef)context
{
- drawLayerContents(context, self, m_layerOwner);
+ PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
+ if (layer)
+ drawLayerContents(context, self, layer->owner());
}
@end // implementation WebTiledLayer
-#pragma mark -
-
-@implementation WebTiledLayer(LayerMacAdditions)
-
-- (void)setLayerOwner:(GraphicsLayer*)aLayer
-{
- m_layerOwner = aLayer;
-}
-
-- (GraphicsLayer*)layerOwner
-{
- return m_layerOwner;
-}
-
-@end
-
#endif // USE(ACCELERATED_COMPOSITING)