/* See epswr_figure.h */ /* Last edited on 2020-10-27 16:59:17 by jstolfi */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include void epswr_check_param(const char *name, double z, double zMin, double zMax) { if ((z < zMin) || (z > zMax)) { fprintf(stderr, "** error: %s = %8.3f not in [%8.3f __ %8.3f]\n", name, z, zMin, zMax); assert(FALSE); } } double epswr_round_to_nice(double x) { /* Special cases for 0 and infinity: */ if ((x == 0) || (x == INF)) { return x; } /* Remove the sign of {x} and save it in {s}: */ double s = (x < 0 ? -1 : +1); x = fabs(x); /* Compensate for rounding errors in the algorithm below: */ x = 0.9999999 * x; /* If {x} is too small, don't bother: */ if (x < 1.0e-300) { return s*1.0e-300; } /* Finds the smallest power {z} of 10 such that {z > x}: */ double z = 1.0; while (z/10.0 > x) { z /= 10.0; } while (z <= x ) { z *= 10.0; } /* Check for overflow: */ if (z == INF) { return s * INF; } /* Finds a nice multiple of that power of 10: */ if (x < 0.20 * z) { return 0.20 * s * z; } else if (x < 0.25 * z) { return 0.25 * s * z; } else if (x < 0.5 * z) { return 0.5 * s * z; } else { return s * z; } } double epswr_round_dim_mm(double x_mm, double dpi) { if (dpi == 0.0) { return x_mm; } else if (x_mm == 0.0) { return 0.0; } else { double dp_per_mm = (dpi/25.4)/2.0; /* Dot pairs per mm. */ double x_dp_raw = x_mm * dp_per_mm; /* Dimension in dot pairs, unrounded. */ double x_dp = floor(x_dp_raw + 0.5); /* Dimension in dot pairs, rounded; */ if (fabs(x_dp) == 0) { x_dp = (x_mm < 0 ? -1.0 : 1.0); }; /* Ensure min size. */ return x_dp/dp_per_mm; } }