| 2676 | #define FIN_HEIGHT_SCALE 0.5 /* 1/2 the width of the vector */ |
| 2677 | |
| 2678 | static int psl_vector (struct PSL_CTRL *PSL, double x, double y, double param[]) { |
| 2679 | /* Will make sure that arrow has a finite width in PS coordinates. |
| 2680 | * param must hold up to 12 values: |
| 2681 | * param[PSL_VEC_XTIP] = xtip; |
| 2682 | * param[PSL_VEC_YTIP] = ytip; |
| 2683 | * param[PSL_VEC_TAIL_WIDTH] = tailwidth; |
| 2684 | * param[PSL_VEC_HEAD_LENGTH] = headlength; |
| 2685 | * param[PSL_VEC_HEAD_WIDTH] = headwidth; |
| 2686 | * param[PSL_VEC_HEAD_SHAPE] = headshape; |
| 2687 | * param[PSL_VEC_STATUS] = status bit flags |
| 2688 | * param[PSL_VEC_HEAD_TYPE_BEGIN] = begin head type; |
| 2689 | * param[PSL_VEC_HEAD_TYPE_END] = end head type |
| 2690 | * param[PSL_VEC_TRIM_BEGIN] = begin trim value; |
| 2691 | * param[PSL_VEC_TRIM_END] = end trim value. |
| 2692 | * param[PSL_VEC_HEAD_PENWIDTH] = head penwidth |
| 2693 | */ |
| 2694 | |
| 2695 | double angle, xtip, ytip, r, s, tailwidth, headlength, headwidth, headshape, length_inch; |
| 2696 | double xx[6], yy[6], xc[3], yc[3], off[2], yshift[2], trim[2], xp = 0.0, h_penwidth; |
| 2697 | int length, asymmetry[2], n, heads, outline, fill, status, head_check; |
| 2698 | unsigned int kind[2]; |
| 2699 | char *line[2] = {"N", "P S"}, *dump[2] = {"", "fs"}; |
| 2700 | |
| 2701 | xtip = param[PSL_VEC_XTIP]; ytip = param[PSL_VEC_YTIP]; |
| 2702 | length_inch = hypot (x-xtip, y-ytip); /* Vector length in inches */ |
| 2703 | length = psl_iz (PSL, length_inch); /* Vector length in PS units */ |
| 2704 | if (length == 0) return (PSL_NO_ERROR); /* NULL vector */ |
| 2705 | angle = atan2 (ytip-y, xtip-x) * R2D; /* Angle vector makes with horizontal, in degrees */ |
| 2706 | status = lrint (param[PSL_VEC_STATUS]); |
| 2707 | h_penwidth = param[PSL_VEC_HEAD_PENWIDTH]; |
| 2708 | /* Make any adjustments caused by trim */ |
| 2709 | trim[PSL_BEGIN] = (status & PSL_VEC_OFF_BEGIN) ? param[PSL_VEC_TRIM_BEGIN] : 0.0; |
| 2710 | trim[PSL_END] = (status & PSL_VEC_OFF_END) ? param[PSL_VEC_TRIM_END] : 0.0; |
| 2711 | if (fabs (angle) == 90.0) { /* Vertical segment; only adjust y coordinates */ |
| 2712 | y += copysign (trim[PSL_BEGIN], angle); ytip -= copysign (trim[PSL_END], angle); |
| 2713 | } |
| 2714 | else { /* General case, use trig */ |
| 2715 | double s, c, a = angle * D2R; |
| 2716 | s = sin (a); c = cos (a); |
| 2717 | x += c * trim[PSL_BEGIN]; y += s * trim[PSL_BEGIN]; |
| 2718 | xtip -= c * trim[PSL_END]; ytip -= s * trim[PSL_END]; |
| 2719 | } |
| 2720 | length_inch = hypot (x-xtip, y-ytip); /* Recalculate vector length in inches */ |
| 2721 | length = psl_iz (PSL, length_inch); /* Vector length in PS units */ |
| 2722 | if (length == 0) return (PSL_NO_ERROR); /* NULL vector */ |
| 2723 | tailwidth = param[PSL_VEC_TAIL_WIDTH]; |
| 2724 | headlength = param[PSL_VEC_HEAD_LENGTH]; headwidth = 0.5 * param[PSL_VEC_HEAD_WIDTH]; headshape = param[PSL_VEC_HEAD_SHAPE]; |
| 2725 | kind[PSL_BEGIN] = (unsigned int)lrint (param[PSL_VEC_HEAD_TYPE_BEGIN]); |
| 2726 | kind[PSL_END] = (unsigned int)lrint (param[PSL_VEC_HEAD_TYPE_END]); |
| 2727 | off[PSL_BEGIN] = (kind[PSL_BEGIN] == PSL_VEC_ARROW) ? 0.5 * (2.0 - headshape) * headlength : 0.0; |
| 2728 | off[PSL_END] = (kind[PSL_END] == PSL_VEC_ARROW) ? 0.5 * (2.0 - headshape) * headlength : 0.0; |
| 2729 | if (kind[PSL_BEGIN] == PSL_VEC_ARROW_PLAIN) off[PSL_BEGIN] = 0.5 * tailwidth * headlength / headwidth; |
| 2730 | else if (kind[PSL_BEGIN] == PSL_VEC_TAIL) off[PSL_BEGIN] = FIN_SLANT_COS * headwidth + FIN_LENGTH_SCALE * headlength - tailwidth; |
| 2731 | if (kind[PSL_END] == PSL_VEC_ARROW_PLAIN) off[PSL_END] = 0.5 * tailwidth * headlength / headwidth; |
| 2732 | else if (kind[PSL_END] == PSL_VEC_TAIL) off[PSL_END] = FIN_SLANT_COS * headwidth + FIN_LENGTH_SCALE * headlength - tailwidth; |
| 2733 | heads = PSL_vec_head (status); /* 1 = at beginning, 2 = at end, 3 = both */ |
| 2734 | head_check = PSL_vec_headcheck (status); /* nonzero if we should always place a head regardless of length */ |
| 2735 | if (head_check) { /* Must worry about head size relative to vector length */ |
no test coverage detected