1 // Demonstrate most pllegend capability including unicode symbols.
2 //
3 // Copyright (C) 2010 Alan Irwin
4 // Copyright (C) 2011 Andrew Ross
5 //
6 // This file is part of PLplot.
7 //
8 // PLplot is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU Library General Public License as published
10 // by the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // PLplot is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU Library General Public License
19 // along with PLplot; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 //
22 
23 // This example designed just for devices (e.g., the cairo-related and
24 // qt-related devices) where the best choice of glyph is automatically
25 // selected by the related libraries (pango/cairo or Qt4) for each
26 // unicode character depending on what system fonts are installed.  Of
27 // course, you must have the appropriate TrueType fonts installed to
28 // have access to all the required glyphs.
29 
30 #include "plc++demos.h"
31 
32 #ifdef PL_USE_NAMESPACE
33 using namespace std;
34 #endif
35 
36 #define COLORBAR_KINDS        4
37 #define COLORBAR_POSITIONS    4
38 #define COLORBAR_LABELS       4
39 #define COLORBAR_CAPS         4
40 
41 class x33 {
42 public:
43     x33( int, char ** );
44 
45 private:
46     // Class data
47     plstream           *pls;
48 
49     static const PLINT position_options[16];
50     static const char  *special_symbols[5];
51     static const PLINT colorbar_option_kinds[COLORBAR_KINDS];
52     static const char  *colorbar_option_kind_labels[COLORBAR_KINDS];
53     static const PLINT colorbar_position_options[COLORBAR_POSITIONS];
54     static const char  *colorbar_position_option_labels[COLORBAR_POSITIONS];
55     static const PLINT colorbar_label_options[COLORBAR_LABELS];
56     static const char  *colorbar_label_option_labels[COLORBAR_LABELS];
57     static const PLINT colorbar_cap_options[COLORBAR_CAPS];
58     static const char  *colorbar_cap_option_labels[COLORBAR_CAPS];
59 
60     void plcolorbar_example_page( int, int, int, PLINT, PLFLT, PLINT, PLFLT * );
61     void plcolorbar_example( const char *, int, PLINT, PLFLT, PLINT, PLFLT * );
62 
MIN(PLFLT x,PLFLT y)63     PLFLT MIN( PLFLT x, PLFLT y ) { return ( x < y ? x : y ); };
MAX(PLFLT x,PLFLT y)64     PLFLT MAX( PLFLT x, PLFLT y ) { return ( x > y ? x : y ); };
65 };
66 
67 const PLINT x33::position_options[16] = {
68     PL_POSITION_LEFT | PL_POSITION_TOP | PL_POSITION_OUTSIDE,
69     PL_POSITION_TOP | PL_POSITION_OUTSIDE,
70     PL_POSITION_RIGHT | PL_POSITION_TOP | PL_POSITION_OUTSIDE,
71     PL_POSITION_RIGHT | PL_POSITION_OUTSIDE,
72     PL_POSITION_RIGHT | PL_POSITION_BOTTOM | PL_POSITION_OUTSIDE,
73     PL_POSITION_BOTTOM | PL_POSITION_OUTSIDE,
74     PL_POSITION_LEFT | PL_POSITION_BOTTOM | PL_POSITION_OUTSIDE,
75     PL_POSITION_LEFT | PL_POSITION_OUTSIDE,
76     PL_POSITION_LEFT | PL_POSITION_TOP | PL_POSITION_INSIDE,
77     PL_POSITION_TOP | PL_POSITION_INSIDE,
78     PL_POSITION_RIGHT | PL_POSITION_TOP | PL_POSITION_INSIDE,
79     PL_POSITION_RIGHT | PL_POSITION_INSIDE,
80     PL_POSITION_RIGHT | PL_POSITION_BOTTOM | PL_POSITION_INSIDE,
81     PL_POSITION_BOTTOM | PL_POSITION_INSIDE,
82     PL_POSITION_LEFT | PL_POSITION_BOTTOM | PL_POSITION_INSIDE,
83     PL_POSITION_LEFT | PL_POSITION_INSIDE
84 };
85 
86 // Pick 5 arbitrary UTF-8 symbols useful for plotting points (✠✚✱✪✽✺✰✴✦).
87 const char *x33::special_symbols[5] = {
88     "✰",
89     "✴",
90     "✱",
91     "✽",
92     "✦"
93 };
94 
95 // plcolorbar options
96 
97 // Colorbar type options
98 const PLINT x33::colorbar_option_kinds[COLORBAR_KINDS] = {
99     PL_COLORBAR_SHADE,
100     PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL,
101     PL_COLORBAR_IMAGE,
102     PL_COLORBAR_GRADIENT
103 };
104 const char  *x33::colorbar_option_kind_labels[COLORBAR_KINDS] = {
105     "Shade colorbars",
106     "Shade colorbars with custom labels",
107     "Image colorbars",
108     "Gradient colorbars"
109 };
110 
111 // Which side of the page are we positioned relative to?
112 const PLINT x33::colorbar_position_options[COLORBAR_POSITIONS] = {
113     PL_POSITION_LEFT,
114     PL_POSITION_RIGHT,
115     PL_POSITION_TOP,
116     PL_POSITION_BOTTOM
117 };
118 const char  *x33::colorbar_position_option_labels[COLORBAR_POSITIONS] = {
119     "Left",
120     "Right",
121     "Top",
122     "Bottom"
123 };
124 
125 // Colorbar label positioning options
126 const PLINT x33::colorbar_label_options[COLORBAR_LABELS] = {
127     PL_COLORBAR_LABEL_LEFT,
128     PL_COLORBAR_LABEL_RIGHT,
129     PL_COLORBAR_LABEL_TOP,
130     PL_COLORBAR_LABEL_BOTTOM
131 };
132 const char  *x33::colorbar_label_option_labels[COLORBAR_LABELS] = {
133     "Label left",
134     "Label right",
135     "Label top",
136     "Label bottom"
137 };
138 
139 // Colorbar cap options
140 const PLINT x33::colorbar_cap_options[COLORBAR_CAPS] = {
141     PL_COLORBAR_CAP_NONE,
142     PL_COLORBAR_CAP_LOW,
143     PL_COLORBAR_CAP_HIGH,
144     PL_COLORBAR_CAP_LOW | PL_COLORBAR_CAP_HIGH
145 };
146 const char  *x33::colorbar_cap_option_labels[COLORBAR_CAPS] = {
147     "No caps",
148     "Low cap",
149     "High cap",
150     "Low and high caps"
151 };
152 
153 void
plcolorbar_example_page(int kind_i,int label_i,int cap_i,PLINT cont_color,PLFLT cont_width,PLINT n_values,PLFLT * values)154 x33::plcolorbar_example_page( int kind_i, int label_i, int cap_i, PLINT cont_color, PLFLT cont_width, PLINT n_values, PLFLT *values )
155 {
156     // Parameters for the colorbars on this page
157     PLINT      position_i, position, opt;
158     PLFLT      x, y, x_length, y_length;
159     PLFLT      ticks[1]     = { 0.0 };
160     PLINT      sub_ticks[1] = { 0 };
161     PLFLT      low_cap_color, high_cap_color;
162     PLINT      vertical, ifn;
163     PLINT      n_axes = 1;
164     const char *axis_opts[1];
165     PLINT      n_labels      = 1;
166     PLINT      label_opts[1] = { 0 };
167     char       *label;
168     char       title[200];
169     PLFLT      colorbar_width, colorbar_height;
170     PLINT      n_values_array[1];
171     PLFLT      *values_array[1];
172 
173     label = new char[200];
174 
175     n_values_array[0] = n_values;
176     values_array[0]   = values;
177 
178     low_cap_color  = 0.0;
179     high_cap_color = 1.0;
180 
181     // Start a new page
182     pls->adv( 0 );
183 
184     // Draw one colorbar relative to each side of the page
185     for ( position_i = 0; position_i < COLORBAR_POSITIONS; position_i++ )
186     {
187         position = colorbar_position_options[position_i];
188         opt      =
189             colorbar_option_kinds[kind_i] |
190             colorbar_label_options[label_i] |
191             colorbar_cap_options[cap_i];
192 
193         vertical = position & PL_POSITION_LEFT || position & PL_POSITION_RIGHT;
194         ifn      = position & PL_POSITION_LEFT || position & PL_POSITION_BOTTOM;
195 
196         // Set the offset position on the page
197         if ( vertical )
198         {
199             x        = 0.0;
200             y        = 0.0;
201             x_length = 0.05;
202             y_length = 0.5;
203         }
204         else
205         {
206             x        = 0.0;
207             y        = 0.0;
208             x_length = 0.5;
209             y_length = 0.05;
210         }
211 
212         // Set appropriate labelling options.
213         if ( ifn )
214         {
215             if ( cont_color == 0 || cont_width == 0. )
216             {
217                 axis_opts[0] = "uwtivn";
218                 //axis_opts[0] = "uwtin";
219             }
220             else
221             {
222                 axis_opts[0] = "uwxvn";
223                 //axis_opts[0] = "uwxn";
224             }
225         }
226         else
227         {
228             if ( cont_color == 0 || cont_width == 0. )
229             {
230                 axis_opts[0] = "uwtivm";
231                 //axis_opts[0] = "uwtim";
232             }
233             else
234             {
235                 axis_opts[0] = "uwxvm";
236                 //axis_opts[0] = "uwxm";
237             }
238         }
239 
240         sprintf( label, "%s, %s",
241             colorbar_position_option_labels[position_i],
242             colorbar_label_option_labels[label_i] );
243 
244         // Smaller text
245         pls->schr( 0.0, 0.75 );
246         // Small ticks on the vertical axis
247         pls->smaj( 0.0, 0.5 );
248         pls->smin( 0.0, 0.5 );
249 
250         pls->vpor( 0.20, 0.80, 0.20, 0.80 );
251         pls->wind( 0.0, 1.0, 0.0, 1.0 );
252         // Set interesting background colour.
253         pls->scol0a( 15, 0, 0, 0, 0.20 );
254         pls->colorbar( &colorbar_width, &colorbar_height,
255             opt | PL_COLORBAR_BOUNDING_BOX | PL_COLORBAR_BACKGROUND, position,
256             x, y, x_length, y_length,
257             15, 1, 1,
258             low_cap_color, high_cap_color,
259             cont_color, cont_width,
260             n_labels, label_opts, (const char **) &label,
261             n_axes, axis_opts,
262             ticks, sub_ticks,
263             n_values_array, (const PLFLT * const *) values_array );
264 
265         // Reset text and tick sizes
266         pls->schr( 0.0, 1.0 );
267         pls->smaj( 0.0, 1.0 );
268         pls->smin( 0.0, 1.0 );
269     }
270 
271     // Draw a page title
272     sprintf( title, "%s - %s",
273         colorbar_option_kind_labels[kind_i],
274         colorbar_cap_option_labels[cap_i] );
275     pls->vpor( 0.0, 1.0, 0.0, 1.0 );
276     pls->wind( 0.0, 1.0, 0.0, 1.0 );
277     pls->ptex( 0.5, 0.5, 0.0, 0.0, 0.5, title );
278 
279     delete [] label;
280 }
281 
282 void
plcolorbar_example(const char * palette,int kind_i,PLINT cont_color,PLFLT cont_width,PLINT n_values,PLFLT * values)283 x33::plcolorbar_example( const char *palette, int kind_i, PLINT cont_color, PLFLT cont_width, PLINT n_values, PLFLT *values )
284 {
285     int label_i, cap_i;
286 
287     // Load the color palette
288     pls->spal1( palette, 1 );
289 
290     for ( label_i = 0; label_i < COLORBAR_LABELS; label_i++ )
291     {
292         for ( cap_i = 0; cap_i < COLORBAR_CAPS; cap_i++ )
293         {
294             plcolorbar_example_page( kind_i, label_i, cap_i,
295                 cont_color, cont_width,
296                 n_values, values );
297         }
298     }
299 }
300 
301 //--------------------------------------------------------------------------
302 // x33
303 //
304 // Demonstrate most pllegend capability including unicode symbols.
305 //--------------------------------------------------------------------------
306 
307 #define MAX_NLEGEND    7
308 
x33(int argc,char ** argv)309 x33::x33( int argc, char **argv )
310 {
311     int        i, k;
312     PLINT      opt;
313     PLINT      nlegend, nturn;
314     PLINT      opt_array[MAX_NLEGEND];
315     PLINT      text_colors[MAX_NLEGEND];
316     PLINT      box_colors[MAX_NLEGEND];
317     PLINT      box_patterns[MAX_NLEGEND];
318     PLFLT      box_scales[MAX_NLEGEND];
319     PLFLT      box_line_widths[MAX_NLEGEND];
320     PLINT      line_colors[MAX_NLEGEND];
321     PLINT      line_styles[MAX_NLEGEND];
322     PLFLT      line_widths[MAX_NLEGEND];
323     PLINT      symbol_numbers[MAX_NLEGEND], symbol_colors[MAX_NLEGEND];
324     PLFLT      symbol_scales[MAX_NLEGEND];
325     char       *text[MAX_NLEGEND];
326     const char *symbols[MAX_NLEGEND];
327     PLFLT      legend_width, legend_height, x, y, xstart, ystart;
328     PLFLT      max_height, text_scale;
329     PLINT      position, opt_base, nrow, ncolumn;
330 
331     pls = new plstream();
332 
333     // Create space to contain legend text.
334     for ( k = 0; k < MAX_NLEGEND; k++ )
335         text[k] = new char[200];
336 
337     // Parse and process command line arguments
338     pls->parseopts( &argc, argv, PL_PARSE_FULL );
339 
340     // Initialize plplot
341     pls->init();
342 
343     // First page illustrating the 16 standard positions.
344     pls->adv( 0 );
345     pls->vpor( 0.25, 0.75, 0.25, 0.75 );
346     pls->wind( 0.0, 1.0, 0.0, 1.0 );
347     pls->box( "bc", 0.0, 0, "bc", 0.0, 0 );
348     pls->sfont( PL_FCI_SANS, -1, -1 );
349     pls->mtex( "t", 8.0, 0.5, 0.5, "The 16 standard legend positions with" );
350     pls->mtex( "t", 6.0, 0.5, 0.5, "the same (0.05) offset in x and y" );
351 
352     nlegend = 1;
353     // Only specify legend data that are required according to the
354     // value of opt_array for that entry.
355     opt_base          = PL_LEGEND_BACKGROUND | PL_LEGEND_BOUNDING_BOX;
356     opt_array[0]      = PL_LEGEND_LINE | PL_LEGEND_SYMBOL;
357     line_styles[0]    = 1;
358     line_widths[0]    = 1.0;
359     symbol_scales[0]  = 1.;
360     symbol_numbers[0] = 4;
361     symbols[0]        = "#(728)";
362 
363     // Use monotype fonts so that all legends are the same size.
364     pls->sfont( PL_FCI_MONO, -1, -1 );
365     pls->scol0a( 15, 32, 32, 32, 0.70 );
366 
367     for ( k = 0; k < 16; k++ )
368     {
369         position = position_options[k];
370         opt      = opt_base;
371         sprintf( text[0], "%2.2d", k );
372         text_colors[0]   = 1 + ( k % 8 );
373         line_colors[0]   = 1 + ( k % 8 );
374         symbol_colors[0] = 1 + ( k % 8 );
375 
376         pls->legend( &legend_width, &legend_height, opt, position, 0.05, 0.05,
377             0.1, 15, 1, 1, 0, 0,
378             nlegend, opt_array, 1.0, 1.0, 2.0,
379             1., text_colors, (const char **) text,
380             NULL, NULL, NULL, NULL,
381             line_colors, line_styles, line_widths,
382             symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
383     }
384 
385     // Second page illustrating effect of nrow, ncolumn for the same legend
386     // data.;
387     pls->adv( 0 );
388     pls->vpor( 0.25, 0.75, 0.25, 0.75 );
389     pls->wind( 0.0, 1.0, 0.0, 1.0 );
390     pls->box( "bc", 0.0, 0, "bc", 0.0, 0 );
391     pls->sfont( PL_FCI_SANS, -1, -1 );
392     pls->mtex( "t", 8.0, 0.5, 0.5, "The effect of nrow, ncolumn, PL_LEGEND_ROW_MAJOR," );
393     pls->mtex( "t", 6.0, 0.5, 0.5, "and position for the same legend data" );
394 
395     nlegend = 7;
396 
397     // Only specify legend data that are required according to the
398     // value of opt_array for that entry.
399     opt_base = PL_LEGEND_BACKGROUND | PL_LEGEND_BOUNDING_BOX;
400     for ( k = 0; k < nlegend; k++ )
401     {
402         opt_array[k]      = PL_LEGEND_LINE | PL_LEGEND_SYMBOL;
403         line_styles[k]    = 1;
404         line_widths[k]    = 1.0;
405         symbol_scales[k]  = 1.;
406         symbol_numbers[k] = 2;
407         symbols[k]        = "#(728)";
408         sprintf( text[k], "%2.2d", k );
409         text_colors[k]   = 1 + ( k % 8 );
410         line_colors[k]   = 1 + ( k % 8 );
411         symbol_colors[k] = 1 + ( k % 8 );
412     }
413 
414     // Use monotype fonts so that all legends are the same size.
415     pls->sfont( PL_FCI_MONO, -1, -1 );
416     pls->scol0a( 15, 32, 32, 32, 0.70 );
417 
418     position = PL_POSITION_TOP | PL_POSITION_OUTSIDE;
419     opt      = opt_base;
420     x        = 0.;
421     y        = 0.1;
422     nrow     = 1;
423     ncolumn  = nlegend;
424     pls->legend( &legend_width, &legend_height, opt, position, x, y,
425         0.05, 15, 1, 1, nrow, ncolumn,
426         nlegend, opt_array, 1.0, 1.0, 2.0,
427         1., text_colors, (const char **) text,
428         NULL, NULL, NULL, NULL,
429         line_colors, line_styles, line_widths,
430         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
431 
432     position = PL_POSITION_BOTTOM | PL_POSITION_OUTSIDE;
433     opt      = opt_base;
434     x        = 0.;
435     y        = 0.1;
436     nrow     = 1;
437     ncolumn  = nlegend;
438     pls->legend( &legend_width, &legend_height, opt, position, x, y,
439         0.05, 15, 1, 1, nrow, ncolumn,
440         nlegend, opt_array, 1.0, 1.0, 2.0,
441         1., text_colors, (const char **) text,
442         NULL, NULL, NULL, NULL,
443         line_colors, line_styles, line_widths,
444         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
445 
446     position = PL_POSITION_LEFT | PL_POSITION_OUTSIDE;
447     opt      = opt_base;
448     x        = 0.1;
449     y        = 0.;
450     nrow     = nlegend;
451     ncolumn  = 1;
452     pls->legend( &legend_width, &legend_height, opt, position, x, y,
453         0.05, 15, 1, 1, nrow, ncolumn,
454         nlegend, opt_array, 1.0, 1.0, 2.0,
455         1., text_colors, (const char **) text,
456         NULL, NULL, NULL, NULL,
457         line_colors, line_styles, line_widths,
458         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
459 
460     position = PL_POSITION_RIGHT | PL_POSITION_OUTSIDE;
461     opt      = opt_base;
462     x        = 0.1;
463     y        = 0.;
464     nrow     = nlegend;
465     ncolumn  = 1;
466     pls->legend( &legend_width, &legend_height, opt, position, x, y,
467         0.05, 15, 1, 1, nrow, ncolumn,
468         nlegend, opt_array, 1.0, 1.0, 2.0,
469         1., text_colors, (const char **) text,
470         NULL, NULL, NULL, NULL,
471         line_colors, line_styles, line_widths,
472         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
473 
474     position = PL_POSITION_LEFT | PL_POSITION_TOP | PL_POSITION_INSIDE;
475     opt      = opt_base;
476     x        = 0.;
477     y        = 0.;
478     nrow     = 6;
479     ncolumn  = 2;
480     pls->legend( &legend_width, &legend_height, opt, position, x, y,
481         0.05, 15, 1, 1, nrow, ncolumn,
482         nlegend, opt_array, 1.0, 1.0, 2.0,
483         1., text_colors, (const char **) text,
484         NULL, NULL, NULL, NULL,
485         line_colors, line_styles, line_widths,
486         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
487 
488     position = PL_POSITION_RIGHT | PL_POSITION_TOP | PL_POSITION_INSIDE;
489     opt      = opt_base | PL_LEGEND_ROW_MAJOR;
490     x        = 0.;
491     y        = 0.;
492     nrow     = 6;
493     ncolumn  = 2;
494     pls->legend( &legend_width, &legend_height, opt, position, x, y,
495         0.05, 15, 1, 1, nrow, ncolumn,
496         nlegend, opt_array, 1.0, 1.0, 2.0,
497         1., text_colors, (const char **) text,
498         NULL, NULL, NULL, NULL,
499         line_colors, line_styles, line_widths,
500         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
501 
502     position = PL_POSITION_BOTTOM | PL_POSITION_INSIDE;
503     opt      = opt_base | PL_LEGEND_ROW_MAJOR;
504     x        = 0.;
505     y        = 0.;
506     nrow     = 3;
507     ncolumn  = 3;
508     pls->legend( &legend_width, &legend_height, opt, position, x, y,
509         0.05, 15, 1, 1, nrow, ncolumn,
510         nlegend, opt_array, 1.0, 1.0, 2.0,
511         1., text_colors, (const char **) text,
512         NULL, NULL, NULL, NULL,
513         line_colors, line_styles, line_widths,
514         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
515 
516     // Third page demonstrating legend alignment
517     pls->adv( 0 );
518     pls->vpor( 0.0, 1.0, 0.0, 0.9 );
519     pls->wind( 0.0, 1.0, 0.0, 1.0 );
520     pls->sfont( PL_FCI_SANS, -1, -1 );
521     pls->mtex( "t", 2.0, 0.5, 0.5, "Demonstrate legend alignment" );
522 
523     x        = 0.1;
524     y        = 0.1;
525     nturn    = 4;
526     nlegend  = 0;
527     position = PL_POSITION_TOP | PL_POSITION_LEFT | PL_POSITION_SUBPAGE;
528     opt_base = PL_LEGEND_BACKGROUND | PL_LEGEND_BOUNDING_BOX;
529     opt      = opt_base;
530     for ( i = 0; i < 9; i++ )
531     {
532         // Set up legend arrays with the correct size, type.
533         if ( i <= nturn )
534             nlegend += 1;
535         else
536             nlegend -= 1;
537         nlegend = MAX( 1, nlegend );
538         // nly specify legend data that are required according to the
539         //  value of opt_array for that entry.
540         for ( k = 0; k < nlegend; k++ )
541         {
542             opt_array[k]      = PL_LEGEND_LINE | PL_LEGEND_SYMBOL;
543             line_styles[k]    = 1;
544             line_widths[k]    = 1.0;
545             symbol_scales[k]  = 1.;
546             symbol_numbers[k] = 2;
547             symbols[k]        = "#(728)";
548             sprintf( text[k], "%2.2d", k );
549             text_colors[k]   = 1 + ( k % 8 );
550             line_colors[k]   = 1 + ( k % 8 );
551             symbol_colors[k] = 1 + ( k % 8 );
552         }
553         // Use monotype fonts so that all legends are the same size.
554         pls->sfont( PL_FCI_MONO, -1, -1 );
555         pls->scol0a( 15, 32, 32, 32, 0.70 );
556 
557         nrow    = MIN( 3, nlegend );
558         ncolumn = 0;
559 
560         pls->legend( &legend_width, &legend_height, opt, position, x, y,
561             0.025, 15, 1, 1, nrow, ncolumn,
562             nlegend, opt_array, 1.0, 1.0, 1.5,
563             1., text_colors, (const char **) text,
564             NULL, NULL, NULL, NULL,
565             line_colors, line_styles, line_widths,
566             symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
567 
568         if ( i == nturn )
569         {
570             position = PL_POSITION_TOP | PL_POSITION_RIGHT | PL_POSITION_SUBPAGE;
571             opt      = opt_base;
572             x        = 1. - x;
573             y       += legend_height;
574         }
575         else
576         {
577             x += legend_width;
578             y += legend_height;
579         }
580     }
581 
582     // Fourth page illustrating various kinds of legends
583     max_height = 0.;
584     xstart     = 0.0;
585     ystart     = 0.1;
586     x          = xstart;
587     y          = ystart;
588     text_scale = 0.90;
589     pls->adv( 0 );
590     pls->vpor( 0.0, 1., 0.0, 0.90 );
591     pls->wind( 0.0, 1.0, 0.0, 1.0 );
592     //plbox("bc", 0.0, 0, "bc", 0.0, 0);
593     pls->sfont( PL_FCI_SANS, -1, -1 );
594     pls->mtex( "t", 2.0, 0.5, 0.5, "Demonstrate Various Kinds of Legends" );
595 
596     nlegend = 5;
597     // Only specify legend data that are required according to the
598     // value of opt_array for that entry.
599     position = PL_POSITION_LEFT | PL_POSITION_TOP;
600     opt_base = PL_LEGEND_BACKGROUND | PL_LEGEND_BOUNDING_BOX | PL_LEGEND_TEXT_LEFT;
601 
602     // Set up None, Box, Line, Symbol, and Line & Symbol legend entries.
603     opt_array[0] = PL_LEGEND_NONE;
604     sprintf( text[0], "%s", "None" );
605     text_colors[0] = 1;
606 
607     opt_array[1] = PL_LEGEND_COLOR_BOX;
608     sprintf( text[1], "%s", "Box" );
609     text_colors[1]     = 2;
610     box_colors[1]      = 2;
611     box_patterns[1]    = 0;
612     box_scales[1]      = 0.8;
613     box_line_widths[1] = 1.0;
614 
615     opt_array[2] = PL_LEGEND_LINE;
616     sprintf( text[2], "%s", "Line" );
617     text_colors[2] = 3;
618     line_colors[2] = 3;
619     line_styles[2] = 1;
620     line_widths[2] = 1.0;
621 
622     opt_array[3] = PL_LEGEND_SYMBOL;
623     sprintf( text[3], "%s", "Symbol" );
624     text_colors[3]    = 4;
625     symbol_colors[3]  = 4;
626     symbol_scales[3]  = text_scale;
627     symbol_numbers[3] = 4;
628     symbols[3]        = special_symbols[2];
629 
630     opt_array[4] = PL_LEGEND_SYMBOL | PL_LEGEND_LINE;
631     sprintf( text[4], "%s", "L & S" );
632     text_colors[4]    = 5;
633     line_colors[4]    = 5;
634     line_styles[4]    = 1;
635     line_widths[4]    = 1.0;
636     symbol_colors[4]  = 5;
637     symbol_scales[4]  = text_scale;
638     symbol_numbers[4] = 4;
639     symbols[4]        = special_symbols[2];
640 
641     opt = opt_base;
642     pls->scol0a( 15, 32, 32, 32, 0.70 );
643 
644     pls->legend( &legend_width, &legend_height, opt, position, x, y,
645         0.1, 15, 1, 1, 0, 0,
646         nlegend, opt_array, 1.0, text_scale, 2.0,
647         0., text_colors, (const char **) text,
648         box_colors, box_patterns, box_scales, box_line_widths,
649         line_colors, line_styles, line_widths,
650         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
651     max_height = MAX( max_height, legend_height );
652 
653     // Set up symbol legend entries with various symbols.
654     for ( i = 0; i < nlegend; i++ )
655     {
656         opt_array[i] = PL_LEGEND_SYMBOL;
657         sprintf( text[i], "%s%s", "Symbol ", special_symbols[i] );
658         text_colors[i]    = i + 1;
659         symbol_colors[i]  = i + 1;
660         symbol_scales[i]  = text_scale;
661         symbol_numbers[i] = 4;
662         symbols[i]        = special_symbols[i];
663     }
664 
665     opt = opt_base;
666     x  += legend_width;
667     pls->scol0a( 15, 32, 32, 32, 0.70 );
668 
669     pls->legend( &legend_width, &legend_height, opt, position, x, y,
670         0.1, 15, 1, 1, 0, 0,
671         nlegend, opt_array, 1.0, text_scale, 2.0,
672         0., text_colors, (const char **) text,
673         NULL, NULL, NULL, NULL,
674         NULL, NULL, NULL,
675         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
676     max_height = MAX( max_height, legend_height );
677 
678     // Set up symbol legend entries with various numbers of symbols.
679     for ( i = 0; i < nlegend; i++ )
680     {
681         opt_array[i] = PL_LEGEND_SYMBOL;
682         sprintf( text[i], "%s %d", "Symbol Number", i + 2 );
683         text_colors[i]    = i + 1;
684         symbol_colors[i]  = i + 1;
685         symbol_scales[i]  = text_scale;
686         symbol_numbers[i] = i + 2;
687         symbols[i]        = special_symbols[2];
688     }
689 
690     opt = opt_base;
691     x  += legend_width;
692     pls->scol0a( 15, 32, 32, 32, 0.70 );
693 
694     pls->legend( &legend_width, &legend_height, opt, position, x, y,
695         0.1, 15, 1, 1, 0, 0,
696         nlegend, opt_array, 1.0, text_scale, 2.0,
697         0., text_colors, (const char **) text,
698         NULL, NULL, NULL, NULL,
699         NULL, NULL, NULL,
700         symbol_colors, symbol_scales, symbol_numbers, (const char **) symbols );
701     max_height = MAX( max_height, legend_height );
702 
703     // Set up box legend entries with various colours.
704     for ( i = 0; i < nlegend; i++ )
705     {
706         opt_array[i] = PL_LEGEND_COLOR_BOX;
707         sprintf( text[i], "%s %d", "Box Color", i + 1 );
708         text_colors[i]     = i + 1;
709         box_colors[i]      = i + 1;
710         box_patterns[i]    = 0;
711         box_scales[i]      = 0.8;
712         box_line_widths[i] = 1.0;
713     }
714 
715     opt = opt_base;
716     // Use new origin
717     x          = xstart;
718     y         += max_height;
719     max_height = 0.;
720     pls->scol0a( 15, 32, 32, 32, 0.70 );
721 
722     pls->legend( &legend_width, &legend_height, opt, position, x, y,
723         0.1, 15, 1, 1, 0, 0,
724         nlegend, opt_array, 1.0, text_scale, 2.0,
725         0., text_colors, (const char **) text,
726         box_colors, box_patterns, box_scales, box_line_widths,
727         NULL, NULL, NULL,
728         NULL, NULL, NULL, NULL );
729     max_height = MAX( max_height, legend_height );
730 
731     // Set up box legend entries with various patterns.
732     for ( i = 0; i < nlegend; i++ )
733     {
734         opt_array[i] = PL_LEGEND_COLOR_BOX;
735         sprintf( text[i], "%s %d", "Box Pattern", i );
736         text_colors[i]     = 2;
737         box_colors[i]      = 2;
738         box_patterns[i]    = i;
739         box_scales[i]      = 0.8;
740         box_line_widths[i] = 1.0;
741     }
742 
743     opt = opt_base;
744     x  += legend_width;
745     pls->scol0a( 15, 32, 32, 32, 0.70 );
746 
747     pls->legend( &legend_width, &legend_height, opt, position, x, y,
748         0.1, 15, 1, 1, 0, 0,
749         nlegend, opt_array, 1.0, text_scale, 2.0,
750         0., text_colors, (const char **) text,
751         box_colors, box_patterns, box_scales, box_line_widths,
752         NULL, NULL, NULL,
753         NULL, NULL, NULL, NULL );
754     max_height = MAX( max_height, legend_height );
755 
756     // Set up box legend entries with various box pattern line widths.
757     for ( i = 0; i < nlegend; i++ )
758     {
759         opt_array[i] = PL_LEGEND_COLOR_BOX;
760         sprintf( text[i], "%s %d", "Box Line Width", i + 1 );
761         text_colors[i]     = 2;
762         box_colors[i]      = 2;
763         box_patterns[i]    = 3;
764         box_scales[i]      = 0.8;
765         box_line_widths[i] = i + 1.0;
766     }
767 
768     opt = opt_base;
769     x  += legend_width;
770     pls->scol0a( 15, 32, 32, 32, 0.70 );
771 
772     pls->legend( &legend_width, &legend_height, opt, position, x, y,
773         0.1, 15, 1, 1, 0, 0,
774         nlegend, opt_array, 1.0, text_scale, 2.0,
775         0., text_colors, (const char **) text,
776         box_colors, box_patterns, box_scales, box_line_widths,
777         NULL, NULL, NULL,
778         NULL, NULL, NULL, NULL );
779     max_height = MAX( max_height, legend_height );
780 
781     // Set up line legend entries with various colours.
782     for ( i = 0; i < nlegend; i++ )
783     {
784         opt_array[i] = PL_LEGEND_LINE;
785         sprintf( text[i], "%s %d", "Line Color", i + 1 );
786         text_colors[i] = i + 1;
787         line_colors[i] = i + 1;
788         line_styles[i] = 1;
789         line_widths[i] = 1.0;
790     }
791 
792     opt = opt_base;
793     // Use new origin
794     x          = xstart;
795     y         += max_height;
796     max_height = 0.;
797     pls->scol0a( 15, 32, 32, 32, 0.70 );
798 
799     pls->legend( &legend_width, &legend_height, opt, position, x, y,
800         0.1, 15, 1, 1, 0, 0,
801         nlegend, opt_array, 1.0, text_scale, 2.0,
802         0., text_colors, (const char **) text,
803         NULL, NULL, NULL, NULL,
804         line_colors, line_styles, line_widths,
805         NULL, NULL, NULL, NULL );
806     max_height = MAX( max_height, legend_height );
807 
808     // Set up line legend entries with various styles.
809     for ( i = 0; i < nlegend; i++ )
810     {
811         opt_array[i] = PL_LEGEND_LINE;
812         sprintf( text[i], "%s %d", "Line Style", i + 1 );
813         text_colors[i] = 2;
814         line_colors[i] = 2;
815         line_styles[i] = i + 1;
816         line_widths[i] = 1.0;
817     }
818 
819     opt = opt_base;
820     x  += legend_width;
821     pls->scol0a( 15, 32, 32, 32, 0.70 );
822 
823     pls->legend( &legend_width, &legend_height, opt, position, x, y,
824         0.1, 15, 1, 1, 0, 0,
825         nlegend, opt_array, 1.0, text_scale, 2.0,
826         0., text_colors, (const char **) text,
827         NULL, NULL, NULL, NULL,
828         line_colors, line_styles, line_widths,
829         NULL, NULL, NULL, NULL );
830     max_height = MAX( max_height, legend_height );
831 
832     // Set up line legend entries with various widths.
833     for ( i = 0; i < nlegend; i++ )
834     {
835         opt_array[i] = PL_LEGEND_LINE;
836         sprintf( text[i], "%s %d", "Line Width", i + 1 );
837         text_colors[i] = 2;
838         line_colors[i] = 2;
839         line_styles[i] = 1;
840         line_widths[i] = i + 1.0;
841     }
842 
843     opt = opt_base;
844     x  += legend_width;
845     pls->scol0a( 15, 32, 32, 32, 0.70 );
846 
847     pls->legend( &legend_width, &legend_height, opt, position, x, y,
848         0.1, 15, 1, 1, 0, 0,
849         nlegend, opt_array, 1.0, text_scale, 2.0,
850         0., text_colors, (const char **) text,
851         NULL, NULL, NULL, NULL,
852         line_colors, line_styles, line_widths,
853         NULL, NULL, NULL, NULL );
854     max_height = MAX( max_height, legend_height );
855 
856 
857     // Free space that contained legend text.
858     for ( k = 0; k < MAX_NLEGEND; k++ )
859         delete [] text[k];
860 
861     // Color bar examples
862     PLFLT values_small[2]  = { -1.0e-20, 1.0e-20 };
863     PLFLT values_uneven[9] = { -1.0e-20, 2.0e-20, 2.6e-20, 3.4e-20, 6.0e-20, 7.0e-20, 8.0e-20, 9.0e-20, 10.0e-20 };
864     PLFLT values_even[9]   = { -2.0e-20, -1.0e-20, 0.0e-20, 1.0e-20, 2.0e-20, 3.0e-20, 4.0e-20, 5.0e-20, 6.0e-20 };
865 
866     // Use unsaturated green background colour to contrast with black caps.
867     pls->scolbg( 70, 185, 70 );
868     // Cut out the greatest and smallest bits of the color spectrum to
869     // leave colors for the end caps.
870     pls->scmap1_range( 0.01, 0.99 );
871 
872     // We can only test image and gradient colorbars with two element arrays
873     for ( i = 2; i < COLORBAR_KINDS; i++ )
874     {
875         plcolorbar_example( "cmap1_blue_yellow.pal", i, 0, 0, 2, values_small );
876     }
877     // Test shade colorbars with larger arrays
878     for ( i = 0; i < 2; i++ )
879     {
880         plcolorbar_example( "cmap1_blue_yellow.pal", i, 4, 2, 9, values_even );
881     }
882     for ( i = 0; i < 2; i++ )
883     {
884         plcolorbar_example( "cmap1_blue_yellow.pal", i, 0, 0, 9, values_uneven );
885     }
886 
887     //plend();
888     delete pls;
889 }
890 
main(int argc,char ** argv)891 int main( int argc, char ** argv )
892 {
893     x33 *x = new x33( argc, argv );
894 
895     delete x;
896 }
897