Skip to content

Commit

Permalink
[react-native] Open-source ReactART for native
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiebits committed Apr 29, 2015
1 parent 483077d commit c6af33e
Show file tree
Hide file tree
Showing 42 changed files with 2,498 additions and 0 deletions.
371 changes: 371 additions & 0 deletions Libraries/ART/ART.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions Libraries/ART/ARTCGFloatArray.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* 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.
*/

// A little helper to make sure we have the right memory allocation ready for use.
// We assume that we will only this in one place so no reference counting is necessary.
// Needs to be freed when dealloced.

// This is fragile since this relies on these values not getting reused. Consider
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.

typedef struct {
size_t count;
CGFloat *array;
} ARTCGFloatArray;
18 changes: 18 additions & 0 deletions Libraries/ART/ARTContainer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* 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.
*/

#import <Foundation/Foundation.h>

@protocol ARTContainer <NSObject>

// This is used as a hook for child to mark it's parent as dirty.
// This bubbles up to the root which gets marked as dirty.
- (void)invalidate;

@end
17 changes: 17 additions & 0 deletions Libraries/ART/ARTGroup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* 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.
*/

#import <Foundation/Foundation.h>

#import "ARTContainer.h"
#import "ARTNode.h"

@interface ARTGroup : ARTNode <ARTContainer>

@end
23 changes: 23 additions & 0 deletions Libraries/ART/ARTGroup.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* 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.
*/

#import "ARTGroup.h"

@implementation ARTGroup

- (void)renderLayerTo:(CGContextRef)context
{
// TO-DO: Clipping rectangle

for (ARTNode *node in self.subviews) {
[node renderTo:context];
}
}

@end
33 changes: 33 additions & 0 deletions Libraries/ART/ARTNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* 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.
*/

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/**
* ART nodes are implemented as empty UIViews but this is just an implementation detail to fit
* into the existing view management. They should also be shadow views and painted on a background
* thread.
*/

@interface ARTNode : UIView

@property (nonatomic, assign) CGFloat opacity;

- (void)invalidate;
- (void)renderTo:(CGContextRef)context;

/**
* renderTo will take opacity into account and draw renderLayerTo off-screen if there is opacity
* specified, then composite that onto the context. renderLayerTo always draws at opacity=1.
* @abstract
*/
- (void)renderLayerTo:(CGContextRef)context;

@end
76 changes: 76 additions & 0 deletions Libraries/ART/ARTNode.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* 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.
*/

#import "ARTNode.h"

#import "ARTContainer.h"

@implementation ARTNode

- (void)insertSubview:(UIView *)subview atIndex:(NSInteger)index
{
[self invalidate];
[super insertSubview:subview atIndex:index];
}

- (void)removeFromSuperview
{
[self invalidate];
[super removeFromSuperview];
}

- (void)setOpacity:(CGFloat)opacity
{
[self invalidate];
_opacity = opacity;
}

- (void)setTransform:(CGAffineTransform)transform
{
[self invalidate];
super.transform = transform;
}

- (void)invalidate
{
id<ARTContainer> container = (id<ARTContainer>)self.superview;
[container invalidate];
}

- (void)renderTo:(CGContextRef)context
{
if (self.opacity <= 0) {
// Nothing to paint
return;
}
if (self.opacity >= 1) {
// Just paint at full opacity
CGContextSaveGState(context);
CGContextConcatCTM(context, self.transform);
CGContextSetAlpha(context, 1);
[self renderLayerTo:context];
CGContextRestoreGState(context);
return;
}
// This needs to be painted on a layer before being composited.
CGContextSaveGState(context);
CGContextConcatCTM(context, self.transform);
CGContextSetAlpha(context, self.opacity);
CGContextBeginTransparencyLayer(context, NULL);
[self renderLayerTo:context];
CGContextEndTransparencyLayer(context);
CGContextRestoreGState(context);
}

- (void)renderLayerTo:(CGContextRef)context
{
// abstract
}

@end
25 changes: 25 additions & 0 deletions Libraries/ART/ARTRenderable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* 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.
*/

#import <Foundation/Foundation.h>

#import "ARTBrush.h"
#import "ARTCGFloatArray.h"
#import "ARTNode.h"

@interface ARTRenderable : ARTNode

@property (nonatomic, strong) ARTBrush *fill;
@property (nonatomic, assign) CGColorRef stroke;
@property (nonatomic, assign) CGFloat strokeWidth;
@property (nonatomic, assign) CGLineCap strokeCap;
@property (nonatomic, assign) CGLineJoin strokeJoin;
@property (nonatomic, assign) ARTCGFloatArray strokeDash;

@end
89 changes: 89 additions & 0 deletions Libraries/ART/ARTRenderable.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* 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.
*/

#import "ARTRenderable.h"

@implementation ARTRenderable

- (void)setFill:(ARTBrush *)fill
{
[self invalidate];
_fill = fill;
}

- (void)setStroke:(CGColorRef)stroke
{
if (stroke == _stroke) {
return;
}
[self invalidate];
CGColorRelease(_stroke);
_stroke = CGColorRetain(stroke);
}

- (void)setStrokeWidth:(CGFloat)strokeWidth
{
[self invalidate];
_strokeWidth = strokeWidth;
}

- (void)setStrokeCap:(CGLineCap)strokeCap
{
[self invalidate];
_strokeCap = strokeCap;
}

- (void)setStrokeJoin:(CGLineJoin)strokeJoin
{
[self invalidate];
_strokeJoin = strokeJoin;
}

- (void)setStrokeDash:(ARTCGFloatArray)strokeDash
{
if (strokeDash.array == _strokeDash.array) {
return;
}
if (_strokeDash.array) {
free(_strokeDash.array);
}
[self invalidate];
_strokeDash = strokeDash;
}

- (void)dealloc
{
CGColorRelease(_stroke);
if (_strokeDash.array) {
free(_strokeDash.array);
}
}

- (void)renderTo:(CGContextRef)context
{
if (self.opacity <= 0 || self.opacity >= 1 || (self.fill && self.stroke)) {
// If we have both fill and stroke, we will need to paint this using normal compositing
[super renderTo: context];
return;
}
// This is a terminal with only one painting. Therefore we don't need to paint this
// off-screen. We can just composite it straight onto the buffer.
CGContextSaveGState(context);
CGContextConcatCTM(context, self.transform);
CGContextSetAlpha(context, self.opacity);
[self renderLayerTo:context];
CGContextRestoreGState(context);
}

- (void)renderLayerTo:(CGContextRef)context
{
// abstract
}

@end
77 changes: 77 additions & 0 deletions Libraries/ART/ARTSerializablePath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* 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.
*
* @providesModule ARTSerializablePath
*/

"use strict";

// TODO: Move this into an ART mode called "serialized" or something

var Class = require('art/core/class.js');
var Path = require('art/core/path.js');

var MOVE_TO = 0;
var CLOSE = 1;
var LINE_TO = 2;
var CURVE_TO = 3;
var ARC = 4;

var SerializablePath = Class(Path, {

initialize: function(path) {
this.reset();
if (path instanceof SerializablePath) {
this.path = path.path.slice(0);
} else if (path) {
if (path.applyToPath) {
path.applyToPath(this);
} else {
this.push(path);
}
}
},

onReset: function() {
this.path = [];
},

onMove: function(sx, sy, x, y) {
this.path.push(MOVE_TO, x, y);
},

onLine: function(sx, sy, x, y) {
this.path.push(LINE_TO, x, y);
},

onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y) {
this.path.push(CURVE_TO, p1x, p1y, p2x, p2y, x, y);
},

_arcToBezier: Path.prototype.onArc,

onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation) {
if (rx !== ry || rotation) {
return this._arcToBezier(
sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation
);
}
this.path.push(ARC, cx, cy, rx, sa, ea, ccw ? 0 : 1);
},

onClose: function() {
this.path.push(CLOSE);
},

toJSON: function() {
return this.path;
}

});

module.exports = SerializablePath;
Loading

0 comments on commit c6af33e

Please sign in to comment.