add filleRule for ios

This commit is contained in:
Horcrux
2016-04-20 23:27:12 +08:00
parent c4a185354a
commit a136063f90
12 changed files with 53 additions and 6 deletions
+2
View File
@@ -13,11 +13,13 @@
#import "RNSVGCGFloatArray.h" #import "RNSVGCGFloatArray.h"
#import "RNSVGTextFrame.h" #import "RNSVGTextFrame.h"
#import "RCTConvert.h" #import "RCTConvert.h"
#import "RNSVGCGFillRule.h"
@interface RCTConvert (RNSVG) @interface RCTConvert (RNSVG)
+ (CGPathRef)CGPath:(id)json; + (CGPathRef)CGPath:(id)json;
+ (CTTextAlignment)CTTextAlignment:(id)json; + (CTTextAlignment)CTTextAlignment:(id)json;
+ (RNSVGCGFillRule)ARTCGFillRule:(id)json;
+ (RNSVGTextFrame)RNSVGTextFrame:(id)json; + (RNSVGTextFrame)RNSVGTextFrame:(id)json;
+ (RNSVGCGFloatArray)RNSVGCGFloatArray:(id)json; + (RNSVGCGFloatArray)RNSVGCGFloatArray:(id)json;
+ (RNSVGBrush *)RNSVGBrush:(id)json; + (RNSVGBrush *)RNSVGBrush:(id)json;
+6
View File
@@ -14,6 +14,7 @@
#import "RNSVGRadialGradient.h" #import "RNSVGRadialGradient.h"
#import "RNSVGSolidColor.h" #import "RNSVGSolidColor.h"
#import "RCTLog.h" #import "RCTLog.h"
#import "RNSVGCGFillRule.h"
@implementation RCTConvert (RNSVG) @implementation RCTConvert (RNSVG)
@@ -72,6 +73,11 @@ RCT_ENUM_CONVERTER(CTTextAlignment, (@{
@"justify": @(kCTTextAlignmentJustified), @"justify": @(kCTTextAlignmentJustified),
}), kCTTextAlignmentNatural, integerValue) }), kCTTextAlignmentNatural, integerValue)
RCT_ENUM_CONVERTER(RNSVGCGFillRule, (@{
@"evenodd": @(kARTCGFillRuleEvenodd),
@"nonzero": @(kARTCGFillRuleNonzero),
}), kARTCGFillRuleEvenodd, intValue)
// This takes a tuple of text lines and a font to generate a CTLine for each text line. // This takes a tuple of text lines and a font to generate a CTLine for each text line.
// This prepares everything for rendering a frame of text in RNSVGText. // This prepares everything for rendering a frame of text in RNSVGText.
+ (RNSVGTextFrame)RNSVGTextFrame:(id)json + (RNSVGTextFrame)RNSVGTextFrame:(id)json
+2
View File
@@ -80,6 +80,7 @@
10A063011CC7320C0000CEEF /* RNSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPath.m; sourceTree = "<group>"; }; 10A063011CC7320C0000CEEF /* RNSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPath.m; sourceTree = "<group>"; };
10A063021CC7320C0000CEEF /* RNSVGSvgView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSvgView.h; sourceTree = "<group>"; }; 10A063021CC7320C0000CEEF /* RNSVGSvgView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSvgView.h; sourceTree = "<group>"; };
10A063031CC7320C0000CEEF /* RNSVGSvgView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSvgView.m; sourceTree = "<group>"; }; 10A063031CC7320C0000CEEF /* RNSVGSvgView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSvgView.m; sourceTree = "<group>"; };
10FEAC6A1CC7D05200F1C23C /* RNSVGCGFillRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGCGFillRule.h; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -99,6 +100,7 @@
0CF68AEA1AF0549300FF9E5C /* Brushes */, 0CF68AEA1AF0549300FF9E5C /* Brushes */,
0CF68AF81AF0549300FF9E5C /* ViewManagers */, 0CF68AF81AF0549300FF9E5C /* ViewManagers */,
0CF68ADB1AF0549300FF9E5C /* RNSVGCGFloatArray.h */, 0CF68ADB1AF0549300FF9E5C /* RNSVGCGFloatArray.h */,
10FEAC6A1CC7D05200F1C23C /* RNSVGCGFillRule.h */,
0CF68ADC1AF0549300FF9E5C /* RNSVGContainer.h */, 0CF68ADC1AF0549300FF9E5C /* RNSVGContainer.h */,
0CF68ADD1AF0549300FF9E5C /* RNSVGGroup.h */, 0CF68ADD1AF0549300FF9E5C /* RNSVGGroup.h */,
0CF68ADE1AF0549300FF9E5C /* RNSVGGroup.m */, 0CF68ADE1AF0549300FF9E5C /* RNSVGGroup.m */,
+13
View File
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
typedef CF_ENUM(int32_t, RNSVGCGFillRule) {
kARTCGFillRuleEvenodd,
kARTCGFillRuleNonzero
};
+3 -1
View File
@@ -35,7 +35,7 @@
CGPathDrawingMode mode = kCGPathStroke; CGPathDrawingMode mode = kCGPathStroke;
if (self.fill) { if (self.fill) {
if ([self.fill applyFillColor:context]) { if ([self.fill applyFillColor:context]) {
mode = kCGPathFill; mode = self.fillRule == kARTCGFillRuleEvenodd ? kCGPathEOFill : kCGPathFill;
} else { } else {
CGContextSaveGState(context); CGContextSaveGState(context);
CGContextAddPath(context, self.d); CGContextAddPath(context, self.d);
@@ -58,6 +58,8 @@
} }
if (mode == kCGPathFill) { if (mode == kCGPathFill) {
mode = kCGPathFillStroke; mode = kCGPathFillStroke;
} else if (mode == kCGPathEOFill) {
mode = kCGPathEOFillStroke;
} }
} }
+2
View File
@@ -11,11 +11,13 @@
#import "RNSVGBrush.h" #import "RNSVGBrush.h"
#import "RNSVGCGFloatArray.h" #import "RNSVGCGFloatArray.h"
#import "RNSVGCGFillRule.h"
#import "RNSVGNode.h" #import "RNSVGNode.h"
@interface RNSVGRenderable : RNSVGNode @interface RNSVGRenderable : RNSVGNode
@property (nonatomic, strong) RNSVGBrush *fill; @property (nonatomic, strong) RNSVGBrush *fill;
@property (nonatomic, assign) RNSVGCGFillRule fillRule;
@property (nonatomic, assign) CGColorRef stroke; @property (nonatomic, assign) CGColorRef stroke;
@property (nonatomic, assign) CGFloat strokeWidth; @property (nonatomic, assign) CGFloat strokeWidth;
@property (nonatomic, assign) CGLineCap strokeLinecap; @property (nonatomic, assign) CGLineCap strokeLinecap;
+6
View File
@@ -17,6 +17,12 @@
_fill = fill; _fill = fill;
} }
- (void)setFillRule:(RNSVGCGFillRule)fillRule
{
[self invalidate];
_fillRule = fillRule;
}
- (void)setStroke:(CGColorRef)stroke - (void)setStroke:(CGColorRef)stroke
{ {
if (stroke == _stroke) { if (stroke == _stroke) {
@@ -10,6 +10,7 @@
#import "RNSVGRenderableManager.h" #import "RNSVGRenderableManager.h"
#import "RCTConvert+RNSVG.h" #import "RCTConvert+RNSVG.h"
#import "RNSVGCGFillRule.h"
@implementation RNSVGRenderableManager @implementation RNSVGRenderableManager
@@ -24,6 +25,7 @@ RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap) RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap)
RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin) RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin)
RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush) RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush)
RCT_EXPORT_VIEW_PROPERTY(fillRule, RNSVGCGFillRule)
RCT_EXPORT_VIEW_PROPERTY(stroke, CGColor) RCT_EXPORT_VIEW_PROPERTY(stroke, CGColor)
RCT_EXPORT_VIEW_PROPERTY(strokeDash, RNSVGCGFloatArray) RCT_EXPORT_VIEW_PROPERTY(strokeDash, RNSVGCGFloatArray)
+3 -2
View File
@@ -59,8 +59,9 @@ var RenderableAttributes = Object.assign({
diff: arrayDiffer diff: arrayDiffer
}, },
strokeWidth: true, strokeWidth: true,
strokeCap: true, strokeLinecap: true,
strokeJoin: true, strokeLinejoin: true,
fillRule: true,
strokeDash: { strokeDash: {
diff: arrayDiffer diff: arrayDiffer
} }
+12 -2
View File
@@ -24,6 +24,11 @@ function remove(id) {
delete fillPatterns[id]; delete fillPatterns[id];
} }
const fillRules = {
evenodd: 0,
nonzero: 1
};
function fillFilter(props) { function fillFilter(props) {
let {fill} = props; let {fill} = props;
@@ -46,7 +51,7 @@ function fillFilter(props) {
if (matched) { if (matched) {
let patternName = `${matched[1]}:${props.svgId}`; let patternName = `${matched[1]}:${props.svgId}`;
let pattern = fillPatterns[patternName]; let pattern = fillPatterns[patternName];
if (pattern) { if (pattern) {
if (pattern.length === 2) { if (pattern.length === 2) {
let dimensions = this.getBoundingBox(); let dimensions = this.getBoundingBox();
@@ -73,7 +78,12 @@ function fillFilter(props) {
export default function(props) { export default function(props) {
let fill = fillFilter.call(this, props); let fill = fillFilter.call(this, props);
return extractBrush(fill, props); let fillRule = fillRules[props.fillRule] === 0 ? 0 : 1;
return {
fill: extractBrush(fill, props),
fillRule
};
} }
export { export {
+1 -1
View File
@@ -17,7 +17,7 @@ export default function(props, options = {stroke: true, join: true, transform: t
} }
if (options.fill) { if (options.fill) {
extractedProps.fill = extractFill.call(this, props); Object.assign(extractedProps, extractFill.call(this, props));
} }
if (options.transform) { if (options.transform) {
+1
View File
@@ -24,6 +24,7 @@ function transformToMatrix(props) {
]; ];
} }
export default function (props) { export default function (props) {
let coords = props.origin ? props.origin.split(/\s*,\s*/) : []; let coords = props.origin ? props.origin.split(/\s*,\s*/) : [];