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