00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00029 #include "plplotP.h"
00030
00031
00046
00047 static void plgvpsp( PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax )
00048 {
00049 if ( plsc->level < 1 )
00050 {
00051 plabort( "plgvpsp: Please call plinit first" );
00052 return;
00053 }
00054 if ( ( plsc->cursub <= 0 ) || ( plsc->cursub > ( plsc->nsubx * plsc->nsuby ) ) )
00055 {
00056 plabort( "plgvpsp: Please call pladv or plenv to go to a subpage" );
00057 return;
00058 }
00059 *p_xmin = ( plsc->vpdxmi - plsc->spdxmi ) / ( plsc->spdxma - plsc->spdxmi );
00060 *p_xmax = ( plsc->vpdxma - plsc->spdxmi ) / ( plsc->spdxma - plsc->spdxmi );
00061 *p_ymin = ( plsc->vpdymi - plsc->spdymi ) / ( plsc->spdyma - plsc->spdymi );
00062 *p_ymax = ( plsc->vpdyma - plsc->spdymi ) / ( plsc->spdyma - plsc->spdymi );
00063 }
00064
00065
00087
00088 static void legend_position( PLINT position, PLFLT legend_width, PLFLT legend_height,
00089 PLFLT *x_legend_position, PLFLT *y_legend_position,
00090 PLFLT *xsign, PLFLT *ysign )
00091 {
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 PLFLT xorigin, yorigin, xlegend, ylegend;
00103
00104 *xsign = 1.;
00105 *ysign = 1.;
00106 if ( position & PL_POSITION_RIGHT )
00107 {
00108 xorigin = 1.;
00109 if ( position & PL_POSITION_TOP )
00110 {
00111 yorigin = 1.;
00112 if ( position & PL_POSITION_INSIDE )
00113 {
00114 xlegend = -legend_width;
00115 ylegend = 0.;
00116 *xsign = -1.;
00117 *ysign = -1.;
00118 }
00119 else if ( position & PL_POSITION_OUTSIDE )
00120 {
00121 xlegend = 0.;
00122 ylegend = legend_height;
00123 }
00124 else
00125 {
00126 plexit( "legend_position: internal logic error 1" );
00127 }
00128 }
00129 else if ( !( position & PL_POSITION_TOP ) && !( position & PL_POSITION_BOTTOM ) )
00130 {
00131 yorigin = 0.5;
00132 ylegend = 0.5 * legend_height;
00133 if ( position & PL_POSITION_INSIDE )
00134 {
00135 xlegend = -legend_width;
00136 *xsign = -1.;
00137 }
00138 else if ( position & PL_POSITION_OUTSIDE )
00139 {
00140 xlegend = 0.;
00141 }
00142 else
00143 {
00144 plexit( "legend_position: internal logic error 2" );
00145 }
00146 }
00147 else if ( position & PL_POSITION_BOTTOM )
00148 {
00149 yorigin = 0.;
00150 if ( position & PL_POSITION_INSIDE )
00151 {
00152 xlegend = -legend_width;
00153 ylegend = legend_height;
00154 *xsign = -1.;
00155 }
00156 else if ( position & PL_POSITION_OUTSIDE )
00157 {
00158 xlegend = 0.;
00159 ylegend = 0.;
00160 *ysign = -1.;
00161 }
00162 else
00163 {
00164 plexit( "legend_position: internal logic error 3" );
00165 }
00166 }
00167 else
00168 {
00169 plexit( "legend_position: internal logic error 4" );
00170 }
00171 }
00172 else if ( !( position & PL_POSITION_RIGHT ) && !( position & PL_POSITION_LEFT ) )
00173 {
00174 xorigin = 0.5;
00175 xlegend = -0.5 * legend_width;
00176 if ( position & PL_POSITION_TOP )
00177 {
00178 yorigin = 1.;
00179 if ( position & PL_POSITION_INSIDE )
00180 {
00181 ylegend = 0.;
00182 *ysign = -1.;
00183 }
00184 else if ( position & PL_POSITION_OUTSIDE )
00185 {
00186 ylegend = legend_height;
00187 }
00188 else
00189 {
00190 plexit( "legend_position: internal logic error 5" );
00191 }
00192 }
00193 else if ( position & PL_POSITION_BOTTOM )
00194 {
00195 yorigin = 0.;
00196 if ( position & PL_POSITION_INSIDE )
00197 {
00198 ylegend = legend_height;
00199 }
00200 else if ( position & PL_POSITION_OUTSIDE )
00201 {
00202 ylegend = 0.;
00203 *ysign = -1.;
00204 }
00205 else
00206 {
00207 plexit( "legend_position: internal logic error 6" );
00208 }
00209 }
00210 else
00211 {
00212 plexit( "legend_position: internal logic error 7" );
00213 }
00214 }
00215 else if ( position & PL_POSITION_LEFT )
00216 {
00217 xorigin = 0.;
00218 if ( position & PL_POSITION_TOP )
00219 {
00220 yorigin = 1.;
00221 if ( position & PL_POSITION_INSIDE )
00222 {
00223 xlegend = 0.;
00224 ylegend = 0.;
00225 *ysign = -1.;
00226 }
00227 else if ( position & PL_POSITION_OUTSIDE )
00228 {
00229 xlegend = -legend_width;
00230 ylegend = legend_height;
00231 *xsign = -1.;
00232 }
00233 else
00234 {
00235 plexit( "legend_position: internal logic error 8" );
00236 }
00237 }
00238 else if ( !( position & PL_POSITION_TOP ) && !( position & PL_POSITION_BOTTOM ) )
00239 {
00240 yorigin = 0.5;
00241 ylegend = 0.5 * legend_height;
00242 if ( position & PL_POSITION_INSIDE )
00243 {
00244 xlegend = 0.;
00245 }
00246 else if ( position & PL_POSITION_OUTSIDE )
00247 {
00248 xlegend = -legend_width;
00249 *xsign = -1.;
00250 }
00251 else
00252 {
00253 plexit( "legend_position: internal logic error 9" );
00254 }
00255 }
00256 else if ( position & PL_POSITION_BOTTOM )
00257 {
00258 yorigin = 0.;
00259 if ( position & PL_POSITION_INSIDE )
00260 {
00261 ylegend = legend_height;
00262 xlegend = 0.;
00263 }
00264 else if ( position & PL_POSITION_OUTSIDE )
00265 {
00266 xlegend = -legend_width;
00267 ylegend = 0.;
00268 *xsign = -1.;
00269 *ysign = -1.;
00270 }
00271 else
00272 {
00273 plexit( "legend_position: internal logic error 10" );
00274 }
00275 }
00276 else
00277 {
00278 plexit( "legend_position: internal logic error 11" );
00279 }
00280 }
00281 else
00282 {
00283 plexit( "legend_position: internal logic error 12" );
00284 }
00285 *x_legend_position = xorigin + xlegend;
00286 *y_legend_position = yorigin + ylegend;
00287 }
00288
00289
00295
00296 static void get_subpage_per_mm( PLFLT *x_subpage_per_mm, PLFLT *y_subpage_per_mm )
00297 {
00298
00299 PLFLT mxmin, mxmax, mymin, mymax;
00300 plgspa( &mxmin, &mxmax, &mymin, &mymax );
00301 *x_subpage_per_mm = 1. / ( mxmax - mxmin );
00302 *y_subpage_per_mm = 1. / ( mymax - mymin );
00303 }
00304
00305
00312
00313 static PLFLT get_character_or_symbol_height( PLBOOL ifcharacter )
00314 {
00315
00316 PLFLT default_mm, char_height_mm;
00317 PLFLT x_subpage_per_mm, y_subpage_per_mm;
00318
00319 if ( ifcharacter )
00320 {
00321 plgchr( &default_mm, &char_height_mm );
00322 }
00323 else
00324 {
00325 default_mm = plsc->symdef;
00326 char_height_mm = plsc->symht;
00327 }
00328 get_subpage_per_mm( &x_subpage_per_mm, &y_subpage_per_mm );
00329 return ( char_height_mm * y_subpage_per_mm );
00330 }
00331
00332
00344
00345 #define adopted_to_subpage_x( nx ) ( ( xdmin_adopted ) + ( nx ) * ( ( xdmax_adopted ) - ( xdmin_adopted ) ) )
00346
00347
00359
00360 #define subpage_to_adopted_x( nx ) ( ( nx - xdmin_adopted ) / ( ( xdmax_adopted ) - ( xdmin_adopted ) ) )
00361
00362
00374
00375 #define adopted_to_subpage_y( ny ) ( ( ydmin_adopted ) + ( ny ) * ( ( ydmax_adopted ) - ( ydmin_adopted ) ) )
00376
00377
00389
00390 #define subpage_to_adopted_y( ny ) ( ( ny - ydmin_adopted ) / ( ( ydmax_adopted ) - ( ydmin_adopted ) ) )
00391
00392
00526
00527 void
00528 c_pllegend( PLFLT *p_legend_width, PLFLT *p_legend_height,
00529 PLINT opt, PLINT position, PLFLT x, PLFLT y, PLFLT plot_width,
00530 PLINT bg_color, PLINT bb_color, PLINT bb_style,
00531 PLINT nrow, PLINT ncolumn,
00532 PLINT nlegend, const PLINT *opt_array,
00533 PLFLT text_offset, PLFLT text_scale, PLFLT text_spacing,
00534 PLFLT text_justification,
00535 const PLINT *text_colors, const char **text,
00536 const PLINT *box_colors, const PLINT *box_patterns,
00537 const PLFLT *box_scales, const PLINT *box_line_widths,
00538 const PLINT *line_colors, const PLINT *line_styles,
00539 const PLINT *line_widths,
00540 const PLINT *symbol_colors, const PLFLT *symbol_scales,
00541 const PLINT *symbol_numbers, const char **symbols )
00542
00543 {
00544
00545 PLFLT plot_x, plot_x_end, plot_x_subpage, plot_x_end_subpage;
00546 PLFLT plot_y, plot_y_subpage;
00547 PLFLT text_x, text_y, text_x_subpage, text_y_subpage;
00548
00549 PLFLT character_height, character_width, symbol_width;
00550
00551 PLFLT ty, xshift, drow, dcolumn;
00552
00553 PLFLT dxs, *xs, *ys, xl[2], yl[2], xbox[4], ybox[4];
00554 PLINT i, j;
00555
00556 PLINT col0_save = plsc->icol0,
00557 line_style_save = plsc->line_style,
00558 line_width_save = plsc->width,
00559 pattern_save = plsc->patt;
00560 PLFLT text_scale_save = plsc->chrht / plsc->chrdef;
00561
00562 PLFLT xwmin_save, xwmax_save, ywmin_save, ywmax_save;
00563
00564
00565 PLFLT xdmin_save, xdmax_save, ydmin_save, ydmax_save;
00566
00567
00568 PLFLT xdmin_adopted, xdmax_adopted, ydmin_adopted, ydmax_adopted;
00569
00570 PLFLT x_subpage_per_mm, y_subpage_per_mm, text_width0 = 0., text_width;
00571 PLFLT width_border, column_separation,
00572 legend_width, legend_height, legend_width_ac, legend_height_ac;
00573 PLFLT x_legend_position, y_legend_position, xsign, ysign;
00574
00575 PLINT some_boxes = 0, some_lines = 0, some_symbols = 0;
00576 PLINT max_symbol_numbers = 0;
00577 PLINT irow = 0, icolumn = 0;
00578
00579
00580 nrow = MAX( nrow, 1 );
00581 ncolumn = MAX( ncolumn, 1 );
00582 if ( nrow * ncolumn < nlegend )
00583 {
00584
00585 if ( ncolumn < nrow )
00586 ncolumn = ( nlegend % nrow ) ? ( nlegend / nrow ) + 1 : nlegend / nrow;
00587 else
00588 nrow = ( nlegend % ncolumn ) ? ( nlegend / ncolumn ) + 1 : nlegend / ncolumn;
00589 }
00590
00591
00592
00593 if ( !( position & PL_POSITION_RIGHT ) && !( position & PL_POSITION_LEFT ) && !( position & PL_POSITION_TOP ) && !( position & PL_POSITION_BOTTOM ) )
00594 {
00595 position = position | PL_POSITION_RIGHT | PL_POSITION_TOP;
00596 }
00597 else if ( ( position & PL_POSITION_RIGHT ) && ( position & PL_POSITION_LEFT ) )
00598 {
00599 plabort( "pllegend: PL_POSITION_RIGHT and PL_POSITION_LEFT cannot be simultaneously set." );
00600 return;
00601 }
00602
00603 else if ( ( position & PL_POSITION_TOP ) && ( position & PL_POSITION_BOTTOM ) )
00604 {
00605 plabort( "pllegend: PL_POSITION_TOP and PL_POSITION_BOTTOM cannot be simultaneously set." );
00606 return;
00607 }
00608
00609 if ( !( position & PL_POSITION_INSIDE ) && !( position & PL_POSITION_OUTSIDE ) )
00610 {
00611 position = position | PL_POSITION_INSIDE;
00612 }
00613 else if ( ( position & PL_POSITION_INSIDE ) && ( position & PL_POSITION_OUTSIDE ) )
00614 {
00615 plabort( "pllegend: PL_POSITION_INSIDE and PL_POSITION_OUTSIDE cannot be simultaneously set." );
00616 return;
00617 }
00618
00619 if ( !( position & PL_POSITION_VIEWPORT ) && !( position & PL_POSITION_SUBPAGE ) )
00620 {
00621 position = position | PL_POSITION_VIEWPORT;
00622 }
00623 else if ( ( position & PL_POSITION_VIEWPORT ) && ( position & PL_POSITION_SUBPAGE ) )
00624 {
00625 plabort( "pllegend: PL_POSITION_VIEWPORT and PL_POSITION_SUBPAGE cannot be simultaneously set." );
00626 return;
00627 }
00628
00629
00630
00631
00632 plgvpsp( &xdmin_save, &xdmax_save, &ydmin_save, &ydmax_save );
00633
00634
00635 if ( position & PL_POSITION_SUBPAGE )
00636 plvpor( 0., 1., 0., 1. );
00637
00638
00639
00640
00641
00642
00643
00644
00645 plgvpsp( &xdmin_adopted, &xdmax_adopted, &ydmin_adopted, &ydmax_adopted );
00646
00647
00648
00649 plgvpw( &xwmin_save, &xwmax_save, &ywmin_save, &ywmax_save );
00650
00651
00652
00653 plvpor( 0., 1., 0., 1. );
00654
00655
00656
00657 plwind( 0., 1., 0., 1. );
00658
00659 for ( i = 0; i < nlegend; i++ )
00660 {
00661 if ( opt_array[i] & PL_LEGEND_COLOR_BOX )
00662 some_boxes = 1;
00663 if ( opt_array[i] & PL_LEGEND_LINE )
00664 some_lines = 1;
00665 if ( opt_array[i] & PL_LEGEND_SYMBOL )
00666 {
00667 max_symbol_numbers = MAX( max_symbol_numbers, symbol_numbers[i] );
00668 some_symbols = 1;
00669 }
00670 }
00671
00672
00673 character_height = get_character_or_symbol_height( TRUE );
00674 character_width = character_height;
00675
00676
00677 plschr( 0., text_scale );
00678 for ( i = 0; i < nlegend; i++ )
00679 {
00680
00681 text_width0 = MAX( text_width0, plstrl( text[i] ) );
00682 }
00683 get_subpage_per_mm( &x_subpage_per_mm, &y_subpage_per_mm );
00684
00685
00686 text_width0 = x_subpage_per_mm * text_width0;
00687
00688
00689 text_width = text_width0 + text_offset * character_width;
00690
00691
00692
00693
00694 width_border = 0.4 * character_width;
00695
00696 column_separation = 2.0 * character_width;
00697
00698
00699 legend_width = 2. * width_border + ( ncolumn - 1 ) * column_separation +
00700 ncolumn * ( text_width +
00701 adopted_to_subpage_x( plot_width ) - adopted_to_subpage_x( 0. ) );
00702 legend_height = nrow * text_spacing * character_height;
00703
00704
00705
00706 legend_width_ac = subpage_to_adopted_x( legend_width ) - subpage_to_adopted_x( 0. );
00707 legend_height_ac = subpage_to_adopted_y( legend_height ) - subpage_to_adopted_y( 0. );
00708 *p_legend_width = legend_width_ac;
00709 *p_legend_height = legend_height_ac;
00710
00711
00712
00713 dcolumn = column_separation + text_width +
00714 adopted_to_subpage_x( plot_width ) - adopted_to_subpage_x( 0. );
00715 drow = text_spacing * character_height;
00716
00717 legend_position( position, legend_width_ac, legend_height_ac, &x_legend_position, &y_legend_position, &xsign, &ysign );
00718 plot_x = x * xsign + x_legend_position;
00719 plot_y = y * ysign + y_legend_position;
00720 plot_x_end = plot_x + plot_width;
00721
00722 plot_x_subpage = adopted_to_subpage_x( plot_x );
00723 plot_y_subpage = adopted_to_subpage_y( plot_y );
00724 plot_x_end_subpage = adopted_to_subpage_x( plot_x_end );
00725
00726
00727 text_x = plot_x_end;
00728 text_y = plot_y;
00729 text_x_subpage = adopted_to_subpage_x( text_x ) +
00730 text_offset * character_width;
00731 text_y_subpage = adopted_to_subpage_y( text_y );
00732
00733 if ( opt & PL_LEGEND_BACKGROUND )
00734 {
00735 PLFLT xbg[4] = {
00736 plot_x_subpage,
00737 plot_x_subpage,
00738 plot_x_subpage + legend_width,
00739 plot_x_subpage + legend_width,
00740 };
00741 PLFLT ybg[4] = {
00742 plot_y_subpage,
00743 plot_y_subpage - legend_height,
00744 plot_y_subpage - legend_height,
00745 plot_y_subpage,
00746 };
00747 plpsty( 0 );
00748 plcol0( bg_color );
00749 plfill( 4, xbg, ybg );
00750 plcol0( col0_save );
00751 }
00752
00753 if ( opt & PL_LEGEND_BOUNDING_BOX )
00754 {
00755 PLFLT xbb[5] = {
00756 plot_x_subpage,
00757 plot_x_subpage,
00758 plot_x_subpage + legend_width,
00759 plot_x_subpage + legend_width,
00760 plot_x_subpage,
00761 };
00762 PLFLT ybb[5] = {
00763 plot_y_subpage,
00764 plot_y_subpage - legend_height,
00765 plot_y_subpage - legend_height,
00766 plot_y_subpage,
00767 plot_y_subpage,
00768 };
00769 pllsty( bb_style );
00770 plcol0( bb_color );
00771 plline( 5, xbb, ybb );
00772 plcol0( col0_save );
00773 pllsty( line_style_save );
00774 }
00775
00776 if ( opt & PL_LEGEND_TEXT_LEFT )
00777 {
00778
00779 text_x_subpage = plot_x_subpage;
00780 plot_x_subpage += text_width;
00781 plot_x_end_subpage += text_width;
00782 }
00783
00784 plot_x_subpage += width_border;
00785 plot_x_end_subpage += width_border;
00786 text_x_subpage += width_border;
00787
00788 if ( some_symbols )
00789 {
00790 max_symbol_numbers = MAX( 2, max_symbol_numbers );
00791 if ( ( ( xs = (PLFLT *) malloc( max_symbol_numbers * sizeof ( PLFLT ) ) ) == NULL ) ||
00792 ( ( ys = (PLFLT *) malloc( max_symbol_numbers * sizeof ( PLFLT ) ) ) == NULL ) )
00793 {
00794 plexit( "pllegend: Insufficient memory" );
00795 }
00796
00797
00798
00799
00800
00801
00802 symbol_width = 0.5 * get_character_or_symbol_height( TRUE );
00803 }
00804
00805
00806 for ( i = 0; i < nlegend; i++ )
00807 {
00808
00809 ty = text_y_subpage - ( (double) irow + 0.5 ) * drow;
00810 xshift = (double) icolumn * dcolumn;
00811
00812 plcol0( text_colors[i] );
00813 plschr( 0., text_scale );
00814 plptex( text_x_subpage + xshift + text_justification * text_width0, ty, 0.1, 0.0, text_justification, text[i] );
00815
00816 if ( !( opt_array[i] & PL_LEGEND_NONE ) )
00817 {
00818 if ( opt_array[i] & PL_LEGEND_COLOR_BOX )
00819 {
00820 plcol0( box_colors[i] );
00821 plpsty( box_patterns[i] );
00822 plwid( box_line_widths[i] );
00823 xbox[0] = plot_x_subpage + xshift;
00824 xbox[1] = xbox[0];
00825 xbox[2] = plot_x_end_subpage + xshift;
00826 xbox[3] = xbox[2];
00827 ybox[0] = ty + 0.5 * drow * box_scales[i];
00828 ybox[1] = ty - 0.5 * drow * box_scales[i];
00829 ybox[2] = ty - 0.5 * drow * box_scales[i];
00830 ybox[3] = ty + 0.5 * drow * box_scales[i];
00831 plfill( 4, xbox, ybox );
00832 pllsty( line_style_save );
00833 plwid( line_width_save );
00834 }
00835 if ( opt_array[i] & PL_LEGEND_LINE )
00836 {
00837 plcol0( line_colors[i] );
00838 pllsty( line_styles[i] );
00839 plwid( line_widths[i] );
00840 xl[0] = plot_x_subpage + xshift;
00841 xl[1] = plot_x_end_subpage + xshift;
00842 yl[0] = ty;
00843 yl[1] = ty;
00844 plline( 2, xl, yl );
00845 pllsty( line_style_save );
00846 plwid( line_width_save );
00847 }
00848
00849 if ( opt_array[i] & PL_LEGEND_SYMBOL )
00850 {
00851 plcol0( symbol_colors[i] );
00852 plschr( 0., symbol_scales[i] );
00853 dxs = ( plot_x_end_subpage - plot_x_subpage - symbol_width ) / (double) ( MAX( symbol_numbers[i], 2 ) - 1 );
00854 for ( j = 0; j < symbol_numbers[i]; j++ )
00855 {
00856 xs[j] = plot_x_subpage + xshift +
00857 0.5 * symbol_width + dxs * (double) j;
00858 ys[j] = ty;
00859 }
00860 plstring( symbol_numbers[i], xs, ys, symbols[i] );
00861 }
00862 }
00863
00864
00865 if ( opt & PL_LEGEND_ROW_MAJOR )
00866 {
00867 icolumn++;
00868 if ( icolumn >= ncolumn )
00869 {
00870 icolumn = 0;
00871 irow++;
00872 }
00873 }
00874 else
00875 {
00876 irow++;
00877 if ( irow >= nrow )
00878 {
00879 irow = 0;
00880 icolumn++;
00881 }
00882 }
00883 }
00884 if ( some_symbols )
00885 {
00886 free( xs );
00887 free( ys );
00888 }
00889
00890
00891 plcol0( col0_save );
00892 plschr( 0., text_scale_save );
00893 plpsty( pattern_save );
00894 plvpor( xdmin_save, xdmax_save, ydmin_save, ydmax_save );
00895 plwind( xwmin_save, xwmax_save, ywmin_save, ywmax_save );
00896
00897 return;
00898 }
00899
00900
00907
00908 void
00909 static remove_characters( char *string, const char *characters )
00910 {
00911 size_t length = strlen( string );
00912 size_t prefix_length = strcspn( string, characters );
00913 if ( prefix_length < length )
00914 {
00915
00916
00917 memmove( string + prefix_length, string + prefix_length + 1, length - prefix_length );
00918
00919 remove_characters( string, characters );
00920 }
00921 }
00922
00923
00943
00944 void
00945 static draw_cap( PLBOOL if_edge, PLINT orientation, PLFLT xmin, PLFLT xmax,
00946 PLFLT ymin, PLFLT ymax, PLFLT color )
00947 {
00948
00949 PLINT col0_save = plsc->icol0;
00950 PLFLT xhalf = 0.5 * ( xmin + xmax );
00951 PLFLT yhalf = 0.5 * ( ymin + ymax );
00952
00953
00954
00955
00956 PLFLT xs[3];
00957 PLFLT ys[3];
00958
00959 if ( orientation == PL_COLORBAR_ORIENT_RIGHT )
00960 {
00961 xs[0] = xmin;
00962 ys[0] = ymin;
00963 xs[1] = xmax;
00964 ys[1] = yhalf;
00965 xs[2] = xmin;
00966 ys[2] = ymax;
00967 }
00968 else if ( orientation == PL_COLORBAR_ORIENT_TOP )
00969 {
00970 xs[0] = xmax;
00971 ys[0] = ymin;
00972 xs[1] = xhalf;
00973 ys[1] = ymax;
00974 xs[2] = xmin;
00975 ys[2] = ymin;
00976 }
00977 else if ( orientation == PL_COLORBAR_ORIENT_LEFT )
00978 {
00979 xs[0] = xmax;
00980 ys[0] = ymax;
00981 xs[1] = xmin;
00982 ys[1] = yhalf;
00983 xs[2] = xmax;
00984 ys[2] = ymin;
00985 }
00986 else if ( orientation == PL_COLORBAR_ORIENT_BOTTOM )
00987 {
00988 xs[0] = xmin;
00989 ys[0] = ymax;
00990 xs[1] = xhalf;
00991 ys[1] = ymin;
00992 xs[2] = xmax;
00993 ys[2] = ymax;
00994 }
00995 else
00996 {
00997 plexit( "draw_cap: internal error. Incorrect orientation" );
00998 }
00999
01000 plcol1( color );
01001 plfill( 3, xs, ys );
01002
01003 plcol0( col0_save );
01004
01005
01006 if ( if_edge )
01007 plline( 3, xs, ys );
01008 }
01009
01010
01032
01033 static void
01034 draw_box( PLBOOL if_bb, PLINT opt, const char *axis_opts, PLBOOL if_edge,
01035 PLFLT ticks, PLINT sub_ticks, PLINT n_values, const PLFLT *values )
01036 {
01037
01038 const char *edge_string;
01039 size_t length_axis_opts = strlen( axis_opts );
01040 char *local_axis_opts;
01041
01042
01043
01044 if ( ( local_axis_opts = (char *) malloc( ( length_axis_opts + 1 ) * sizeof ( char ) ) ) == NULL )
01045 {
01046 plexit( "draw_box: Insufficient memory" );
01047 }
01048 strcpy( local_axis_opts, axis_opts );
01049
01050 plsc->if_boxbb = if_bb;
01051
01052
01053
01054
01055
01056 if ( opt & PL_COLORBAR_SHADE && opt & PL_COLORBAR_SHADE_LABEL )
01057 {
01058 if ( opt & PL_COLORBAR_ORIENT_RIGHT || opt & PL_COLORBAR_ORIENT_LEFT )
01059 label_box_custom( local_axis_opts, n_values, values, "", 0, NULL );
01060 else
01061 label_box_custom( "", 0, NULL, local_axis_opts, n_values, values );
01062 if ( if_bb )
01063 {
01064 plsc->if_boxbb = FALSE;
01065 free( local_axis_opts );
01066 return;
01067 }
01068
01069
01070 remove_characters( local_axis_opts, "TtXx" );
01071 }
01072
01073
01074
01075 if ( if_edge )
01076 edge_string = "bc";
01077 else
01078 edge_string = "uw";
01079 if ( opt & PL_COLORBAR_ORIENT_TOP || opt & PL_COLORBAR_ORIENT_BOTTOM )
01080 {
01081 plbox( edge_string, 0.0, 0, local_axis_opts, ticks, sub_ticks );
01082 }
01083 else
01084 {
01085 plbox( local_axis_opts, ticks, sub_ticks, edge_string, 0.0, 0 );
01086 }
01087 plsc->if_boxbb = FALSE;
01088
01089 free( local_axis_opts );
01090 }
01091
01092
01111
01112 static void
01113 draw_label( PLBOOL if_bb, PLINT opt, const char *label )
01114 {
01115
01116 PLFLT just;
01117
01118
01119
01120 PLFLT label_offset = 1.2;
01121
01122
01123 #define max_opts 25
01124 char opt_label[max_opts];
01125 char perp;
01126
01127
01128 PLINT nlabel = 0;
01129
01130
01131 PLFLT aspspp = ( ( plsc->sppxma - plsc->sppxmi ) / plsc->xpmm ) /
01132 ( ( plsc->sppyma - plsc->sppymi ) / plsc->ypmm );
01133
01134
01135 PLFLT character_height_y = get_character_or_symbol_height( TRUE );
01136
01137
01138 PLFLT character_height_x = character_height_y / aspspp;
01139
01140
01141
01142 PLFLT spxpmm = plsc->xpmm / ( plsc->sppxma - plsc->sppxmi );
01143 PLFLT spypmm = plsc->ypmm / ( plsc->sppyma - plsc->sppymi );
01144 PLFLT label_length_mm = plstrl( label );
01145
01146 PLFLT parallel_height_mm, perpendicular_height_mm,
01147 default_mm, char_height_mm;
01148
01149 plgchr( &default_mm, &char_height_mm );
01150
01151
01152
01153 if ( opt & PL_COLORBAR_LABEL_RIGHT )
01154 {
01155 nlabel = 1;
01156 }
01157 if ( opt & PL_COLORBAR_LABEL_TOP )
01158 {
01159 if ( nlabel == 1 )
01160 opt = opt & ~PL_COLORBAR_LABEL_TOP;
01161 else
01162 nlabel = 1;
01163 }
01164 if ( opt & PL_COLORBAR_LABEL_LEFT )
01165 {
01166 if ( nlabel == 1 )
01167 opt = opt & ~PL_COLORBAR_LABEL_LEFT;
01168 else
01169 nlabel = 1;
01170 }
01171 if ( opt & PL_COLORBAR_LABEL_BOTTOM )
01172 {
01173 if ( nlabel == 1 )
01174 opt = opt & ~PL_COLORBAR_LABEL_BOTTOM;
01175 else
01176 nlabel = 1;
01177 }
01178
01179
01180
01181
01182 if ( if_bb )
01183 {
01184
01185
01186 plsc->boxbb_xmin = plsc->vppxmi / plsc->xpmm;
01187 plsc->boxbb_xmax = plsc->vppxma / plsc->xpmm;
01188 plsc->boxbb_ymin = plsc->vppymi / plsc->ypmm;
01189 plsc->boxbb_ymax = plsc->vppyma / plsc->ypmm;
01190
01191
01192
01193
01194
01195
01196 parallel_height_mm = ( label_offset + 0.8 ) * char_height_mm;
01197
01198
01199
01200
01201
01202
01203 perpendicular_height_mm = ( label_offset - 0.5 + 0.0 ) * char_height_mm;
01204 }
01205 if ( opt & PL_COLORBAR_LABEL_LEFT )
01206 {
01207 if ( opt & PL_COLORBAR_ORIENT_TOP || opt & PL_COLORBAR_ORIENT_BOTTOM )
01208 {
01209 perp = '\0';
01210 just = 0.5;
01211 if ( if_bb )
01212 {
01213 plsc->boxbb_xmin = MIN( plsc->boxbb_xmin, plsc->vppxmi /
01214 plsc->xpmm - parallel_height_mm );
01215 plsc->boxbb_ymin = MIN( plsc->boxbb_ymin,
01216 0.5 * ( plsc->vppymi + plsc->vppyma ) /
01217 plsc->ypmm - 0.5 * label_length_mm );
01218 plsc->boxbb_ymax = MAX( plsc->boxbb_ymax,
01219 0.5 * ( plsc->vppymi + plsc->vppyma ) /
01220 plsc->ypmm + 0.5 * label_length_mm );
01221 }
01222 }
01223 else
01224 {
01225 perp = 'v';
01226 just = 1.0;
01227 label_offset -= 0.5;
01228 if ( if_bb )
01229 {
01230 plsc->boxbb_xmin = MIN( plsc->boxbb_xmin, plsc->vppxmi /
01231 plsc->xpmm - perpendicular_height_mm - label_length_mm );
01232 }
01233 }
01234 snprintf( opt_label, max_opts, "l%c", perp );
01235 }
01236 else if ( opt & PL_COLORBAR_LABEL_RIGHT )
01237 {
01238 if ( opt & PL_COLORBAR_ORIENT_TOP || opt & PL_COLORBAR_ORIENT_BOTTOM )
01239 {
01240 perp = '\0';
01241 just = 0.5;
01242 if ( if_bb )
01243 {
01244 plsc->boxbb_xmax = MAX( plsc->boxbb_xmax, plsc->vppxma /
01245 plsc->xpmm + parallel_height_mm );
01246 plsc->boxbb_ymin = MIN( plsc->boxbb_ymin,
01247 0.5 * ( plsc->vppymi + plsc->vppyma ) /
01248 plsc->ypmm - 0.5 * label_length_mm );
01249 plsc->boxbb_ymax = MAX( plsc->boxbb_ymax,
01250 0.5 * ( plsc->vppymi + plsc->vppyma ) /
01251 plsc->ypmm + 0.5 * label_length_mm );
01252 }
01253 }
01254 else
01255 {
01256 perp = 'v';
01257 just = 0.0;
01258 label_offset -= 0.5;
01259 if ( if_bb )
01260 {
01261 plsc->boxbb_xmax = MAX( plsc->boxbb_xmax, plsc->vppxma /
01262 plsc->xpmm + perpendicular_height_mm + label_length_mm );
01263 }
01264 }
01265 snprintf( opt_label, max_opts, "r%c", perp );
01266 }
01267 else if ( opt & PL_COLORBAR_LABEL_TOP )
01268 {
01269 perp = '\0';
01270 just = 0.5;
01271 snprintf( opt_label, max_opts, "t%c", perp );
01272 if ( if_bb )
01273 {
01274 plsc->boxbb_ymax = MAX( plsc->boxbb_ymax, plsc->vppyma /
01275 plsc->ypmm + parallel_height_mm );
01276 plsc->boxbb_xmin = MIN( plsc->boxbb_xmin,
01277 0.5 * ( plsc->vppxmi + plsc->vppxma ) /
01278 plsc->xpmm - 0.5 * label_length_mm );
01279 plsc->boxbb_xmax = MAX( plsc->boxbb_xmax,
01280 0.5 * ( plsc->vppxmi + plsc->vppxma ) /
01281 plsc->xpmm + 0.5 * label_length_mm );
01282 }
01283 }
01284 else if ( opt & PL_COLORBAR_LABEL_BOTTOM )
01285 {
01286 perp = '\0';
01287 just = 0.5;
01288 snprintf( opt_label, max_opts, "b%c", perp );
01289 if ( if_bb )
01290 {
01291 plsc->boxbb_ymin = MIN( plsc->boxbb_ymin, plsc->vppymi /
01292 plsc->ypmm - parallel_height_mm );
01293 plsc->boxbb_xmin = MIN( plsc->boxbb_xmin,
01294 0.5 * ( plsc->vppxmi + plsc->vppxma ) /
01295 plsc->xpmm - 0.5 * label_length_mm );
01296 plsc->boxbb_xmax = MAX( plsc->boxbb_xmax,
01297 0.5 * ( plsc->vppxmi + plsc->vppxma ) /
01298 plsc->xpmm + 0.5 * label_length_mm );
01299 }
01300 }
01301 if ( !if_bb )
01302 plmtex( opt_label, label_offset, 0.5, just, label );
01303 }
01304
01305
01316
01317
01318
01319 static void
01320 calculate_limits( PLINT position, PLFLT x, PLFLT y,
01321 PLFLT xdmin_adopted, PLFLT xdmax_adopted, PLFLT ydmin_adopted, PLFLT ydmax_adopted,
01322 PLFLT prior_bb_height,
01323 PLFLT *p_colorbar_width_bb, PLFLT *p_colorbar_height_bb,
01324 PLFLT *p_colorbar_width_ac, PLFLT *p_colorbar_height_ac,
01325 PLFLT *p_plot_x_subpage_bb, PLFLT *p_plot_y_subpage_bb,
01326 PLFLT *p_dx_subpage, PLFLT *p_dy_subpage
01327 )
01328 {
01329 PLFLT x_colorbar_position, y_colorbar_position, xsign, ysign;
01330 PLFLT plot_x, plot_y;
01331
01332
01333 PLFLT spxpmm = plsc->xpmm / ( plsc->sppxma - plsc->sppxmi );
01334 PLFLT spypmm = plsc->ypmm / ( plsc->sppyma - plsc->sppymi );
01335
01336
01337 *p_colorbar_width_bb = ( plsc->boxbb_xmax - plsc->boxbb_xmin ) * spxpmm;
01338 *p_colorbar_height_bb = ( plsc->boxbb_ymax - plsc->boxbb_ymin ) * spypmm;
01339
01340
01341
01342
01343
01344 *p_dx_subpage = -plsc->boxbb_xmin * spxpmm;
01345 *p_dy_subpage = prior_bb_height - plsc->boxbb_ymax * spypmm;
01346
01347
01348
01349 *p_colorbar_width_ac = subpage_to_adopted_x( *p_colorbar_width_bb ) -
01350 subpage_to_adopted_x( 0. );
01351 *p_colorbar_height_ac = subpage_to_adopted_y( *p_colorbar_height_bb ) -
01352 subpage_to_adopted_y( 0. );
01353
01354
01355
01356
01357 legend_position( position, *p_colorbar_width_ac, *p_colorbar_height_ac, &x_colorbar_position, &y_colorbar_position, &xsign, &ysign );
01358 plot_x = x * xsign + x_colorbar_position;
01359 plot_y = y * ysign + y_colorbar_position;
01360
01361 *p_plot_x_subpage_bb = adopted_to_subpage_x( plot_x );
01362 *p_plot_y_subpage_bb = adopted_to_subpage_y( plot_y );
01363 }
01364
01365
01366
01449
01450 void
01451 c_plcolorbar( PLFLT *p_colorbar_width, PLFLT *p_colorbar_height,
01452 PLINT opt, PLINT position, PLFLT x, PLFLT y,
01453 PLFLT x_length, PLFLT y_length,
01454 PLINT bg_color, PLINT bb_color, PLINT bb_style,
01455 PLFLT low_cap_color, PLFLT high_cap_color,
01456 PLINT cont_color, PLINT cont_width,
01457 PLFLT ticks, PLINT sub_ticks,
01458 const char *axis_opts, const char *label,
01459 PLINT n_values, const PLFLT *values )
01460 {
01461
01462
01463
01464 PLFLT min_value, max_value, max_abs;
01465
01466
01467 PLFLT cap_extent, cap_extent_mm;
01468
01469
01470
01471
01472
01473
01474 PLFLT cap_angle = 45.;
01475
01476
01477
01478
01479 PLFLT cap_ratio = 0.5 / tan( PI / 360. * cap_angle );
01480
01481
01482 PLFLT aspspp = ( ( plsc->sppxma - plsc->sppxmi ) / plsc->xpmm ) /
01483 ( ( plsc->sppyma - plsc->sppymi ) / plsc->ypmm );
01484
01485
01486 PLFLT min_color, max_color;
01487
01488
01489 PLFLT xwmin_save, xwmax_save, ywmin_save, ywmax_save;
01490
01491
01492 PLFLT xdmin_save, xdmax_save, ydmin_save, ydmax_save;
01493
01494
01495
01496 PLFLT xdmin_adopted, xdmax_adopted, ydmin_adopted, ydmax_adopted;
01497
01498
01499 PLINT col0_save = plsc->icol0,
01500 line_style_save = plsc->line_style;
01501
01502
01503 PLFLT plot_x_subpage_bb, plot_y_subpage_bb;
01504
01505
01506
01507
01508
01509
01510 PLFLT colorbar_width, colorbar_height,
01511 colorbar_width_d, colorbar_height_d,
01512 colorbar_width_l, colorbar_height_l;
01513
01514
01515
01516
01517
01518 PLFLT colorbar_width_ac, colorbar_height_ac,
01519 colorbar_width_mm, colorbar_height_mm;
01520
01521
01522
01523
01524
01525 PLFLT dx_subpage_omd, dy_subpage_omd, dx_subpage_dml, dy_subpage_dml;
01526
01527
01528 PLFLT plot_x_subpage, plot_y_subpage;
01529
01530
01531 PLFLT vx_min, vx_max, vy_min, vy_max;
01532
01533
01534 PLFLT wx_min, wx_max, wy_min, wy_max;
01535
01536
01537 PLFLT **color_data;
01538
01539
01540 PLINT i, j, ni, nj, n_steps;
01541 PLFLT step_size;
01542
01543 PLBOOL if_edge;
01544
01545
01546
01547 PLFLT spxpmm = plsc->xpmm / ( plsc->sppxma - plsc->sppxmi );
01548 PLFLT spypmm = plsc->ypmm / ( plsc->sppyma - plsc->sppymi );
01549
01550
01551 PLFLT label_vpor_xmin, label_vpor_xmax, label_vpor_ymin, label_vpor_ymax;
01552
01553
01554 if ( !( position & PL_POSITION_RIGHT ) && !( position & PL_POSITION_LEFT ) && !( position & PL_POSITION_TOP ) && !( position & PL_POSITION_BOTTOM ) )
01555 {
01556 position = position | PL_POSITION_RIGHT;
01557 }
01558 else if ( ( position & PL_POSITION_RIGHT ) && ( position & PL_POSITION_LEFT ) )
01559 {
01560 plabort( "plcolorbar: PL_POSITION_RIGHT and PL_POSITION_LEFT cannot be simultaneously set." );
01561 return;
01562 }
01563
01564 else if ( ( position & PL_POSITION_TOP ) && ( position & PL_POSITION_BOTTOM ) )
01565 {
01566 plabort( "plcolorbar: PL_POSITION_TOP and PL_POSITION_BOTTOM cannot be simultaneously set." );
01567 return;
01568 }
01569
01570 if ( !( position & PL_POSITION_INSIDE ) && !( position & PL_POSITION_OUTSIDE ) )
01571 {
01572 position = position | PL_POSITION_OUTSIDE;
01573 }
01574 else if ( ( position & PL_POSITION_INSIDE ) && ( position & PL_POSITION_OUTSIDE ) )
01575 {
01576 plabort( "plcolorbar: PL_POSITION_INSIDE and PL_POSITION_OUTSIDE cannot be simultaneously set." );
01577 return;
01578 }
01579
01580 if ( !( position & PL_POSITION_VIEWPORT ) && !( position & PL_POSITION_SUBPAGE ) )
01581 {
01582 position = position | PL_POSITION_VIEWPORT;
01583 }
01584 else if ( ( position & PL_POSITION_VIEWPORT ) && ( position & PL_POSITION_SUBPAGE ) )
01585 {
01586 plabort( "plcolorbar: PL_POSITION_VIEWPORT and PL_POSITION_SUBPAGE cannot be simultaneously set." );
01587 return;
01588 }
01589
01590
01591
01592
01593 plgvpsp( &xdmin_save, &xdmax_save, &ydmin_save, &ydmax_save );
01594
01595
01596 if ( position & PL_POSITION_SUBPAGE )
01597 plvpor( 0., 1., 0., 1. );
01598
01599
01600
01601
01602
01603
01604
01605
01606 plgvpsp( &xdmin_adopted, &xdmax_adopted, &ydmin_adopted, &ydmax_adopted );
01607
01608
01609
01610 plgvpw( &xwmin_save, &xwmax_save, &ywmin_save, &ywmax_save );
01611
01612
01613 if ( !( opt & PL_COLORBAR_ORIENT_RIGHT ||
01614 opt & PL_COLORBAR_ORIENT_TOP ||
01615 opt & PL_COLORBAR_ORIENT_LEFT ||
01616 opt & PL_COLORBAR_ORIENT_BOTTOM ) )
01617 {
01618 if ( position & PL_POSITION_LEFT || position & PL_POSITION_RIGHT )
01619 opt = opt | PL_COLORBAR_ORIENT_TOP;
01620 else
01621 opt = opt | PL_COLORBAR_ORIENT_RIGHT;
01622 }
01623
01624 if_edge = plP_stsearch( axis_opts, 'b' ) &&
01625 !plP_stsearch( axis_opts, 'u' ) &&
01626 plP_stsearch( axis_opts, 'c' ) &&
01627 !plP_stsearch( axis_opts, 'w' );
01628
01629 min_value = values[0];
01630 max_value = values[ n_values - 1 ];
01631 max_abs = MAX( fabs( min_value ), fabs( max_value ) );
01632
01633
01634 plgcmap1_range( &min_color, &max_color );
01635
01636
01637
01638 colorbar_width = adopted_to_subpage_x( x_length ) -
01639 adopted_to_subpage_x( 0. );
01640 colorbar_height = adopted_to_subpage_y( y_length ) -
01641 adopted_to_subpage_y( 0. );
01642 colorbar_width_mm = colorbar_width / spxpmm;
01643 colorbar_height_mm = colorbar_height / spypmm;
01644
01645
01646 if ( opt & PL_COLORBAR_ORIENT_RIGHT || opt & PL_COLORBAR_ORIENT_LEFT )
01647 {
01648 cap_extent = cap_ratio * colorbar_height / aspspp;
01649 cap_extent_mm = cap_extent / spxpmm;
01650 }
01651 else
01652 {
01653 cap_extent = cap_ratio * colorbar_width * aspspp;
01654 cap_extent_mm = cap_extent / spypmm;
01655 }
01656
01657
01658
01659 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
01660 {
01661 wx_min = min_value;
01662 wx_max = max_value;
01663 wy_min = 0.0;
01664 wy_max = max_abs;
01665 }
01666 else if ( opt & PL_COLORBAR_ORIENT_TOP )
01667 {
01668 wx_min = 0.0;
01669 wx_max = max_abs;
01670 wy_min = min_value;
01671 wy_max = max_value;
01672 }
01673 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
01674 {
01675 wx_min = max_value;
01676 wx_max = min_value;
01677 wy_min = 0.0;
01678 wy_max = max_abs;
01679 }
01680 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
01681 {
01682 wx_min = 0.0;
01683 wx_max = max_abs;
01684 wy_min = max_value;
01685 wy_max = min_value;
01686 }
01687 else
01688 {
01689 plabort( "plcolorbar: Invalid PL_COLORBAR_ORIENT_* bits" );
01690 }
01691
01692
01693
01694
01695
01696 plvpor( 0., colorbar_width, 0., colorbar_height );
01697 plwind( wx_min, wx_max, wy_min, wy_max );
01698
01699
01700
01701 draw_box( TRUE, opt, axis_opts, if_edge,
01702 ticks, sub_ticks, n_values, values );
01703
01704 if ( opt & PL_COLORBAR_CAP_LOW )
01705 {
01706 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
01707 plsc->boxbb_xmin = MIN( plsc->boxbb_xmin, -cap_extent_mm );
01708 if ( opt & PL_COLORBAR_ORIENT_TOP )
01709 plsc->boxbb_ymin = MIN( plsc->boxbb_ymin, -cap_extent_mm );
01710 if ( opt & PL_COLORBAR_ORIENT_LEFT )
01711 plsc->boxbb_xmax = MAX( plsc->boxbb_xmax, colorbar_width_mm + cap_extent_mm );
01712 if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
01713 plsc->boxbb_ymax = MAX( plsc->boxbb_ymax, colorbar_height_mm + cap_extent_mm );
01714 }
01715 if ( opt & PL_COLORBAR_CAP_HIGH )
01716 {
01717 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
01718 plsc->boxbb_xmax = MAX( plsc->boxbb_xmax, colorbar_width_mm + cap_extent_mm );
01719 if ( opt & PL_COLORBAR_ORIENT_TOP )
01720 plsc->boxbb_ymax = MAX( plsc->boxbb_ymax, colorbar_height_mm + cap_extent_mm );
01721 if ( opt & PL_COLORBAR_ORIENT_LEFT )
01722 plsc->boxbb_xmin = MIN( plsc->boxbb_xmin, -cap_extent_mm );
01723 if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
01724 plsc->boxbb_ymin = MIN( plsc->boxbb_ymin, -cap_extent_mm );
01725 }
01726
01727
01728 calculate_limits( position, x, y,
01729 xdmin_adopted, xdmax_adopted, ydmin_adopted, ydmax_adopted,
01730 colorbar_height,
01731 &colorbar_width_d, &colorbar_height_d,
01732 &colorbar_width_ac, &colorbar_height_ac,
01733 &plot_x_subpage_bb, &plot_y_subpage_bb,
01734 &dx_subpage_omd, &dy_subpage_omd );
01735
01736
01737
01738
01739 plvpor( 0., colorbar_width_d, 0., colorbar_height_d );
01740
01741
01742 draw_label( TRUE, opt, label );
01743
01744
01745 calculate_limits( position, x, y,
01746 xdmin_adopted, xdmax_adopted, ydmin_adopted, ydmax_adopted,
01747 colorbar_height_d,
01748 &colorbar_width_l, &colorbar_height_l,
01749 &colorbar_width_ac, &colorbar_height_ac,
01750 &plot_x_subpage_bb, &plot_y_subpage_bb,
01751 &dx_subpage_dml, &dy_subpage_dml );
01752
01753
01754
01755 plot_x_subpage = plot_x_subpage_bb + dx_subpage_omd + dx_subpage_dml;
01756 plot_y_subpage = plot_y_subpage_bb + dy_subpage_omd + dy_subpage_dml;
01757
01758
01759 label_vpor_xmin = plot_x_subpage_bb + dx_subpage_dml;
01760 label_vpor_xmax = label_vpor_xmin + colorbar_width_d;
01761 label_vpor_ymax = plot_y_subpage_bb + dy_subpage_dml;
01762 label_vpor_ymin = label_vpor_ymax - colorbar_height_d;
01763
01764
01765
01766 *p_colorbar_width = colorbar_width_ac;
01767 *p_colorbar_height = colorbar_height_ac;
01768
01769
01770
01771 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
01772 {
01773 vx_min = plot_x_subpage;
01774 vx_max = plot_x_subpage + colorbar_width;
01775 vy_min = plot_y_subpage - colorbar_height;
01776 vy_max = plot_y_subpage;
01777 }
01778 else if ( opt & PL_COLORBAR_ORIENT_TOP )
01779 {
01780 vx_min = plot_x_subpage;
01781 vx_max = plot_x_subpage + colorbar_width;
01782 vy_min = plot_y_subpage - colorbar_height;
01783 vy_max = plot_y_subpage;
01784 }
01785 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
01786 {
01787 vx_min = plot_x_subpage;
01788 vx_max = plot_x_subpage + colorbar_width;
01789 vy_min = plot_y_subpage - colorbar_height;
01790 vy_max = plot_y_subpage;
01791 }
01792 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
01793 {
01794 vx_min = plot_x_subpage;
01795 vx_max = plot_x_subpage + colorbar_width;
01796 vy_min = plot_y_subpage - colorbar_height;
01797 vy_max = plot_y_subpage;
01798 }
01799 else
01800 {
01801 plabort( "plcolorbar: Invalid PL_COLORBAR_ORIENT_* bits" );
01802 }
01803
01804
01805 plvpor( 0., 1., 0., 1. );
01806 plwind( 0., 1., 0., 1. );
01807
01808 if ( opt & PL_COLORBAR_BACKGROUND )
01809 {
01810 PLFLT xbg[4] = {
01811 plot_x_subpage_bb,
01812 plot_x_subpage_bb,
01813 plot_x_subpage_bb + colorbar_width_l,
01814 plot_x_subpage_bb + colorbar_width_l,
01815 };
01816 PLFLT ybg[4] = {
01817 plot_y_subpage_bb,
01818 plot_y_subpage_bb - colorbar_height_l,
01819 plot_y_subpage_bb - colorbar_height_l,
01820 plot_y_subpage_bb,
01821 };
01822 plpsty( 0 );
01823 plcol0( bg_color );
01824 plfill( 4, xbg, ybg );
01825 plcol0( col0_save );
01826 }
01827
01828
01829 plvpor( vx_min, vx_max, vy_min, vy_max );
01830 plwind( wx_min, wx_max, wy_min, wy_max );
01831
01832
01833 if ( opt & PL_COLORBAR_IMAGE )
01834 {
01835
01836
01837
01838 if ( n_values == 2 )
01839 {
01840
01841
01842
01843 n_steps = plsc->ncol1;
01844 step_size = ( max_value - min_value ) / (PLFLT) n_steps;
01845 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
01846 {
01847 ni = n_steps;
01848 nj = 2;
01849 plAlloc2dGrid( &color_data, ni, nj );
01850 for ( i = 0; i < ni; i++ )
01851 {
01852 for ( j = 0; j < nj; j++ )
01853 {
01854 color_data[i][j] = min_value + (PLFLT) i * step_size;
01855 }
01856 }
01857 }
01858 else if ( opt & PL_COLORBAR_ORIENT_TOP )
01859 {
01860 ni = 2;
01861 nj = n_steps;
01862 plAlloc2dGrid( &color_data, ni, nj );
01863 for ( i = 0; i < ni; i++ )
01864 {
01865 for ( j = 0; j < nj; j++ )
01866 {
01867 color_data[i][j] = min_value + (PLFLT) j * step_size;
01868 }
01869 }
01870 }
01871 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
01872 {
01873 ni = n_steps;
01874 nj = 2;
01875 plAlloc2dGrid( &color_data, ni, nj );
01876 for ( i = 0; i < ni; i++ )
01877 {
01878 for ( j = 0; j < nj; j++ )
01879 {
01880 color_data[i][j] = max_value - (PLFLT) i * step_size;
01881 }
01882 }
01883 }
01884 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
01885 {
01886 ni = 2;
01887 nj = n_steps;
01888 plAlloc2dGrid( &color_data, ni, nj );
01889 for ( i = 0; i < ni; i++ )
01890 {
01891 for ( j = 0; j < nj; j++ )
01892 {
01893 color_data[i][j] = max_value - (PLFLT) j * step_size;
01894 }
01895 }
01896 }
01897 else
01898 {
01899 plabort( "plcolorbar: Invalid orientation bits" );
01900 }
01901 }
01902
01903 else
01904 {
01905 n_steps = n_values;
01906
01907 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
01908 {
01909 ni = n_steps;
01910 nj = 2;
01911 plAlloc2dGrid( &color_data, ni, nj );
01912 for ( i = 0; i < ni; i++ )
01913 {
01914 for ( j = 0; j < nj; j++ )
01915 {
01916 color_data[i][j] = values[i];
01917 }
01918 }
01919 }
01920 else if ( opt & PL_COLORBAR_ORIENT_TOP )
01921 {
01922 ni = 2;
01923 nj = n_steps;
01924 plAlloc2dGrid( &color_data, ni, nj );
01925 for ( i = 0; i < ni; i++ )
01926 {
01927 for ( j = 0; j < nj; j++ )
01928 {
01929 color_data[i][j] = values[j];
01930 }
01931 }
01932 }
01933 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
01934 {
01935 ni = n_steps;
01936 nj = 2;
01937 plAlloc2dGrid( &color_data, ni, nj );
01938 for ( i = 0; i < ni; i++ )
01939 {
01940 for ( j = 0; j < nj; j++ )
01941 {
01942 color_data[i][j] = values[ni - 1 - i];
01943 }
01944 }
01945 }
01946 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
01947 {
01948 ni = 2;
01949 nj = n_steps;
01950 plAlloc2dGrid( &color_data, ni, nj );
01951 for ( i = 0; i < ni; i++ )
01952 {
01953 for ( j = 0; j < nj; j++ )
01954 {
01955 color_data[i][j] = values[nj - 1 - j];
01956 }
01957 }
01958 }
01959 else
01960 {
01961 plabort( "plcolorbar: Invalid side" );
01962 }
01963 }
01964
01965 plimage( (const PLFLT **) color_data, ni, nj, wx_min, wx_max, wy_min, wy_max,
01966 min_value, max_value, wx_min, wx_max, wy_min, wy_max );
01967 plFree2dGrid( color_data, ni, nj );
01968 }
01969 else if ( opt & PL_COLORBAR_SHADE )
01970 {
01971
01972
01973
01974
01975
01976 PLcGrid grid;
01977 PLFLT grid_axis[2] = { 0.0, max_abs };
01978 n_steps = n_values;
01979
01980 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
01981 {
01982 grid.xg = (PLFLT *) values;
01983 grid.yg = grid_axis;
01984 grid.nx = n_steps;
01985 grid.ny = 2;
01986 ni = n_steps;
01987 nj = 2;
01988 plAlloc2dGrid( &color_data, ni, nj );
01989 for ( i = 0; i < ni; i++ )
01990 {
01991 for ( j = 0; j < nj; j++ )
01992 {
01993 color_data[i][j] = values[i];
01994 }
01995 }
01996 }
01997 else if ( opt & PL_COLORBAR_ORIENT_TOP )
01998 {
01999 grid.xg = grid_axis;
02000 grid.yg = (PLFLT *) values;
02001 grid.nx = 2;
02002 grid.ny = n_steps;
02003 ni = 2;
02004 nj = n_steps;
02005 plAlloc2dGrid( &color_data, ni, nj );
02006 for ( i = 0; i < ni; i++ )
02007 {
02008 for ( j = 0; j < nj; j++ )
02009 {
02010 color_data[i][j] = values[j];
02011 }
02012 }
02013 }
02014 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
02015 {
02016 grid.xg = (PLFLT *) values;
02017 grid.yg = grid_axis;
02018 grid.nx = n_steps;
02019 grid.ny = 2;
02020 ni = n_steps;
02021 nj = 2;
02022 plAlloc2dGrid( &color_data, ni, nj );
02023 for ( i = 0; i < ni; i++ )
02024 {
02025 for ( j = 0; j < nj; j++ )
02026 {
02027 color_data[i][j] = values[ni - 1 - i];
02028 }
02029 }
02030 }
02031 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
02032 {
02033 grid.xg = grid_axis;
02034 grid.yg = (PLFLT *) values;
02035 grid.nx = 2;
02036 grid.ny = n_steps;
02037 ni = 2;
02038 nj = n_steps;
02039 plAlloc2dGrid( &color_data, ni, nj );
02040 for ( i = 0; i < ni; i++ )
02041 {
02042 for ( j = 0; j < nj; j++ )
02043 {
02044 color_data[i][j] = values[nj - 1 - j];
02045 }
02046 }
02047 }
02048 else
02049 {
02050 plabort( "plcolorbar: Invalid orientation" );
02051 }
02052
02053
02054 plshades( (const PLFLT **) color_data, ni, nj, NULL, wx_min, wx_max, wy_min, wy_max,
02055 values, n_steps, 0, cont_color, cont_width, plfill, TRUE,
02056 pltr1, (void *) ( &grid ) );
02057 plFree2dGrid( color_data, ni, nj );
02058 }
02059 else if ( opt & PL_COLORBAR_GRADIENT )
02060 {
02061 PLFLT xs[4], ys[4];
02062 PLFLT angle;
02063 xs[0] = wx_min;
02064 ys[0] = wy_min;
02065 xs[1] = wx_max;
02066 ys[1] = wy_min;
02067 xs[2] = wx_max;
02068 ys[2] = wy_max;
02069 xs[3] = wx_min;
02070 ys[3] = wy_max;
02071
02072 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
02073 {
02074 angle = 0.0;
02075 }
02076 else if ( opt & PL_COLORBAR_ORIENT_TOP )
02077 {
02078 angle = 90.0;
02079 }
02080 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
02081 {
02082 angle = 180.0;
02083 }
02084 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
02085 {
02086 angle = 270.0;
02087 }
02088 else
02089 {
02090 plabort( "plcolorbar: Invalid orientation" );
02091 }
02092 plgradient( 4, xs, ys, angle );
02093 }
02094 else
02095 {
02096 plabort( "plcolorbar: One of PL_COLORBAR_IMAGE, PL_COLORBAR_SHADE, or PL_COLORBAR_GRADIENT bits must be set in opt" );
02097 }
02098
02099
02100 plcol0( col0_save );
02101
02102
02103
02104
02105 plvpor( 0., 1., 0., 1. );
02106 plwind( 0., 1., 0., 1. );
02107
02108 if ( opt & PL_COLORBAR_CAP_LOW )
02109 {
02110
02111 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
02112 draw_cap( if_edge, PL_COLORBAR_ORIENT_LEFT,
02113 plot_x_subpage - cap_extent, plot_x_subpage,
02114 plot_y_subpage - colorbar_height, plot_y_subpage,
02115 low_cap_color );
02116 else if ( opt & PL_COLORBAR_ORIENT_TOP )
02117 draw_cap( if_edge, PL_COLORBAR_ORIENT_BOTTOM,
02118 plot_x_subpage, plot_x_subpage + colorbar_width,
02119 plot_y_subpage - colorbar_height - cap_extent, plot_y_subpage - colorbar_height,
02120 low_cap_color );
02121 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
02122 draw_cap( if_edge, PL_COLORBAR_ORIENT_RIGHT,
02123 plot_x_subpage + colorbar_width, plot_x_subpage + colorbar_width + cap_extent,
02124 plot_y_subpage - colorbar_height, plot_y_subpage,
02125 low_cap_color );
02126 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
02127 draw_cap( if_edge, PL_COLORBAR_ORIENT_TOP,
02128 plot_x_subpage, plot_x_subpage + colorbar_width,
02129 plot_y_subpage, plot_y_subpage + cap_extent,
02130 low_cap_color );
02131 }
02132 if ( opt & PL_COLORBAR_CAP_HIGH )
02133 {
02134
02135 if ( opt & PL_COLORBAR_ORIENT_RIGHT )
02136 draw_cap( if_edge, PL_COLORBAR_ORIENT_RIGHT,
02137 plot_x_subpage + colorbar_width, plot_x_subpage + colorbar_width + cap_extent,
02138 plot_y_subpage - colorbar_height, plot_y_subpage,
02139 high_cap_color );
02140 else if ( opt & PL_COLORBAR_ORIENT_TOP )
02141 draw_cap( if_edge, PL_COLORBAR_ORIENT_TOP,
02142 plot_x_subpage, plot_x_subpage + colorbar_width,
02143 plot_y_subpage, plot_y_subpage + cap_extent,
02144 high_cap_color );
02145 else if ( opt & PL_COLORBAR_ORIENT_LEFT )
02146 draw_cap( if_edge, PL_COLORBAR_ORIENT_LEFT,
02147 plot_x_subpage - cap_extent, plot_x_subpage,
02148 plot_y_subpage - colorbar_height, plot_y_subpage,
02149 high_cap_color );
02150 else if ( opt & PL_COLORBAR_ORIENT_BOTTOM )
02151 draw_cap( if_edge, PL_COLORBAR_ORIENT_BOTTOM,
02152 plot_x_subpage, plot_x_subpage + colorbar_width,
02153 plot_y_subpage - colorbar_height - cap_extent, plot_y_subpage - colorbar_height,
02154 high_cap_color );
02155 }
02156
02157
02158 plvpor( vx_min, vx_max, vy_min, vy_max );
02159 plwind( wx_min, wx_max, wy_min, wy_max );
02160
02161
02162
02163 draw_box( FALSE, opt, axis_opts, if_edge,
02164 ticks, sub_ticks, n_values, values );
02165
02166
02167 plvpor( 0., 1., 0., 1. );
02168 plwind( 0., 1., 0., 1. );
02169
02170 if ( opt & PL_COLORBAR_BOUNDING_BOX )
02171 {
02172 PLFLT xbb[5] = {
02173 plot_x_subpage_bb,
02174 plot_x_subpage_bb,
02175 plot_x_subpage_bb + colorbar_width_l,
02176 plot_x_subpage_bb + colorbar_width_l,
02177 plot_x_subpage_bb,
02178 };
02179 PLFLT ybb[5] = {
02180 plot_y_subpage_bb,
02181 plot_y_subpage_bb - colorbar_height_l,
02182 plot_y_subpage_bb - colorbar_height_l,
02183 plot_y_subpage_bb,
02184 plot_y_subpage_bb,
02185 };
02186 pllsty( bb_style );
02187 plcol0( bb_color );
02188 plline( 5, xbb, ybb );
02189 plcol0( col0_save );
02190 pllsty( line_style_save );
02191 }
02192
02193
02194
02195 plvpor( label_vpor_xmin, label_vpor_xmax, label_vpor_ymin, label_vpor_ymax );
02196 draw_label( FALSE, opt, label );
02197
02198
02199 plcol0( col0_save );
02200 plvpor( xdmin_save, xdmax_save, ydmin_save, ydmax_save );
02201 plwind( xwmin_save, xwmax_save, ywmin_save, ywmax_save );
02202
02203 return;
02204 }