[GRASS-SVN] r68699 - grass/trunk/display/d.legend

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Jun 16 18:11:09 PDT 2016


Author: annakrat
Date: 2016-06-16 18:11:09 -0700 (Thu, 16 Jun 2016)
New Revision: 68699

Added:
   grass/trunk/display/d.legend/draw.c
Modified:
   grass/trunk/display/d.legend/histogram.c
   grass/trunk/display/d.legend/local_proto.h
   grass/trunk/display/d.legend/main.c
Log:
d.legend: major rewrite to add features - ticks, more options where to put labels, background, title; author Adam Laza

Added: grass/trunk/display/d.legend/draw.c
===================================================================
--- grass/trunk/display/d.legend/draw.c	                        (rev 0)
+++ grass/trunk/display/d.legend/draw.c	2016-06-17 01:11:09 UTC (rev 68699)
@@ -0,0 +1,1020 @@
+/* draw.c:
+ *    Compute position of legend, title, labels and ticks
+ *    Extracted from original d.legend/main.c for background purpose
+ *    Moving to seperate file: Adam Laza, GSoC 2016
+ *
+ *    Copyright (C) 2014 by Hamish Bowman, and the GRASS Development Team*
+ *    This program is free software under the GPL (>=v2)
+ *    Read the COPYING file that comes with GRASS for details.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/raster3d.h>
+#include <grass/display.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+void draw(const char *map_name, int maptype, int color, int thin, int lines, int steps,
+          int fp, int label_indent, int hide_catnum, int hide_catstr, int show_ticks,
+          int hide_nodata, int do_smooth, struct Categories cats,
+          struct Colors colors, double X0, double X1, double Y0, double Y1, int flip,
+          int UserRange, double UserRangeMin, double UserRangeMax,
+          double *catlist, int catlistCount, int use_catlist, int ticksCount,
+          double fontsize, double tit_fontsize, const char *title, double *tick_values,
+          double t_step, int colorb, int colorbg,
+          struct Option *opt_use, struct Option *opt_at, struct Option *opt_fontsize,
+          struct Option *opt_ticks, struct Option *opt_tstep, struct Option *opt_range,
+          struct Flag *histo, struct Flag *hidestr, int draw)
+{
+    char buff[512];
+    int black, white;
+    int cats_num;
+    int cur_dot_row;
+    int do_cats;
+    int dots_per_line;
+    int i, j, k;
+    double t, b, l, r;
+    char *cstr;
+    double x_box[5], y_box[5];
+    struct Range range;
+    struct FPRange fprange, render_range;
+    CELL min_ind, max_ind;
+    DCELL dmin, dmax, val;
+    CELL min_colr, max_colr;
+    DCELL min_dcolr, max_dcolr;
+    int x0, x1, y0, y1, xyTemp;
+    int SigDigits;
+    unsigned int MaxLabelLen;
+    char DispFormat[5];		/*  %.Xf\0  */
+    double maxCat;
+    int horiz;
+    char *units;
+    double t_start;
+    double max_hist;
+    double txsiz, titsiz;
+    int tcell;
+    float ScaleFactor = 1.0;
+    double x_tit, y_tit, x1_tit;
+    double x0bg, y0bg, x1bg, y1bg;
+    double wleg, lleg;
+    int true_l, true_r;
+    int dx, dy;
+    double coef;
+    double ppl;
+
+
+    if (draw){
+        /* init colors */
+        black = D_translate_color(DEFAULT_FG_COLOR);
+        white = D_translate_color(DEFAULT_BG_COLOR);
+    }
+
+    /* Figure out where to put text */
+    D_setup_unity(0);
+    D_get_src(&t, &b, &l, &r);
+
+    x0 = l + (int)((r - l) * X0 / 100.);
+    x1 = l + (int)((r - l) * X1 / 100.);
+    y0 = t + (int)((b - t) * (100. - Y0) / 100.);  /* make lower left the origin */
+    y1 = t + (int)((b - t) * (100. - Y1) / 100.);
+
+    if (y0 > y1) {		/* allow for variety in order of corner */
+    flip = !flip;		/*   selection without broken output    */
+    xyTemp = y0;
+    y0 = y1;
+    y1 = xyTemp;
+    }
+    if (x0 > x1) {
+    xyTemp = x0;
+    x0 = x1;
+    x1 = xyTemp;
+    }
+
+    if (x0 == x1)
+    x1++;			/* avoid 0 width boxes */
+    if (y0 == y1)
+    y1++;
+
+    if (draw) {
+        if ((x0 < l) || (x1 > r) || (y0 < t) || (y1 > b))	/* for mouse or at= 0- or 100+; needs to be after order check */
+        G_warning(_("Legend box lies outside of frame. Text may not display properly."));
+    }
+
+    horiz = (x1 - x0 > y1 - y0);
+    if (horiz && draw)
+    G_message(_("Drawing horizontal legend as box width exceeds height"));
+
+    if (!fp && horiz)		/* better than nothing */
+    do_smooth = TRUE;
+
+    MaxLabelLen = 0;		/* init variable */
+
+    /* How many categories to show */
+    /* not fp */
+    if (!fp) {
+    if (Rast_read_range(map_name, "", &range) == -1)
+        G_fatal_error(_("Range information for <%s> not available (run r.support)"),
+              map_name);
+
+    Rast_get_range_min_max(&range, &min_ind, &max_ind);
+    if (Rast_is_c_null_value(&min_ind))
+        G_fatal_error(_("Input map contains no data"));
+
+    Rast_get_c_color_range(&min_colr, &max_colr, &colors);
+
+    if (UserRange) {
+        if (min_ind < UserRangeMin)
+        min_ind = (int)ceil(UserRangeMin);
+        if (max_ind > UserRangeMax)
+        max_ind = (int)floor(UserRangeMax);
+        if (min_ind > UserRangeMin) {
+        min_ind =
+            UserRangeMin <
+            min_colr ? min_colr : (int)ceil(UserRangeMin);
+        if (draw)
+            G_warning(_("Requested range exceeds lower limit of actual data"));
+        }
+        if (max_ind < UserRangeMax) {
+        max_ind =
+            UserRangeMax >
+            max_colr ? max_colr : (int)floor(UserRangeMax);
+        if (draw)
+            G_warning(_("Requested range exceeds upper limit of actual data"));
+        }
+    }
+
+    /*  cats_num is total number of categories in raster                  */
+    /*  do_cats is  total number of categories to be displayed            */
+    /*  k is number of cats to be displayed after skipping unlabeled cats */
+    /*  lines is number of text lines/legend window                       */
+
+    cats_num = max_ind - min_ind + 1;
+
+    if (lines == 0)
+        lines = cats_num;
+
+    do_cats = cats_num > lines ? lines : cats_num;
+
+    if (do_cats == cats_num)
+        lines = (int)ceil((1.0 * lines) / thin);
+
+    if (!use_catlist) {
+        catlist = (double *)G_calloc(lines + 1, sizeof(double));
+        catlistCount = lines;
+    }
+    /* see how many boxes there REALLY will be */
+    maxCat = 0.0;
+    for (i = min_ind, j = 1, k = 0; j <= do_cats && i <= max_ind;
+         j++, i += thin) {
+        if (!flip)
+        cstr = Rast_get_c_cat(&i, &cats);
+        else {
+        CELL cat = max_ind - (i - min_ind);
+        cstr = Rast_get_c_cat(&cat, &cats);
+        }
+
+        if (!use_catlist)
+        catlist[j - 1] = (double)i;
+
+        if (!cstr[0]) {	/* no cat label found, skip str output */
+        if (hide_nodata)
+            continue;
+        }
+        else {		/* ie has a label */
+        if (!hide_catstr && (MaxLabelLen < strlen(cstr)))
+            MaxLabelLen = strlen(cstr);
+        }
+
+        if (!hide_catnum)
+        if (i > maxCat)
+            maxCat = (double)i;
+        k++;	/* count of actual boxes drawn (hide_nodata option invaidates using j-1) */
+    }
+    lines = k;
+
+    /* figure out how long the category + label will be */
+    if (use_catlist) {
+        MaxLabelLen = 0;
+        maxCat = 0;		/* reset */
+        for (i = 0, k = 0; i < catlistCount; i++) {
+        if ((catlist[i] < min_ind) || (catlist[i] > max_ind)) {
+            G_fatal_error(_("use=%s out of range [%d,%d] (extend with range= ?)"),
+                  opt_use->answers[i], min_ind, max_ind);
+        }
+
+        cstr = Rast_get_d_cat(&catlist[i], &cats);
+        if (!cstr[0]) {	/* no cat label found, skip str output */
+            if (hide_nodata)
+            continue;
+        }
+        else {		/* ie has a label */
+            if (!hide_catstr && (MaxLabelLen < strlen(cstr)))
+            MaxLabelLen = strlen(cstr);
+        }
+        if (!hide_catnum)
+            if (catlist[i] > maxCat)
+            maxCat = catlist[i];
+        k++;
+        }
+        if (0 == k)		/* nothing to draw */
+        lines = 0;
+    }
+
+    if (MaxLabelLen > 0) {	/* ie we've picked up at least one label */
+        MaxLabelLen++;	/* compensate for leading space */
+        if (!hide_catnum)
+        MaxLabelLen += 3;	/* compensate for "%2d) " */
+    }
+    else {
+        if (!hide_catnum)
+        MaxLabelLen = 1;
+    }
+
+    /* compensate for categories >100 */
+    if (!hide_catnum) {
+        if (maxCat > 99)
+        MaxLabelLen += (int)(log10(maxCat));
+    }
+
+    /* following covers both the above if(do_cats == cats_num) and k++ loop */
+    if (lines < 1) {
+        lines = 1;		/* ward off the dpl floating point exception */
+        G_fatal_error(_("Nothing to draw! (no categories with labels? out of range?)"));
+    }
+
+    /* Figure number of lines, number of pixles per line and text size */
+    dots_per_line = ((y1 - y0) / lines);
+
+    /* switch to a smooth legend for CELL maps with too many cats */
+    /*  an alternate solution is to set   dots_per_line=1         */
+    if ((dots_per_line == 0) && (do_smooth == FALSE)) {
+        if (!use_catlist) {
+            if (draw)
+                G_message(_("Forcing a smooth legend: too many categories for current window height"));
+        do_smooth = TRUE;
+        }
+    }
+
+    /* center really tiny legends */
+    if (opt_at->answer == NULL) {	/* if defualt scaling */
+        if (!do_smooth && (dots_per_line < 4))	/* if so small that there's no box */
+        if ((b - (dots_per_line * lines)) / (b * 1.0) > 0.15)	/* if there's more than a 15% blank at the bottom */
+            y0 = ((b - t) - (dots_per_line * lines)) / 2;
+    }
+
+    /* D_text_size(dots_per_line*4/5., dots_per_line*4/5.);    redundant */
+    /* if(Rast_is_c_null_value(&min_ind) && Rast_is_c_null_value(&max_ind))
+       {
+       min_ind = 1;
+       max_ind = 0;
+       } */
+
+    if (horiz)
+        sprintf(DispFormat, "%%d");
+    else {
+        if (maxCat > 0.0)
+        sprintf(DispFormat, "%%%dd", (int)(log10(fabs(maxCat))) + 1);
+        else
+        sprintf(DispFormat, "%%2d");
+    }
+    }   /* end of if(!fp) */
+
+    else {	/* is fp */
+    if (maptype == MAP_TYPE_RASTER2D) {
+        if (Rast_read_fp_range(map_name, "", &fprange) == -1)
+        G_fatal_error(_("Range information for <%s> not available"),
+                map_name);
+    }
+    else {
+        if (Rast3d_read_range(map_name, "", &fprange) == -1)
+        G_fatal_error(_("Range information for <%s> not available"),
+                map_name);
+    }
+
+    Rast_get_fp_range_min_max(&fprange, &dmin, &dmax);
+    Rast_get_d_color_range(&min_dcolr, &max_dcolr, &colors);
+
+    if (UserRange) {
+        if (dmin < UserRangeMin)
+        dmin = UserRangeMin;
+        if (dmax > UserRangeMax)
+        dmax = UserRangeMax;
+        if (dmin > UserRangeMin) {
+        dmin = UserRangeMin < min_dcolr ? min_dcolr : UserRangeMin;
+        G_warning(_("Color range exceeds lower limit of actual data"));
+        }
+        if (dmax < UserRangeMax) {
+        dmax = UserRangeMax > max_dcolr ? max_dcolr : UserRangeMax;
+        G_warning(_("Color range exceeds upper limit of actual data"));
+        }
+    }
+
+    if (use_catlist) {
+        for (i = 0; i < catlistCount; i++) {
+        if ((catlist[i] < dmin) || (catlist[i] > dmax)) {
+            G_fatal_error(_("use=%s out of range [%.3f, %.3f] (extend with range= ?)"),
+                  opt_use->answers[i], dmin, dmax);
+        }
+        if (strlen(opt_use->answers[i]) > MaxLabelLen)
+            MaxLabelLen = strlen(opt_use->answers[i]);
+        }
+    }
+    do_cats = 0;		/* if only to get rid of the compiler warning  */
+    cats_num = 0;		/* if only to get rid of the compiler warning  */
+    /* determine how many significant digits to display based on range */
+    if (0 == (dmax - dmin))	/* trap divide by 0 for single value rasters */
+        sprintf(DispFormat, "%%f");
+    else {
+        SigDigits = (int)ceil(log10(fabs(25 / (dmax - dmin))));
+        if (SigDigits < 0)
+        SigDigits = 0;
+        if (SigDigits < 7)
+        sprintf(DispFormat, "%%.%df", SigDigits);
+        else
+        sprintf(DispFormat, "%%.2g");	/* eg 4.2e-9  */
+    }
+    } /* end of is fp */
+
+    if (use_catlist) {
+    cats_num = catlistCount;
+    do_cats = catlistCount;
+    lines = catlistCount;
+    do_smooth = FALSE;
+    }
+
+
+    if (do_smooth) {
+    if (horiz) {
+        if (draw) {
+            lleg = x1 - x0;
+            dx = 0;
+            dy = y1 - y0;
+        }
+        if (fp)
+        flip = !flip;	/* horiz floats look better not flipped by default */
+    }
+    else {
+        if (draw) {
+            lleg = y1 - y0;
+            dy = 0;
+            dx = x1 - x0;
+        }
+    }
+
+    /* Draw colors */
+    /* Draw the legend bar */
+    if (draw) {
+    for (k = 0; k < lleg; k++) {
+        if (!fp) {
+        if (!flip)
+            tcell =
+            min_ind + k * (double)(1 + max_ind - min_ind) / lleg;
+        else
+            tcell =
+            (max_ind + 1) - k * (double)(1 + max_ind -
+                             min_ind) / lleg;
+        D_color((CELL) tcell, &colors);
+        }
+        else {
+        if (!flip)
+            val = dmin + k * (dmax - dmin) / lleg;
+        else
+            val = dmax - k * (dmax - dmin) / lleg;
+        D_d_color(val, &colors);
+        }
+
+        if (dx < dy)
+        D_box_abs(x0 + k, y0, x0 + k + (dx ? -dx : 1),
+              y0 - (dy ? -dy : 1));
+        else
+        D_box_abs(x0, y0 + k, x0 - (dx ? -dx : 1),
+              y0 + k + (dy ? -dy : 1));
+    }
+    }
+
+    /* Format text */
+    if (!fp) {		/* cut down labelnum so they don't repeat */
+        if (do_cats < steps)
+        steps = do_cats;
+        if ((steps < 2))
+        steps = 2;	/* ward off the ppl floating point exception */
+    }
+
+    /* Draw text and ticks */
+    if (!horiz)
+    txsiz = (y1 - y0) / 20;
+    else
+    txsiz = (x1 - x0) / 20;
+
+    wleg = x1 - x0;
+    lleg = y1 - y0;
+
+    /* scale text to fit in window if position not manually set */
+    /* usually not needed, except when frame is really narrow   */
+    if (opt_at->answer == NULL) {	/* ie default scaling */
+    ScaleFactor = ((r - x1) / ((MaxLabelLen + 1) * txsiz * 0.81));	/* ?? txsiz*.81=actual text width. */
+    if (ScaleFactor < 1.0) {
+        txsiz = txsiz * ScaleFactor;
+    }
+    }
+
+    if (opt_fontsize->answer != NULL)
+    txsiz = fontsize;
+
+    if (txsiz < 0)
+    txsiz = 0;	/* keep it sane */
+
+    if (tit_fontsize == 0)
+        titsiz = txsiz;
+    else
+        titsiz = tit_fontsize;
+
+    if (draw) {
+        D_text_size(txsiz, txsiz);
+        D_use_color(color);
+    }
+
+    /* Draw labels and ticks */
+    /* LABELNUM OPTION */
+    if (steps >= 2) {
+        for (k = 0; k < steps; k++) {
+            if (!fp) {
+            if (!flip)
+                tcell =
+                min_ind + k * (double)(max_ind - min_ind) / (steps - 1);
+            else
+                tcell =
+                max_ind - k * (double)(max_ind - min_ind) / (steps - 1);
+
+            if (!cstr[0])	/* no cats found, disable str output */
+                hide_catstr = 1;
+            else
+                hide_catstr = hidestr->answer;
+
+            buff[0] = 0;	/* blank string */
+
+            if (!hide_catnum) {	/* num */
+                sprintf(buff, DispFormat, tcell);
+                if (!hide_catstr)	/* both */
+                strcat(buff, ")");
+            }
+            if (!hide_catstr)	/* str */
+                sprintf(buff + strlen(buff), " %s", cstr);
+            }
+            else {		/* ie FP map */
+            if (hide_catnum)
+                buff[0] = 0;	/* no text */
+            else {
+                if (!flip)
+                val = dmin + k * (dmax - dmin) / (steps - 1);
+                else
+                val = dmax - k * (dmax - dmin) / (steps - 1);
+
+                sprintf(buff, DispFormat, val);
+
+            }
+            }
+
+            if (draw) {
+                ppl = (lleg) / (steps * 1.0 - 1);
+                if (!hide_catnum) {
+                    if (!horiz) {
+                        D_pos_abs(x1 + label_indent, y0 + ppl * k + txsiz / 2);
+                        if (show_ticks)
+                            D_line_abs(x1, y0 + ppl * k, x1 + 6, y0 + ppl * k);
+                    }
+                    else {
+                    /* text width is 0.81 of text height? so even though we set width
+                       to txsiz with D_text_size(), we still have to reduce.. hmmm */
+                        D_pos_abs(x0 + ppl * k - (strlen(buff) * txsiz * .81 / 2),
+                                  y1 + label_indent + txsiz);
+                        if (show_ticks)
+                            D_line_abs(x0 + ppl * k, y1, x0 + ppl * k, y1 + 6);
+                    }
+                    if (color)
+                    D_text(buff);
+                }
+            }
+            if (strlen(buff) > MaxLabelLen)
+            MaxLabelLen = strlen(buff);
+        }	/* for */
+    }
+
+    /* LABEL_VALUE OPTION */
+    if (ticksCount > 0) {
+        for (i = 0; i < ticksCount; i++) {
+            if ((tick_values[i] < dmin) || (tick_values[i] > dmax)) {
+                G_fatal_error(_("tick_value=%s out of range [%.3f, %.3f]"),
+                      opt_ticks->answers[i], dmin, dmax);
+            }
+            sprintf(buff, DispFormat, tick_values[i]);
+
+            coef = (tick_values[i] - dmin) / ((dmax - dmin) * 1.0);
+            if (draw) {
+                if (!flip){
+                    if (!horiz) {
+                        if (show_ticks)
+                            D_line_abs(x1, y0 + coef * lleg,
+                                       x1 + 6, y0 + coef * lleg);
+                        D_pos_abs(x1 + label_indent, y0 + coef * lleg + txsiz/2);}
+                    else {
+                        if (show_ticks)
+                            D_line_abs(x0 + coef * wleg, y1,
+                                       x0 + coef * wleg, y1 + 6);
+                        D_pos_abs(x0 + coef * wleg - (strlen(buff) * txsiz * .81 / 2),
+                                  y1 + label_indent + txsiz);}
+                }
+                else{
+                    if (!horiz) {
+                        if (show_ticks)
+                            D_line_abs(x1, y1 - coef * lleg,
+                                       x1 + 6, y1 - coef * lleg);
+                        D_pos_abs(x1 + label_indent, y1 - coef * lleg + txsiz/2);}
+                    else {
+                        if (show_ticks)
+                            D_line_abs(x1 - coef * wleg, y1,
+                                       x1 - coef * wleg, y1 + 6);
+                        D_pos_abs(x1 - coef * wleg - (strlen(buff) * txsiz * .81 / 2),
+                                  y1 + label_indent + txsiz);}
+                }
+            D_text(buff);
+            }
+
+            if (strlen(buff) > MaxLabelLen)
+            MaxLabelLen = strlen(buff);
+        }
+    }
+
+    /* LABEL_STEP OPTION */
+    if (opt_tstep->answer) {
+        t_start = ceil(dmin/t_step) * t_step;
+        if (t_start == -0)
+            t_start = 0;
+
+        if (!flip){
+            if (!horiz)
+                while (t_start<dmax) {
+                    sprintf(buff, DispFormat, t_start);
+                    if (strlen(buff) > MaxLabelLen)
+                    MaxLabelLen = strlen(buff);
+
+                    if (draw) {
+                        coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
+                        if (show_ticks)
+                            D_line_abs(x1, y0 + coef * lleg,
+                                       x1 + 6, y0 + coef * lleg);
+                        D_pos_abs(x1 + label_indent, y0 + coef * lleg + txsiz/2);
+                        D_text(buff);
+                    }
+                    t_start += t_step;}
+            else
+                while (t_start<dmax) {
+                    sprintf(buff, DispFormat, t_start);
+                    if (strlen(buff) > MaxLabelLen)
+                    MaxLabelLen = strlen(buff);
+
+                    if (draw) {
+                        coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
+                        if (show_ticks)
+                            D_line_abs(x0 + coef * wleg,y1,
+                                       x0 + coef * wleg, y1 + 6);
+                        D_pos_abs(x0 + coef * wleg - (strlen(buff) * txsiz * .81 / 2),
+                                  y1 + label_indent + txsiz);
+                        D_text(buff);
+                    }
+                    t_start += t_step;}
+        }
+        else{
+            if (!horiz)
+                while (t_start<dmax) {
+                    sprintf(buff, DispFormat, t_start);
+                    if (strlen(buff) > MaxLabelLen)
+                    MaxLabelLen = strlen(buff);
+
+                    if (draw) {
+                        coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
+                        if (show_ticks)
+                            D_line_abs(x1, y1 - coef * lleg,
+                                       x1 + 6, y1 - coef * lleg);
+                        D_pos_abs(x1 + label_indent, y1 - coef * lleg + txsiz/2);
+                        D_text(buff);
+                    }
+                    t_start += t_step;}
+            else
+                while (t_start<dmax) {
+                    sprintf(buff, DispFormat, t_start);
+                    if (strlen(buff) > MaxLabelLen)
+                    MaxLabelLen = strlen(buff);
+
+                    if (draw) {
+                        coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
+                        if (show_ticks)
+                            D_line_abs(x1 - coef * wleg, y1,
+                                       x1 - coef * wleg, y1 + 6);
+                        D_pos_abs(x1 - coef * wleg - (strlen(buff) * txsiz * .81 / 2),
+                                  y1 + label_indent + txsiz);
+                        D_text(buff);
+                    }
+                    t_start += t_step;}
+        }
+    }
+
+    if (draw) {
+    /* Draw boxes outside of legend bar */
+    /* White box */
+    D_use_color(white);
+    D_begin();
+    D_move_abs(x0 + 1, y0 + 1);
+    D_cont_rel(0, lleg - 2);
+    D_cont_rel(wleg - 2, 0);
+    D_cont_rel(0, -lleg + 2);
+    D_close();
+    D_end();
+    D_stroke();
+
+    /* Black box */
+    D_use_color(black);
+    D_begin();
+    D_move_abs(x0, y0 );
+    D_cont_rel(0, lleg);
+    D_cont_rel(wleg, 0);
+    D_cont_rel(0, -lleg);
+    D_close();
+    D_end();
+    D_stroke();
+    }
+
+    /* Display sidebar histogram, if requested.
+    /  In case of horizontal legend, maximum of histogram - max_hist
+       will efect the title position */
+    max_hist = 0;
+    if (histo->answer) {
+        render_range.min = (DCELL)(fp ? dmin : min_ind);
+        render_range.max = (DCELL)(fp ? dmax : max_ind);
+        /* reuse flag to indicate if user-specified or default ranging */
+        render_range.first_time = opt_range->answer ? TRUE : FALSE;
+
+        if (draw)
+            max_hist = histogram(map_name, x0, y0, wleg, lleg, color, flip, horiz,
+                                  maptype, fp, render_range, 1);
+        else
+            max_hist = histogram(map_name, x0, y0, wleg, lleg, color, flip, horiz,
+                                  maptype, fp, render_range, 0);
+    }
+
+
+    /* display title or units */
+    if(strlen(title) > 0){
+    /* title */
+        if (horiz){
+            x_tit = (x0 + x1)/2. - (strlen(title) * titsiz * 0.81)/2;
+            y_tit = y0 - (titsiz) - max_hist;
+        }
+        else{
+            x_tit = x0;
+            y_tit = y0 - (titsiz);
+        }
+        x1_tit = x_tit + strlen(title) * titsiz * 0.81;
+
+        if (draw) {
+            D_use_color(color);
+            /* use tit_fontsize */
+            D_text_size(titsiz, titsiz);
+
+            D_pos_abs(x_tit, y_tit);
+            D_text(title);
+            /* restart fontsize */
+            D_text_size(txsiz, txsiz);
+        }
+    }
+    else{
+    /* units */
+        /* print units label, if present */
+        if (maptype == MAP_TYPE_RASTER2D)
+            units = Rast_read_units(map_name, "");
+        else
+            units = "";
+        /* FIXME: does the raster3d really need to be opened to read the units?
+           units = Rast3d_get_unit(map_fid); */
+
+        if (!units)
+            units = "";
+
+        if(strlen(units)) {
+            if (horiz) {
+            x_tit = (x0 + x1)/2. - (strlen(units) * txsiz * 0.81)/2;
+            y_tit = y1 + (txsiz * 2.75);
+            }
+            else {
+            x_tit = x0;
+            }
+            x1_tit = x_tit + strlen(units) * titsiz * 0.81;
+
+            if (draw) {
+                D_use_color(color);
+                D_pos_abs(x_tit, y_tit);
+                D_text(units);
+            }
+        }
+    }   /* end of display units) */
+
+    if (!draw){
+        /* Draw background */
+        if (!horiz){
+            x0bg = x0 - max_hist - txsiz;
+            x1bg = x0 + wleg + label_indent + (MaxLabelLen * txsiz * 0.81) + txsiz;
+            if (x1bg < x1_tit)
+                x1bg = x1_tit + txsiz;
+            y1bg = y0 + lleg + txsiz;
+            if (strlen(title) > 0)
+                y0bg = y0 - (2.5 * titsiz);
+            else
+                y0bg = y0 - titsiz;
+        }
+        else{
+            x0bg = x0 - (MaxLabelLen * txsiz * 0.81)/2 - txsiz ;
+            x1bg = x0 + wleg + (MaxLabelLen * txsiz * 0.81)/2 + txsiz;
+            if (x1bg < x1_tit){
+                x0bg = x_tit - txsiz;
+                x1bg = x1_tit + txsiz;
+            }
+            y1bg = y0 + lleg + label_indent + 1.5 * txsiz;
+            if (strlen(title) > 0)
+                y0bg = y0 - (2.5 * titsiz) - max_hist;
+            else
+                y0bg = y0 - titsiz - max_hist;
+        }
+
+        D_use_color(colorbg);
+        D_box_abs(x0bg, y0bg, x1bg, y1bg);
+
+        D_use_color(colorb);
+        D_begin();
+        D_move_abs(x0bg, y0bg);
+        D_cont_abs(x0bg, y1bg);
+        D_cont_abs(x1bg, y1bg);
+        D_cont_abs(x1bg, y0bg);
+        D_close();
+        D_end();
+        D_stroke();
+    }
+
+    }   /* end of if(do_smooth) */
+
+    else {	/* non FP, no smoothing */
+    ScaleFactor = 1.0;
+
+    if (histo->answer)
+        G_warning(_("Histogram plotting not implemented for categorical legends. "
+            "Use the '-s' flag"));
+
+    /* set legend box bounds */
+    true_l = l;
+    true_r = r;	/* preserve window width */
+    l = x0;
+    t = y0;
+    r = x1;
+    b = y1;
+
+    /* figure out box height  */
+    if (do_cats == cats_num)
+        dots_per_line = (b - t) / (lines + 1);	/* +1 line for the two 1/2s at top and bottom */
+    else
+        dots_per_line = (b - t) / (lines + 2);	/* + another line for 'x of y categories' text */
+
+    /* adjust text size */
+    /*  txsiz = (int)((y1-y0)/(1.5*(lines+5))); */
+    txsiz = (y1 - y0) / (2.0 * lines);
+
+    if (tit_fontsize == 0)
+        titsiz = txsiz;
+    else
+        titsiz = tit_fontsize;
+
+    /* scale text to fit in window if position not manually set */
+    if (opt_at->answer == NULL) {	/* ie defualt scaling */
+        ScaleFactor = ((true_r - true_l) / ((MaxLabelLen + 3) * txsiz * 0.81));	/* ?? txsiz*.81=actual text width. */
+        if (ScaleFactor < 1.0) {
+        txsiz = txsiz * ScaleFactor;
+        dots_per_line = (int)floor(dots_per_line * ScaleFactor);
+        }
+    }
+
+    if (dots_per_line < txsiz)
+        txsiz = dots_per_line;
+
+    if (opt_fontsize->answer != NULL)
+        txsiz = fontsize;
+
+    /* Set up box arrays */
+    x_box[0] = 0;
+    y_box[0] = 0;
+    x_box[1] = 0;
+    y_box[1] = (5 - dots_per_line);
+    x_box[2] = (dots_per_line - 5);
+    y_box[2] = 0;
+    x_box[3] = 0;
+    y_box[3] = (dots_per_line - 5);
+    x_box[4] = (5 - dots_per_line);
+    y_box[4] = 0;
+
+
+    /* Draw away */
+
+    /* if(ScaleFactor < 1.0)   */
+    /*    cur_dot_row = ((b-t) - (dots_per_line*lines))/2; *//* this will center the legend */
+    /* else    */
+    cur_dot_row = t + dots_per_line / 2;
+
+    /*  j = (do_cats == cats_num ? 1 : 2 ); */
+
+    if (draw) {
+        D_pos_abs(x0, y0);
+        D_text_size(txsiz, txsiz);
+    }
+
+    for (i = 0, k = 0; i < catlistCount; i++)
+        /* for(i=min_ind, j=1, k=0; j<=do_cats && i<=max_ind; j++, i+=thin) */
+    {
+        if (!flip)
+        cstr = Rast_get_d_cat(&catlist[i], &cats);
+        else
+        cstr = Rast_get_d_cat(&catlist[catlistCount - i - 1], &cats);
+
+
+        if (!cstr[0]) {	/* no cat label found, skip str output */
+        hide_catstr = 1;
+        if (hide_nodata)
+            continue;
+        }
+        else
+        hide_catstr = hidestr->answer;
+
+        k++;  /* count of actual boxes drawn (hide_nodata option invaidates using j-1) */
+
+        cur_dot_row += dots_per_line;
+
+        if (draw) {
+            /* Black box */
+            D_use_color(black);
+            D_begin();
+            D_move_abs(l + 2, (cur_dot_row - 1));
+            D_cont_rel(0, (3 - dots_per_line));
+            D_cont_rel((dots_per_line - 3), 0);
+            D_cont_rel(0, (dots_per_line - 3));
+            D_close();
+            D_end();
+            D_stroke();
+
+            /* White box */
+            D_use_color(white);
+            D_begin();
+            D_move_abs(l + 3, (cur_dot_row - 2));
+            D_cont_rel(0, (5 - dots_per_line));
+            D_cont_rel((dots_per_line - 5), 0);
+            D_cont_rel(0, (dots_per_line - 5));
+            D_close();
+            D_end();
+            D_stroke();
+
+
+            /* Color solid box */
+            if (!fp) {
+            if (!flip)
+                D_color((CELL) (int)catlist[i], &colors);
+            else
+                D_color((CELL) (int)catlist[catlistCount - i - 1],
+                    &colors);
+            }
+            else {
+            if (!flip)
+                D_d_color(catlist[i], &colors);
+            else
+                D_d_color(catlist[catlistCount - i - 1], &colors);
+            }
+
+            D_pos_abs(l + 3, (cur_dot_row - 2));
+            D_polygon_rel(x_box, y_box, 5);
+
+            /* Draw text */
+            D_use_color(color);
+        }
+
+
+        if (!fp) {
+        /* nothing, box only */
+        buff[0] = 0;
+        if (!hide_catnum) {	/* num */
+            sprintf(buff, DispFormat, (int)catlist[i]);
+            if (!flip)
+            sprintf(buff, DispFormat, (int)catlist[i]);
+            else
+            sprintf(buff, DispFormat,
+                (int)catlist[catlistCount - i - 1]);
+            if (!hide_catstr)	/* both */
+            strcat(buff, ")");
+        }
+        if (!hide_catstr)	/* str */
+            sprintf(buff + strlen(buff), " %s", cstr);
+        }
+        else {		/* is fp */
+        if (!flip) {
+            if (use_catlist)
+            /* pass through format exactly as given by the user in
+               the use= command line parameter (helps with log scale) */
+            sprintf(buff, "%s", opt_use->answers[i]);
+            else
+            /* automatically generated/tuned decimal precision format */
+            sprintf(buff, DispFormat, catlist[i]);
+        }
+        else {
+            if(use_catlist)
+            sprintf(buff, "%s", opt_use->answers[catlistCount - i - 1]);
+            else
+            sprintf(buff, DispFormat, catlist[catlistCount - i - 1]);
+        }
+        }
+        if (strlen(buff)>MaxLabelLen)
+            MaxLabelLen = strlen(buff);
+
+        if (draw) {
+            D_pos_abs((l + 3 + dots_per_line), (cur_dot_row) - 3);
+            if (color)
+            D_text(buff);
+        }
+    }
+
+    if (0 == k)
+        G_fatal_error(_("Nothing to draw! (no categories with labels?)"));	/* "(..., out of range?)" */
+
+    /* display title */
+    if(strlen(title) > 0){
+        x_tit = x0;
+        y_tit = y0;
+        x1_tit = x_tit + strlen(title) * titsiz * 0.81;
+
+        if (draw) {
+            D_use_color(color);
+            /* use tit_fontsize */
+            D_text_size(titsiz, titsiz);
+            D_pos_abs(x_tit, y_tit);
+            D_text(title);
+            /* restart fontsize */
+            D_text_size(txsiz, txsiz);
+        }
+    }
+
+    /* Display info line about numbers of categories */
+    if (do_cats != cats_num) {
+        cur_dot_row += dots_per_line;
+        /* sprintf(buff, "%d of %d categories\n", (j-1), cats_num); */
+
+        sprintf(buff, "%d of %d categories\n", k, cats_num);
+        if (strlen(buff)>MaxLabelLen)
+            MaxLabelLen = strlen(buff);
+
+        if (draw) {
+            if (opt_fontsize->answer != NULL)
+                txsiz = fontsize;
+            D_text_size(txsiz, txsiz);
+            D_use_color(black);
+            D_pos_abs((l + 3 + dots_per_line), (cur_dot_row));
+            if (color)
+            D_text(buff);
+        }
+    }
+
+    if (!draw) {
+        /* Draw background */
+        x0bg = x0 - txsiz;
+        x1bg = x0 + dots_per_line + 3 + (MaxLabelLen * txsiz * 0.81) + txsiz;
+        if (x1bg < x1_tit)
+            x1bg = x1_tit + txsiz;
+        y1bg = cur_dot_row + txsiz;
+        if (strlen(title) > 0)
+            y0bg = y0 - (2 * titsiz);
+        else
+            y0bg = y0 ;
+
+
+        D_use_color(colorbg);
+        D_box_abs(x0bg, y0bg, x1bg, y1bg);
+
+        D_use_color(colorb);
+        D_begin();
+        D_move_abs(x0bg, y0bg);
+        D_cont_abs(x0bg, y1bg);
+        D_cont_abs(x1bg, y1bg);
+        D_cont_abs(x1bg, y0bg);
+        D_close();
+        D_end();
+        D_stroke();
+    }
+
+    }
+    D_save_command(G_recreate_command());
+}


Property changes on: grass/trunk/display/d.legend/draw.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass/trunk/display/d.legend/histogram.c
===================================================================
--- grass/trunk/display/d.legend/histogram.c	2016-06-16 14:39:05 UTC (rev 68698)
+++ grass/trunk/display/d.legend/histogram.c	2016-06-17 01:11:09 UTC (rev 68699)
@@ -13,13 +13,13 @@
 #include <grass/glocale.h>
 #include "local_proto.h"
 
-void draw_histogram(const char *map_name, int x0, int y0, int width,
-		    int height, int color, int flip, int horiz,
-		    int map_type, int is_fp, struct FPRange render_range)
+double histogram(const char *map_name, int x0, int y0, int width,
+            int height, int color, int flip, int horiz, int map_type,
+            int is_fp, struct FPRange render_range, int drawh)
 {
     int i, nsteps, ystep;
     long cell_count = 0;
-    double max_width, width_mult, dx;
+    double max_width, width_mult, dx, max;
     double dy, y0_adjust;	/* only needed for CELL maps */
     struct stat_list dist_stats;
     struct stat_node *ptr;
@@ -39,7 +39,10 @@
 	nsteps = height - 3;
     }
 
+    /* reset return value max */
+    max = 0;
 
+
     if (render_range.first_time) {
 	/* user specified range, can be either larger
 	    or smaller than actual map's range */
@@ -107,7 +110,7 @@
     if (!is_fp && render_range.first_time) {
 	G_warning(_("Histogram constrained by range not yet implemented for "
 		  "categorical rasters"));
-	return;
+	return max;
     }
 
 
@@ -115,12 +118,12 @@
     get_stats(map_name, &dist_stats, nsteps, map_type);
 
     width_mult = max_width / dist_stats.maxstat;
+    ptr = dist_stats.ptr;
 
+    if (drawh) {
     D_use_color(color);
     D_begin();
 
-    ptr = dist_stats.ptr;
-
     if (!is_fp) {
 	dy = (nsteps + 3.0) / (1 + dist_stats.maxcat - dist_stats.mincat);
 
@@ -135,6 +138,7 @@
 	if (!flip)  /* mmph */
 	    y0_adjust += 0.5;
     }
+    }
 
 
     G_debug(3, "mincat=%ld  maxcat=%ld", dist_stats.mincat, dist_stats.maxcat);
@@ -198,6 +202,7 @@
 
 	dx = cell_count * width_mult;
 
+    if (drawh){
 	if (is_fp) {
 	    if (horiz) {
 		if (flip)
@@ -246,8 +251,15 @@
 	    }
 	}
     }
+    if (dx > max)
+        max = dx;
+    }
 
+    if (drawh) {
     D_close();
     D_end();
     D_stroke();
 }
+
+    return max;
+}

Modified: grass/trunk/display/d.legend/local_proto.h
===================================================================
--- grass/trunk/display/d.legend/local_proto.h	2016-06-16 14:39:05 UTC (rev 68698)
+++ grass/trunk/display/d.legend/local_proto.h	2016-06-17 01:11:09 UTC (rev 68699)
@@ -29,9 +29,26 @@
 
 
 /* histogram.c */
-void draw_histogram(const char *, int, int, int, int, int, int, int, int,
-		    int, struct FPRange);
+double histogram(const char *, int, int, int, int, int, int, int, int,
+            int, struct FPRange, int);
 
 /* get_stats.c */
 void get_stats(const char *, struct stat_list *, int, int);
 void run_stats(const char *, int, const char *, int);
+
+/* background.c */
+void background(const char *, int, int, int, int, int, int, int, int, int, int,
+                int, int, struct Categories, struct Colors, double, double, double,
+                double, int, int, double, double, double *, int, int, int, double,
+                double, const char *, double *, double, int, int, struct Option *,
+                struct Option *, struct Option *, struct Option *, struct Option *,
+                struct Option *, struct Flag *, struct Flag *);
+
+/* draw.c */
+void draw(const char *, int, int, int, int, int, int, int, int, int, int, int, int,
+          struct Categories, struct Colors, double, double, double, double, int, int,
+          double, double, double *, int, int, int, double, double ,const char *,
+          double *, double, int, int, struct Option *, struct Option *, struct Option *,
+          struct Option *, struct Option *, struct Option *, struct Flag *,
+          struct Flag *, int);
+

Modified: grass/trunk/display/d.legend/main.c
===================================================================
--- grass/trunk/display/d.legend/main.c	2016-06-16 14:39:05 UTC (rev 68698)
+++ grass/trunk/display/d.legend/main.c	2016-06-17 01:11:09 UTC (rev 68699)
@@ -39,51 +39,34 @@
 
 int main(int argc, char **argv)
 {
-    char buff[512];
     char *map_name;
     int maptype;
-    int black, white, color;
-    int cats_num;
-    int cur_dot_row;
-    int do_cats;
-    int dots_per_line;
-    int i, j, k;
+    int color;
+    int i;
     int thin, lines, steps;
     int fp;
     int label_indent;
-    double t, b, l, r;
-    int hide_catnum, hide_catstr, show_ticks, hide_nodata, do_smooth;
-    char *cstr;
-    double x_box[5], y_box[5];
+    int hide_catnum, hide_catstr, show_ticks, show_bg, hide_nodata, do_smooth;
     struct Categories cats;
     struct Colors colors;
     struct GModule *module;
     struct Option *opt_rast2d, *opt_rast3d, *opt_color, *opt_lines,
 		  *opt_thin, *opt_labelnum, *opt_at, *opt_use, *opt_range,
           *opt_font, *opt_path, *opt_charset, *opt_fontsize, *opt_title,
-          *opt_ticks, *opt_tstep;
+          *opt_ticks, *opt_tstep, *opt_brdcolor, *opt_bgcolor, *opt_tit_fontsize;
     struct Flag *hidestr, *hidenum, *hidenodata, *smooth, *flipit, *histo,
-            *showtick;
-    struct Range range;
-    struct FPRange fprange, render_range;
-    CELL min_ind, max_ind;
-    DCELL dmin, dmax, val;
-    CELL min_colr, max_colr;
-    DCELL min_dcolr, max_dcolr;
-    int x0, x1, y0, y1, xyTemp;
+            *showtick, *showbg;
     double X0, X1, Y0, Y1;
-    int SigDigits;
-    unsigned int MaxLabelLen;
-    char DispFormat[5];		/*  %.Xf\0  */
-    int flip, horiz, UserRange;
+    int flip, UserRange;
     double UserRangeMin, UserRangeMax, UserRangeTemp;
-    double *catlist, maxCat;
+    double *catlist;
     int catlistCount, use_catlist, ticksCount;
     double fontsize;
-    char *units;
     char *title;
     double *tick_values;
-    double t_start, t_step;
+    double t_step;
+    int colorb, colorbg;
+    double tit_fontsize;
 
     /* Initialize the GIS calls */
     G_gisinit(argv[0]);
@@ -111,7 +94,17 @@
     opt_title->type = TYPE_STRING;
     opt_title->required = NO;
     opt_title->description = _("Legend title");
+    opt_title->guisection = _("Title");
 
+    opt_tit_fontsize = G_define_option();
+    opt_tit_fontsize->key = "title_fontsize";
+    opt_tit_fontsize->type = TYPE_DOUBLE;
+    opt_tit_fontsize->required = NO;
+    opt_tit_fontsize->options = "1-360";
+    opt_tit_fontsize->label = _("Title font size");
+    opt_tit_fontsize->description = _("Default: Same as fontsize");
+    opt_tit_fontsize->guisection = _("Title");
+
     opt_lines = G_define_option();
     opt_lines->key = "lines";
     opt_lines->type = TYPE_INTEGER;
@@ -145,7 +138,7 @@
     opt_ticks->type = TYPE_DOUBLE;
     opt_ticks->required = NO;
     opt_ticks->description =
-    _("Specific values of text labels");
+    _("Specific values to draw ticks");
     opt_ticks->required = NO;
     opt_ticks->multiple = YES;
     opt_ticks->guisection = _("Gradient");
@@ -225,6 +218,19 @@
 	_("Text encoding (only applicable to TrueType fonts)");
     opt_charset->guisection = _("Font settings");
 
+    opt_brdcolor = G_define_standard_option(G_OPT_CN);
+    opt_brdcolor->key = "borde_color";
+    opt_brdcolor->answer = "black";
+    opt_brdcolor->label = _("Border color");
+    opt_brdcolor->guisection = _("Background");
+
+    opt_bgcolor = G_define_standard_option(G_OPT_CN);
+    opt_bgcolor->key = "bgcolor";
+    opt_bgcolor->answer = "white";
+    opt_bgcolor->label = _("Background color");
+    opt_bgcolor->guisection = _("Background");
+
+
     hidestr = G_define_flag();
     hidestr->key = 'v';
     hidestr->description = _("Do not show category labels");
@@ -260,6 +266,11 @@
     histo->description = _("Add histogram to smoothed legend");
     histo->guisection = _("Gradient");
 
+    showbg = G_define_flag();
+    showbg->key = 'b';
+    showbg->description = _("Show background");
+    showbg->guisection = _("Background");
+
     G_option_required(opt_rast2d, opt_rast3d, NULL);
     G_option_exclusive(opt_rast2d, opt_rast3d, NULL);
     G_option_exclusive(hidenum, opt_ticks, NULL);
@@ -280,6 +291,8 @@
 
     if (opt_title->answer)
         title = opt_title->answer;
+    else
+        title = "";
 
     hide_catstr = hidestr->answer;	/* note hide_catstr gets changed and re-read below */
     hide_catnum = hidenum->answer;
@@ -287,9 +300,9 @@
     hide_nodata = hidenodata->answer;
     do_smooth = smooth->answer;
     flip = flipit->answer;
+    show_bg = showbg->answer;
 
     if (showtick->answer){
-        show_ticks = showtick->answer;
         label_indent = 12;
     }
     else
@@ -308,7 +321,7 @@
 
     if (opt_labelnum->answer != NULL)
 	sscanf(opt_labelnum->answer, "%d", &steps);
-
+    
     if ((opt_tstep->answer) || (opt_ticks->answer))
         steps = 0;
 
@@ -383,8 +396,9 @@
 
     D_open_driver();
 
-    black = D_translate_color(DEFAULT_FG_COLOR);
-    white = D_translate_color(DEFAULT_BG_COLOR);
+    /* Parse and select background color */
+    colorb = D_parse_color(opt_brdcolor->answer, TRUE);
+    colorbg = D_parse_color(opt_bgcolor->answer, TRUE);
 
     if (opt_font->answer)
 	D_font(opt_font->answer);
@@ -399,9 +413,10 @@
     if (opt_charset->answer)
 	D_encoding(opt_charset->answer);
 
-    /* Figure out where to put text */
-    D_setup_unity(0);
-    D_get_src(&t, &b, &l, &r);
+    if (opt_tit_fontsize->answer != NULL)
+        tit_fontsize = atof(opt_tit_fontsize->answer);
+    else
+        tit_fontsize = 0;
 
     if (opt_at->answer != NULL) {
 	sscanf(opt_at->answers[0], "%lf", &Y1);
@@ -420,811 +435,29 @@
 	    X1 += 5;
 	}
     }
+//    if (show_bg)
+//        background(map_name, maptype, color, thin, lines, steps, fp, label_indent, hide_catnum,
+//                   hide_catstr, show_ticks, hide_nodata, do_smooth, cats, colors, X0,
+//                   X1, Y0, Y1, flip, UserRange, UserRangeMin, UserRangeMax, catlist, catlistCount,
+//                   use_catlist, ticksCount, fontsize, tit_fontsize, title, tick_values, t_step,
+//                   colorb, colorbg, opt_use, opt_at, opt_fontsize, opt_ticks, opt_tstep, opt_range,
+//                   histo, hidestr);
 
-    x0 = l + (int)((r - l) * X0 / 100.);
-    x1 = l + (int)((r - l) * X1 / 100.);
-    y0 = t + (int)((b - t) * (100. - Y0) / 100.);  /* make lower left the origin */
-    y1 = t + (int)((b - t) * (100. - Y1) / 100.);
+    if (show_bg)
+        draw(map_name, maptype, color, thin, lines, steps, fp, label_indent, hide_catnum,
+             hide_catstr, show_ticks, hide_nodata, do_smooth, cats, colors, X0,
+             X1, Y0, Y1, flip, UserRange, UserRangeMin, UserRangeMax, catlist, catlistCount,
+             use_catlist, ticksCount, fontsize, tit_fontsize, title, tick_values, t_step, colorb,
+             colorbg, opt_use, opt_at, opt_fontsize, opt_ticks, opt_tstep, opt_range, histo, hidestr,
+             0);
 
-    if (y0 > y1) {		/* allow for variety in order of corner */
-	flip = !flip;		/*   selection without broken output    */
-	xyTemp = y0;
-	y0 = y1;
-	y1 = xyTemp;
-    }
-    if (x0 > x1) {
-	xyTemp = x0;
-	x0 = x1;
-	x1 = xyTemp;
-    }
+    draw(map_name, maptype, color, thin, lines, steps, fp, label_indent, hide_catnum,
+         hide_catstr, show_ticks, hide_nodata, do_smooth, cats, colors, X0,
+         X1, Y0, Y1, flip, UserRange, UserRangeMin, UserRangeMax, catlist, catlistCount,
+         use_catlist, ticksCount, fontsize, tit_fontsize, title, tick_values, t_step, colorb,
+         colorbg, opt_use, opt_at, opt_fontsize, opt_ticks, opt_tstep, opt_range, histo, hidestr,
+         1);
 
-    if (x0 == x1)
-	x1++;			/* avoid 0 width boxes */
-    if (y0 == y1)
-	y1++;
-
-    if ((x0 < l) || (x1 > r) || (y0 < t) || (y1 > b))	/* for mouse or at= 0- or 100+; needs to be after order check */
-	G_warning(_("Legend box lies outside of frame. Text may not display properly."));
-
-    horiz = (x1 - x0 > y1 - y0);
-    if (horiz)
-	G_message(_("Drawing horizontal legend as box width exceeds height"));
-
-    if (!fp && horiz)		/* better than nothing */
-	do_smooth = TRUE;
-
-
-    MaxLabelLen = 0;		/* init variable */
-
-    /* How many categories to show */
-    if (!fp) {
-	if (Rast_read_range(map_name, "", &range) == -1)
-	    G_fatal_error(_("Range information for <%s> not available (run r.support)"),
-			  map_name);
-
-	Rast_get_range_min_max(&range, &min_ind, &max_ind);
-	if (Rast_is_c_null_value(&min_ind))
-	    G_fatal_error(_("Input map contains no data"));
-
-	Rast_get_c_color_range(&min_colr, &max_colr, &colors);
-
-	if (UserRange) {
-	    if (min_ind < UserRangeMin)
-		min_ind = (int)ceil(UserRangeMin);
-	    if (max_ind > UserRangeMax)
-		max_ind = (int)floor(UserRangeMax);
-	    if (min_ind > UserRangeMin) {
-		min_ind =
-		    UserRangeMin <
-		    min_colr ? min_colr : (int)ceil(UserRangeMin);
-		G_warning(_("Requested range exceeds lower limit of actual data"));
-	    }
-	    if (max_ind < UserRangeMax) {
-		max_ind =
-		    UserRangeMax >
-		    max_colr ? max_colr : (int)floor(UserRangeMax);
-		G_warning(_("Requested range exceeds upper limit of actual data"));
-	    }
-	}
-
-	/*  cats_num is total number of categories in raster                  */
-	/*  do_cats is  total number of categories to be displayed            */
-	/*  k is number of cats to be displayed after skipping unlabeled cats */
-	/*  lines is number of text lines/legend window                       */
-
-	cats_num = max_ind - min_ind + 1;
-
-	if (lines == 0)
-	    lines = cats_num;
-
-	do_cats = cats_num > lines ? lines : cats_num;
-
-	if (do_cats == cats_num)
-	    lines = (int)ceil((1.0 * lines) / thin);
-
-	if (!use_catlist) {
-	    catlist = (double *)G_calloc(lines + 1, sizeof(double));
-	    catlistCount = lines;
-	}
-	/* see how many boxes there REALLY will be */
-	maxCat = 0.0;
-	for (i = min_ind, j = 1, k = 0; j <= do_cats && i <= max_ind;
-	     j++, i += thin) {
-	    if (!flip)
-		cstr = Rast_get_c_cat(&i, &cats);
-	    else {
-		CELL cat = max_ind - (i - min_ind);
-		cstr = Rast_get_c_cat(&cat, &cats);
-	    }
-
-	    if (!use_catlist)
-		catlist[j - 1] = (double)i;
-
-	    if (!cstr[0]) {	/* no cat label found, skip str output */
-		if (hide_nodata)
-		    continue;
-	    }
-	    else {		/* ie has a label */
-		if (!hide_catstr && (MaxLabelLen < strlen(cstr)))
-		    MaxLabelLen = strlen(cstr);
-	    }
-
-	    if (!hide_catnum)
-		if (i > maxCat)
-		    maxCat = (double)i;
-	    k++;	/* count of actual boxes drawn (hide_nodata option invaidates using j-1) */
-	}
-	lines = k;
-
-	/* figure out how long the category + label will be */
-	if (use_catlist) {
-	    MaxLabelLen = 0;
-	    maxCat = 0;		/* reset */
-	    for (i = 0, k = 0; i < catlistCount; i++) {
-		if ((catlist[i] < min_ind) || (catlist[i] > max_ind)) {
-		    G_fatal_error(_("use=%s out of range [%d,%d] (extend with range= ?)"),
-				  opt_use->answers[i], min_ind, max_ind);
-		}
-
-		cstr = Rast_get_d_cat(&catlist[i], &cats);
-		if (!cstr[0]) {	/* no cat label found, skip str output */
-		    if (hide_nodata)
-			continue;
-		}
-		else {		/* ie has a label */
-		    if (!hide_catstr && (MaxLabelLen < strlen(cstr)))
-			MaxLabelLen = strlen(cstr);
-		}
-		if (!hide_catnum)
-		    if (catlist[i] > maxCat)
-			maxCat = catlist[i];
-		k++;
-	    }
-	    if (0 == k)		/* nothing to draw */
-		lines = 0;
-	}
-
-	if (MaxLabelLen > 0) {	/* ie we've picked up at least one label */
-	    MaxLabelLen++;	/* compensate for leading space */
-	    if (!hide_catnum)
-		MaxLabelLen += 3;	/* compensate for "%2d) " */
-	}
-	else {
-	    if (!hide_catnum)
-		MaxLabelLen = 1;
-	}
-
-	/* compensate for categories >100 */
-	if (!hide_catnum) {
-	    if (maxCat > 99)
-		MaxLabelLen += (int)(log10(maxCat));
-	}
-
-	/* following covers both the above if(do_cats == cats_num) and k++ loop */
-	if (lines < 1) {
-	    lines = 1;		/* ward off the dpl floating point exception */
-	    G_fatal_error(_("Nothing to draw! (no categories with labels? out of range?)"));
-	}
-
-	/* Figure number of lines, number of pixles per line and text size */
-	dots_per_line = ((y1 - y0) / lines);
-
-	/* switch to a smooth legend for CELL maps with too many cats */
-	/*  an alternate solution is to set   dots_per_line=1         */
-	if ((dots_per_line == 0) && (do_smooth == FALSE)) {
-	    if (!use_catlist) {
-		G_message(_("Forcing a smooth legend: too many categories for current window height"));
-		do_smooth = TRUE;
-	    }
-	}
-
-	/* center really tiny legends */
-	if (opt_at->answer == NULL) {	/* if defualt scaling */
-	    if (!do_smooth && (dots_per_line < 4))	/* if so small that there's no box */
-		if ((b - (dots_per_line * lines)) / (b * 1.0) > 0.15)	/* if there's more than a 15% blank at the bottom */
-		    y0 = ((b - t) - (dots_per_line * lines)) / 2;
-	}
-
-	/* D_text_size(dots_per_line*4/5., dots_per_line*4/5.);    redundant */
-	/* if(Rast_is_c_null_value(&min_ind) && Rast_is_c_null_value(&max_ind))
-	   {
-	   min_ind = 1;
-	   max_ind = 0;
-	   } */
-
-	if (horiz)
-	    sprintf(DispFormat, "%%d");
-	else {
-	    if (maxCat > 0.0)
-		sprintf(DispFormat, "%%%dd", (int)(log10(fabs(maxCat))) + 1);
-	    else
-		sprintf(DispFormat, "%%2d");
-	}
-    }
-    else {	/* is fp */
-	if (maptype == MAP_TYPE_RASTER2D) {
-	    if (Rast_read_fp_range(map_name, "", &fprange) == -1)
-		G_fatal_error(_("Range information for <%s> not available"),
-				map_name);
-	}
-	else {
-	    if (Rast3d_read_range(map_name, "", &fprange) == -1)
-		G_fatal_error(_("Range information for <%s> not available"),
-				map_name);
-	}
-
-	Rast_get_fp_range_min_max(&fprange, &dmin, &dmax);
-	Rast_get_d_color_range(&min_dcolr, &max_dcolr, &colors);
-
-	if (UserRange) {
-	    if (dmin < UserRangeMin)
-		dmin = UserRangeMin;
-	    if (dmax > UserRangeMax)
-		dmax = UserRangeMax;
-	    if (dmin > UserRangeMin) {
-		dmin = UserRangeMin < min_dcolr ? min_dcolr : UserRangeMin;
-		G_warning(_("Color range exceeds lower limit of actual data"));
-	    }
-	    if (dmax < UserRangeMax) {
-		dmax = UserRangeMax > max_dcolr ? max_dcolr : UserRangeMax;
-		G_warning(_("Color range exceeds upper limit of actual data"));
-	    }
-	}
-
-	if (use_catlist) {
-	    for (i = 0; i < catlistCount; i++) {
-		if ((catlist[i] < dmin) || (catlist[i] > dmax)) {
-		    G_fatal_error(_("use=%s out of range [%.3f, %.3f] (extend with range= ?)"),
-				  opt_use->answers[i], dmin, dmax);
-		}
-		if (strlen(opt_use->answers[i]) > MaxLabelLen)
-		    MaxLabelLen = strlen(opt_use->answers[i]);
-	    }
-	}
-	do_cats = 0;		/* if only to get rid of the compiler warning  */
-	cats_num = 0;		/* if only to get rid of the compiler warning  */
-	/* determine how many significant digits to display based on range */
-	if (0 == (dmax - dmin))	/* trap divide by 0 for single value rasters */
-	    sprintf(DispFormat, "%%f");
-	else {
-	    SigDigits = (int)ceil(log10(fabs(25 / (dmax - dmin))));
-	    if (SigDigits < 0)
-		SigDigits = 0;
-	    if (SigDigits < 7)
-		sprintf(DispFormat, "%%.%df", SigDigits);
-	    else
-		sprintf(DispFormat, "%%.2g");	/* eg 4.2e-9  */
-	}
-    }
-
-    if (use_catlist) {
-	cats_num = catlistCount;
-	do_cats = catlistCount;
-	lines = catlistCount;
-	do_smooth = FALSE;
-    }
-
-
-    if (do_smooth) {
-	int wleg, lleg, dx, dy;
-    double txsiz, coef;
-    double ppl;
-	int tcell;
-	float ScaleFactor = 1.0;
-
-	if (horiz) {
-	    lleg = x1 - x0;
-	    dx = 0;
-	    dy = y1 - y0;
-	    if (fp)
-		flip = !flip;	/* horiz floats look better not flipped by default */
-	}
-	else {
-	    lleg = y1 - y0;
-	    dy = 0;
-	    dx = x1 - x0;
-	}
-
-	/* Draw colors */
-	for (k = 0; k < lleg; k++) {
-	    if (!fp) {
-		if (!flip)
-		    tcell =
-			min_ind + k * (double)(1 + max_ind - min_ind) / lleg;
-		else
-		    tcell =
-			(max_ind + 1) - k * (double)(1 + max_ind -
-						     min_ind) / lleg;
-		D_color((CELL) tcell, &colors);
-	    }
-	    else {
-		if (!flip)
-		    val = dmin + k * (dmax - dmin) / lleg;
-		else
-		    val = dmax - k * (dmax - dmin) / lleg;
-		D_d_color(val, &colors);
-	    }
-
-	    if (dx < dy)
-		D_box_abs(x0 + k, y0, x0 + k + (dx ? -dx : 1),
-			  y0 - (dy ? -dy : 1));
-	    else
-		D_box_abs(x0, y0 + k, x0 - (dx ? -dx : 1),
-			  y0 + k + (dy ? -dy : 1));
-	}
-
-	/* Format text */
-	if (!fp) {		/* cut down labelnum so they don't repeat */
-	    if (do_cats < steps)
-		steps = do_cats;
-        if ((steps < 2))
-		steps = 2;	/* ward off the ppl floating point exception */
-	}
-
-
-    if (strlen(buff) > MaxLabelLen)
-    MaxLabelLen = strlen(buff);
-
-    /* Draw text and ticks */
-    if (!horiz)
-    txsiz = (y1 - y0) / 20;
-    else
-    txsiz = (x1 - x0) / 20;
-
-    /* scale text to fit in window if position not manually set */
-    /* usually not needed, except when frame is really narrow   */
-    if (opt_at->answer == NULL) {	/* ie default scaling */
-    ScaleFactor = ((r - x1) / ((MaxLabelLen + 1) * txsiz * 0.81));	/* ?? txsiz*.81=actual text width. */
-    if (ScaleFactor < 1.0) {
-        txsiz = txsiz * ScaleFactor;
-    }
-    }
-
-    if (opt_fontsize->answer != NULL)
-    txsiz = fontsize;
-
-    if (txsiz < 0)
-    txsiz = 0;	/* keep it sane */
-
-    D_text_size(txsiz, txsiz);
-    D_use_color(color);
-
-
-    if (steps >= 2) {
-	for (k = 0; k < steps; k++) {
-	    if (!fp) {
-		if (!flip)
-		    tcell =
-                min_ind + k * (double)(max_ind - min_ind) / (steps - 1);
-		else
-		    tcell =
-                max_ind - k * (double)(max_ind - min_ind) / (steps - 1);
-
-		if (!cstr[0])	/* no cats found, disable str output */
-		    hide_catstr = 1;
-		else
-		    hide_catstr = hidestr->answer;
-
-		buff[0] = 0;	/* blank string */
-
-		if (!hide_catnum) {	/* num */
-		    sprintf(buff, DispFormat, tcell);
-		    if (!hide_catstr)	/* both */
-			strcat(buff, ")");
-		}
-		if (!hide_catstr)	/* str */
-		    sprintf(buff + strlen(buff), " %s", cstr);
-	    }
-	    else {		/* ie FP map */
-		if (hide_catnum)
-		    buff[0] = 0;	/* no text */
-		else {
-		    if (!flip)
-			val = dmin + k * (dmax - dmin) / (steps - 1);
-		    else
-			val = dmax - k * (dmax - dmin) / (steps - 1);
-
-		    sprintf(buff, DispFormat, val);
-		}
-	    }
-
-            ppl = (lleg) / (steps * 1.0 - 1);
-
-            if (!hide_catnum) {
-                if (!horiz) {
-                    D_pos_abs(x1 + label_indent, y0 + ppl * k + txsiz / 2);
-                    if (show_ticks)
-                        D_line_abs(x1, y0 + ppl * k, x1 + 6, y0 + ppl * k);
-                }
-                else {
-                /* text width is 0.81 of text height? so even though we set width
-                   to txsiz with D_text_size(), we still have to reduce.. hmmm */
-                    D_pos_abs(x0 + ppl * k - (strlen(buff) * txsiz * .81 / 2),
-                              y1 + label_indent + txsiz);
-                    if (show_ticks)
-                        D_line_abs(x0 + ppl * k, y1, x0 + ppl * k, y1 + 6);
-                }
-
-                if (color)
-                D_text(buff);
-		}
-
-        }	/* for */
-	    }
-
-    lleg = y1 - y0;
-    wleg = x1 - x0;
-
-    /* draw tick_values labels and ticks */
-    if (ticksCount > 0) {
-        for (i = 0; i < ticksCount; i++) {
-            if ((tick_values[i] < dmin) || (tick_values[i] > dmax)) {
-                G_fatal_error(_("tick_value=%s out of range [%.3f, %.3f]"),
-                      opt_ticks->answers[i], dmin, dmax);
-            }
-            coef = (tick_values[i] - dmin) / ((dmax - dmin) * 1.0);
-            sprintf(buff, DispFormat, tick_values[i]);
-            if (!flip){
-                if (!horiz) {
-                    if (show_ticks)
-                        D_line_abs(x1, y0 + coef * lleg,
-                                   x1 + 6, y0 + coef * lleg);
-                    D_pos_abs(x1 + label_indent, y0 + coef * lleg + txsiz/2);}
-                else {
-                    if (show_ticks)
-                        D_line_abs(x0 + coef * wleg, y1,
-                                   x0 + coef * wleg, y1 + 6);
-                    D_pos_abs(x0 + coef * wleg - (strlen(buff) * txsiz * .81 / 2),
-                              y1 + label_indent + txsiz);}
-            }
-            else{
-                if (!horiz) {
-                    if (show_ticks)
-                        D_line_abs(x1, y1 - coef * lleg,
-                                   x1 + 6, y1 - coef * lleg);
-                    D_pos_abs(x1 + label_indent, y1 - coef * lleg + txsiz/2);}
-                else {
-                    if (show_ticks)
-                        D_line_abs(x1 - coef * wleg, y1,
-                                   x1 - coef * wleg, y1 + 6);
-                    D_pos_abs(x1 - coef * wleg - (strlen(buff) * txsiz * .81 / 2),
-                              y1 + label_indent + txsiz);}
-            }
-            D_text(buff);
-        }
-    }
-
-    /* draw tick_step */
-    if (opt_tstep->answer) {
-        t_start = ceil(dmin/t_step) * t_step;
-        if (t_start == -0)
-            t_start = 0;
-
-        if (!flip){
-            if (!horiz)
-                while (t_start<dmax) {
-                    sprintf(buff, DispFormat, t_start);
-                    coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
-                    if (show_ticks)
-                        D_line_abs(x1, y0 + coef * lleg,
-                                   x1 + 6, y0 + coef * lleg);
-                    D_pos_abs(x1 + label_indent, y0 + coef * lleg + txsiz/2);
-                    D_text(buff);
-
-                    t_start += t_step;}
-		else
-                while (t_start<dmax) {
-                    sprintf(buff, DispFormat, t_start);
-                    coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
-                    if (show_ticks)
-                        D_line_abs(x0 + coef * wleg,y1,
-                                   x0 + coef * wleg, y1 + 6);
-                    D_pos_abs(x0 + coef * wleg - (strlen(buff) * txsiz * .81 / 2),
-                              y1 + label_indent + txsiz);
-                    D_text(buff);
-
-                    t_start += t_step;}
-	    }
-	    else {
-            if (!horiz)
-                while (t_start<dmax) {
-                    sprintf(buff, DispFormat, t_start);
-                    coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
-                    if (show_ticks)
-                        D_line_abs(x1, y1 - coef * lleg,
-                                   x1 + 6, y1 - coef * lleg);
-                    D_pos_abs(x1 + label_indent, y1 - coef * lleg + txsiz/2);
-                    D_text(buff);
-
-                    t_start += t_step;}
-		else
-                while (t_start<dmax) {
-                    sprintf(buff, DispFormat, t_start);
-                    coef = (t_start - dmin) / ((dmax - dmin) * 1.0);
-                    if (show_ticks)
-                        D_line_abs(x1 - coef * wleg, y1,
-                                   x1 - coef * wleg, y1 + 6);
-                    D_pos_abs(x1 - coef * wleg - (strlen(buff) * txsiz * .81 / 2),
-                              y1 + label_indent + txsiz);
-		D_text(buff);
-
-                    t_start += t_step;}
-        }
-    }
-
-    /* White box */
-    D_use_color(white);
-    D_begin();
-    D_move_abs(x0 + 1, y0 + 1);
-    D_cont_rel(0, lleg - 2);
-    D_cont_rel(wleg - 2, 0);
-    D_cont_rel(0, -lleg + 2);
-    D_close();
-    D_end();
-    D_stroke();
-    
-    /* Black box */
-    D_use_color(black);
-    D_begin();
-    D_move_abs(x0, y0 );
-    D_cont_rel(0, lleg);
-    D_cont_rel(wleg, 0);
-    D_cont_rel(0, -lleg);
-    D_close();
-    D_end();
-    D_stroke();
-	
-    if(opt_title->answer){
-    /* Display title */
-        double x_tit, y_tit;
-
-        D_use_color(color);
-
-        if (horiz){
-            x_tit = (x0 + x1)/2. - (strlen(title) * txsiz * 0.81)/2;
-            y_tit = y0 - (txsiz);
-        }
-        else{
-            x_tit = x0;
-            y_tit = y0 - (txsiz);
-        }
-
-        D_pos_abs(x_tit, y_tit);
-        D_text(title);
-    }
-    else{
-    /* Display units label */
-	/* print units label, if present */
-	if (maptype == MAP_TYPE_RASTER2D)
-	    units = Rast_read_units(map_name, "");
-	else
-	    units = "";
-/* FIXME: does the raster3d really need to be opened to read the units?
-	    units = Rast3d_get_unit(map_fid); */
-
-	if (!units)
-	    units = "";
-
-	if(strlen(units)) {
-	    double x_pos, y_pos;
-	    int default_pos = TRUE;
-
-	    D_use_color(color);
-	    /* D_text_size() should be already set */
-
-	    if (horiz) {
-		x_pos = (x0 + x1)/2. - (strlen(units) * txsiz * 0.81)/2;
-            y_pos = y1 + (txsiz * 2.75);
-	    }
-	    else {
-            x_pos = x0;
-		if (default_pos)
-		    y_pos = y0 - (txsiz * 1.75);
-		else
-		    y_pos = y1 + (txsiz * 2.75);
-	    }
-
-	    D_pos_abs(x_pos, y_pos);
-	    D_text(units);
-	}
-    }
-
-
-	/* display sidebar histogram, if requested */
-	if (histo->answer) {
-
-	    render_range.min = (DCELL)(fp ? dmin : min_ind);
-	    render_range.max = (DCELL)(fp ? dmax : max_ind);
-	    /* reuse flag to indicate if user-specified or default ranging */
-	    render_range.first_time = opt_range->answer ? TRUE : FALSE;
-
-	    draw_histogram(map_name, x0, y0, wleg, lleg, color, flip, horiz,
-			   maptype, fp, render_range);
-	}
-
-    }
-    else {	/* non FP, no smoothing */
-
-	int true_l, true_r;
-	double txsiz;
-	float ScaleFactor = 1.0;
-
-	if (histo->answer)
-	    G_warning(_("Histogram plotting not implemented for categorical legends. "
-			"Use the '-s' flag"));
-
-	/* set legend box bounds */
-	true_l = l;
-	true_r = r;	/* preserve window width */
-	l = x0;
-	t = y0;
-	r = x1;
-	b = y1;
-
-	D_pos_abs(x0, y0);
-
-	/* figure out box height  */
-	if (do_cats == cats_num)
-	    dots_per_line = (b - t) / (lines + 1);	/* +1 line for the two 1/2s at top and bottom */
-	else
-	    dots_per_line = (b - t) / (lines + 2);	/* + another line for 'x of y categories' text */
-
-	/* adjust text size */
-	/*  txsiz = (int)((y1-y0)/(1.5*(lines+5))); */
-	txsiz = (y1 - y0) / (2.0 * lines);
-
-	/* scale text to fit in window if position not manually set */
-	if (opt_at->answer == NULL) {	/* ie defualt scaling */
-	    ScaleFactor = ((true_r - true_l) / ((MaxLabelLen + 3) * txsiz * 0.81));	/* ?? txsiz*.81=actual text width. */
-	    if (ScaleFactor < 1.0) {
-		txsiz = txsiz * ScaleFactor;
-		dots_per_line = (int)floor(dots_per_line * ScaleFactor);
-	    }
-	}
-
-	if (dots_per_line < txsiz)
-	    txsiz = dots_per_line;
-
-	if (opt_fontsize->answer != NULL)
-	    txsiz = fontsize;
-
-	D_text_size(txsiz, txsiz);
-
-
-	/* Set up box arrays */
-	x_box[0] = 0;
-	y_box[0] = 0;
-	x_box[1] = 0;
-	y_box[1] = (5 - dots_per_line);
-	x_box[2] = (dots_per_line - 5);
-	y_box[2] = 0;
-	x_box[3] = 0;
-	y_box[3] = (dots_per_line - 5);
-	x_box[4] = (5 - dots_per_line);
-	y_box[4] = 0;
-
-
-	/* Draw away */
-
-	/* if(ScaleFactor < 1.0)   */
-	/*    cur_dot_row = ((b-t) - (dots_per_line*lines))/2; *//* this will center the legend */
-	/* else    */
-	cur_dot_row = t + dots_per_line / 2;
-
-	/*  j = (do_cats == cats_num ? 1 : 2 ); */
-
-	for (i = 0, k = 0; i < catlistCount; i++)
-	    /* for(i=min_ind, j=1, k=0; j<=do_cats && i<=max_ind; j++, i+=thin) */
-	{
-	    if (!flip)
-		cstr = Rast_get_d_cat(&catlist[i], &cats);
-	    else
-		cstr = Rast_get_d_cat(&catlist[catlistCount - i - 1], &cats);
-
-
-	    if (!cstr[0]) {	/* no cat label found, skip str output */
-		hide_catstr = 1;
-		if (hide_nodata)
-		    continue;
-	    }
-	    else
-		hide_catstr = hidestr->answer;
-
-	    k++;  /* count of actual boxes drawn (hide_nodata option invaidates using j-1) */
-
-        /* Black box */
-	    cur_dot_row += dots_per_line;
-        D_use_color(black);
-	    D_begin();
-	    D_move_abs(l + 2, (cur_dot_row - 1));
-	    D_cont_rel(0, (3 - dots_per_line));
-	    D_cont_rel((dots_per_line - 3), 0);
-	    D_cont_rel(0, (dots_per_line - 3));
-	    D_close();
-	    D_end();
-	    D_stroke();
-
-        /* White box */
-        D_use_color(white);
-	    D_begin();
-	    D_move_abs(l + 3, (cur_dot_row - 2));
-	    D_cont_rel(0, (5 - dots_per_line));
-	    D_cont_rel((dots_per_line - 5), 0);
-	    D_cont_rel(0, (dots_per_line - 5));
-	    D_close();
-	    D_end();
-	    D_stroke();
-
-	    /* Color solid box */
-	    if (!fp) {
-		if (!flip)
-		    D_color((CELL) (int)catlist[i], &colors);
-		else
-		    D_color((CELL) (int)catlist[catlistCount - i - 1],
-			    &colors);
-	    }
-	    else {
-		if (!flip)
-		    D_d_color(catlist[i], &colors);
-		else
-		    D_d_color(catlist[catlistCount - i - 1], &colors);
-	    }
-
-	    D_pos_abs(l + 3, (cur_dot_row - 2));
-	    D_polygon_rel(x_box, y_box, 5);
-
-	    /* Draw text */
-	    D_use_color(color);
-
-	    if (!fp) {
-		/* nothing, box only */
-		buff[0] = 0;
-		if (!hide_catnum) {	/* num */
-		    sprintf(buff, DispFormat, (int)catlist[i]);
-		    if (!flip)
-			sprintf(buff, DispFormat, (int)catlist[i]);
-		    else
-			sprintf(buff, DispFormat,
-				(int)catlist[catlistCount - i - 1]);
-		    if (!hide_catstr)	/* both */
-			strcat(buff, ")");
-		}
-		if (!hide_catstr)	/* str */
-		    sprintf(buff + strlen(buff), " %s", cstr);
-	    }
-	    else {		/* is fp */
-		if (!flip) {
-		    if (use_catlist)
-			/* pass through format exactly as given by the user in
-			   the use= command line parameter (helps with log scale) */
-			sprintf(buff, "%s", opt_use->answers[i]);
-		    else
-			/* automatically generated/tuned decimal precision format */
-			sprintf(buff, DispFormat, catlist[i]);
-		}
-		else {
-		    if(use_catlist)
-			sprintf(buff, "%s", opt_use->answers[catlistCount - i - 1]);
-		    else
-			sprintf(buff, DispFormat, catlist[catlistCount - i - 1]);
-		}
-	    }
-
-	    D_pos_abs((l + 3 + dots_per_line), (cur_dot_row) - 3);
-
-	    if (color)
-		D_text(buff);
-	}
-
-	if (0 == k)
-	    G_fatal_error(_("Nothing to draw! (no categories with labels?)"));	/* "(..., out of range?)" */
-
-
-	if (do_cats != cats_num) {
-	    cur_dot_row += dots_per_line;
-	    /* sprintf(buff, "%d of %d categories\n", (j-1), cats_num); */
-
-	    sprintf(buff, "%d of %d categories\n", k, cats_num);
-
-	    /* shrink text if it will run off the screen */
-	    MaxLabelLen = strlen(buff) + 4;
-	    ScaleFactor = ((true_r - true_l) / (MaxLabelLen * txsiz * 0.81));	/* ?? txsiz*.81=actual text width. */
-	    if (ScaleFactor < 1.0) {
-		txsiz = txsiz * ScaleFactor;
-
-		if (opt_fontsize->answer != NULL)
-		    txsiz = fontsize;
-
-		D_text_size(txsiz, txsiz);
-	    }
-	    D_use_color(white);
-	    D_pos_abs((l + 3 + dots_per_line), (cur_dot_row));
-	    if (color)
-		D_text(buff);
-	}
-    }
-
-    D_save_command(G_recreate_command());
     D_close_driver();
 
     exit(EXIT_SUCCESS);



More information about the grass-commit mailing list