typedef struct arrowtype_t {
int type;
- double lenfact; /* ratio of length of this arrow type to standards arrow */
- void (*gen) (GVJ_t * job, pointf p, pointf u, double wscale, int flag); /* generator function for type */
+ double lenfact; /* ratio of length of this arrow type to standard arrow */
+ void (*gen) (GVJ_t * job, pointf p, pointf u, double penwidth, int flag); /* generator function for type */
} arrowtype_t;
/* forward declaration of functions used in Arrowtypes[] */
-static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
+static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
static arrowtype_t Arrowtypes[] = {
{ARR_TYPE_NORM, 1.0, arrow_type_normal},
return startp;
}
-static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
{
pointf q, v, a[5];
+ double arrowwidth;
- v.x = -u.y * 0.35 * wscale;
- v.y = u.x * 0.35 * wscale;
+ arrowwidth = 0.35;
+ if (penwidth > 4)
+ arrowwidth *= penwidth / 4;
+
+ v.x = -u.y * arrowwidth;
+ v.y = u.x * arrowwidth;
q.x = p.x + u.x;
q.y = p.y + u.y;
if (flag & ARR_MOD_INV) {
gvrender_polygon(job, &a[1], 3, !(flag & ARR_MOD_OPEN));
}
-static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
{
- pointf m, n, q, v, a[7];
+ pointf m, n, q, v, w, a[9];
+ double arrowwidth, shaftwidth;
+
+ arrowwidth = 0.45;
+ if (penwidth > 4)
+ arrowwidth *= penwidth / 4;
+
+ shaftwidth = 0;
+ if (penwidth > 1)
+ shaftwidth = 0.05 * (penwidth - 1);
- v.x = -u.y * 0.45;
- v.y = u.x * 0.45;
+ v.x = -u.y * arrowwidth;
+ v.y = u.x * arrowwidth;
+ w.x = -u.y * shaftwidth;
+ w.y = u.x * shaftwidth;
q.x = p.x + u.x;
q.y = p.y + u.y;
m.x = p.x + u.x * 0.3;
n.x = p.x + u.x * 0.7;
n.y = p.y + u.y * 0.7;
if (flag & ARR_MOD_INV) {
- a[0] = a[6] = p;
+ a[0] = a[8] = p;
a[1].x = q.x - v.x;
a[1].y = q.y - v.y;
- a[2] = a[4] = m;
- a[3] = q;
- a[5].x = q.x + v.x;
- a[5].y = q.y + v.y;
+ a[2].x = m.x - w.x;
+ a[2].y = m.y - w.y;
+ a[3].x = q.x - w.x;
+ a[3].y = q.y - w.y;
+ a[4] = q;
+ a[5].x = q.x + w.x;
+ a[5].y = q.y + w.y;
+ a[6].x = m.x + w.x;
+ a[6].y = m.y + w.y;
+ a[7].x = q.x + v.x;
+ a[7].y = q.y + v.y;
} else {
- a[0] = a[6] = q;
+ a[0] = a[8] = q;
a[1].x = p.x - v.x;
a[1].y = p.y - v.y;
- a[2] = a[4] = n;
- a[3] = p;
- a[5].x = p.x + v.x;
- a[5].y = p.y + v.y;
+ a[2].x = n.x - w.x;
+ a[2].y = n.y - w.y;
+ a[3].x = p.x;
+ a[3].y = p.y;
+ a[4] = p;
+ a[5].x = p.x;
+ a[5].y = p.y;
+ a[6].x = n.x + w.x;
+ a[6].y = n.y + w.y;
+ a[7].x = p.x + v.x;
+ a[7].y = p.y + v.y;
}
if (flag & ARR_MOD_LEFT)
- gvrender_polygon(job, a, 5, 1);
+ gvrender_polygon(job, a, 6, 1);
else if (flag & ARR_MOD_RIGHT)
- gvrender_polygon(job, &a[2], 5, 1);
+ gvrender_polygon(job, &a[3], 6, 1);
else
- gvrender_polygon(job, a, 7, 1);
+ gvrender_polygon(job, a, 9, 1);
}
-static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
{
pointf m, n, q, v, a[4];
gvrender_polyline(job, a, 2);
}
-static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
{
pointf m, q, v, a[4];
gvrender_polyline(job, a, 2);
}
-static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
{
pointf q, r, v, a[5];
gvrender_polygon(job, a, 4, !(flag & ARR_MOD_OPEN));
}
-static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
{
double r;
pointf AF[2];
gvrender_ellipse(job, AF, 2, !(flag & ARR_MOD_OPEN));
}
-static pointf arrow_gen_type(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static pointf arrow_gen_type(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
{
int f;
arrowtype_t *arrowtype;
if (f == arrowtype->type) {
u.x *= arrowtype->lenfact;
u.y *= arrowtype->lenfact;
- (arrowtype->gen) (job, p, u, wscale, flag);
+ (arrowtype->gen) (job, p, u, penwidth, flag);
p.x = p.x + u.x;
p.y = p.y + u.y;
break;
return bb;
}
-void arrow_newgen(GVJ_t * job, emit_state_t emit_state, pointf p, pointf u, double scale, double wscale, int flag)
+void arrow_newgen(GVJ_t * job, emit_state_t emit_state, pointf p, pointf u, double scale, double penwidth, int flag)
{
obj_state_t *obj = job->obj;
double s;
/* arrow head closest to node */
f = flag & ((1 << 16) - 1);
- p = arrow_gen_type(job, p, u, wscale, f);
+ p = arrow_gen_type(job, p, u, penwidth, f);
/* arrow head furthest from node */
/* start where first one ended */
f = (flag >> 16) & ((1 << 16) - 1);
- arrow_gen_type(job, p, u, wscale, f);
+ arrow_gen_type(job, p, u, penwidth, f);
gvrender_end_context(job);
}
/* FIXME emit.c and output.c require wrapper for int point coords */
-void arrow_gen(GVJ_t * job, emit_state_t emit_state, point p, point u, double scale, double wscale, int flag)
+void arrow_gen(GVJ_t * job, emit_state_t emit_state, point p, point u, double scale, double penwidth, int flag)
{
pointf P, U;
P2PF(p, P);
P2PF(u, U);
- arrow_newgen(job, emit_state, P, U, scale, wscale, flag);
+ arrow_newgen(job, emit_state, P, U, scale, penwidth, flag);
}
bezierf bzf;
splinesf offspl, tmpspl;
pointf pf0, pf1, pf2 = { 0, 0 }, pf3, *offlist, *tmplist;
- double scale, wscale = 1., numc2;
+ double scale, numc2;
char* p;
#define SEP 2.0
scale = late_double(e, E_arrowsz, 1.0, 0.0);
color = late_string(e, E_color, "");
- if (job->obj->penwidth > 4)
- wscale = job->obj->penwidth / 4;
-
/* need to know how many colors separated by ':' */
for (p = color; *p; p++)
if (*p == ':')
}
}
arrow_gen(job, EMIT_TDRAW, bz.sp, bz.list[0],
- scale, wscale, bz.sflag);
+ scale, job->obj->penwidth, bz.sflag);
}
if (bz.eflag) {
if (color != headcolor) {
}
}
arrow_gen(job, EMIT_HDRAW, bz.ep, bz.list[bz.size - 1],
- scale, wscale, bz.eflag);
+ scale, job->obj->penwidth, bz.eflag);
}
free(colors);
for (i = 0; i < offspl.size; i++) {
FALSE, FALSE);
if (bz.sflag) {
arrow_gen(job, EMIT_TDRAW, bz.sp, bz.list[0],
- scale, wscale, bz.sflag);
+ scale, job->obj->penwidth, bz.sflag);
}
if (bz.eflag) {
arrow_gen(job, EMIT_HDRAW, bz.ep, bz.list[bz.size - 1],
- scale, wscale, bz.eflag);
+ scale, job->obj->penwidth, bz.eflag);
}
/* arrow_gen resets the job style
* If we have more splines to do, restore the old one.