1
/* This file is part of the GNU plotutils package. Copyright (C) 1995,
2
1996, 1997, 1998, 1999, 2000, 2005, Free Software Foundation, Inc.
4
The GNU plotutils package is free software. You may redistribute it
5
and/or modify it under the terms of the GNU General Public License as
6
published by the Free Software foundation; either version 2, or (at your
7
option) any later version.
9
The GNU plotutils package is distributed in the hope that it will be
10
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
General Public License for more details.
14
You should have received a copy of the GNU General Public License along
15
with the GNU plotutils package; see the file COPYING. If not, write to
16
the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
17
Boston, MA 02110-1301, USA. */
1
19
/* This file contains the internal paint_path() and paint_paths() methods,
2
20
which the public method endpath() is a wrapper around. */
12
30
#include "extern.h"
14
32
/* 16-bit brush patterns for idraw (1 = on, 0 = off), indexed by our
15
internal numbering of line styles, i.e. by L_{SOLID,DOTTED,DOTDASHED,
33
internal numbering of line types, i.e. by L_{SOLID,DOTTED,DOTDASHED,
16
34
SHORTDASHED,LONGDASHED,DOTDOTDASHED,DOTDOTDOTDASHED} */
17
const long _idraw_brush_pattern[NUM_LINE_STYLES] =
35
static const long idraw_brush_pattern[PL_NUM_LINE_TYPES] =
18
36
{ 0xffff, 0x8888, 0xfc30, 0xf0f0, 0xffc0, 0xfccc, 0xfdb6 };
20
38
/* PS join styles, indexed by internal number (miter/rd./bevel/triangular) */
21
const int _ps_join_style[] =
39
static const int ps_join_style[PL_NUM_JOIN_TYPES] =
22
40
{ PS_LINE_JOIN_MITER, PS_LINE_JOIN_ROUND, PS_LINE_JOIN_BEVEL, PS_LINE_JOIN_ROUND };
24
42
/* PS cap styles, indexed by internal number (butt/rd./project/triangular) */
25
const int _ps_cap_style[] =
43
static const int ps_cap_style[PL_NUM_CAP_TYPES] =
26
44
{ PS_LINE_CAP_BUTT, PS_LINE_CAP_ROUND, PS_LINE_CAP_PROJECT, PS_LINE_CAP_ROUND };
30
_p_paint_path (S___(Plotter *_plotter))
32
_p_paint_path (S___(_plotter))
33
S___(Plotter *_plotter;)
47
_pl_p_paint_path (S___(Plotter *_plotter))
36
49
double granularity;
87
100
/* scale up each point coordinate by granularity factor and round
88
101
it to closest integer, removing runs of points with the same
89
102
scaled integer coordinates */
90
xarray = (plIntPoint *)_plot_xmalloc (_plotter->drawstate->path->num_segments * sizeof(plIntPoint));
103
xarray = (plIntPoint *)_pl_xmalloc (_plotter->drawstate->path->num_segments * sizeof(plIntPoint));
92
105
for (i = 0; i < _plotter->drawstate->path->num_segments; i++)
136
149
/* emit common attributes: CTM, fill rule, cap and join styles and
137
150
miter limit, dash array, foreground and background colors, and
139
_p_emit_common_attributes (S___(_plotter));
152
_pl_p_emit_common_attributes (S___(_plotter));
141
154
/* emit transformation matrix (all 6 elements) */
142
155
strcpy (_plotter->data->page->point, "%I t\n[");
278
291
/* emit common attributes: CTM, fill rule, cap and join styles and
279
292
miter limit, dash array, foreground and background colors, and
281
_p_emit_common_attributes (S___(_plotter));
294
_pl_p_emit_common_attributes (S___(_plotter));
283
296
/* emit transformation matrix (all 6 elements) */
284
297
strcpy (_plotter->data->page->point, "%I t\n[");
364
377
radius = _plotter->drawstate->path->radius;
366
379
/* final arg flags this for idraw as a circle, not an ellipse */
367
_p_fellipse_internal (R___(_plotter) pc.x, pc.y, radius, radius,
380
_pl_p_fellipse_internal (R___(_plotter) pc.x, pc.y, radius, radius,
378
391
double angle = _plotter->drawstate->path->angle;
380
393
/* final arg flags this for idraw as an ellipse, not a circle */
381
_p_fellipse_internal (R___(_plotter) x, y, rx, ry, angle, false);
394
_pl_p_fellipse_internal (R___(_plotter) x, y, rx, ry, angle, false);
403
/* ARGS: circlep = drawn as a circle in user frame? */
392
_p_fellipse_internal (R___(Plotter *_plotter) double x, double y, double rx, double ry, double angle, bool circlep)
394
_p_fellipse_internal (R___(_plotter) x, y, rx, ry, angle, circlep)
395
S___(Plotter *_plotter;)
396
double x, y, rx, ry, angle;
397
bool circlep; /* drawn as a circle in user frame? */
405
_pl_p_fellipse_internal (R___(Plotter *_plotter) double x, double y, double rx, double ry, double angle, bool circlep)
400
407
if (_plotter->drawstate->pen_type || _plotter->drawstate->fill_type)
401
408
/* have something to draw */
416
423
/* emit common attributes: CTM, fill rule, cap and join styles and
417
424
miter limit, dash array, foreground and background colors, and
419
granularity = _p_emit_common_attributes (S___(_plotter));
426
granularity = _pl_p_emit_common_attributes (S___(_plotter));
421
428
/* An affine tranformation must be applied to the ellipse produced by
422
429
the Elli routine in the idraw prologue, to turn it into the
502
509
coordinates. The CTM emitted here will automatically compensate for the
503
510
granularity factor.
505
Note: some of the functions that call this one (see _p_paint_path()
512
Note: some of the functions that call this one (see _pl_p_paint_path()
506
513
above) need to compute the granularity themselves, since they can't need
507
514
to quit if the granularity is zero, without calling this function . */
511
_p_emit_common_attributes (S___(Plotter *_plotter))
513
_p_emit_common_attributes (S___(_plotter))
514
S___(Plotter *_plotter;)
517
_pl_p_emit_common_attributes (S___(Plotter *_plotter))
517
519
bool singular_map;
576
578
/* specify cap style and join style, and miter limit if mitering */
577
if (_plotter->drawstate->join_type == JOIN_MITER)
579
if (_plotter->drawstate->join_type == PL_JOIN_MITER)
578
580
sprintf (_plotter->data->page->point, "\
579
581
%d setlinecap %d setlinejoin %.4g setmiterlimit\n",
580
_ps_cap_style[_plotter->drawstate->cap_type],
581
_ps_join_style[_plotter->drawstate->join_type],
582
ps_cap_style[_plotter->drawstate->cap_type],
583
ps_join_style[_plotter->drawstate->join_type],
582
584
_plotter->drawstate->miter_limit);
584
586
sprintf (_plotter->data->page->point, "\
585
587
%d setlinecap %d setlinejoin\n",
586
_ps_cap_style[_plotter->drawstate->cap_type],
587
_ps_join_style[_plotter->drawstate->join_type]);
588
ps_cap_style[_plotter->drawstate->cap_type],
589
ps_join_style[_plotter->drawstate->join_type]);
588
590
_update_buffer (_plotter->data->page);
590
592
/* specify fill rule (i.e. whether to use even-odd filling) */
591
if (_plotter->drawstate->fill_rule_type == FILL_NONZERO_WINDING)
593
if (_plotter->drawstate->fill_rule_type == PL_FILL_NONZERO_WINDING)
592
594
sprintf (_plotter->data->page->point, "\
593
595
/eoFillRule false def\n");
616
618
num_dashes = _plotter->drawstate->dash_array_len;
617
619
if (num_dashes > 0)
618
dashbuf = (double *)_plot_xmalloc (num_dashes * sizeof(double));
620
dashbuf = (double *)_pl_xmalloc (num_dashes * sizeof(double));
620
622
dashbuf = NULL; /* solid line */
621
623
/* take the adjustment to the CTM into account */
653
655
/* idraw brush type (spec'd as bit vector) */
654
656
sprintf (_plotter->data->page->point, "\
656
_idraw_brush_pattern[_plotter->drawstate->line_type]);
658
idraw_brush_pattern[_plotter->drawstate->line_type]);
657
659
_update_buffer (_plotter->data->page);
659
if (_plotter->drawstate->line_type == L_SOLID)
661
if (_plotter->drawstate->line_type == PL_L_SOLID)
670
672
/* compute PS dash array for this line type */
672
_line_styles[_plotter->drawstate->line_type].dash_array;
674
_pl_g_line_styles[_plotter->drawstate->line_type].dash_array;
674
_line_styles[_plotter->drawstate->line_type].dash_array_len;
675
dashbuf = (double *)_plot_xmalloc (num_dashes * sizeof(double));
676
_pl_g_line_styles[_plotter->drawstate->line_type].dash_array_len;
677
dashbuf = (double *)_pl_xmalloc (num_dashes * sizeof(double));
677
679
/* scale the array of integers by line width (actually by
678
680
floored line width) */
679
681
display_size_in_points =
680
682
DMIN(_plotter->data->xmax - _plotter->data->xmin,
681
683
_plotter->data->ymax - _plotter->data->ymin);
682
min_dash_unit = (MIN_DASH_UNIT_AS_FRACTION_OF_DISPLAY_SIZE
684
min_dash_unit = (PL_MIN_DASH_UNIT_AS_FRACTION_OF_DISPLAY_SIZE
683
685
* display_size_in_points);
684
686
scale = DMAX(min_dash_unit,
685
687
_plotter->drawstate->device_line_width);
721
723
/* idraw instruction: set foreground color */
722
_p_set_pen_color (S___(_plotter)); /* invoked lazily, when needed */
724
_pl_p_set_pen_color (S___(_plotter)); /* invoked lazily, when needed */
723
725
sprintf (_plotter->data->page->point, "\
725
727
%g %g %g SetCFg\n",
726
_idraw_stdcolornames[_plotter->drawstate->ps_idraw_fgcolor],
728
_pl_p_idraw_stdcolornames[_plotter->drawstate->ps_idraw_fgcolor],
727
729
_plotter->drawstate->ps_fgcolor_red,
728
730
_plotter->drawstate->ps_fgcolor_green,
729
731
_plotter->drawstate->ps_fgcolor_blue);
730
732
_update_buffer (_plotter->data->page);
732
734
/* idraw instruction: set background color */
733
_p_set_fill_color (S___(_plotter)); /* invoked lazily, when needed */
735
_pl_p_set_fill_color (S___(_plotter)); /* invoked lazily, when needed */
734
736
sprintf (_plotter->data->page->point, "\
736
738
%g %g %g SetCBg\n",
737
_idraw_stdcolornames[_plotter->drawstate->ps_idraw_bgcolor],
739
_pl_p_idraw_stdcolornames[_plotter->drawstate->ps_idraw_bgcolor],
738
740
_plotter->drawstate->ps_fillcolor_red,
739
741
_plotter->drawstate->ps_fillcolor_green,
740
742
_plotter->drawstate->ps_fillcolor_blue);
749
751
sprintf (_plotter->data->page->point, "\
752
_idraw_stdshadings[_plotter->drawstate->ps_idraw_shading]);
754
_pl_p_idraw_stdshadings[_plotter->drawstate->ps_idraw_shading]);
753
755
_update_buffer (_plotter->data->page);
755
757
/* return factor we'll later use to scale up user-frame coordinates */