| /* |
| * 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 WKCACFLayer_h |
| #define WKCACFLayer_h |
| |
| #if USE(ACCELERATED_COMPOSITING) |
| |
| #include "StringHash.h" |
| |
| #include <wtf/RefCounted.h> |
| |
| #include <QuartzCore/CACFLayer.h> |
| #include <QuartzCore/CACFVector.h> |
| #include <wtf/PassRefPtr.h> |
| #include <wtf/RetainPtr.h> |
| #include <wtf/Vector.h> |
| |
| #include "GraphicsContext.h" |
| #include "PlatformString.h" |
| #include "TransformationMatrix.h" |
| |
| namespace WebCore { |
| |
| class WKCACFAnimation; |
| class WKCACFTimingFunction; |
| |
| class WKCACFLayer : public RefCounted<WKCACFLayer> { |
| public: |
| enum LayerType { Layer, TransformLayer }; |
| enum FilterType { Linear, Nearest, Trilinear, Lanczos }; |
| enum ContentsGravityType { Center, Top, Bottom, Left, Right, TopLeft, TopRight, |
| BottomLeft, BottomRight, Resize, ResizeAspect, ResizeAspectFill }; |
| |
| static PassRefPtr<WKCACFLayer> create(LayerType); |
| static WKCACFLayer* layer(CACFLayerRef layer) { return static_cast<WKCACFLayer*>(CACFLayerGetUserData(layer)); } |
| |
| virtual ~WKCACFLayer(); |
| |
| virtual void setNeedsRender() { } |
| virtual void drawInContext(PlatformGraphicsContext*) { } |
| virtual void setNeedsDisplay(const CGRect* dirtyRect); |
| void setNeedsDisplay(); |
| |
| // Makes this layer the root when the passed context is rendered |
| void becomeRootLayerForContext(CACFContextRef); |
| |
| static RetainPtr<CFTypeRef> cfValue(float value) { return RetainPtr<CFTypeRef>(AdoptCF, CFNumberCreate(0, kCFNumberFloat32Type, &value)); } |
| static RetainPtr<CFTypeRef> cfValue(const TransformationMatrix& value) |
| { |
| CATransform3D t; |
| t.m11 = value.m11(); |
| t.m12 = value.m12(); |
| t.m13 = value.m13(); |
| t.m14 = value.m14(); |
| t.m21 = value.m21(); |
| t.m22 = value.m22(); |
| t.m23 = value.m23(); |
| t.m24 = value.m24(); |
| t.m31 = value.m31(); |
| t.m32 = value.m32(); |
| t.m33 = value.m33(); |
| t.m34 = value.m34(); |
| t.m41 = value.m41(); |
| t.m42 = value.m42(); |
| t.m43 = value.m43(); |
| t.m44 = value.m44(); |
| return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreateTransform(t)); |
| } |
| static RetainPtr<CFTypeRef> cfValue(const FloatPoint& value) |
| { |
| CGPoint p; |
| p.x = value.x(); p.y = value.y(); |
| return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreatePoint(p)); |
| } |
| static RetainPtr<CFTypeRef> cfValue(const FloatRect& rect) |
| { |
| CGRect r; |
| r.origin.x = rect.x(); |
| r.origin.y = rect.y(); |
| r.size.width = rect.width(); |
| r.size.height = rect.height(); |
| CGFloat v[4] = { CGRectGetMinX(r), CGRectGetMinY(r), CGRectGetMaxX(r), CGRectGetMaxY(r) }; |
| return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreate(4, v)); |
| } |
| static RetainPtr<CFTypeRef> cfValue(const Color& color) |
| { |
| return RetainPtr<CFTypeRef>(AdoptCF, CGColorCreateGenericRGB(color.red(), color.green(), color.blue(), color.alpha())); |
| } |
| |
| bool isTransformLayer() const; |
| |
| void addSublayer(PassRefPtr<WKCACFLayer> sublayer); |
| void insertSublayer(PassRefPtr<WKCACFLayer>, size_t index); |
| void insertSublayerAboveLayer(PassRefPtr<WKCACFLayer>, const WKCACFLayer* reference); |
| void insertSublayerBelowLayer(PassRefPtr<WKCACFLayer>, const WKCACFLayer* reference); |
| void replaceSublayer(WKCACFLayer* reference, PassRefPtr<WKCACFLayer>); |
| void removeFromSuperlayer(); |
| |
| WKCACFLayer* ancestorOrSelfWithSuperlayer(WKCACFLayer*) const; |
| |
| void setAnchorPoint(const CGPoint& p) { CACFLayerSetAnchorPoint(layer(), p); setNeedsCommit(); } |
| CGPoint anchorPoint() const { return CACFLayerGetAnchorPoint(layer()); } |
| |
| void setAnchorPointZ(CGFloat z) { CACFLayerSetAnchorPointZ(layer(), z); setNeedsCommit(); } |
| CGFloat anchorPointZ() const { return CACFLayerGetAnchorPointZ(layer()); } |
| |
| void setBackgroundColor(CGColorRef color) { CACFLayerSetBackgroundColor(layer(), color); setNeedsCommit(); } |
| CGColorRef backgroundColor() const { return CACFLayerGetBackgroundColor(layer()); } |
| |
| void setBorderColor(CGColorRef color) { CACFLayerSetBorderColor(layer(), color); setNeedsCommit(); } |
| CGColorRef borderColor() const { return CACFLayerGetBorderColor(layer()); } |
| |
| void setBorderWidth(CGFloat width) { CACFLayerSetBorderWidth(layer(), width); setNeedsCommit(); } |
| CGFloat borderWidth() const { return CACFLayerGetBorderWidth(layer()); } |
| |
| void setBounds(const CGRect&); |
| CGRect bounds() const { return CACFLayerGetBounds(layer()); } |
| |
| void setClearsContext(bool clears) { CACFLayerSetClearsContext(layer(), clears); setNeedsCommit(); } |
| bool clearsContext() const { return CACFLayerGetClearsContext(layer()); } |
| |
| void setContents(CGImageRef contents) { CACFLayerSetContents(layer(), contents); setNeedsCommit(); } |
| CGImageRef contents() const { return static_cast<CGImageRef>(const_cast<void*>(CACFLayerGetContents(layer()))); } |
| |
| void setContentsRect(const CGRect& contentsRect) { CACFLayerSetContentsRect(layer(), contentsRect); setNeedsCommit(); } |
| CGRect contentsRect() const { return CACFLayerGetContentsRect(layer()); } |
| |
| void setContentsGravity(ContentsGravityType); |
| ContentsGravityType contentsGravity() const; |
| |
| void setDoubleSided(bool b) { CACFLayerSetDoubleSided(layer(), b); setNeedsCommit(); } |
| bool doubleSided() const { return CACFLayerIsDoubleSided(layer()); } |
| |
| void setEdgeAntialiasingMask(uint32_t mask) { CACFLayerSetEdgeAntialiasingMask(layer(), mask); setNeedsCommit(); } |
| uint32_t edgeAntialiasingMask() const { return CACFLayerGetEdgeAntialiasingMask(layer()); } |
| |
| void setFilters(CFArrayRef filters) { CACFLayerSetFilters(layer(), filters); setNeedsCommit(); } |
| CFArrayRef filters() const { return CACFLayerGetFilters(layer()); } |
| |
| void setFrame(const CGRect&); |
| CGRect frame() const { return CACFLayerGetFrame(layer()); } |
| |
| void setHidden(bool hidden) { CACFLayerSetHidden(layer(), hidden); setNeedsCommit(); } |
| bool isHidden() const { return CACFLayerIsHidden(layer()); } |
| |
| void setMasksToBounds(bool b) { CACFLayerSetMasksToBounds(layer(), b); } |
| bool masksToBounds() const { return CACFLayerGetMasksToBounds(layer()); } |
| |
| void setMagnificationFilter(FilterType); |
| FilterType magnificationFilter() const; |
| |
| void setMinificationFilter(FilterType); |
| FilterType minificationFilter() const; |
| |
| void setMinificationFilterBias(float bias) { CACFLayerSetMinificationFilterBias(layer(), bias); } |
| float minificationFilterBias() const { return CACFLayerGetMinificationFilterBias(layer()); } |
| |
| void setName(const String& name) { CACFLayerSetName(layer(), RetainPtr<CFStringRef>(AdoptCF, name.createCFString()).get()); } |
| String name() const { return CACFLayerGetName(layer()); } |
| |
| void setNeedsDisplayOnBoundsChange(bool needsDisplay) { m_needsDisplayOnBoundsChange = needsDisplay; } |
| |
| void setOpacity(float opacity) { CACFLayerSetOpacity(layer(), opacity); setNeedsCommit(); } |
| float opacity() const { return CACFLayerGetOpacity(layer()); } |
| |
| void setOpaque(bool b) { CACFLayerSetOpaque(layer(), b); setNeedsCommit(); } |
| bool opaque() const { return CACFLayerIsOpaque(layer()); } |
| |
| void setPosition(const CGPoint& position) { CACFLayerSetPosition(layer(), position); setNeedsCommit(); } |
| CGPoint position() const { return CACFLayerGetPosition(layer()); } |
| |
| void setZPosition(CGFloat position) { CACFLayerSetZPosition(layer(), position); setNeedsCommit(); } |
| CGFloat zPosition() const { return CACFLayerGetZPosition(layer()); } |
| |
| void setSpeed(float speed) { CACFLayerSetSpeed(layer(), speed); } |
| CFTimeInterval speed() const { CACFLayerGetSpeed(layer()); } |
| |
| void setTimeOffset(CFTimeInterval t) { CACFLayerSetTimeOffset(layer(), t); } |
| CFTimeInterval timeOffset() const { CACFLayerGetTimeOffset(layer()); } |
| |
| WKCACFLayer* rootLayer() const; |
| |
| void setSortsSublayers(bool sorts) { CACFLayerSetSortsSublayers(layer(), sorts); setNeedsCommit(); } |
| bool sortsSublayers() const { return CACFLayerGetSortsSublayers(layer()); } |
| |
| void removeAllSublayers(); |
| |
| void setSublayers(const Vector<RefPtr<WKCACFLayer> >&); |
| |
| void setSublayerTransform(const CATransform3D& transform) { CACFLayerSetSublayerTransform(layer(), transform); setNeedsCommit(); } |
| CATransform3D sublayerTransform() const { return CACFLayerGetSublayerTransform(layer()); } |
| |
| WKCACFLayer* superlayer() const; |
| |
| void setTransform(const CATransform3D& transform) { CACFLayerSetTransform(layer(), transform); setNeedsCommit(); } |
| CATransform3D transform() const { return CACFLayerGetTransform(layer()); } |
| |
| void setGeometryFlipped(bool flipped) { CACFLayerSetGeometryFlipped(layer(), flipped); setNeedsCommit(); } |
| bool geometryFlipped() const { return CACFLayerIsGeometryFlipped(layer()); } |
| |
| #ifndef NDEBUG |
| // Print the tree from the root. Also does consistency checks |
| void printTree() const; |
| #endif |
| |
| protected: |
| WKCACFLayer(LayerType); |
| |
| void setNeedsCommit(); |
| |
| private: |
| CACFLayerRef layer() const { return m_layer.get(); } |
| size_t numSublayers() const |
| { |
| CFArrayRef sublayers = CACFLayerGetSublayers(layer()); |
| return sublayers ? CFArrayGetCount(sublayers) : 0; |
| } |
| |
| const WKCACFLayer* sublayerAtIndex(int) const; |
| |
| // Returns the index of the passed layer in this layer's sublayers list |
| // or -1 if not found |
| int indexOfSublayer(const WKCACFLayer*); |
| |
| // This should only be called from removeFromSuperlayer. |
| void removeSublayer(const WKCACFLayer*); |
| |
| #ifndef NDEBUG |
| // Print this layer and its children to the console |
| void printLayer(int indent) const; |
| #endif |
| |
| RetainPtr<CACFLayerRef> m_layer; |
| bool m_needsDisplayOnBoundsChange; |
| }; |
| |
| } |
| |
| #endif // USE(ACCELERATED_COMPOSITING) |
| |
| #endif // WKCACFLayer_h |