123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691 |
- #include "sys-defines.h"
- #include "extern.h"
- #define P_OPEN 1
- #define P_BOX 2
- #define P_CLOSED 3
- #define SUBTYPE_ELLIPSE 1
- #define SUBTYPE_CIRCLE 3
- const int _pl_f_fig_line_style[PL_NUM_LINE_TYPES] =
- { FIG_L_SOLID, FIG_L_DOTTED, FIG_L_DASHDOTTED, FIG_L_DASHED, FIG_L_DASHED,
- FIG_L_DASHDOUBLEDOTTED, FIG_L_DASHTRIPLEDOTTED };
- const int _pl_f_fig_join_style[PL_NUM_JOIN_TYPES] =
- { FIG_JOIN_MITER, FIG_JOIN_ROUND, FIG_JOIN_BEVEL, FIG_JOIN_ROUND };
- const int _pl_f_fig_cap_style[PL_NUM_CAP_TYPES] =
- { FIG_CAP_BUTT, FIG_CAP_ROUND, FIG_CAP_PROJECT, FIG_CAP_ROUND };
- #define FUZZ 0.0000001
- void
- _pl_f_paint_path (S___(Plotter *_plotter))
- {
- if (_plotter->drawstate->pen_type == 0
- && _plotter->drawstate->fill_type == 0)
-
- return;
- switch ((int)_plotter->drawstate->path->type)
- {
- case (int)PATH_SEGMENT_LIST:
- {
- bool closed;
- const char *format;
- int i, polyline_subtype, line_style;
- double nominal_spacing;
- double device_line_width;
- int quantized_device_line_width;
-
- if (_plotter->drawstate->path->num_segments == 0)
- break;
- if (_plotter->drawstate->path->num_segments == 1)
- break;
-
- if (_plotter->drawstate->path->num_segments == 2
- && _plotter->drawstate->path->segments[1].type == S_ARC)
-
- {
- double x0 = _plotter->drawstate->path->segments[0].p.x;
- double y0 = _plotter->drawstate->path->segments[0].p.y;
- double x1 = _plotter->drawstate->path->segments[1].p.x;
- double y1 = _plotter->drawstate->path->segments[1].p.y;
- double xc = _plotter->drawstate->path->segments[1].pc.x;
- double yc = _plotter->drawstate->path->segments[1].pc.y;
-
- _pl_f_draw_arc_internal (R___(_plotter) xc, yc, x0, y0, x1, y1);
- break;
- }
-
- if ((_plotter->drawstate->path->num_segments >= 3)
- && (_plotter->drawstate->path->segments[_plotter->drawstate->path->num_segments - 1].p.x == _plotter->drawstate->path->segments[0].p.x)
- && (_plotter->drawstate->path->segments[_plotter->drawstate->path->num_segments - 1].p.y == _plotter->drawstate->path->segments[0].p.y))
- closed = true;
- else
- closed = false;
-
- if (closed)
- {
- polyline_subtype = P_CLOSED;
- format = "#POLYLINE [CLOSED]\n%d %d %d %d %d %d %d %d %d %.3f %d %d %d %d %d %d";
- }
- else
- {
- polyline_subtype = P_OPEN;
- format = "#POLYLINE [OPEN]\n%d %d %d %d %d %d %d %d %d %.3f %d %d %d %d %d %d";
- }
-
-
- _pl_f_set_pen_color (S___(_plotter));
- _pl_f_set_fill_color (S___(_plotter));
-
-
- device_line_width =
- FIG_UNITS_TO_FIG_DISPLAY_UNITS(_plotter->drawstate->device_line_width);
- if (device_line_width > 0.75)
- device_line_width += 1.0;
-
- quantized_device_line_width = IROUND(device_line_width);
- if (quantized_device_line_width == 0 && device_line_width > 0.0)
- quantized_device_line_width = 1;
-
- _pl_f_compute_line_style (R___(_plotter) &line_style, &nominal_spacing);
-
-
- if (_plotter->fig_drawing_depth > 0)
- (_plotter->fig_drawing_depth)--;
-
- sprintf(_plotter->data->page->point,
- format,
- 2,
- polyline_subtype,
- line_style,
-
- (_plotter->drawstate->pen_type == 0 ? 0 :
- quantized_device_line_width),
- _plotter->drawstate->fig_fgcolor,
- _plotter->drawstate->fig_fillcolor,
- _plotter->fig_drawing_depth,
- 0,
- _plotter->drawstate->fig_fill_level,
- nominal_spacing,
- _pl_f_fig_join_style[_plotter->drawstate->join_type],
- _pl_f_fig_cap_style[_plotter->drawstate->cap_type],
- 0,
- 0,
- 0,
- _plotter->drawstate->path->num_segments
- );
- _update_buffer (_plotter->data->page);
-
- for (i=0; i<_plotter->drawstate->path->num_segments; i++)
- {
- plPathSegment datapoint;
- double xu, yu, xd, yd;
- int device_x, device_y;
-
- datapoint = _plotter->drawstate->path->segments[i];
- xu = datapoint.p.x;
- yu = datapoint.p.y;
- xd = XD(xu, yu);
- yd = YD(xu, yu);
- device_x = IROUND(xd);
- device_y = IROUND(yd);
-
- if ((i%5) == 0)
- sprintf (_plotter->data->page->point, "\n\t");
- else
- sprintf (_plotter->data->page->point, " ");
- _update_buffer (_plotter->data->page);
-
- sprintf (_plotter->data->page->point, "%d %d", device_x, device_y);
- _update_buffer (_plotter->data->page);
- }
- sprintf (_plotter->data->page->point, "\n");
- _update_buffer (_plotter->data->page);
- }
- break;
-
- case (int)PATH_BOX:
- {
- plPoint p0, p1;
- p0 = _plotter->drawstate->path->p0;
- p1 = _plotter->drawstate->path->p1;
- _pl_f_draw_box_internal (R___(_plotter) p0, p1);
- }
- break;
- case (int)PATH_CIRCLE:
- {
- double x = _plotter->drawstate->path->pc.x;
- double y = _plotter->drawstate->path->pc.y;
- double r = _plotter->drawstate->path->radius;
- _pl_f_draw_ellipse_internal (R___(_plotter)
- x, y, r, r, 0.0, SUBTYPE_CIRCLE);
- }
- break;
- case (int)PATH_ELLIPSE:
- {
- double x = _plotter->drawstate->path->pc.x;
- double y = _plotter->drawstate->path->pc.y;
- double rx = _plotter->drawstate->path->rx;
- double ry = _plotter->drawstate->path->ry;
- double angle = _plotter->drawstate->path->angle;
- _pl_f_draw_ellipse_internal (R___(_plotter)
- x, y, rx, ry, angle, SUBTYPE_ELLIPSE);
- }
- break;
- default:
- break;
- }
- }
- #define DIST(p1, p2) sqrt( ((p1).x - (p2).x) * ((p1).x - (p2).x) \
- + ((p1).y - (p2).y) * ((p1).y - (p2).y))
- void
- _pl_f_draw_arc_internal (R___(Plotter *_plotter) double xc, double yc, double x0, double y0, double x1, double y1)
- {
- plPoint p0, p1, pc, pb;
- plVector v, v0, v1;
- double cross, radius, nominal_spacing;
- int line_style, orientation;
- double device_line_width;
- int quantized_device_line_width;
- pc.x = xc, pc.y = yc;
- p0.x = x0, p0.y = y0;
- p1.x = x1, p1.y = y1;
-
- v0.x = p0.x - pc.x;
- v0.y = p0.y - pc.y;
- v1.x = p1.x - pc.x;
- v1.y = p1.y - pc.y;
-
- cross = v0.x * v1.y - v1.x * v0.y;
-
- orientation = (cross >= 0.0 ? 1 : -1);
- radius = DIST(pc, p0);
- v.x = p1.x - p0.x;
- v.y = p1.y - p0.y;
-
- _vscale(&v, radius);
- pb.x = pc.x + orientation * v.y;
- pb.y = pc.y - orientation * v.x;
-
-
- _pl_f_set_pen_color (S___(_plotter));
- _pl_f_set_fill_color (S___(_plotter));
-
-
- device_line_width =
- FIG_UNITS_TO_FIG_DISPLAY_UNITS(_plotter->drawstate->device_line_width);
-
- if (device_line_width > 0.75)
- device_line_width += 1.0;
-
- quantized_device_line_width = IROUND(device_line_width);
- if (quantized_device_line_width == 0 && device_line_width > 0.0)
- quantized_device_line_width = 1;
-
- _pl_f_compute_line_style (R___(_plotter) &line_style, &nominal_spacing);
-
- if (_plotter->fig_drawing_depth > 0)
- (_plotter->fig_drawing_depth)--;
-
- orientation *= (_plotter->drawstate->transform.nonreflection ? 1 : -1);
- if (orientation == -1)
-
- {
- plPoint ptmp;
-
- ptmp = p0;
- p0 = p1;
- p1 = ptmp;
- }
- sprintf(_plotter->data->page->point,
- "#ARC\n%d %d %d %d %d %d %d %d %d %.3f %d %d %d %d %.3f %.3f %d %d %d %d %d %d\n",
- 5,
- 1,
- line_style,
-
- (_plotter->drawstate->pen_type == 0 ? 0 :
- quantized_device_line_width),
- _plotter->drawstate->fig_fgcolor,
- _plotter->drawstate->fig_fillcolor,
- _plotter->fig_drawing_depth,
- 0,
- _plotter->drawstate->fig_fill_level,
- nominal_spacing,
- _pl_f_fig_cap_style[_plotter->drawstate->cap_type],
- 1,
- 0,
- 0,
- XD(pc.x, pc.y),
- YD(pc.x, pc.y),
- IROUND(XD(p0.x, p0.y)),
- IROUND(YD(p0.x, p0.y)),
- IROUND(XD(pb.x, pb.y)),
- IROUND(YD(pb.x, pb.y)),
- IROUND(XD(p1.x, p1.y)),
- IROUND(YD(p1.x, p1.y)));
- _update_buffer (_plotter->data->page);
- }
- void
- _pl_f_draw_box_internal (R___(Plotter *_plotter) plPoint p0, plPoint p1)
- {
- int xd0, xd1, yd0, yd1;
- double nominal_spacing;
- int line_style;
- double device_line_width;
- int quantized_device_line_width;
-
- _pl_f_set_pen_color (S___(_plotter));
- _pl_f_set_fill_color (S___(_plotter));
-
-
- device_line_width =
- FIG_UNITS_TO_FIG_DISPLAY_UNITS(_plotter->drawstate->device_line_width);
-
- if (device_line_width > 0.75)
- device_line_width += 1.0;
-
- quantized_device_line_width = IROUND(device_line_width);
- if (quantized_device_line_width == 0 && device_line_width > 0.0)
- quantized_device_line_width = 1;
-
- _pl_f_compute_line_style (R___(_plotter) &line_style, &nominal_spacing);
-
-
- if (_plotter->fig_drawing_depth > 0)
- (_plotter->fig_drawing_depth)--;
-
- sprintf(_plotter->data->page->point,
- "#POLYLINE [BOX]\n%d %d %d %d %d %d %d %d %d %.3f %d %d %d %d %d %d\n",
- 2,
- P_BOX,
- line_style,
-
- (_plotter->drawstate->pen_type == 0 ? 0 :
- quantized_device_line_width),
- _plotter->drawstate->fig_fgcolor,
- _plotter->drawstate->fig_fillcolor,
- _plotter->fig_drawing_depth,
- 0,
- _plotter->drawstate->fig_fill_level,
- nominal_spacing,
- _pl_f_fig_join_style[_plotter->drawstate->join_type],
- _pl_f_fig_cap_style[_plotter->drawstate->cap_type],
- 0,
- 0,
- 0,
- 5
- );
- _update_buffer (_plotter->data->page);
-
- p0 = _plotter->drawstate->path->p0;
- p1 = _plotter->drawstate->path->p1;
- xd0 = IROUND(XD(p0.x, p0.y));
- yd0 = IROUND(YD(p0.x, p0.y));
- xd1 = IROUND(XD(p1.x, p1.y));
- yd1 = IROUND(YD(p1.x, p1.y));
-
- sprintf (_plotter->data->page->point, "\t%d %d ", xd0, yd0);
- _update_buffer (_plotter->data->page);
- sprintf (_plotter->data->page->point, "%d %d ", xd0, yd1);
- _update_buffer (_plotter->data->page);
- sprintf (_plotter->data->page->point, "%d %d ", xd1, yd1);
- _update_buffer (_plotter->data->page);
- sprintf (_plotter->data->page->point, "%d %d ", xd1, yd0);
- _update_buffer (_plotter->data->page);
- sprintf (_plotter->data->page->point, "%d %d\n", xd0, yd0);
- _update_buffer (_plotter->data->page);
- }
- void
- _pl_f_draw_ellipse_internal (R___(Plotter *_plotter) double x, double y, double rx, double ry, double angle, int subtype)
- {
- const char *format;
- double theta, mixing_angle;
- double ux, uy, vx, vy;
- double semi_axis_1_x, semi_axis_1_y;
- double semi_axis_2_x, semi_axis_2_y;
- double rx_device, ry_device, theta_device;
- double costheta, sintheta;
- double nominal_spacing;
- int line_style;
- double device_line_width;
- int quantized_device_line_width;
-
- theta = M_PI * angle / 180.0;
- costheta = cos (theta);
- sintheta = sin (theta);
-
- ux = XDV(rx * costheta, rx * sintheta);
- uy = YDV(rx * costheta, rx * sintheta);
- vx = XDV(-ry * sintheta, ry * costheta);
- vy = YDV(-ry * sintheta, ry * costheta);
-
- mixing_angle = 0.5 * _xatan2 (2.0 * (ux * vx + uy * vy),
- ux * ux + uy * uy - vx * vx + vy * vy);
-
-
- semi_axis_1_x = ux * cos(mixing_angle) + vx * sin(mixing_angle);
- semi_axis_1_y = uy * cos(mixing_angle) + vy * sin(mixing_angle);
- semi_axis_2_x = ux * cos(mixing_angle + M_PI_2)
- + vx * sin(mixing_angle + M_PI_2);
- semi_axis_2_y = uy * cos(mixing_angle + M_PI_2)
- + vy * sin(mixing_angle + M_PI_2);
-
- rx_device = sqrt (semi_axis_1_x * semi_axis_1_x
- + semi_axis_1_y * semi_axis_1_y);
- ry_device = sqrt (semi_axis_2_x * semi_axis_2_x
- + semi_axis_2_y * semi_axis_2_y);
-
- theta_device = - _xatan2 (semi_axis_1_y, semi_axis_1_x);
- if (theta_device == 0.0)
- theta_device = 0.0;
- if (subtype == SUBTYPE_CIRCLE &&
- IROUND (rx_device) != IROUND (ry_device))
- subtype = SUBTYPE_ELLIPSE;
-
- _pl_f_set_pen_color (S___(_plotter));
- _pl_f_set_fill_color (S___(_plotter));
-
-
- device_line_width =
- FIG_UNITS_TO_FIG_DISPLAY_UNITS(_plotter->drawstate->device_line_width);
-
- if (device_line_width > 0.75)
- device_line_width += 1.0;
-
- quantized_device_line_width = IROUND(device_line_width);
- if (quantized_device_line_width == 0 && device_line_width > 0.0)
- quantized_device_line_width = 1;
-
- _pl_f_compute_line_style (R___(_plotter) &line_style, &nominal_spacing);
-
- if (_plotter->fig_drawing_depth > 0)
- (_plotter->fig_drawing_depth)--;
- if (subtype == SUBTYPE_CIRCLE)
- format = "#ELLIPSE [CIRCLE]\n%d %d %d %d %d %d %d %d %d %.3f %d %.3f %d %d %d %d %d %d %d %d\n";
- else
- format = "#ELLIPSE\n%d %d %d %d %d %d %d %d %d %.3f %d %.3f %d %d %d %d %d %d %d %d\n";
- sprintf(_plotter->data->page->point,
- format,
- 1,
- subtype,
- line_style,
-
- (_plotter->drawstate->pen_type == 0 ? 0 :
- quantized_device_line_width),
- _plotter->drawstate->fig_fgcolor,
- _plotter->drawstate->fig_fillcolor,
- _plotter->fig_drawing_depth,
- 0,
- _plotter->drawstate->fig_fill_level,
- nominal_spacing,
- 1,
- theta_device,
- IROUND(XD(x,y)),
- IROUND(YD(x,y)),
- IROUND(rx_device),
- IROUND(ry_device),
- IROUND(XD(x,y)),
- IROUND(YD(x,y)),
- IROUND(XD(x,y)
- + semi_axis_1_x + semi_axis_2_x),
- IROUND(YD(x,y)
- + semi_axis_1_y + semi_axis_2_y)
- );
- _update_buffer(_plotter->data->page);
- }
- void
- _pl_f_compute_line_style (R___(Plotter *_plotter) int *style, double *spacing)
- {
- int fig_line_style;
- double fig_nominal_spacing;
-
- if (_plotter->drawstate->dash_array_in_effect
- && _plotter->drawstate->dash_array_len == 2
- && (_plotter->drawstate->dash_array[1]
- == _plotter->drawstate->dash_array[0]))
-
- {
- double min_sing_val, max_sing_val;
-
- _matrix_sing_vals (_plotter->drawstate->transform.m,
- &min_sing_val, &max_sing_val);
-
- fig_nominal_spacing =
- FIG_UNITS_TO_FIG_DISPLAY_UNITS(min_sing_val * 2.0 * _plotter->drawstate->dash_array[0]);
- fig_line_style = FIG_L_DASHED;
- }
- else if (_plotter->drawstate->dash_array_in_effect
- && _plotter->drawstate->dash_array_len == 2
- && (_plotter->drawstate->dash_array[1]
- > (3 - FUZZ) * _plotter->drawstate->dash_array[0])
- && (_plotter->drawstate->dash_array[1]
- < (3 + FUZZ) * _plotter->drawstate->dash_array[0]))
-
- {
- double min_sing_val, max_sing_val;
- _matrix_sing_vals (_plotter->drawstate->transform.m,
- &min_sing_val, &max_sing_val);
-
- fig_nominal_spacing =
- FIG_UNITS_TO_FIG_DISPLAY_UNITS(min_sing_val * 4.0 * _plotter->drawstate->dash_array[0]);
- fig_line_style = FIG_L_DOTTED;
- }
- else
-
- {
- int i, num_dashes, cycle_length;
- const int *dash_array;
- double display_size_in_fig_units, min_dash_unit, dash_unit;
- num_dashes =
- _pl_g_line_styles[_plotter->drawstate->line_type].dash_array_len;
- dash_array = _pl_g_line_styles[_plotter->drawstate->line_type].dash_array;
- cycle_length = 0;
- for (i = 0; i < num_dashes; i++)
- cycle_length += dash_array[i];
-
- display_size_in_fig_units = DMIN(_plotter->data->xmax - _plotter->data->xmin,
-
- _plotter->data->ymin - _plotter->data->ymax);
- min_dash_unit = PL_MIN_DASH_UNIT_AS_FRACTION_OF_DISPLAY_SIZE
- * FIG_UNITS_TO_FIG_DISPLAY_UNITS(display_size_in_fig_units);
- dash_unit = DMAX(min_dash_unit,
- FIG_UNITS_TO_FIG_DISPLAY_UNITS(_plotter->drawstate->device_line_width));
-
- fig_nominal_spacing = cycle_length * dash_unit;
- fig_line_style = _pl_f_fig_line_style[_plotter->drawstate->line_type];
- }
-
-
- switch (fig_line_style)
- {
- case FIG_L_SOLID:
- default:
- break;
- case FIG_L_DOTTED:
- fig_nominal_spacing -= 1.0;
- break;
- case FIG_L_DASHDOTTED:
- fig_nominal_spacing -= 1.0;
-
- case FIG_L_DASHED:
- fig_nominal_spacing *= 0.5;
- break;
- case FIG_L_DASHDOUBLEDOTTED:
- fig_nominal_spacing -= 2.0;
- fig_nominal_spacing /= (1.9 + 1/3.0);
- break;
- case FIG_L_DASHTRIPLEDOTTED:
- fig_nominal_spacing -= 3.0;
- fig_nominal_spacing /= 2.4;
- break;
- }
- if (fig_nominal_spacing <= 1.0)
- fig_nominal_spacing = 1.0;
-
- *style = fig_line_style;
- *spacing = fig_nominal_spacing;
- }
- bool
- _pl_f_paint_paths (S___(Plotter *_plotter))
- {
- return false;
- }
|