refactor renderLayerTo in Renderable

This commit is contained in:
Horcrux
2017-01-10 16:30:53 +08:00
parent a493141bd6
commit 0bb87a6eb3
3 changed files with 53 additions and 58 deletions
+2 -4
View File
@@ -31,8 +31,7 @@
- (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity - (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity
{ {
CGFloat aplpha = CGColorGetAlpha(_color); CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * CGColorGetAlpha(_color));
CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * aplpha);
CGContextSetFillColorWithColor(context, color); CGContextSetFillColorWithColor(context, color);
CGColorRelease(color); CGColorRelease(color);
return YES; return YES;
@@ -40,8 +39,7 @@
- (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity - (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity
{ {
CGFloat aplpha = CGColorGetAlpha(_color); CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * CGColorGetAlpha(_color));
CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * aplpha);
CGContextSetStrokeColorWithColor(context, color); CGContextSetStrokeColorWithColor(context, color);
CGColorRelease(color); CGColorRelease(color);
return YES; return YES;
+1 -1
View File
@@ -59,7 +59,7 @@
return; return;
} }
if (opacity < 0) { if (opacity <= 0) {
opacity = 0; opacity = 0;
} else if (opacity > 1) { } else if (opacity > 1) {
opacity = 1; opacity = 1;
+50 -53
View File
@@ -17,6 +17,7 @@
RNSVGPercentageConverter *_heightConverter; RNSVGPercentageConverter *_heightConverter;
CGRect _contextBoundingBox; CGRect _contextBoundingBox;
CGRect _renderBoundingBox; CGRect _renderBoundingBox;
BOOL _fillEvenodd;
} }
- (id)init - (id)init
@@ -53,6 +54,7 @@
return; return;
} }
[self invalidate]; [self invalidate];
_fillEvenodd = fillRule == kRNSVGCGFCRuleEvenodd;
_fillRule = fillRule; _fillRule = fillRule;
} }
@@ -136,7 +138,7 @@
if (hitArea == _hitArea) { if (hitArea == _hitArea) {
return; return;
} }
[self invalidate]; [self invalidate];
CGPathRelease(_hitArea); CGPathRelease(_hitArea);
_hitArea = CGPathRetain(hitArea); _hitArea = CGPathRetain(hitArea);
@@ -166,101 +168,96 @@
CGContextSaveGState(context); CGContextSaveGState(context);
CGContextConcatCTM(context, self.matrix); CGContextConcatCTM(context, self.matrix);
CGContextSetAlpha(context, self.opacity); CGContextSetAlpha(context, self.opacity);
[self beginTransparencyLayer:context]; [self beginTransparencyLayer:context];
[self renderLayerTo:context]; [self renderLayerTo:context];
[self endTransparencyLayer:context]; [self endTransparencyLayer:context];
CGContextRestoreGState(context); CGContextRestoreGState(context);
} }
- (void)renderLayerTo:(CGContextRef)context - (void)renderLayerTo:(CGContextRef)context
{ {
// todo: add detection if path has changed since last update. BOOL shouldStroke = self.stroke && self.strokeWidth;
CGPathRef path = [self getPath:context];
if ((!self.fill && !self.stroke) || !path) { if (!self.fill && !shouldStroke) {
return; return;
} }
CGPathRef path = [self getPath:context];
if ([self getSvgView].responsible) { if ([self getSvgView].responsible) {
// Add path to hitArea // Add path to hitArea
CGMutablePathRef hitArea = CGPathCreateMutableCopy(path); CGMutablePathRef hitArea = CGPathCreateMutableCopy(path);
if (self.stroke && self.strokeWidth) { if (self.stroke && self.strokeWidth) {
// Add stroke to hitArea // Add stroke to hitArea
CGPathRef strokePath = CGPathCreateCopyByStrokingPath(hitArea, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit); CGPathRef strokePath = CGPathCreateCopyByStrokingPath(hitArea, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit);
CGPathAddPath(hitArea, nil, strokePath); CGPathAddPath(hitArea, nil, strokePath);
CGPathRelease(strokePath); CGPathRelease(strokePath);
} }
self.hitArea = CFAutorelease(CGPathCreateCopy(hitArea)); self.hitArea = CFAutorelease(CGPathCreateCopy(hitArea));
CGPathRelease(hitArea); CGPathRelease(hitArea);
} }
if (self.opacity == 0) { if (self.opacity == 0) {
return; return;
} }
CGPathDrawingMode mode = kCGPathStroke; CGPathDrawingMode mode = kCGPathStroke;
BOOL fillColor = YES; BOOL fillColor = YES;
[self clip:context];
if (self.fill) { if (self.fill) {
mode = self.fillRule == kRNSVGCGFCRuleEvenodd ? kCGPathEOFill : kCGPathFill; mode = _fillEvenodd ? kCGPathEOFill : kCGPathFill;
fillColor = [self.fill applyFillColor:context opacity:self.fillOpacity]; fillColor = [self.fill applyFillColor:context opacity:self.fillOpacity];
if (!fillColor) { if (!fillColor) {
[self clip:context];
CGContextSaveGState(context); CGContextSaveGState(context);
CGContextAddPath(context, path); CGContextAddPath(context, path);
CGContextClip(context); CGContextClip(context);
RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.fill brushRef]]; [self.fill paint:context
[self.fill paint:context opacity:self.fillOpacity brushConverter:brushConverter]; opacity:self.fillOpacity
brushConverter:[[self getSvgView] getDefinedBrushConverter:self.fill.brushRef]
];
CGContextRestoreGState(context); CGContextRestoreGState(context);
if (!self.stroke) {
if (!shouldStroke) {
return; return;
} }
} }
} }
if (self.stroke && self.strokeWidth) { if (shouldStroke) {
CGContextSetLineWidth(context, self.strokeWidth); CGContextSetLineWidth(context, self.strokeWidth);
CGContextSetLineCap(context, self.strokeLinecap); CGContextSetLineCap(context, self.strokeLinecap);
CGContextSetLineJoin(context, self.strokeLinejoin); CGContextSetLineJoin(context, self.strokeLinejoin);
RNSVGCGFloatArray dash = self.strokeDasharray; RNSVGCGFloatArray dash = self.strokeDasharray;
if (dash.count) { if (dash.count) {
CGContextSetLineDash(context, self.strokeDashoffset, dash.array, dash.count); CGContextSetLineDash(context, self.strokeDashoffset, dash.array, dash.count);
} }
if (!fillColor) { BOOL strokeColor = [self.stroke applyStrokeColor:context opacity:self.strokeOpacity];
if (!fillColor || !strokeColor) {
CGContextAddPath(context, path); CGContextAddPath(context, path);
CGContextReplacePathWithStrokedPath(context); CGContextReplacePathWithStrokedPath(context);
CGContextClip(context); CGContextClip(context);
} }
if ([self.stroke applyStrokeColor:context opacity:self.strokeOpacity]) { if (!strokeColor) {
if (mode == kCGPathFill) { [self.stroke paint:context
mode = kCGPathFillStroke; opacity:self.strokeOpacity
} else if (mode == kCGPathEOFill) { brushConverter:[[self getSvgView] getDefinedBrushConverter:self.stroke.brushRef]
mode = kCGPathEOFillStroke; ];
}
} else {
// draw fill
[self clip:context];
CGContextAddPath(context, path);
CGContextDrawPath(context, mode);
// draw stroke
CGContextAddPath(context, path);
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.stroke brushRef]];
[self.stroke paint:context opacity:self.strokeOpacity brushConverter:brushConverter];
return; return;
} else if (self.fill) {
mode = _fillEvenodd ? kCGPathEOFillStroke : kCGPathFillStroke;
} }
} }
[self clip:context];
CGContextAddPath(context, path); CGContextAddPath(context, path);
CGContextDrawPath(context, mode); CGContextDrawPath(context, mode);
} }
@@ -280,15 +277,15 @@
} }
return self; return self;
} }
CGAffineTransform matrix = CGAffineTransformConcat(self.matrix, transform); CGAffineTransform matrix = CGAffineTransformConcat(self.matrix, transform);
CGPathRef hitArea = CGPathCreateCopyByTransformingPath(self.hitArea, &matrix); CGPathRef hitArea = CGPathCreateCopyByTransformingPath(self.hitArea, &matrix);
BOOL contains = CGPathContainsPoint(hitArea, nil, point, NO); BOOL contains = CGPathContainsPoint(hitArea, nil, point, NO);
CGPathRelease(hitArea); CGPathRelease(hitArea);
if (contains) { if (contains) {
CGPathRef clipPath = [self getClipPath]; CGPathRef clipPath = [self getClipPath];
if (!clipPath) { if (!clipPath) {
return self; return self;
} else { } else {
@@ -338,22 +335,22 @@
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList - (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList
{ {
[self mergeProperties:target mergeList:mergeList inherited:NO]; [self mergeProperties:target mergeList:mergeList inherited:NO];
} }
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList inherited:(BOOL)inherited - (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList inherited:(BOOL)inherited
{ {
_lastMergedList = mergeList; _lastMergedList = mergeList;
if (mergeList.count == 0) { if (mergeList.count == 0) {
return; return;
} }
NSMutableArray* attributeList = [self.propList mutableCopy]; NSMutableArray* attributeList = [self.propList mutableCopy];
_originProperties = [[NSMutableDictionary alloc] init]; _originProperties = [[NSMutableDictionary alloc] init];
for (NSString *key in mergeList) { for (NSString *key in mergeList) {
if (inherited) { if (inherited) {
if (![attributeList containsObject:key]) { if (![attributeList containsObject:key]) {
@@ -366,7 +363,7 @@
[self setValue:[target valueForKey:key] forKey:key]; [self setValue:[target valueForKey:key] forKey:key];
} }
} }
_attributeList = [attributeList copy]; _attributeList = [attributeList copy];
} }