1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/* Function: scale
**
** This function returns the horizontal extent of the map in inches and
** modifies the text string. Much of this code is from p.map's scale.c.
**
** Author: Paul W. Carlson April 1992
*/
#include <stdlib.h>
#include <string.h>
#include "local_proto.h"
#include "ps_info.h"
#define METERS_TO_INCHES ((double)39.37)
#define MILES_TO_INCHES ((double)5280*12)
#define PWIDTH (PS.page_width-PS.left_marg-PS.right_marg)
static double do_scale(char *);
#ifdef __GNUC_MINOR__
static int OOPS (void) __attribute__ ((__noreturn__));
#else
static int OOPS();
#endif
double scale(char *text)
{
double inches;
inches = do_scale(text);
return inches;
}
static double do_scale(char *text)
{
char unit1[30];
char unit2[30];
char equals[30];
char dummy[2];
long n1,n2;
double u1,u2;
/*
* absolute horizontal width specification
* x inches
* x panels
* convert text to 1 : n
*/
u1 = 0;
*unit1 = 0;
*dummy = 0;
if (sscanf(text, "%lf %s %1s", &u1, unit1, dummy) == 2 && *dummy == 0)
{
u2 = -1;
if (strncmp(unit1, "panel", 5) == 0 && u1 > 0) u2 = u1 * (PWIDTH);
else if (strncmp(unit1, "inch", 4) == 0 && u1 > 0) u2 = u1;
if (u2 > 0)
{
sprintf(text, "1 : %.0f",
METERS_TO_INCHES * distance(PS.w.east, PS.w.west) / u2);
return u2;
}
}
/*
* unitless ratio specification
* n : m
*/
*dummy = 0;
n1 = n2 = 0;
if (sscanf(text, "%ld : %ld%1s", &n1, &n2, dummy) == 2)
{
if (n1 <= 0 || n2 <= 0 || *dummy) OOPS();
sprintf(text, "%ld : %ld", n1, n2);
return METERS_TO_INCHES * distance(PS.w.east, PS.w.west) * n1 / n2;
}
/*
*
* ratio specification with unit conversions
* x inches equals y miles
* x inches equals y meters
* x inches equals y kilometers
*/
*unit1 = 0;
*unit2 = 0;
*equals = 0;
n1 = n2 = 0;
if (sscanf(text, "%ld %s %s %ld %s", &n1, unit1, equals, &n2, unit2) == 5)
{
if (n1 <= 0 || n2 <= 0) OOPS();
if (strcmp(equals, "=") != 0 && strncmp(equals, "equal",5) != 0) OOPS();
/* unit1: inches */
if (strncmp(unit1, "inch", 4) == 0) u1 = n1;
else OOPS();
/* unit2: meters, miles, kilometers */
if (strncmp(unit2, "mile", 4) == 0)
{
u2 = MILES_TO_INCHES;
strcpy(unit2, "mile");
}
else if (strncmp(unit2, "meter", 5) == 0)
{
u2 = METERS_TO_INCHES;
strcpy(unit2, "meter");
}
else if (strncmp(unit2, "kilometer", 9) == 0)
{
u2 = METERS_TO_INCHES * 1000;
strcpy(unit2, "kilometer");
}
else OOPS();
u2 *= n2;
strcpy(unit1, "inch");
strcpy(equals, "equal");
if (n1 == 1) strcat(equals, "s");
else strcat(unit1, "es");
if (n2 != 1) strcat(unit2, "s");
sprintf(text, "%ld %s %s %ld %s", n1, unit1, equals, n2, unit2);
return METERS_TO_INCHES * distance(PS.w.east, PS.w.west) * u1 / u2;
}
OOPS();
}
static int OOPS (void)
{
G_fatal_error("PSmap: do_scale(): shouldn't happen");
exit(1);
}
|