123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /* Function: ps_colortable
- **
- ** Author: Paul W. Carlson April 1992
- */
- #include <grass/raster.h>
- #include <grass/glocale.h>
- #include "colortable.h"
- #include "local_proto.h"
- #define NSTEPS 5 /* number of steps to divide color box when
- showing color for category data range */
- #define FONTFIT_FACT 4.0 /* how agressive to be with shrinking the font size
- to get it to fit in the column (normal range: 2-4) */
- #define PRETEXT_MULT 2.0 /* space between box and text (this*fontsize) */
- int PS_colortable(void)
- {
- char *label;
- int num_cats;
- int i, j, k, jj;
- int R, G, B;
- int center_cols;
- DCELL dmin, dmax, val;
- struct Colors colors;
- double t, l /*, r */;
- double x1, x2, y, dy, fontsize, tl;
- double col_width;
- int do_color;
- double grey_color_val;
- RASTER_MAP_TYPE rast_type;
- /* let user know what's happenning */
- G_message(_("Creating color table for <%s in %s>..."),
- ct.name, ct.mapset);
- if (Rast_read_cats(ct.name, ct.mapset, &PS.cats) == -1) {
- G_warning(_("Category file for <%s> not available"), ct.name);
- return 1;
- }
- if (Rast_read_colors(ct.name, ct.mapset, &colors) == -1)
- G_warning(_("Unable to read colors for colorbar"));
- rast_type = Rast_map_type(ct.name, ct.mapset);
- do_color = (PS.grey == 0 && PS.level == 2);
- /* How many categories to show */
- num_cats = Rast_number_of_cats(&PS.cats);
- G_debug(3, "clrtbl: %d categories", num_cats);
- if (!num_cats) {
- G_warning(_("Your cats/ file is invalid. A cats/ file with categories "
- "and labels is required for 'colortable' when using "
- "categorical legends; see the r.category help page. "
- "Colortable creation has been skipped."));
- return 1;
- }
- /* set font */
- fontsize = (double)ct.fontsize;
- fprintf(PS.fp, "(%s) FN %.1f SF\n", ct.font, fontsize);
- /* set colortable location */
- dy = 1.5 * fontsize;
- if (ct.y < PS.top_marg) {
- G_warning(_("Colorbar y location beyond page margins. Adjusting."));
- ct.y = PS.top_marg;
- }
- t = 72.0 * (PS.page_height - ct.y);
- if (ct.x < PS.left_marg) {
- G_warning(_("Colorbar x location beyond page margins. Adjusting."));
- ct.x = PS.left_marg + 0.1;
- }
- l = 72.0 * ct.x + 0.5;
- if (ct.width <= 0.0 || ct.width > PS.page_width - PS.right_marg - ct.x)
- ct.width = PS.page_width - PS.right_marg - ct.x;
- /* r = l + 72.0 * ct.width; */ /* unused */
- col_width = ct.width / (double)ct.cols;
- G_debug(3, "clrtbl: adjusted ct.x=[%.3f] ct.y=[%.3f] ct.width=[%.3f] "
- "col_width=[%.3f]", ct.x, ct.y, ct.width, col_width);
- /* read cats into PostScript array "a" */
- fprintf(PS.fp, "/a [\n");
- for (i = 0; i <= num_cats; i++) {
- if (!i && !ct.nodata)
- i++; /* step over 'no data' */
- if (!i)
- fprintf(PS.fp, "(%s)\n", "no data");
- else {
- fprintf(PS.fp, "(%s)\n",
- Rast_get_ith_d_cat(&PS.cats, i - 1, &dmin, &dmax));
- G_debug(5, "i=%d dmin=%f dmax=%f catlabel=[%s]", i, dmin, dmax,
- Rast_get_ith_d_cat(&PS.cats, i - 1, &dmin, &dmax));
- }
- }
- fprintf(PS.fp, "] def\n");
- /* get width of widest string in PostScript variable "mw" */
- fprintf(PS.fp, "/mw 0 def 0 1 a length 1 sub { /i XD\n");
- fprintf(PS.fp, "a i get SW pop /t XD t mw gt {/mw t def} if } for\n");
- /* shrink font size to fit in width */
- if (ct.cols == 1)
- tl = 72.0 * col_width - 2.0 * fontsize;
- else
- tl = 72.0 * col_width - FONTFIT_FACT * fontsize;
- G_debug(5, "clrtbl: fontsize=%.1f adjusted tl=%.1f", fontsize, tl);
- fprintf(PS.fp, "/s %.1f def\n", fontsize);
- fprintf(PS.fp, "mw %.1f gt {/s s %.1f mul mw div def } if\n", tl, tl);
- fprintf(PS.fp, "(%s) FN s SF\n", ct.font);
- /* make proc to center multiple columns */
- center_cols = (ct.cols > 1);
- if (center_cols) {
- fprintf(PS.fp, "/k %d def\n", ct.cols - 1);
- fprintf(PS.fp, "/mlw 0 def 0 k a length 1 sub { /i XD\n");
- fprintf(PS.fp,
- "a i get SW pop /t XD t mlw gt {/mlw t def} if } for\n");
- fprintf(PS.fp, "/xo mw mlw sub D2 s mul %1.0f div %1.0f add def\n",
- fontsize, fontsize);
- fprintf(PS.fp, "/mvx {xo add} BD\n");
- }
- y = t - fontsize;
- k = 0;
- for (i = 0; i <= num_cats;) {
- if (!i && !ct.nodata)
- i++; /* step over 'no data' */
- /* test for bottom of page */
- y -= dy;
- if (y < 72.0 * PS.bot_marg) {
- y = 72.0 * (PS.page_height - PS.top_marg) - 0.5 * fontsize;
- fprintf(PS.fp, "showpage\n");
- }
- for (j = 0; j < ct.cols; j++) {
- /* get the data range */
- /* fill box and outline in black */
- if (i) {
- label = Rast_get_ith_d_cat(&PS.cats, i - 1, &dmin, &dmax);
- G_debug(5, "j=%d i=%d label=[%s]", j, i, label);
- }
- x1 = l + (double)j *72.0 * col_width;
- x2 = x1 + fontsize;
- if (!i || dmax == dmin) {
- /* draw a 1-color rectangle */
- /* set box fill color */
- if (!i)
- Rast_get_null_value_color(&R, &G, &B, &colors);
- else {
- if (rast_type == CELL_TYPE) {
- CELL cmin = (CELL)dmin;
- Rast_get_c_color(&cmin, &R, &G, &B, &colors);
- }
- else if (rast_type == FCELL_TYPE) {
- FCELL fmin = (FCELL)dmin;
- Rast_get_f_color(&fmin, &R, &G, &B, &colors);
- }
- else if (rast_type == DCELL_TYPE)
- Rast_get_color(&dmin, &R, &G, &B, &colors, rast_type);
- else G_fatal_error("Please contact development team");
- G_debug(5, " dmin=%f RGB=%d:%d:%d", dmin, R, G, B);
- }
- if (do_color)
- fprintf(PS.fp, "%.3f %.3f %.3f C\n",
- (double)R / 255., (double)G / 255.,
- (double)B / 255.);
- else {
- grey_color_val =
- (.3 * (double)R + .59 * (double)G +
- .11 * (double)B) / 255.;
- fprintf(PS.fp, "%.3f setgray\n", grey_color_val);
- }
- fprintf(PS.fp, "%.1f ", x1);
- if (center_cols)
- fprintf(PS.fp, "mvx ");
- fprintf(PS.fp, "%.1f ", y);
- fprintf(PS.fp, "%.1f ", x2);
- if (center_cols)
- fprintf(PS.fp, "mvx ");
- fprintf(PS.fp, "%.1f ", y + fontsize);
- /* no border fprintf(PS.fp, "B CF stroke\n"); */
- /* grey border fprintf(PS.fp, "B F .247 .247 .247 C 1 W stroke\n"); */
- fprintf(PS.fp, "B F ");
- set_ps_color(&ct.color);
- fprintf(PS.fp, "%.2f W stroke\n", ct.lwidth);
- }
- else {
- /* split the rectangle into NSTEPS horizontal strips and
- draw each with the corresponding value's color */
- for (jj = 0; jj < NSTEPS; jj++) {
- /* set box fill color */
- val = dmin + (double)jj *(dmax - dmin) / NSTEPS;
- Rast_get_d_color(&val, &R, &G, &B, &colors);
- fprintf(PS.fp, "%.3f %.3f %.3f C\n",
- (double)R / 255., (double)G / 255.,
- (double)B / 255.);
- fprintf(PS.fp, "%.1f ", x1);
- if (center_cols)
- fprintf(PS.fp, "mvx ");
- fprintf(PS.fp, "%.1f ",
- y + (fontsize * (double)jj) / NSTEPS);
- fprintf(PS.fp, "%.1f ", x2);
- if (center_cols)
- fprintf(PS.fp, "mvx ");
- fprintf(PS.fp, "%.1f ",
- y + (fontsize * (double)(jj + 1)) / NSTEPS);
- fprintf(PS.fp, "B CF stroke\n");
- } /* done filling the box */
- /* outline the box in the specified color, see above */
- fprintf(PS.fp, "%.1f ", x1);
- if (center_cols)
- fprintf(PS.fp, "mvx ");
- fprintf(PS.fp, "%.1f ", y);
- fprintf(PS.fp, "%.1f ", x2);
- if (center_cols)
- fprintf(PS.fp, "mvx ");
- fprintf(PS.fp, "%.1f ", y + fontsize);
- fprintf(PS.fp, "B ");
- set_ps_color(&ct.color);
- fprintf(PS.fp, "%.2f W stroke\n", ct.lwidth);
- } /* done drawing the box */
- /* do the text */
- set_ps_color(&ct.color);
- fprintf(PS.fp, "a %d get %.1f ", k++, x1 + PRETEXT_MULT * fontsize);
- if (center_cols)
- fprintf(PS.fp, "mvx ");
- fprintf(PS.fp, "%.1f MS\n", y);
- i++;
- if (i > num_cats)
- j = ct.cols + 1;
- }
- }
- y -= dy;
- if (PS.min_y > y)
- PS.min_y = y;
- Rast_free_colors(&colors);
- return 0;
- }
|