_CLICKABLE IMAGES IN HTML_ by Andrew Davison Listing One
Aside from Chico, Groucho and Harpo (shown above), there were two other brothers: Gummo (1893-1977) (Milton Marx) and Zeppo (1901-1979) (Herbert Marx) who left the team early on.
"); name++; /* ignore first '/' */ /* if the name contains a '/' then it represents a partial UNIX path */ if (strchr(name,'/')) strcpy(map, getenv("PATH_TRANSLATED")); else servererr("Map name must include a partial UNIX path."); } void get_clickpt(char *arg, double clickpt[]) /* extract the (X,Y) coord clicked upon */ { char *t; if((t = strchr(arg,',')) == NULL) servererr("Your client doesn't support image mapping properly."); *t++ = '\0'; clickpt[X] = (double) atoi(arg); clickpt[Y] = (double) atoi(t); } void process_map(FILE *fp, double clickpt[]) /* parse the image map file, locate clickpt inside a hot shape, invoke the associated URL */ { char input[MAXLINE]; /* a line from the image map file */ char type[MAXLINE]; /* type of hot spot shape */ char url[MAXLINE]; /* URL associated with shape type */ char deflt[MAXLINE]; /* the URL for the default case */ double coords[MAXVERTS][2]; /* the coordinates of a shape */ int num_ptshapes = 0; /* number of point hot spots used */ double dist, min_dist; /* for nearest point hot spot calc */ int i; while((fgets(input, MAXLINE, fp)) != NULL) { i = 0; if((input[i] == '#') || (!input[i])) continue; get_word(input, &i, type); while(isspace(input[i])) i++; get_word(input, &i, url); if((strcmp(type,"default") == 0) && (num_ptshapes == 0)) { strcpy(deflt,url); continue; } get_coords(input, &i, coords, MAXVERTS, fp); if(strcmp(type,"poly") == 0) /* poly type */ if(clickpt_in_poly(clickpt,coords)) sendmesg(url); if(strcmp(type,"circle") == 0) /* circle type */ if(clickpt_in_circle(clickpt,coords)) sendmesg(url); if(strcmp(type,"rect") == 0) /* rect type */ if(clickpt_in_rect(clickpt,coords)) sendmesg(url); if(strcmp(type,"point") == 0) { /* point type */ dist = sdist_apart(clickpt, coords); /* If first point hot spot, or the nearest, set the default. */ if ((num_ptshapes == 0) || (dist < min_dist)) { min_dist = dist; strcpy(deflt,url); } num_ptshapes++; } } if(deflt[0]) sendmesg(deflt); else servererr("No default specified."); } void get_word(char *input, int *pi, char *word) /* extract a word from an input line */ { int i; for(i=0; ((!isspace(input[*pi])) && (input[*pi])); i++) { word[i] = input[*pi]; (*pi)++; } word[i] = '\0'; } void get_num(char *input, int *pi, char *num) /* extract a number (as characters) from an input line */ { int i = 0; while ((isspace(input[*pi])) || (input[*pi] == ',')) /* find char */ (*pi)++; while (isdigit(input[*pi])) num[i++] = input[(*pi)++]; num[i] = '\0'; } void get_coords(char *input, int *pi, double coords[][2], int size, FILE *fp) /* extract the (X,Y) coords from an input line, and store them in the coords array */ { char num[MAXLINE]; /* a X or Y part of a coord */ int k=0; while ((input[*pi]) && (k < size)) { get_num(input, pi, num); if (num[0] != '\0') coords[k][X] = (double) atoi(num); /* X part of a coord */ else break; get_num(input, pi, num); if (num[0] != '\0') { coords[k][Y] = (double) atoi(num); /* Y part of a coord */ k++; } else { fclose(fp); servererr("Missing Y value in a co-ordinate."); } } if (k < size) coords[k][X] = -1; /* sentinel */ else coords[k-1][X] = -1; /* overwrite last coord */ } /* HTML print utilities */ void servererr(char *msg) { printf("Content-type: text/html%c%c",LF,LF); printf("
"); printf("%s", msg); exit(-1); } void sendmesg(char *url) { if (strchr(url, ':')) /* It is a full URL */ printf("Location: "); else /* It is a virtual URL */ printf("Location: http://%s", getenv("SERVER_NAME")); printf("%s%c%c",url,LF,LF); exit(0); } /* clickpt locating functions */ double sdist_apart(double clickpt[2], double coords[MAXVERTS][2]) /* Find the square of the distance between the click point and the coords of a point hot spot. Don't need to take square root */ { return ((clickpt[X] - coords[0][X]) * (clickpt[X] - coords[0][X])) + ((clickpt[Y] - coords[0][Y]) * (clickpt[Y] - coords[0][Y])); } int clickpt_in_rect(double clickpt[2], double coords[MAXVERTS][2]) /* is the clickpt inside a rectangle? */ { return ((clickpt[X] >= coords[0][X] && clickpt[X] <= coords[1][X]) && (clickpt[Y] >= coords[0][Y] && clickpt[Y] <= coords[1][Y])); } int clickpt_in_circle(double clickpt[2], double coords[MAXVERTS][2]) /* is the clickpt inside a circle? */ { int radius1, radius2; radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y])) + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X])); radius2 = ((coords[0][Y] - clickpt[Y]) * (coords[0][Y] - clickpt[Y])) + ((coords[0][X] - clickpt[X]) * (coords[0][X] - clickpt[X])); return (radius2 <= radius1); } int clickpt_in_poly(double clickpt[2], double pgon[MAXVERTS][2]) /* is the clickpt inside a polygon? */ { int i, numverts, inside_flag, xflag0; int crossings; double *p, *stop; double tx, ty, y; for (i = 0; pgon[i][X] != -1 && i < MAXVERTS; i++) ; numverts = i; crossings = 0; tx = clickpt[X]; ty = clickpt[Y]; y = pgon[numverts - 1][Y]; p = (double *) pgon + 1; if ((y >= ty) != (*p >= ty)) { if ((xflag0 = (pgon[numverts - 1][X] >= tx)) == (*(double *) pgon >= tx)) { if (xflag0) crossings++; } else { crossings += (pgon[numverts - 1][X] - (y - ty) * (*(double *) pgon - pgon[numverts - 1][X]) / (*p - y)) >= tx; } } stop = pgon[numverts]; for (y = *p, p += 2; p < stop; y = *p, p += 2) { if (y >= ty) { while ((p < stop) && (*p >= ty)) p += 2; if (p >= stop) break; if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) { if (xflag0) crossings++; } else { crossings += (*(p - 3) - (*(p - 2) - ty) * (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx; } } else { while ((p < stop) && (*p < ty)) p += 2; if (p >= stop) break; if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) { if (xflag0) crossings++; } else { crossings += (*(p - 3) - (*(p - 2) - ty) * (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx; } } } inside_flag = crossings & 0x01; return (inside_flag); } Example 1: