~ubuntu-branches/ubuntu/gutsy/plotutils/gutsy

« back to all changes in this revision

Viewing changes to libplot/s_path.c

  • Committer: Bazaar Package Importer
  • Author(s): Floris Bruynooghe
  • Date: 2007-05-10 19:48:54 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070510194854-mrr3lgwzpxd8hovo
Tags: 2.5-2
Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the GNU plotutils package.  Copyright (C) 1995,
 
2
   1996, 1997, 1998, 1999, 2000, 2005, Free Software Foundation, Inc.
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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. */
 
18
 
1
19
/* This file contains the internal paint_path() and paint_paths() methods,
2
20
   which the public method endpath() is a wrapper around. */
3
21
 
10
28
 
11
29
/* SVG join styles, i.e., stroke-linejoin attribute, indexed by internal
12
30
   number (miter/rd./bevel/triangular) */
13
 
static const char * _svg_join_style[] =
 
31
static const char * const svg_join_style[PL_NUM_JOIN_TYPES] =
14
32
{ "miter", "round", "bevel", "round" };
15
33
 
16
34
/* SVG cap styles, i.e., stroke-linecap attribute, indexed by internal
17
35
   number (butt/rd./project/triangular) */
18
 
static const char * _svg_cap_style[] =
 
36
static const char * const svg_cap_style[PL_NUM_CAP_TYPES] =
19
37
{ "butt", "round", "square", "round" };
20
38
 
21
39
/* SVG fill rule styles, i.e., fill-rule attribute, indexed by internal
22
40
   number (even-odd/nonzero winding number) */
23
 
static const char * _svg_fill_style[] =
 
41
static const char * const svg_fill_style[PL_NUM_FILL_RULES] =
24
42
{ "evenodd", "nonzero" };
25
43
 
26
 
static const double _identity_matrix[6] = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
 
44
static const double identity_matrix[6] = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
27
45
 
28
46
/* forward references */
29
 
static void _write_svg_path_data ____P((plOutbuf *page, const plPath *path));
30
 
static void _write_svg_path_style ____P((plOutbuf *page, const plDrawState *drawstate, bool need_cap, bool need_join));
 
47
static void write_svg_path_data (plOutbuf *page, const plPath *path);
 
48
static void write_svg_path_style (plOutbuf *page, const plDrawState *drawstate, bool need_cap, bool need_join);
31
49
 
32
50
void
33
 
#ifdef _HAVE_PROTOS
34
 
_s_paint_path (S___(Plotter *_plotter))
35
 
#else
36
 
_s_paint_path (S___(_plotter))
37
 
     S___(Plotter *_plotter;)
38
 
#endif
 
51
_pl_s_paint_path (S___(Plotter *_plotter))
39
52
{
40
53
  switch ((int)_plotter->drawstate->path->type)
41
54
    {
79
92
            sprintf (_plotter->data->page->point, "<line ");
80
93
            _update_buffer (_plotter->data->page);
81
94
 
82
 
            _s_set_matrix (R___(_plotter) 
83
 
                           _plotter->drawstate->transform.m_user_to_ndc,
84
 
                           _identity_matrix); 
 
95
            _pl_s_set_matrix (R___(_plotter) identity_matrix); 
85
96
 
86
97
            sprintf (_plotter->data->page->point,
87
98
                     "x1=\"%.5g\" y1=\"%.5g\" x2=\"%.5g\" y2=\"%.5g\" ",
91
102
                     _plotter->drawstate->path->segments[1].p.y);
92
103
            _update_buffer (_plotter->data->page);
93
104
 
94
 
            _write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
 
105
            write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
95
106
                                   true, false);
96
107
 
97
108
            sprintf (_plotter->data->page->point, "/>\n");
104
115
            sprintf (_plotter->data->page->point, "<polyline ");
105
116
            _update_buffer (_plotter->data->page);
106
117
 
107
 
            _s_set_matrix (R___(_plotter) 
108
 
                           _plotter->drawstate->transform.m_user_to_ndc,
109
 
                           _identity_matrix); 
 
118
            _pl_s_set_matrix (R___(_plotter) identity_matrix); 
110
119
 
111
120
            sprintf (_plotter->data->page->point,
112
121
                     "points=\"");
125
134
                     "\" ");
126
135
            _update_buffer (_plotter->data->page);
127
136
 
128
 
            _write_svg_path_style (_plotter->data->page, _plotter->drawstate,
 
137
            write_svg_path_style (_plotter->data->page, _plotter->drawstate,
129
138
                                   true, true);
130
139
 
131
140
            sprintf (_plotter->data->page->point,
139
148
            sprintf (_plotter->data->page->point, "<polygon ");
140
149
            _update_buffer (_plotter->data->page);
141
150
 
142
 
            _s_set_matrix (R___(_plotter) 
143
 
                           _plotter->drawstate->transform.m_user_to_ndc,
144
 
                           _identity_matrix); 
 
151
            _pl_s_set_matrix (R___(_plotter) identity_matrix); 
145
152
 
146
153
            sprintf (_plotter->data->page->point,
147
154
                     "points=\"");
160
167
                     "\" ");
161
168
            _update_buffer (_plotter->data->page);
162
169
 
163
 
            _write_svg_path_style (_plotter->data->page, _plotter->drawstate,
 
170
            write_svg_path_style (_plotter->data->page, _plotter->drawstate,
164
171
                                   false, true);
165
172
 
166
173
            sprintf (_plotter->data->page->point,
174
181
            sprintf (_plotter->data->page->point, "<path ");
175
182
            _update_buffer (_plotter->data->page);
176
183
 
177
 
            _s_set_matrix (R___(_plotter) 
178
 
                           _plotter->drawstate->transform.m_user_to_ndc,
179
 
                           _identity_matrix); 
 
184
            _pl_s_set_matrix (R___(_plotter) identity_matrix); 
180
185
 
181
186
            sprintf (_plotter->data->page->point,
182
187
                     "d=\"");
183
188
            _update_buffer (_plotter->data->page);
184
189
            
185
190
            /* write SVG path data string */
186
 
            _write_svg_path_data (_plotter->data->page, 
 
191
            write_svg_path_data (_plotter->data->page, 
187
192
                                  _plotter->drawstate->path);
188
193
 
189
194
            sprintf (_plotter->data->page->point,
190
195
                     "\" ");
191
196
            _update_buffer (_plotter->data->page);
192
197
 
193
 
            _write_svg_path_style (_plotter->data->page, _plotter->drawstate,
 
198
            write_svg_path_style (_plotter->data->page, _plotter->drawstate,
194
199
                                   true, true);
195
200
 
196
201
            sprintf (_plotter->data->page->point,
215
220
        sprintf (_plotter->data->page->point, "<rect ");
216
221
        _update_buffer (_plotter->data->page);
217
222
 
218
 
        _s_set_matrix (R___(_plotter) 
219
 
                       _plotter->drawstate->transform.m_user_to_ndc,
220
 
                       _identity_matrix); 
 
223
        _pl_s_set_matrix (R___(_plotter) identity_matrix); 
221
224
 
222
225
        sprintf (_plotter->data->page->point,
223
226
                 "x=\"%.5g\" y=\"%.5g\" width=\"%.5g\" height=\"%.5g\" ",
224
227
                 xmin, ymin, xmax - xmin, ymax - ymin);
225
228
        _update_buffer (_plotter->data->page);
226
229
 
227
 
        _write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
 
230
        write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
228
231
                               false, true);
229
232
        sprintf (_plotter->data->page->point,
230
233
                 "/>\n");
240
243
        sprintf (_plotter->data->page->point, "<circle ");
241
244
        _update_buffer (_plotter->data->page);
242
245
 
243
 
        _s_set_matrix (R___(_plotter) 
244
 
                       _plotter->drawstate->transform.m_user_to_ndc,
245
 
                       _identity_matrix); 
 
246
        _pl_s_set_matrix (R___(_plotter) identity_matrix); 
246
247
 
247
248
        pc = _plotter->drawstate->path->pc;
248
249
        sprintf (_plotter->data->page->point,
250
251
                 pc.x, pc.y, radius);
251
252
        _update_buffer (_plotter->data->page);
252
253
 
253
 
        _write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
 
254
        write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
254
255
                               false, false);
255
256
 
256
257
        sprintf (_plotter->data->page->point,
277
278
        local_matrix[3] = cos (M_PI * angle / 180.0);
278
279
        local_matrix[4] = pc.x;
279
280
        local_matrix[5] = pc.y;
280
 
        _s_set_matrix (R___(_plotter) 
281
 
                       _plotter->drawstate->transform.m_user_to_ndc,
282
 
                       local_matrix);
 
281
        _pl_s_set_matrix (R___(_plotter) local_matrix);
283
282
 
284
283
        sprintf (_plotter->data->page->point, "rx=\"%.5g\" ry=\"%.5g\" ",
285
284
                 rx, ry);
286
285
        _update_buffer (_plotter->data->page);
287
286
 
288
 
        _write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
 
287
        write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
289
288
                               false, false);
290
289
 
291
290
        sprintf (_plotter->data->page->point, "/>\n");
299
298
}
300
299
 
301
300
bool
302
 
#ifdef _HAVE_PROTOS
303
 
_s_paint_paths (S___(Plotter *_plotter))
304
 
#else
305
 
_s_paint_paths (S___(_plotter))
306
 
     S___(Plotter *_plotter;)
307
 
#endif
 
301
_pl_s_paint_paths (S___(Plotter *_plotter))
308
302
{
309
303
  int i;
310
304
 
312
306
           "<path ");
313
307
  _update_buffer (_plotter->data->page);
314
308
  
315
 
  _s_set_matrix (R___(_plotter) 
316
 
                 _plotter->drawstate->transform.m_user_to_ndc,
317
 
                 _identity_matrix); 
 
309
  _pl_s_set_matrix (R___(_plotter) identity_matrix); 
318
310
 
319
311
  sprintf (_plotter->data->page->point,
320
312
           "d=\"");
328
320
        {
329
321
        case (int)PATH_SEGMENT_LIST:
330
322
          /* write SVG path data string */
331
 
          _write_svg_path_data (_plotter->data->page, path);
 
323
          write_svg_path_data (_plotter->data->page, path);
332
324
          break;
333
325
          
334
326
        case (int)PATH_CIRCLE:
452
444
           "\" ");
453
445
  _update_buffer (_plotter->data->page);
454
446
 
455
 
  _write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
 
447
  write_svg_path_style (_plotter->data->page, _plotter->drawstate, 
456
448
                         true, true);
457
449
 
458
450
  sprintf (_plotter->data->page->point,
467
459
   that consists of a single closed path primitive (box/circle/ellipse). */
468
460
 
469
461
static void
470
 
#ifdef _HAVE_PROTOS
471
 
_write_svg_path_data (plOutbuf *page, const plPath *path)
472
 
#else
473
 
_write_svg_path_data (page, path)
474
 
     plOutbuf *page;
475
 
     const plPath *path;
476
 
#endif
 
462
write_svg_path_data (plOutbuf *page, const plPath *path)
477
463
{
478
464
  bool closed;
479
465
  plPoint p, oldpoint;
623
609
}
624
610
 
625
611
static void
626
 
#ifdef _HAVE_PROTOS
627
 
_write_svg_path_style (plOutbuf *page, const plDrawState *drawstate, bool need_cap, bool need_join)
628
 
#else
629
 
_write_svg_path_style (page, drawstate, need_cap, need_join)
630
 
     plOutbuf *page; 
631
 
     const plDrawState *drawstate; 
632
 
     bool need_cap, need_join;
633
 
#endif
 
612
write_svg_path_style (plOutbuf *page, const plDrawState *drawstate, bool need_cap, bool need_join)
634
613
{
635
614
  char color_buf[8];            /* enough room for "#ffffff", incl. NUL */
636
615
 
637
 
  sprintf (page->point, "style=\"");
638
 
  _update_buffer (page);
639
 
 
640
616
  if (drawstate->pen_type)
641
617
    {
642
618
      if (drawstate->fgcolor.red != 0
644
620
          || drawstate->fgcolor.blue != 0)
645
621
        /* non-black, i.e. non-default */
646
622
        {
647
 
          sprintf (page->point, "stroke:%s;",
 
623
          sprintf (page->point, "stroke=\"%s\" ",
648
624
                   _libplot_color_to_svg_color (drawstate->fgcolor, 
649
625
                                                color_buf));
650
626
          _update_buffer (page);
651
627
        }
652
628
      
653
 
      sprintf (page->point, "stroke-width:%.5g;",
 
629
      /* should use `px' here to specify user units, per the SVG Authoring
 
630
         Guide, but ImageMagick objects to that */
 
631
      sprintf (page->point, "stroke-width=\"%.5g\" ",
654
632
               drawstate->line_width);
655
633
      _update_buffer (page);
656
634
      
657
635
      if (need_cap)
658
636
        {
659
 
          if (drawstate->cap_type != CAP_BUTT) /* i.e. not default */
 
637
          if (drawstate->cap_type != PL_CAP_BUTT) /* i.e. not default */
660
638
            {
661
 
              sprintf (page->point, "stroke-linecap:%s;",
662
 
                       _svg_cap_style[drawstate->cap_type]);
 
639
              sprintf (page->point, "stroke-linecap=\"%s\" ",
 
640
                       svg_cap_style[drawstate->cap_type]);
663
641
              _update_buffer (page);
664
642
            }
665
643
        }
666
644
      
667
645
      if (need_join)
668
646
        {
669
 
          if (drawstate->join_type != JOIN_MITER) /* i.e. not default */
 
647
          if (drawstate->join_type != PL_JOIN_MITER) /* i.e. not default */
670
648
            {
671
 
              sprintf (page->point, "stroke-linejoin:%s;",
672
 
                       _svg_join_style[drawstate->join_type]);
 
649
              sprintf (page->point, "stroke-linejoin=\"%s\" ",
 
650
                       svg_join_style[drawstate->join_type]);
673
651
              _update_buffer (page);
674
652
            }
675
653
          
676
 
          if (drawstate->join_type == JOIN_MITER
677
 
              && drawstate->miter_limit != DEFAULT_MITER_LIMIT)
 
654
          if (drawstate->join_type == PL_JOIN_MITER
 
655
              && drawstate->miter_limit != PL_DEFAULT_MITER_LIMIT)
678
656
            {
679
 
              sprintf (page->point, "stroke-miterlimit:%.5g;",
 
657
              sprintf (page->point, "stroke-miterlimit=\"%.5g\" ",
680
658
                       drawstate->miter_limit);
681
659
              _update_buffer (page);
682
660
            }
686
664
           && drawstate->dash_array_len > 0)
687
665
          ||
688
666
          (drawstate->dash_array_in_effect == false
689
 
           && drawstate->line_type != L_SOLID)) /* non-solid builtin linetype*/
 
667
           && drawstate->line_type != PL_L_SOLID)) /* non-solid builtin linetype*/
690
668
        /* need to specify stroke-array, maybe stroke-offset too */
691
669
        {
692
670
          int i;
712
690
                                 &min_sing_val, &max_sing_val);
713
691
              if (max_sing_val != 0.0)
714
692
                min_width = 
715
 
                 DEFAULT_LINE_WIDTH_AS_FRACTION_OF_DISPLAY_SIZE / max_sing_val;
 
693
                 PL_DEFAULT_LINE_WIDTH_AS_FRACTION_OF_DISPLAY_SIZE / max_sing_val;
716
694
              else
717
695
                min_width = 0.0;
718
696
              scale = DMAX(drawstate->line_width, min_width);
720
698
              /* take normalized dash array (linemode-specific) from
721
699
                 internal table */
722
700
              dash_array = 
723
 
                _line_styles[drawstate->line_type].dash_array;
 
701
                _pl_g_line_styles[drawstate->line_type].dash_array;
724
702
              num_dashes =
725
 
                _line_styles[drawstate->line_type].dash_array_len;
726
 
              dashbuf = (double *)_plot_xmalloc (num_dashes * sizeof(double));
 
703
                _pl_g_line_styles[drawstate->line_type].dash_array_len;
 
704
              dashbuf = (double *)_pl_xmalloc (num_dashes * sizeof(double));
727
705
 
728
706
              /* scale length of each dash by current line width, unless
729
707
                 it's too small (see above computation) */
732
710
              offset = 0.0;     /* true for all builtin line types */
733
711
            }
734
712
 
735
 
          sprintf (page->point, "stroke-dasharray:");
 
713
          sprintf (page->point, "stroke-dasharray=\"");
736
714
          _update_buffer (page);
737
715
          for (i = 0; i < num_dashes; i++)
738
716
            {
739
717
              sprintf (page->point, "%.5g%s",
740
718
                       dashbuf[i],
741
 
                       i < num_dashes - 1 ? " " : ";");
 
719
                       i < num_dashes - 1 ? " " : "\"");
742
720
              _update_buffer (page);
743
721
            }
744
722
 
745
723
          if (offset != 0.0) /* not default */
746
724
            {
747
 
              sprintf (page->point, "stroke-dashoffset:%.5g;",
 
725
              /* should use `px' here to specify user units, per the SVG
 
726
                 Authoring Guide, but ImageMagick objects to that */
 
727
              sprintf (page->point, "stroke-dashoffset=\"%.5g\" ",
748
728
                       offset);
749
729
              _update_buffer (page);
750
730
            }
760
740
    }
761
741
  else
762
742
    {
763
 
      sprintf (page->point, "stroke:none;");
 
743
      sprintf (page->point, "stroke=\"none\" ");
764
744
      _update_buffer (page);
765
745
    }
766
746
 
767
747
  if (drawstate->fill_type)
768
748
    {
769
 
      sprintf (page->point, "fill:%s;",
 
749
      sprintf (page->point, "fill=\"%s\" ",
770
750
               _libplot_color_to_svg_color (drawstate->fillcolor, color_buf));
771
751
      _update_buffer (page);
772
752
 
773
 
      if (drawstate->fill_rule_type != FILL_ODD_WINDING) /* not default */
 
753
      if (drawstate->fill_rule_type != PL_FILL_ODD_WINDING) /* not default */
774
754
        {
775
 
          sprintf (page->point, "fill-rule:%s;",
776
 
                   _svg_fill_style[drawstate->fill_rule_type]);
 
755
          sprintf (page->point, "fill-rule=\"%s\" ",
 
756
                   svg_fill_style[drawstate->fill_rule_type]);
777
757
          _update_buffer (page);
778
758
        }
779
759
    }
780
 
  
781
 
  sprintf (page->point, "\"");
782
 
  _update_buffer (page);
783
760
}