PLplot  5.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plvpor.c
Go to the documentation of this file.
1 // $Id: plvpor.c 11973 2011-10-17 21:16:39Z andrewross $
2 //
3 // Functions dealing with viewports.
4 //
5 // Copyright (C) 2004 Joao Cardoso
6 //
7 // This file is part of PLplot.
8 //
9 // PLplot is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as published
11 // by the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // PLplot is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with PLplot; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 
24 #include "plplotP.h"
25 
26 static void
28  PLINT just, PLINT axis, PLINT old );
29 
30 //--------------------------------------------------------------------------
31 // void plenv()
32 //
33 // Simple interface for defining viewport and window.
34 //
35 // The "just" parameter control how the axes will be scaled:
36 //
37 // just=-1 : The scales will not be set, the user must set up the scale
38 // before calling plenv() using plsvpa(), plvasp() or other;
39 // just= 0 : The scales will be set up to optimize plot area;
40 // just= 1 : The scales will be the same;
41 // just= 2 : The axes will be equal, the plot box will be square.
42 //
43 // The "axis" parameter is interpreted as follows:
44 //
45 // axis=-2 : draw no box, no tick marks, no numeric tick labels, no axes.
46 // axis=-1 : draw box only.
47 // axis= 0 : Draw box, ticks, and numeric tick labels.
48 // axis= 1 : Also draw coordinate axes at X=0, and Y=0.
49 // axis= 2 : Also draw a grid at major tick positions in both coordinates.
50 // axis= 3 : Same as 2, but the grid will be also at the minor ticks.
51 // axis=10 : Same as 0 except Logarithmic X tick marks. (The X data have
52 // to be converted to logarithms separately.)
53 // axis=11 : Same as 1 except Logarithmic X tick marks. (The X data have
54 // to be converted to logarithms separately.)
55 // axis=12 : Same as 2 except Logarithmic X tick marks. (The X data have
56 // to be converted to logarithms separately.)
57 // axis=13 : Same as 12, but the grid will be also at the minor ticks.
58 // axis=20 : Same as 0 except Logarithmic Y tick marks. (The Y data have
59 // to be converted to logarithms separately.)
60 // axis=21 : Same as 1 except Logarithmic Y tick marks. (The Y data have
61 // to be converted to logarithms separately.)
62 // axis=22 : Same as 2 except Logarithmic Y tick marks. (The Y data have
63 // to be converted to logarithms separately.)
64 // axis=23 : Same as 22, but the grid will be also at the minor ticks.
65 // axis=30 : Same as 0 except Logarithmic X,Y tick marks. (The X,Y data have
66 // to be converted to logarithms separately.)
67 // axis=31 : Same as 1 except Logarithmic X,Y tick marks. (The X,Y data have
68 // to be converted to logarithms separately.)
69 // axis=32 : Same as 2 except Logarithmic X,Y tick marks. (The X,Y data have
70 // to be converted to logarithms separately.)
71 // axis=33 : Same as 32, but the grid will be also at the minor ticks.
72 // axis=40 : Same as 0 except date / time X tick marks.
73 // axis=41 : Same as 1 except date / time X tick marks.
74 // axis=42 : Same as 2 except date / time X tick marks.
75 // axis=43 : Same as 42, but the grid will be also at the minor ticks.
76 // axis=50 : Same as 0 except date / time Y tick marks.
77 // axis=51 : Same as 1 except date / time Y tick marks.
78 // axis=52 : Same as 2 except date / time Y tick marks.
79 // axis=53 : Same as 52, but the grid will be also at the minor ticks.
80 // axis=60 : Same as 0 except date / time X,Y tick marks.
81 // axis=61 : Same as 1 except date / time X,Y tick marks.
82 // axis=62 : Same as 2 except date / time X,Y tick marks.
83 // axis=63 : Same as 62, but the grid will be also at the minor ticks.
84 // axis=70 : Same as 0 except custom X,Y labels.
85 // axis=71 : Same as 1 except custom X,Y labels.
86 // axis=72 : Same as 2 except custom X,Y labels.
87 // axis=73 : Same as 72, but the grid will be also at the minor ticks.
88 //--------------------------------------------------------------------------
89 
90 void
92  PLINT just, PLINT axis )
93 {
94  c_plenvi( xmin, xmax, ymin, ymax, just, axis, 1 );
95 }
96 
97 //--------------------------------------------------------------------------
98 // void plenv0()
99 //
100 // same as plenv() above, but if in multiplot mode does not advance the subpage,
101 // instead clears it.
102 //--------------------------------------------------------------------------
103 
104 void
106  PLINT just, PLINT axis )
107 {
108  c_plenvi( xmin, xmax, ymin, ymax, just, axis, 0 );
109 }
110 
111 
112 static void
114  PLINT just, PLINT axis, PLINT old )
115 {
116  PLFLT lb, rb, tb, bb, dx, dy;
117  PLFLT xsize, ysize, size, xscale, yscale, scale;
118  PLFLT spxmin, spxmax, spymin, spymax;
119  PLFLT vpxmin, vpxmax, vpymin, vpymax;
120 
121  if ( plsc->level < 1 )
122  {
123  plabort( "plenv: Please call plinit first" );
124  return;
125  }
126  if ( xmin == xmax )
127  {
128  plabort( "plenv: Invalid xmin and xmax arguments" );
129  return;
130  }
131  if ( ymin == ymax )
132  {
133  plabort( "plenv: Invalid ymin and ymax arguments" );
134  return;
135  }
136  if ( just < -1 || just > 2 )
137  {
138  plabort( "plenv: Invalid just option" );
139  return;
140  }
141 
142  if ( plsc->nsubx * plsc->nsuby == 1 ) // not multiplot mode
143  old = 1;
144 
145  if ( old == 1 )
146  pladv( 0 );
147  else
148  plclear();
149 
150  if ( just == 0 )
151  plvsta();
152  else if ( just == 1 )
153  {
154  lb = 8.0 * plsc->chrht;
155  rb = 5.0 * plsc->chrht;
156  tb = 5.0 * plsc->chrht;
157  bb = 5.0 * plsc->chrht;
158  dx = ABS( xmax - xmin );
159  dy = ABS( ymax - ymin );
160  plgspa( &spxmin, &spxmax, &spymin, &spymax );
161  xsize = spxmax - spxmin;
162  ysize = spymax - spymin;
163  xscale = dx / ( xsize - lb - rb );
164  yscale = dy / ( ysize - tb - bb );
165  scale = MAX( xscale, yscale );
166  vpxmin = MAX( lb, 0.5 * ( xsize - dx / scale ) );
167  vpxmax = vpxmin + ( dx / scale );
168  vpymin = MAX( bb, 0.5 * ( ysize - dy / scale ) );
169  vpymax = vpymin + ( dy / scale );
170  plsvpa( vpxmin, vpxmax, vpymin, vpymax );
171  }
172  else if ( just == 2 )
173  {
174  lb = 8.0 * plsc->chrht;
175  rb = 5.0 * plsc->chrht;
176  tb = 5.0 * plsc->chrht;
177  bb = 5.0 * plsc->chrht;
178  plgspa( &spxmin, &spxmax, &spymin, &spymax );
179  xsize = spxmax - spxmin;
180  ysize = spymax - spymin;
181  size = MIN( xsize - lb - rb, ysize - tb - bb );
182  dx = ( xsize - size - lb - rb ) / 2;
183  vpxmin = lb + dx;
184  vpxmax = vpxmin + size;
185  dy = ( ysize - size - bb - tb ) / 2;
186  vpymin = bb + dy;
187  vpymax = vpymin + size;
188  plsvpa( vpxmin, vpxmax, vpymin, vpymax );
189  }
190 
191  plwind( xmin, xmax, ymin, ymax );
192 
193  switch ( axis )
194  {
195  case -2:
196  break;
197  case -1:
198  plbox( "bc", (PLFLT) 0.0, 0, "bc", (PLFLT) 0.0, 0 );
199  break;
200  case 0:
201  plbox( "bcnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0 );
202  break;
203  case 1:
204  plbox( "abcnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0 );
205  break;
206  case 2:
207  plbox( "abcgnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0 );
208  break;
209  case 3:
210  plbox( "abcgnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0 );
211  break;
212  case 10:
213  plbox( "bclnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0 );
214  break;
215  case 11:
216  plbox( "abclnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0 );
217  break;
218  case 12:
219  plbox( "abcglnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0 );
220  break;
221  case 13:
222  plbox( "abcglnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0 );
223  break;
224  case 20:
225  plbox( "bcnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0 );
226  break;
227  case 21:
228  plbox( "abcnst", (PLFLT) 0.0, 0, "abclnstv", (PLFLT) 0.0, 0 );
229  break;
230  case 22:
231  plbox( "abcgnst", (PLFLT) 0.0, 0, "abcglnstv", (PLFLT) 0.0, 0 );
232  break;
233  case 23:
234  plbox( "abcgnsth", (PLFLT) 0.0, 0, "abcglnstvh", (PLFLT) 0.0, 0 );
235  break;
236  case 30:
237  plbox( "bclnst", (PLFLT) 0.0, 0, "bclnstv", (PLFLT) 0.0, 0 );
238  break;
239  case 31:
240  plbox( "abclnst", (PLFLT) 0.0, 0, "abclnstv", (PLFLT) 0.0, 0 );
241  break;
242  case 32:
243  plbox( "abcglnst", (PLFLT) 0.0, 0, "abcglnstv", (PLFLT) 0.0, 0 );
244  break;
245  case 33:
246  plbox( "abcglnsth", (PLFLT) 0.0, 0, "abcglnstvh", (PLFLT) 0.0, 0 );
247  break;
248  case 40:
249  plbox( "bcdnst", (PLFLT) 0.0, 0, "bcnstv", (PLFLT) 0.0, 0 );
250  break;
251  case 41:
252  plbox( "abcdnst", (PLFLT) 0.0, 0, "abcnstv", (PLFLT) 0.0, 0 );
253  break;
254  case 42:
255  plbox( "abcgdnst", (PLFLT) 0.0, 0, "abcgnstv", (PLFLT) 0.0, 0 );
256  break;
257  case 43:
258  plbox( "abcgdnsth", (PLFLT) 0.0, 0, "abcgnstvh", (PLFLT) 0.0, 0 );
259  break;
260  case 50:
261  plbox( "bcnst", (PLFLT) 0.0, 0, "bcdnstv", (PLFLT) 0.0, 0 );
262  break;
263  case 51:
264  plbox( "abcnst", (PLFLT) 0.0, 0, "abcdnstv", (PLFLT) 0.0, 0 );
265  break;
266  case 52:
267  plbox( "abcgnst", (PLFLT) 0.0, 0, "abcgdnstv", (PLFLT) 0.0, 0 );
268  break;
269  case 53:
270  plbox( "abcgnsth", (PLFLT) 0.0, 0, "abcgdnstvh", (PLFLT) 0.0, 0 );
271  break;
272  case 60:
273  plbox( "bcdnst", (PLFLT) 0.0, 0, "bcdnstv", (PLFLT) 0.0, 0 );
274  break;
275  case 61:
276  plbox( "abcdnst", (PLFLT) 0.0, 0, "abcdnstv", (PLFLT) 0.0, 0 );
277  break;
278  case 62:
279  plbox( "abcgdnst", (PLFLT) 0.0, 0, "abcgdnstv", (PLFLT) 0.0, 0 );
280  break;
281  case 63:
282  plbox( "abcgdnsth", (PLFLT) 0.0, 0, "abcgdnstvh", (PLFLT) 0.0, 0 );
283  break;
284  case 70:
285  plbox( "bcnost", (PLFLT) 0.0, 0, "bcnostv", (PLFLT) 0.0, 0 );
286  break;
287  case 71:
288  plbox( "abcnost", (PLFLT) 0.0, 0, "abcnostv", (PLFLT) 0.0, 0 );
289  break;
290  case 72:
291  plbox( "abcgnost", (PLFLT) 0.0, 0, "abcgnostv", (PLFLT) 0.0, 0 );
292  break;
293  case 73:
294  plbox( "abcgnosth", (PLFLT) 0.0, 0, "abcgnostvh", (PLFLT) 0.0, 0 );
295  break;
296  default:
297  plwarn( "plenv: Invalid axis argument" );
298  }
299 }
300 
301 //--------------------------------------------------------------------------
302 // void plvsta()
303 //
304 // Defines a "standard" viewport with seven character heights for
305 // the left margin and four character heights everywhere else.
306 //--------------------------------------------------------------------------
307 
308 void
309 c_plvsta( void )
310 {
311  PLFLT xmin, xmax, ymin, ymax;
312  PLFLT lb, rb, tb, bb;
313 
314  if ( plsc->level < 1 )
315  {
316  plabort( "plvsta: Please call plinit first" );
317  return;
318  }
319 
320 // Find out position of subpage boundaries in millimetres, reduce by
321 // the desired border, and convert back into normalized subpage
322 // coordinates
323 
324  lb = 8.0 * plsc->chrht;
325  rb = 5.0 * plsc->chrht;
326  tb = 5.0 * plsc->chrht;
327  bb = 5.0 * plsc->chrht;
328 
329  xmin = plP_dcscx( plP_mmdcx( (PLFLT) ( plP_dcmmx( plsc->spdxmi ) + lb ) ) );
330  xmax = plP_dcscx( plP_mmdcx( (PLFLT) ( plP_dcmmx( plsc->spdxma ) - rb ) ) );
331  ymin = plP_dcscy( plP_mmdcy( (PLFLT) ( plP_dcmmy( plsc->spdymi ) + tb ) ) );
332  ymax = plP_dcscy( plP_mmdcy( (PLFLT) ( plP_dcmmy( plsc->spdyma ) - bb ) ) );
333 
334  plvpor( xmin, xmax, ymin, ymax );
335 }
336 
337 //--------------------------------------------------------------------------
338 // void plvpor()
339 //
340 // Creates a viewport with the specified normalized subpage coordinates.
341 //--------------------------------------------------------------------------
342 
343 void
345 {
346  if ( plsc->level < 1 )
347  {
348  plabort( "plvpor: Please call plinit first" );
349  return;
350  }
351  if ( ( xmin >= xmax ) || ( ymin >= ymax ) )
352  {
353  plabort( "plvpor: Invalid limits" );
354  return;
355  }
356  if ( ( plsc->cursub <= 0 ) || ( plsc->cursub > ( plsc->nsubx * plsc->nsuby ) ) )
357  {
358  plabort( "plvpor: Please call pladv or plenv to go to a subpage" );
359  return;
360  }
361 
362  plsc->vpdxmi = plsc->spdxmi + ( plsc->spdxma - plsc->spdxmi ) * xmin;
363  plsc->vpdxma = plsc->spdxmi + ( plsc->spdxma - plsc->spdxmi ) * xmax;
364  plsc->vpdymi = plsc->spdymi + ( plsc->spdyma - plsc->spdymi ) * ymin;
365  plsc->vpdyma = plsc->spdymi + ( plsc->spdyma - plsc->spdymi ) * ymax;
366 
367  plsc->vppxmi = plP_dcpcx( plsc->vpdxmi );
368  plsc->vppxma = plP_dcpcx( plsc->vpdxma );
369  plsc->vppymi = plP_dcpcy( plsc->vpdymi );
370  plsc->vppyma = plP_dcpcy( plsc->vpdyma );
371 
372  plsc->clpxmi = MAX( plsc->vppxmi, plsc->phyxmi );
373  plsc->clpxma = MIN( plsc->vppxma, plsc->phyxma );
374  plsc->clpymi = MAX( plsc->vppymi, plsc->phyymi );
375  plsc->clpyma = MIN( plsc->vppyma, plsc->phyyma );
376 
377  plsc->level = 2;
378 }
379 
380 //--------------------------------------------------------------------------
381 // void plvpas()
382 //
383 // Creates the largest viewport of the specified aspect ratio that fits
384 // within the specified normalized subpage coordinates.
385 //--------------------------------------------------------------------------
386 
387 void
389 {
390  PLFLT spxmin, spxmax, spymin, spymax;
391  PLFLT vpxmin, vpxmax, vpymin, vpymax;
392  PLFLT xsize, ysize, nxsize, nysize;
393  PLFLT xoffset, yoffset;
394 
395  if ( plsc->level < 1 )
396  {
397  plabort( "plvpas: Please call plinit first" );
398  return;
399  }
400  if ( ( xmin >= xmax ) || ( ymin >= ymax ) )
401  {
402  plabort( "plvpas: Invalid limits" );
403  return;
404  }
405 
406  if ( aspect <= 0.0 )
407  {
408  c_plvpor( xmin, xmax, ymin, ymax );
409  return;
410  }
411 
412  plgspa( &spxmin, &spxmax, &spymin, &spymax );
413 
414  xsize = spxmax - spxmin;
415  ysize = spymax - spymin;
416 
417  xoffset = xsize * xmin;
418  yoffset = ysize * ymin;
419 
420  spxmax = spxmin + xsize * xmax;
421  spxmin = spxmin + xsize * xmin;
422  spymax = spymin + ysize * ymax;
423  spymin = spymin + ysize * ymin;
424 
425  // Adjust size for the requested edging
426  xsize = spxmax - spxmin;
427  ysize = spymax - spymin;
428 
429  if ( aspect * xsize > ysize )
430  {
431  nxsize = ysize / aspect;
432  nysize = ysize;
433  }
434  else
435  {
436  nxsize = xsize;
437  nysize = xsize * aspect;
438  }
439 
440 // center plot within page
441 
442  vpxmin = 0.5 * ( xsize - nxsize ) + xoffset;
443  vpxmax = vpxmin + nxsize;
444  vpymin = 0.5 * ( ysize - nysize ) + yoffset;
445  vpymax = vpymin + nysize;
446 
447  plsvpa( vpxmin, vpxmax, vpymin, vpymax );
448 }
449 
450 //--------------------------------------------------------------------------
451 // void plvasp()
452 //
453 // Sets the edges of the viewport with the given aspect ratio, leaving
454 // room for labels.
455 //--------------------------------------------------------------------------
456 
457 void
458 c_plvasp( PLFLT aspect )
459 {
460  PLFLT spxmin, spxmax, spymin, spymax;
461  PLFLT vpxmin, vpxmax, vpymin, vpymax;
462  PLFLT xsize, ysize, nxsize, nysize;
463  PLFLT lb, rb, tb, bb;
464 
465  if ( plsc->level < 1 )
466  {
467  plabort( "plvasp: Please call plinit first" );
468  return;
469  }
470 
471  lb = 8.0 * plsc->chrht;
472  rb = 5.0 * plsc->chrht;
473  tb = 5.0 * plsc->chrht;
474  bb = 5.0 * plsc->chrht;
475 
476  plgspa( &spxmin, &spxmax, &spymin, &spymax );
477  xsize = spxmax - spxmin;
478  ysize = spymax - spymin;
479  xsize -= lb + rb; // adjust for labels
480  ysize -= bb + tb;
481  if ( aspect * xsize > ysize )
482  {
483  nxsize = ysize / aspect;
484  nysize = ysize;
485  }
486  else
487  {
488  nxsize = xsize;
489  nysize = xsize * aspect;
490  }
491 
492 // center plot within page
493 
494  vpxmin = .5 * ( xsize - nxsize ) + lb;
495  vpxmax = vpxmin + nxsize;
496  vpymin = .5 * ( ysize - nysize ) + bb;
497  vpymax = vpymin + nysize;
498 
499  plsvpa( vpxmin, vpxmax, vpymin, vpymax );
500 }
501 
502 //--------------------------------------------------------------------------
503 // void plsvpa()
504 //
505 // Sets the edges of the viewport to the specified absolute coordinates
506 // (mm), measured with respect to the current subpage boundaries.
507 //--------------------------------------------------------------------------
508 
509 void
511 {
512  PLFLT sxmin, symin;
513 
514  if ( plsc->level < 1 )
515  {
516  plabort( "plsvpa: Please call plinit first" );
517  return;
518  }
519  if ( ( xmin >= xmax ) || ( ymin >= ymax ) )
520  {
521  plabort( "plsvpa: Invalid limits" );
522  return;
523  }
524  if ( ( plsc->cursub <= 0 ) || ( plsc->cursub > ( plsc->nsubx * plsc->nsuby ) ) )
525  {
526  plabort( "plsvpa: Please call pladv or plenv to go to a subpage" );
527  return;
528  }
529 
530  sxmin = plP_dcmmx( plsc->spdxmi );
531  symin = plP_dcmmy( plsc->spdymi );
532 
533  plsc->vpdxmi = plP_mmdcx( (PLFLT) ( sxmin + xmin ) );
534  plsc->vpdxma = plP_mmdcx( (PLFLT) ( sxmin + xmax ) );
535  plsc->vpdymi = plP_mmdcy( (PLFLT) ( symin + ymin ) );
536  plsc->vpdyma = plP_mmdcy( (PLFLT) ( symin + ymax ) );
537 
538  plsc->vppxmi = plP_dcpcx( plsc->vpdxmi );
539  plsc->vppxma = plP_dcpcx( plsc->vpdxma );
540  plsc->vppymi = plP_dcpcy( plsc->vpdymi );
541  plsc->vppyma = plP_dcpcy( plsc->vpdyma );
542 
543  plsc->clpxmi = plP_dcpcx( plsc->vpdxmi );
544  plsc->clpxma = plP_dcpcx( plsc->vpdxma );
545  plsc->clpymi = plP_dcpcy( plsc->vpdymi );
546  plsc->clpyma = plP_dcpcy( plsc->vpdyma );
547 
548  plsc->level = 2;
549 }