GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
gsd_legend.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/gsd_legend.c
3 
4  \brief OGSF library - legend creation
5 
6  GRASS OpenGL gsurf OGSF Library
7 
8  Converted code from legend.c in SG3d
9  routines to set viewport, close viewport, and make legend
10 
11  (C) 1999-2008 by the GRASS Development Team
12 
13  This program is free software under the
14  GNU General Public License (>=v2).
15  Read the file COPYING that comes with GRASS
16  for details.
17 
18  \author Bill Brown USACERL
19  \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
20  */
21 
22 #include <stdlib.h>
23 
24 #include <grass/config.h>
25 
26 #if defined(OPENGL_X11) || defined(OPENGL_WINDOWS)
27 #include <GL/gl.h>
28 #include <GL/glu.h>
29 #elif defined(OPENGL_AQUA)
30 #include <OpenGL/gl.h>
31 #include <OpenGL/glu.h>
32 #endif
33 
34 #include <grass/gis.h>
35 #include <grass/raster.h>
36 #include <grass/glocale.h>
37 #include <grass/ogsf.h>
38 
39 #include "rgbpack.h"
40 
41 static float *Listcats;
42 static int Listnum = 0;
43 
44 /**** TODO
45 static int bigger(float *f1, float *f2)
46 {
47  return (*f1 < *f2 ? -1 : (*f1 > *f2));
48 }
49 *****/
50 
51 #define MAX_LEGEND 256
52 
53 /*!
54  \brief ADD
55 
56  \param wl
57  \param wb
58  \param wr
59  \param wt
60  */
61 void gsd_bgn_legend_viewport(GLint wl, GLint wb, GLint wr, GLint wt)
62 {
63  /* sets the viewport for the legend and the model matrix */
64 
66  glPushAttrib(GL_VIEWPORT);
67 
68  glMatrixMode(GL_PROJECTION);
69 
72  GS_ready_draw();
73 
74  gsd_linewidth(1);
75 
76  gsd_popmatrix();
77 
78  glViewport(wl, wb, (wr - wl), (wt - wb));
79  glLoadIdentity();
80  gluOrtho2D(-0.5, (wr - wl) + 0.5, -0.5, (wt - wb) + 0.5);
81  glMatrixMode(GL_MODELVIEW);
82  glPushMatrix();
83  glLoadIdentity();
84 
85  return;
86 }
87 
88 /*!
89  \brief ADD
90  */
92 {
93  /* closes the legend viewport and resets matrix and buffers */
94 
95  gsd_popmatrix();
96  glMatrixMode(GL_PROJECTION);
97  gsd_popmatrix();
98 
99  glPopAttrib();
100  glMatrixMode(GL_MODELVIEW);
101  gsd_popmatrix();
102 
103  GS_done_draw();
105 
106  return;
107 }
108 
109 /*!
110  \brief ADD
111 
112  \param lownum
113  \param highnum
114  \param numvals
115  \param vals
116 
117  \return 0 on failure
118  \return range value
119  */
120 int gsd_get_nice_range(float lownum, float highnum, int numvals, float *vals)
121 {
122  /* get a nice range for displaying legend */
123 
124  int num = 0;
125  float curnum, step, start;
126 
127  if (!numvals)
128  return (0);
129 
130  step = (highnum - lownum) / (float)numvals;
131  gsd_make_nice_number(&step);
132 
133  /* get a starting point */
134  start = step * (int)(1 + lownum / step);
135  if (start - lownum < .65 * step)
136  start += step;
137 
138  for (curnum = start; curnum < (highnum - .65 * step); curnum += step) {
139  vals[num++] = curnum;
140  }
141 
142  return (num);
143 
144 }
145 
146 /*!
147  \brief ADD
148 
149  \param num
150 
151  \return 0 on error
152  \return 1 on success
153  */
154 int gsd_make_nice_number(float *num)
155 {
156  float newnum, nextnum;
157 
158  if (*num < 0)
159  return (0);
160 
161  if (*num < 1) {
162  newnum = 1.;
163  while (.5 * newnum > *num) {
164  nextnum = newnum / 10.;
165  newnum /= 2.;
166  if (.5 * newnum > *num)
167  newnum /= 2.;
168  if (.5 * newnum > *num)
169  newnum = nextnum;
170  }
171  }
172  else {
173  newnum = 1.;
174  while (2 * newnum <= *num) {
175  nextnum = newnum * 10.;
176  newnum *= 2.5;
177  if (2 * newnum <= *num)
178  newnum *= 2.;
179  if (2 * newnum <= *num)
180  newnum = nextnum;
181  }
182  if (newnum == 2.5)
183  newnum = 3;
184  /* 2.5 isn't nice, but .25, 25, 250 ... are */
185  }
186  *num = newnum;
187  return (1);
188 }
189 
190 /*!
191  \brief Put legend
192 
193  \param name
194  \param fontbase font-base
195  \param size
196  \param flags
197  \param rangef
198  \param pt
199 
200  \return
201  */
202 GLuint gsd_put_legend(const char *name, GLuint fontbase, int size, int *flags,
203  float *rangef, int *pt)
204 {
205  GLint sl, sr, sb, st;
206  GLuint legend_list;
207  int cat_labs = 0, cat_vals = 0, do_invert = 0, discrete = 0;
208  int is_fp, fprec, iprec;
209  struct Categories cats;
210  struct Range range;
211  struct FPRange fp_range;
212  const char *mapset;
213  struct Colors colors;
214  CELL min, max;
215  DCELL fmin, fmax;
216  float labvals[12];
217 
218  legend_list = gsd_makelist();
219  gsd_bgnlist(legend_list, 1);
220 
221  /* set coords from pt */
222  sl = pt[0];
223  sr = pt[1];
224  sb = pt[2];
225  st = pt[3];
226 
227  /* set legend flags */
228  if (flags[0])
229  cat_vals = 1;
230  if (flags[1])
231  cat_labs = 1;
232  if (flags[3])
233  discrete = 1;
234  if (flags[2])
235  do_invert = 1;
236 
237  mapset = G_find_raster2(name, "");
238  if (mapset == NULL) {
239  G_warning(_("Raster map <%s> not found"), name);
240  return (-1);
241  }
242 
243  is_fp = Rast_map_is_fp(name, mapset);
244 
245  if (Rast_read_colors(name, mapset, &colors) == -1) {
246  G_warning(_("Unable to read color file of raster map <%s>"), name);
247  return (-1);
248  }
249 
250  if (cat_labs)
251  if (Rast_read_cats(name, mapset, &cats) == -1) {
252  G_warning(_("Unable to read category file of raster map <%s>"),
253  name);
254  cat_labs = 0;
255  }
256 
257 
258  if (flags[4] && rangef[0] != -9999. && rangef[1] != -9999.) {
259  fmin = rangef[0];
260  fmax = rangef[1];
261  if (!is_fp) {
262  min = (int)fmin;
263  max = (int)fmax;
264  }
265  }
266  else {
267  if (is_fp) {
268  if (Rast_read_fp_range(name, mapset, &fp_range) != 1) {
269  G_warning(_("Unable to read fp range of raster map <%s>"),
270  name);
271  return (-1);
272  }
273  Rast_get_fp_range_min_max(&fp_range, &fmin, &fmax);
274  if (flags[4] && rangef[0] != -9999.)
275  fmin = rangef[0];
276  if (flags[4] && rangef[1] != -9999.)
277  fmax = rangef[1];
278  }
279  else {
280  if (Rast_read_range(name, mapset, &range) == -1) {
281  G_warning(_("Unable to read range of raster map <%s>"), name);
282  return (-1);
283  }
284  Rast_get_range_min_max(&range, &min, &max);
285  if (flags[4] && rangef[0] != -9999.)
286  min = rangef[0];
287  if (flags[4] && rangef[1] != -9999.)
288  max = rangef[1];
289  fmin = min;
290  fmax = max;
291  }
292  }
293 
294  if (fmin == fmax)
295  G_warning(_("Range request error for legend"));
296 
297  /* set a reasonable precision */
298  if (is_fp) {
299  float df;
300 
301  df = fmax - fmin;
302  if (df < .1)
303  fprec = 6;
304  else if (df < 1)
305  fprec = 4;
306  else if (df < 10)
307  fprec = 3;
308  else if (df < 100)
309  fprec = 2;
310  else
311  fprec = 1;
312 
313  }
314  else {
315  int tmp, p1, p2;
316 
317  iprec = p1 = p2 = 1;
318  if (max > 0)
319  for (tmp = 1; tmp < max; tmp *= 10, p1++) ;
320  if (min < 0)
321  for (tmp = -1; tmp > min; tmp *= 10, p2++) ;
322 
323  iprec = (p1 > p2 ? p1 : p2);
324  }
325 
326 /*********
327  * TODO incorp lists
328 
329  if(list && (legend_type & LT_LIST)){
330  Listcats = list;
331  Listnum = nlist;
332  qsort(Listcats, Listnum, sizeof(float), bigger);
333  discrete = 1;
334  }
335  else
336  Listnum = 0;
337 
338 *********/
339 
340 
341  /* how many labels? */
342  /*
343  numlabs can't be = max - min + 1 any more because of floating point
344  maybe shouldn't allow discrete legend for floating point maps (unless list)
345  or else check number of different values in floating point map
346  and use each if "reasonable"
347  gs_get_values_in_range(gs, att, low, high, values, &nvals)
348  the nvals sent has a max number to return, nvals returned is the actual
349  number set in values, return val is 1 on success, -1 if > max vals found
350 
351  might need to think about doing histograms first & use same routines here
352  could also have a LT_MOST that would limit # to some N most frequent
353  */
354 
355  /*!
356  ???
357  */
358  {
359  int i, k, lleg, horiz;
360  int red, green, blue;
361  CELL tcell;
362  DCELL tdcell, pdcell;
363  float vert1[2], vert2[2], vert3[2], vert4[2];
364  float *dv1, *dv2; /* changing vertex coord */
365  float *sv1, *sv2; /* stable vertex coord */
366  float stab1, stab2;
367  unsigned long colr;
368  float *dividers;
369  int labw, maxlabw, numlabs;
370  float labpos, labpt[3];
371  const char *cstr;
372  char buff[80];
373  GLint wt, wb, wl, wr; /* Whole legend area, not just box */
374  int xoff, yoff;
375  int incr; /* for do_invert */
376 
377  horiz = (sr - sl > st - sb);
378  dividers = NULL;
379 
380  if (discrete) {
381  numlabs = Listnum ? Listnum : max - min + 1;
382  /* watch out for trying to display mega cats */
383  if (is_fp && !Listnum) {
384  discrete = 0; /* maybe later do stats & allow if few #s */
385  G_warning(_("Unable to show discrete FP range (use list)"));
386  return (-1);
387  }
388  if (numlabs < MAX_LEGEND)
389  dividers = (float *)G_malloc(numlabs * sizeof(float));
390  }
391  else {
392  numlabs = gsd_get_nice_range(fmin, fmax, 4, labvals + 1);
393  labvals[0] = fmin;
394  labvals[numlabs + 1] = fmax;
395  numlabs += 2;
396  }
397 
398  /* find longest string, reset viewport & saveunder */
399  maxlabw = 0;
400 
401  if (cat_labs || cat_vals) {
402  for (k = 0; k < numlabs; k++) {
403  if (is_fp) {
404  tdcell = discrete ? Listcats[k] : labvals[k];
405  if (cat_labs) {
406  cstr = Rast_get_d_cat(&tdcell, &cats);
407  }
408  if (cat_labs && !cat_vals) {
409  sprintf(buff, "%s", cstr);
410  }
411  else {
412  if (cat_labs && cat_vals) {
413  if (cstr)
414  sprintf(buff, "%.*lf) %s",
415  fprec, tdcell, cstr);
416  else
417  sprintf(buff, "%.*lf", fprec, tdcell);
418  }
419  else if (cat_vals)
420  sprintf(buff, "%.*lf", fprec, tdcell);
421  }
422  }
423  else {
424  tcell = discrete ? Listnum ?
425  Listcats[k] : min + k : labvals[k];
426  if (cat_labs && !cat_vals)
427  sprintf(buff, "%s", Rast_get_c_cat(&tcell, &cats));
428  else {
429  if (cat_labs && cat_vals) {
430  cstr = Rast_get_c_cat(&tcell, &cats);
431  if (cstr[0])
432  sprintf(buff, "%*d) %s", iprec, tcell, cstr);
433  else
434  sprintf(buff, "%d", tcell);
435  }
436  else if (cat_vals)
437  sprintf(buff, "%d", tcell);
438  }
439  }
440  labw = gsd_get_txtwidth(buff, size);
441  if (labw > maxlabw) {
442  maxlabw = labw;
443  }
444  }
445  }
446 
447  if (horiz) {
448  xoff = maxlabw / 2 + get_txtxoffset();
449  wl = sl - xoff;
450  wr = sr + xoff;
451  yoff = 0;
452  wb = sb;
453  /*
454  wt = st + gsd_get_txtheight() + get_txtdescender() +3;
455  */
456  wt = st + gsd_get_txtheight(size) * 2 + 3;
457  }
458  else {
459  xoff = 0;
460  wl = sl;
461  wr = sr + maxlabw + get_txtxoffset() + 3;
462  /*
463  yoff = gsd_get_txtheight()/2 + get_txtdescender();
464  */
465  yoff = gsd_get_txtheight(size);
466  wb = sb - yoff;
467  wt = st + yoff;
468  }
469 
470  /* initialize viewport */
471  gsd_bgn_legend_viewport(wl, wb, wr, wt);
472 
473 
474  vert1[X] = vert2[X] = xoff;
475  vert1[Y] = vert2[Y] = yoff;
476  if (horiz) {
477  lleg = sr - sl;
478  dv1 = vert1 + X;
479  dv2 = vert2 + X;
480  sv1 = vert1 + Y;
481  sv2 = vert2 + Y;
482  stab2 = vert2[Y] = st - sb + yoff;
483  stab1 = vert1[Y] = yoff;
484  if (do_invert)
485  vert1[X] = vert2[X] = sr - sl + xoff;
486  }
487  else {
488  lleg = st - sb;
489  dv1 = vert1 + Y;
490  dv2 = vert2 + Y;
491  sv1 = vert1 + X;
492  sv2 = vert2 + X;
493  stab2 = vert2[X] = sr - sl + xoff;
494  stab1 = vert1[X] = xoff;
495  if (do_invert)
496  vert1[Y] = vert2[Y] = st - sb + yoff;
497  }
498 
499  if (discrete) {
500  if (numlabs > lleg / 5)
501  G_warning(_("Too many categories to show as discrete!"));
502  else if (numlabs > 1.2 * lleg / gsd_get_txtheight(size))
503  G_warning(_("Try using smaller font!"));
504  }
505 
506  incr = do_invert ? -1 : 1;
507  for (k = 0, i = 0; k < lleg; k++) {
508  if (discrete && Listnum)
509  tdcell = Listcats[(int)((float)k * numlabs / lleg)];
510  else {
511  tcell = min + k * (max - min + 1) / lleg;
512  tdcell = fmin + k * (fmax - fmin) / lleg;
513  if (!is_fp)
514  tdcell = tcell;
515  }
516  if (k == 0 || tdcell != pdcell) {
517  if (is_fp)
518  Rast_get_d_color(&tdcell,
519  &red, &green, &blue, &colors);
520  else
521  Rast_get_c_color((CELL *)&tdcell, &red, &green, &blue, &colors);
522 
523  RGB_TO_INT(red, green, blue, colr);
524  if (discrete) { /* draw black-white-black separator */
525  if (k > 0) {
526  *dv1 -= 2. * incr;
527  *dv2 -= 2. * incr;
528  gsd_color_func(0x0);
529  gsd_bgnline();
530  glVertex2fv(vert1);
531  glVertex2fv(vert2);
532  gsd_endline();
533 
534  *dv1 += 1. * incr;
535  *dv2 += 1. * incr;
536  if (dividers)
537  dividers[i++] = *dv1;
538 
539  *dv1 += 1. * incr;
540  *dv2 += 1. * incr;
541  gsd_color_func(0x0);
542  gsd_bgnline();
543  glVertex2fv(vert1);
544  glVertex2fv(vert2);
545  gsd_endline();
546 
547  *dv1 += 1. * incr;
548  *dv2 += 1. * incr;
549  pdcell = tdcell;
550  continue;
551  }
552  }
553  }
554 
555  gsd_color_func(colr);
556  gsd_bgnline();
557  glVertex2fv(vert1);
558  glVertex2fv(vert2);
559  gsd_endline();
560  glFlush();
561  *dv1 += 1. * incr;
562  *dv2 += 1. * incr;
563  pdcell = tdcell;
564  }
565 
566  /* Black box */
567  vert1[X] = vert2[X] = 1. + xoff;
568  vert1[Y] = vert4[Y] = 1. + yoff;
569  vert3[X] = vert4[X] = sr - sl - 1. + xoff;
570  vert3[Y] = vert2[Y] = st - sb - 1. + yoff;
571 
572  gsd_color_func(0x000000);
573  gsd_bgnline();
574  glVertex2fv(vert1);
575  glVertex2fv(vert2);
576  glVertex2fv(vert3);
577  glVertex2fv(vert4);
578  glVertex2fv(vert1);
579  gsd_endline();
580 
581  /* White box */
582  vert1[X] = vert2[X] = xoff;
583  vert1[Y] = vert4[Y] = yoff;
584  vert3[X] = vert4[X] = sr - sl + xoff;
585  vert3[Y] = vert2[Y] = st - sb + yoff;
586 
587  gsd_color_func(0xFFFFFF);
588  gsd_bgnline();
589  glVertex2fv(vert1);
590  glVertex2fv(vert2);
591  glVertex2fv(vert3);
592  glVertex2fv(vert4);
593  glVertex2fv(vert1);
594  gsd_endline();
595 
596  /* draw discrete dividers */
597  if (dividers) {
598  gsd_color_func(0xFFFFFFFF);
599  *sv1 = stab1;
600  *sv2 = stab2;
601  for (k = 0; k < i; k++) {
602  *dv1 = *dv2 = dividers[k];
603  gsd_bgnline();
604  glVertex2fv(vert1);
605  glVertex2fv(vert2);
606  gsd_endline();
607  }
608  }
609 
610  if (cat_labs || cat_vals) {
611  labpt[Z] = 0;
612  for (k = 0; k < numlabs; k++) {
613  if (is_fp) {
614  if (discrete && Listnum) {
615  tdcell = Listcats[k];
616  labpos = (k + .5) / numlabs;
617  }
618  else {
619  /* show_all not supported unless Listnum */
620  tdcell = labvals[k];
621  labpos = (tdcell - fmin) / (fmax - fmin);
622  }
623  }
624  else {
625  if (discrete && Listnum) {
626  tcell = Listcats[k];
627  labpos = (k + .5) / numlabs;
628  }
629  else {
630  tcell = discrete ? min + k : labvals[k];
631  labpos = (tcell - min + .5) / (max - min + 1);
632  }
633  }
634  if (do_invert)
635  labpos = 1. - labpos;
636  if (cat_labs) {
637  if (!is_fp)
638  cstr = Rast_get_c_cat(&tcell, &cats);
639  else
640  cstr = Rast_get_d_cat(&tdcell, &cats);
641  }
642  if (cat_labs && !cat_vals)
643  sprintf(buff, "%s", cstr);
644  else {
645  if (cat_labs && cat_vals) {
646  if (cstr)
647  if (is_fp)
648  sprintf(buff, "%.*lf) %s",
649  fprec, tdcell, cstr);
650  else
651  sprintf(buff, "%*d) %s", iprec, tcell, cstr);
652  else if (is_fp)
653  sprintf(buff, "%.*lf", fprec, tdcell);
654  else
655  sprintf(buff, "%d", tcell);
656  }
657  else if (cat_vals) {
658  if (is_fp)
659  sprintf(buff, "%.*lf", fprec, tdcell);
660  else
661  sprintf(buff, "%d", tcell);
662  }
663  }
664  if (horiz) {
665  labpt[X] = labpos * (sr - sl) + xoff -
666  gsd_get_txtwidth(buff, size) / 2 - get_txtxoffset();
667  labpt[Y] =
668  st - sb + yoff + 3 + gsd_get_txtheight(size) / 2;
669  }
670  else {
671  labpt[X] = sr - sl + xoff + get_txtxoffset() + 3;
672  /*
673  labpt[Y] = labpos * (st - sb) + yoff -
674  gsd_get_txtheight()/2 + get_txtdescender();
675  */
676  labpt[Y] = labpos * (st - sb) + yoff -
677  gsd_get_txtheight(size);
678  }
679  /* set color for black text -- maybe add option for color
680  * supplied with font ??
681  */
682  gsd_color_func(0x000000);
683  do_label_display(fontbase, labpt, buff);
684  }
685  }
686 
687  if (discrete)
688  G_free(dividers);
689  }
690 
691  if (cat_labs)
692  Rast_free_cats(&cats);
693 
694  Rast_free_colors(&colors);
695 
697 
698  /*
699  gsd_unset_font(fontbase);
700  */
701 
702  gsd_endlist();
703 
704  return (legend_list);
705 }
void gsd_end_legend_viewport(void)
ADD.
Definition: gsd_legend.c:91
#define G_malloc(n)
Definition: defs/gis.h:112
void do_label_display(GLuint, float *, const char *)
Display label.
Definition: gsd_fonts.c:98
#define RGB_TO_INT(r, g, b, i)
Definition: rgbpack.h:12
void GS_ready_draw(void)
Definition: gs2.c:2488
#define min(x, y)
Definition: draw2.c:31
double DCELL
Definition: gis.h:603
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
int gsd_get_txtheight(int size)
Get text height.
Definition: gsd_fonts.c:53
#define NULL
Definition: ccmath.h:32
#define max(x, y)
Definition: draw2.c:32
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
Definition: range.c:160
void Rast_get_fp_range_min_max(const struct FPRange *, DCELL *, DCELL *)
Get minimum and maximum value from fp range.
Definition: range.c:764
struct state * st
Definition: parser.c:104
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:97
char * Rast_get_c_cat(CELL *, struct Categories *)
Get a raster category label (CELL)
Definition: raster/cats.c:323
#define CM_COLOR
Definition: ogsf.h:145
void gsd_color_func(unsigned int)
Set current color.
Definition: gsd_prim.c:701
char * Rast_get_d_cat(DCELL *, struct Categories *)
Get a raster category label (DCELL)
Definition: raster/cats.c:371
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
#define MAX_LEGEND
Definition: gsd_legend.c:51
void Rast_free_colors(struct Colors *)
Free color structure memory.
Definition: color_free.c:30
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2501
#define Z
Definition: ogsf.h:139
Definition: raster.h:225
Definition: gis.h:665
#define GSD_BACK
Definition: ogsf.h:102
#define Y
Definition: ogsf.h:138
int Rast_get_d_color(const DCELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (DCELL)
Definition: color_get.c:110
GLuint gsd_put_legend(const char *name, GLuint fontbase, int size, int *flags, float *rangef, int *pt)
Put legend.
Definition: gsd_legend.c:202
void gsd_bgnlist(int, int)
ADD.
Definition: gsd_prim.c:1128
int Rast_read_fp_range(const char *, const char *, struct FPRange *)
Read floating-point range.
Definition: range.c:71
int Rast_get_c_color(const CELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (CELL)
Definition: color_get.c:68
void gsd_linewidth(short)
Set width of rasterized lines.
Definition: gsd_prim.c:266
int Rast_read_cats(const char *, const char *, struct Categories *)
Read raster category file.
Definition: raster/cats.c:104
int gsd_get_nice_range(float lownum, float highnum, int numvals, float *vals)
ADD.
Definition: gsd_legend.c:120
int Rast_read_colors(const char *, const char *, struct Colors *)
Read color table of raster map.
void gsd_bgn_legend_viewport(GLint wl, GLint wb, GLint wr, GLint wt)
ADD.
Definition: gsd_legend.c:61
void G_warning(const char *,...) __attribute__((format(printf
int CELL
Definition: gis.h:602
void gsd_endlist(void)
End list.
Definition: gsd_prim.c:1143
#define GSD_FRONT
Definition: ogsf.h:101
void Rast_free_cats(struct Categories *)
Free category structure memory.
Definition: raster/cats.c:1213
#define _(str)
Definition: glocale.h:10
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
#define X
Definition: ogsf.h:137
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don&#39;t touch)
Definition: find_rast.c:76
int gsd_makelist(void)
ADD.
Definition: gsd_prim.c:1096
const char * name
Definition: named_colr.c:7
int gsd_get_txtwidth(const char *, int)
Get text width.
Definition: gsd_fonts.c:36
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2462
int get_txtxoffset(void)
Get text offset.
Definition: gsd_fonts.c:86
int Rast_map_is_fp(const char *, const char *)
Check if raster map is floating-point.
Definition: raster/open.c:847
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
int gsd_make_nice_number(float *num)
ADD.
Definition: gsd_legend.c:154
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
Definition: range.c:714