summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomguy3 <randomguy3@7c02a99a-9b00-45e3-bf44-6f3dd7fddb64>2012-01-17 19:47:18 +0000
committerrandomguy3 <randomguy3@7c02a99a-9b00-45e3-bf44-6f3dd7fddb64>2012-01-17 19:47:18 +0000
commit659d89d7410f3addd563b8eb9e8ba7ddaaeb3cbe (patch)
tree312896e96e59e59ea92ebf686db8f8c4575fa162
parent79de5d881ffa864b8c33462fda27608a9b20a651 (diff)
We can now render arrow heads (in the GTK port, at least).
git-svn-id: https://tikzit.svn.sourceforge.net/svnroot/tikzit/trunk@390 7c02a99a-9b00-45e3-bf44-6f3dd7fddb64
-rw-r--r--tikzit/src/common/Edge.h22
-rw-r--r--tikzit/src/common/Edge.m60
-rw-r--r--tikzit/src/linux/Edge+Render.m46
3 files changed, 108 insertions, 20 deletions
diff --git a/tikzit/src/common/Edge.h b/tikzit/src/common/Edge.h
index b92d7a7..959a724 100644
--- a/tikzit/src/common/Edge.h
+++ b/tikzit/src/common/Edge.h
@@ -73,6 +73,8 @@ typedef enum {
NSPoint cp2;
NSPoint mid;
NSPoint midTan;
+ NSPoint headTan;
+ NSPoint tailTan;
}
/*!
@@ -200,6 +202,26 @@ typedef enum {
@property (readonly) NSPoint rightNormal;
/*!
+ @property leftHeadNormal
+ */
+@property (readonly) NSPoint leftHeadNormal;
+
+/*!
+ @property rightHeadNormal
+ */
+@property (readonly) NSPoint rightHeadNormal;
+
+/*!
+ @property leftTailNormal
+ */
+@property (readonly) NSPoint leftTailNormal;
+
+/*!
+ @property rightTailNormal
+ */
+@property (readonly) NSPoint rightTailNormal;
+
+/*!
@property isSelfLoop
@brief Returns YES if this edge is a self loop.
*/
diff --git a/tikzit/src/common/Edge.m b/tikzit/src/common/Edge.m
index 1878165..d95d528 100644
--- a/tikzit/src/common/Edge.m
+++ b/tikzit/src/common/Edge.m
@@ -107,6 +107,22 @@
return rayStart;
}
+- (NSPoint) _findTanFor:(NSPoint)pt usingSpanFrom:(float)t1 to:(float)t2 {
+ float dx = bezierInterpolate(t2, head.x, cp1.x, cp2.x, tail.x) -
+ bezierInterpolate(t1, head.x, cp1.x, cp2.x, tail.x);
+ float dy = bezierInterpolate(t2, head.y, cp1.y, cp2.y, tail.y) -
+ bezierInterpolate(t1, head.y, cp1.y, cp2.y, tail.y);
+
+ // normalise
+ float len = sqrt(dx*dx+dy*dy);
+ if (len != 0) {
+ dx = (dx/len) * 0.1f;
+ dy = (dy/len) * 0.1f;
+ }
+
+ return NSMakePoint (pt.x + dx, pt.y + dy);
+}
+
- (void)updateControls {
// check for external modification to the node locations
if (src.x != [source point].x || src.y != [source point].y ||
@@ -146,24 +162,12 @@
cp2 = NSMakePoint(targ.x + (cdist * cos(angleTarg)),
targ.y + (cdist * sin(angleTarg)));
-
- mid.x = bezierInterpolate(0.5f, src.x, cp1.x, cp2.x, targ.x);
- mid.y = bezierInterpolate(0.5f, src.y, cp1.y, cp2.y, targ.y);
-
- dx = bezierInterpolate(0.6f, src.x, cp1.x, cp2.x, targ.x) -
- bezierInterpolate(0.4f, src.x, cp1.x, cp2.x, targ.x);
- dy = bezierInterpolate(0.6f, src.y, cp1.y, cp2.y, targ.y) -
- bezierInterpolate(0.4f, src.y, cp1.y, cp2.y, targ.y);
-
- // normalise
- float len = sqrt(dx*dx+dy*dy);
- if (len != 0) {
- dx = (dx/len) * 0.1f;
- dy = (dy/len) * 0.1f;
- }
-
- midTan.x = mid.x + dx;
- midTan.y = mid.y + dy;
+
+ mid = bezierInterpolateFull (0.5f, head, cp1, cp2, tail);
+ midTan = [self _findTanFor:mid usingSpanFrom:0.4f to:0.6f];
+
+ headTan = [self _findTanFor:head usingSpanFrom:0.0f to:0.1f];
+ tailTan = [self _findTanFor:tail usingSpanFrom:1.0f to:0.9f];
}
dirty = NO;
}
@@ -221,6 +225,26 @@
return NSMakePoint(mid.x - (mid.y - midTan.y), mid.y + (mid.x - midTan.x));
}
+- (NSPoint)leftHeadNormal {
+ [self updateControls];
+ return NSMakePoint(headTan.x + (head.y - headTan.y), headTan.y - (head.x - headTan.x));
+}
+
+- (NSPoint)rightHeadNormal {
+ [self updateControls];
+ return NSMakePoint(headTan.x - (head.y - headTan.y), headTan.y + (head.x - headTan.x));
+}
+
+- (NSPoint)leftTailNormal {
+ [self updateControls];
+ return NSMakePoint(tailTan.x + (tail.y - tailTan.y), tailTan.y - (tail.x - tailTan.x));
+}
+
+- (NSPoint)rightTailNormal {
+ [self updateControls];
+ return NSMakePoint(tailTan.x - (tail.y - tailTan.y), tailTan.y + (tail.x - tailTan.x));
+}
+
- (NSPoint) head {
[self updateControls];
return head;
diff --git a/tikzit/src/linux/Edge+Render.m b/tikzit/src/linux/Edge+Render.m
index c64b35f..d4a49c9 100644
--- a/tikzit/src/linux/Edge+Render.m
+++ b/tikzit/src/linux/Edge+Render.m
@@ -124,6 +124,43 @@ static const float cpLineWidth = 1.0;
[context restoreState];
}
+- (void) createArrowStrokePathInContext:(id<RenderContext>)context withTransformer:(Transformer*)transformer {
+ [context startPath];
+
+ if ([self style] != nil) {
+ switch ([[self style] headStyle]) {
+ case AH_None:
+ break;
+ case AH_Plain:
+ [context moveTo:[transformer toScreen:[self leftHeadNormal]]];
+ [context lineTo:[transformer toScreen:head]];
+ [context lineTo:[transformer toScreen:[self rightHeadNormal]]];
+ break;
+ case AH_Latex:
+ [context moveTo:[transformer toScreen:[self leftHeadNormal]]];
+ [context lineTo:[transformer toScreen:head]];
+ [context lineTo:[transformer toScreen:[self rightHeadNormal]]];
+ [context closeSubPath];
+ break;
+ }
+ switch ([[self style] tailStyle]) {
+ case AH_None:
+ break;
+ case AH_Plain:
+ [context moveTo:[transformer toScreen:[self leftTailNormal]]];
+ [context lineTo:[transformer toScreen:tail]];
+ [context lineTo:[transformer toScreen:[self rightTailNormal]]];
+ break;
+ case AH_Latex:
+ [context moveTo:[transformer toScreen:[self leftTailNormal]]];
+ [context lineTo:[transformer toScreen:tail]];
+ [context lineTo:[transformer toScreen:[self rightTailNormal]]];
+ [context closeSubPath];
+ break;
+ }
+ }
+}
+
- (void) createStrokePathInContext:(id<RenderContext>)context withTransformer:(Transformer*)transformer {
NSPoint c_head = [transformer toScreen:head];
NSPoint c_cp1 = [transformer toScreen:cp1];
@@ -149,8 +186,8 @@ static const float cpLineWidth = 1.0;
[context lineTo:[transformer toScreen:[self rightNormal]]];
break;
}
- }
+ }
}
- (void) renderToSurface:(id <Surface>)surface withContext:(id<RenderContext>)context selected:(BOOL)selected {
@@ -159,12 +196,17 @@ static const float cpLineWidth = 1.0;
[context saveState];
const CGFloat lineWidth = style ? [style thickness] : edgeWidth;
[context setLineWidth:lineWidth];
- [self createStrokePathInContext:context withTransformer:[surface transformer]];
RColor color = BlackRColor;
if (selected) {
color.alpha = 0.5;
}
+
+ [self createStrokePathInContext:context withTransformer:[surface transformer]];
[context strokePathWithColor:color];
+
+ [self createArrowStrokePathInContext:context withTransformer:[surface transformer]];
+ [context strokePathWithColor:color andFillWithColor:color];
+
[context restoreState];
if (selected) {