|
|
1.1 ! root 1: /* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved. */ ! 2: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T. */ ! 3: /* The copyright notice does not imply actual or intended publication. */ ! 4: /* AUTHORS: */ ! 5: /* H. S. Baird - ATT-BL MH - first versions */ ! 6: /* Coord.h - defines, typedefs, Inits, empties, and function declarations ! 7: for basic Coordinate geometry data items. ! 8: See Coord.c for associated functions. ! 9: */ ! 10: ! 11: /* Round signed floating-pt no. F: ! 12: (a) ROUND - to nearest integer; ! 13: (b) ROUND_UP - up to next int; ! 14: (c) ROUND_DN - down to prior int. ! 15: Evaluates the argument exactly once. */ ! 16: static double _round,_round_up,_round_dn; ! 17: #define ROUND(F) ((int)(((_round=(F))>=0.0)? _round+0.5: _round-0.5)) ! 18: #define ROUND_UP(F) ((int)(((_round_up=(F))>=0.0)? _round_up+0.999999: _round_up)) ! 19: #define ROUND_DN(F) ((int)(((_round_dn=(F))>=0.0)? _round_dn: _round_dn-0.999999)) ! 20: ! 21: /* The basic unit is the scanner pixel, located in the X,Y plane. As in many ! 22: graphics coordinate systems, X increases left-to-right, while Y increases ! 23: top-down. Pixel coordinates are usually integer values. The physical extent ! 24: of integer coordinate `x' along the real X-axis is the half-open interval ! 25: [x,x+1), and similarly for Y. The actual digitizing resolution (e.g. ! 26: pixels/inch) represented can vary from document to document, and is almost ! 27: always known to the algorithms. X & Y resolution can be different, though ! 28: for simplicity of discussion we will usually assume that they are equal, ! 29: i.e. that pixels are square. Thus pixel (x,y) may be thought of as the region ! 30: [x,x+1)X[y,y+1) in the real plane. ! 31: Half-pixel resolution is also supported, with its own data types for ! 32: clarity. However, to avoid distracting struggles with the type system, they ! 33: are for the most part #defined to be identical to ordinary coordinates. The ! 34: principle effect is that the limits of scanner coordinates have been halved ! 35: to allow for safe use of half-pixels everywhere. (This still permits images ! 36: 80 inches square at 400 pixels/inch, assuming `short' is at least 16-bit 2's ! 37: complement.) ! 38: Half-pixel coordinates can also be used to describe boundaries of regions, ! 39: as a set of ideal point locations at the corners and edge midpoints of pixels. ! 40: The half-pixel data type is used; boundary points are identified by flags ! 41: in the Bdy "boundary" structure, and may be displayed differently. */ ! 42: ! 43: #define Scoor short /* Scanner pixel coordinate value */ ! 44: #define Hcoor Scoor /* Half-pixel coordinate value */ ! 45: #define Bcoor Hcoor /* Half-pixel boundary coordinate value */ ! 46: ! 47: /* Each Scoor value `v' is associated of course with two Hcoor values `a' < `b'. ! 48: Conventionally, the physical extent of the `a' half-coordinate is the real ! 49: interval [v,v+0.5), and `b' is [v+0.5,v+1). */ ! 50: #define StoHa(S) ((S)*2) ! 51: #define StoHb(S) ((S)*2+1) ! 52: #define HtoS(H) ((H)/2) ! 53: ! 54: /* The 3 half-pixel boundary points of a pixel coordinate `C' are: */ ! 55: #define StoBa(S) (StoHa((S))) /* minimum of interval */ ! 56: #define StoBb(S) (StoHb((S))) /* midpoint of interval */ ! 57: #define StoBc(S) (StoHa((S)+1)) /* maximum of interval */ ! 58: ! 59: #define Scoor_MIN (SHRT_MIN/2) /* minimum possible value */ ! 60: #define Scoor_MAX (SHRT_MAX/2) /* maximum possible value */ ! 61: ! 62: #define Hcoor_MIN (SHRT_MIN) /* minimum possible value */ ! 63: #define Hcoor_MAX (SHRT_MAX) /* maximum possible value */ ! 64: ! 65: #define fwri_Scoor(F,V) fwri_int2((F),(V)) ! 66: #define frdi_Scoor(F) frdi_int2(F) ! 67: ! 68: #define fwri_Hcoor(F,V) fwri_int2((F),(V)) ! 69: #define frdi_Hcoor(F) frdi_int2(F) ! 70: ! 71: #define fwri_Bcoor(F,V) fwri_int2((F),(V)) ! 72: #define frdi_Bcoor(F) frdi_int2(F) ! 73: ! 74: typedef struct Sp { /* point: pixel address */ ! 75: Scoor x; /* increases left-to-right: Scoor_MIN is left of image */ ! 76: Scoor y; /* increases down: Scoor_MIN is top of image */ ! 77: } Sp; ! 78: #define Hp Sp /* Half-pixel point */ ! 79: ! 80: #define Init_Zero_Sp {0,0} ! 81: #define Init_Min_Sp {Scoor_MIN,Scoor_MIN} ! 82: #define Init_Max_Sp {Scoor_MAX,Scoor_MAX} ! 83: ! 84: #if MAIN ! 85: Sp zero_Sp = Init_Zero_Sp; ! 86: #else ! 87: extern Sp zero_Sp; ! 88: #endif ! 89: ! 90: #define fwri_Sp(F,P) { fwri_Scoor((F),(P)->x); fwri_Scoor((F),(P)->y); } ! 91: #define frdi_Sp(F,P) (feof(F)? 0: ( \ ! 92: (P)->x=frdi_Scoor(F), \ ! 93: (P)->y=frdi_Scoor(F), \ ! 94: (ferror(F)? -errno: 1) ) ) ! 95: ! 96: /* Is Sp *p1 exactly equal to Sp *p2? */ ! 97: #define sp_eq(p1,p2) ( \ ! 98: ((p1)->x == (p2)->x) \ ! 99: && ((p1)->y == (p2)->y) \ ! 100: ) ! 101: ! 102: typedef struct Sps { /* Set of Points */ ! 103: int mny; /* no. points (mny==0 ==> pa==NULL) */ ! 104: Sp **pa; /* NULL-terminated Sp *pa[mny+1] (malloc space)*/ ! 105: } Sps; ! 106: ! 107: #define Init_Sps {0,NULL} ! 108: #if MAIN ! 109: Sps empty_Sps = Init_Sps; ! 110: #else ! 111: extern Sps empty_Sps; ! 112: #endif ! 113: ! 114: typedef struct Spa { /* array of Points */ ! 115: int mny; /* no. points in array */ ! 116: Sp *a; /* Sp a[mny] (malloc space)*/ ! 117: } Spa; ! 118: /** #define Pointa Spa **/ /* OBSOLESCENT */ ! 119: ! 120: #define Init_Spa {0,NULL} ! 121: #if MAIN ! 122: Spa empty_Spa = Init_Spa; ! 123: #else ! 124: extern Spa empty_Spa; ! 125: #endif ! 126: ! 127: /* An edge is an ordered pair of vertices. */ ! 128: typedef struct Edge { ! 129: Sp a,b; /* endpoints */ ! 130: } Edge; ! 131: ! 132: #define Init_Edge {Init_Zero_Sp,Init_Zero_Sp} ! 133: #if MAIN ! 134: Edge empty_Edge = Init_Edge; ! 135: #else ! 136: extern Edge empty_Edge; ! 137: #endif ! 138: ! 139: #define fwri_Edge(F,P) { fwri_Sp((F),&((P)->a)); fwri_Sp((F),&((P)->b)); } ! 140: #define frdi_Edge(F,P) ( feof(F)? 0: ( \ ! 141: frdi_Sp(F,&((P)->a)), \ ! 142: frdi_Sp(F,&((P)->b)), \ ! 143: (ferror(F)? -errno: 1) ) ) ! 144: ! 145: /* A bounding box is a rectangle */ ! 146: typedef struct { /* bounding box: inclusive of boundary values */ ! 147: Sp a; /* top-left corner */ ! 148: Sp b; /* bottom-right corner */ ! 149: } Bbx; ! 150: ! 151: typedef struct DSp { /* point: pixel address */ ! 152: double x; /* increases down the page, MinScoor at top */ ! 153: double y; /* increases across the page, MinScoor at left */ ! 154: } DSp; ! 155: ! 156: #define Init_Bbx {Init_Max_Sp,Init_Min_Sp} ! 157: #define Init_Max_Bbx {Init_Min_Sp,Init_Max_Sp} ! 158: #if MAIN ! 159: Bbx empty_Bbx = Init_Bbx; ! 160: Bbx max_Bbx = Init_Max_Bbx; ! 161: #else ! 162: extern Bbx empty_Bbx; ! 163: extern Bbx max_Bbx; ! 164: #endif ! 165: ! 166: #define fwri_Bbx(F,P) { fwri_Sp((F),&((P)->a)); fwri_Sp((F),&((P)->b)); } ! 167: #define frdi_Bbx(F,P) ( feof(F)? 0: ( \ ! 168: frdi_Sp(F,&((P)->a)), \ ! 169: frdi_Sp(F,&((P)->b)), \ ! 170: (ferror(F)? -errno: 1) ) ) ! 171: ! 172: /* OBSOLESCENT: */ ! 173: #if MAIN ! 174: Bbx null_Bbx = {Init_Max_Sp,Init_Min_Sp}; ! 175: #else ! 176: extern Bbx null_Bbx; ! 177: #endif ! 178: ! 179: /* height, width, area of Bbx in pixels */ ! 180: #define bbx_hgt(bxp) ((bxp)->b.y-(bxp)->a.y+1) ! 181: #define bbx_wid(bxp) ((bxp)->b.x-(bxp)->a.x+1) ! 182: #define bbx_area(bxp) (bbx_hgt((bxp))*bbx_wid((bxp))) ! 183: ! 184: /* Is Bbx *b1 exactly equal to Bbx *b2? */ ! 185: #define bbx_eq(b1,b2) ( \ ! 186: ((b1)->a.x == (b2)->a.x) \ ! 187: && ((b1)->a.y == (b2)->a.y) \ ! 188: && ((b1)->b.x == (b2)->b.x) \ ! 189: && ((b1)->b.y == (b2)->b.y) \ ! 190: ) ! 191: ! 192: /* Is Bbx *b1 wholly inside Bbx *b2? */ ! 193: #define bbx_inside_all(b1,b2) ( \ ! 194: ((b1)->a.x >= (b2)->a.x) \ ! 195: && ((b1)->a.y >= (b2)->a.y) \ ! 196: && ((b1)->b.x <= (b2)->b.x) \ ! 197: && ((b1)->b.y <= (b2)->b.y) \ ! 198: ) ! 199: ! 200: /* Is any of Bbx *b1 inside Bbx *b2? */ ! 201: #define bbx_inside_any(b1,b2) ( \ ! 202: ((b1)->a.x <= (b2)->b.x) \ ! 203: && ((b1)->a.y <= (b2)->b.y) \ ! 204: && ((b1)->b.x >= (b2)->a.x) \ ! 205: && ((b1)->b.y >= (b2)->a.y) \ ! 206: ) ! 207: ! 208: typedef struct Bbxs { /* A set of Bbxs */ ! 209: int mny; /* if mny==0, then pa==NULL */ ! 210: Bbx **pa; /* NULL-terminated array (in malloc space) of `mny+1' ! 211: pointers to Bbxs (in malloc space) */ ! 212: int alloc; /* no. slots in pa[] actually allocated (>=mny+1) */ ! 213: int incr; /* no. slots in pa[] to reallocate at a time */ ! 214: } Bbxs; ! 215: ! 216: #define Init_Bbxs {0,NULL,0,512} ! 217: #if MAIN ! 218: Bbxs empty_Bbxs = Init_Bbxs; ! 219: #else ! 220: extern Bbxs empty_Bbxs; ! 221: #endif ! 222: ! 223: Sp *alloc_sp(); ! 224: free_sp(); ! 225: char *sp_toa(); /* Sp to ascii printable string */ ! 226: Sp *ato_sp(); /* Sp from ascii printable string */ ! 227: frda_sps(); ! 228: Sps *dup_sps(); ! 229: Sp *append_sp_sps(); ! 230: Sp *append_sp_spa(); ! 231: Sp *rotate_Sp(); /* rotate Sp about given fixed-point */ ! 232: Sp *hshear_Sp(); /* horiz-shear Sp about given fixed-point */ ! 233: Edge *alloc_edge(); ! 234: free_edge(); ! 235: char *edge_toa(); /* Edge to ascii printable string */ ! 236: Edge *ato_edge(); /* Edge from ascii printable string */ ! 237: Bbx *alloc_bbx(); ! 238: Bbx *append_bbx(); ! 239: Bbxs *dup_bbxs(); ! 240: char *bbx_toa(); /* Bbx to ascii printable string */ ! 241: Bbx *ato_bbx(); /* Bbx from ascii printable string */ ! 242: Bbx *translate_bbx(); ! 243: boolean bbx_inside_most(); /* Is Bbx 1 mostly inside Bbx 2? */ ! 244: Bbx *expand_bbx();
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.