blob: 774f3205f9a80c1e1b72a9ae0b487392b7187786 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "WXInnerLayer.h"
@implementation WXInnerLayer
@dynamic boxShadowColor, boxShadowOffset, boxShadowRadius, boxShadowOpacity;
+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([key isEqualToString:@"boxShadowRadius"] || [key isEqualToString:@"boxShadowOffset"] || [key isEqualToString:@"boxShadowColor"] || [key isEqualToString:@"boxShadowOpacity"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
- (id)actionForKey:(NSString *) key {
if ([key isEqualToString:@"boxShadowRadius"] || [key isEqualToString:@"boxShadowOffset"] ||[key isEqualToString:@"boxShadowColor"] || [key isEqualToString:@"boxShadowOpacity"] ) {
CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:key];
theAnimation.fromValue = [self.presentationLayer valueForKey:key];
return theAnimation;
}
return [super actionForKey:key];
}
- (void)drawInContext:(CGContextRef)context {
CGFloat radius = self.cornerRadius;
CGRect rect = self.bounds;
if (self.borderWidth != 0) {
rect = CGRectInset(rect, self.borderWidth, self.borderWidth);
radius -= self.borderWidth;
radius = MAX(radius, 0);
}
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetShouldAntialias(context, YES);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
CGContextAddPath(context, bezierPath.CGPath);
CGContextClip(context);
CGMutablePathRef outer = CGPathCreateMutable();
CGPathAddRect(outer, NULL, CGRectInset(rect, -1*rect.size.width, -1*rect.size.height));
CGPathAddPath(outer, NULL, bezierPath.CGPath);
CGPathCloseSubpath(outer);
CGFloat *oldComponents = (CGFloat *)CGColorGetComponents(self.boxShadowColor.CGColor);
CGFloat newComponents[4];
NSInteger numberOfComponents = CGColorGetNumberOfComponents(self.boxShadowColor.CGColor);
switch (numberOfComponents)
{
case 2:
{
//grayscale
newComponents[0] = oldComponents[0];
newComponents[1] = oldComponents[0];
newComponents[2] = oldComponents[0];
newComponents[3] = oldComponents[1] * self.boxShadowOpacity;
break;
}
case 4:
{
//RGBA
newComponents[0] = oldComponents[0];
newComponents[1] = oldComponents[1];
newComponents[2] = oldComponents[2];
newComponents[3] = oldComponents[3] * self.boxShadowOpacity;
break;
}
}
CGColorRef shadowColorWithMultipliedAlpha = CGColorCreate(colorspace, newComponents);
CGColorSpaceRelease(colorspace);
CGContextSetFillColorWithColor(context, shadowColorWithMultipliedAlpha);
CGContextSetShadowWithColor(context, self.boxShadowOffset, self.boxShadowRadius, shadowColorWithMultipliedAlpha);
CGContextAddPath(context, outer);
CGContextEOFillPath(context);
CGPathRelease(outer);
CGColorRelease(shadowColorWithMultipliedAlpha);
}
@end