_CLICKABLE IMAGES IN HTML_ by Andrew Davison Listing One The Marx Brothers

The Marx Brothers

A family of Jewish-American comics whose zany humour convulsed minority audiences in its time and influenced later comedy writing to an enormous extent.

Groucho (1890-1977)

(Julius Marx) had a painted moustache, a cigar, a loping walk and the lion's share of the wisecracks.

Harpo (1888-1964)

(Adolph Marx) was a child-like mute who also played a harp.

Chico (1886-1961)

(Leonard Marx) played the piano eccentrically and spoke with an impossible Italian accent.

The Other Brothers

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.


To Start
Listing Two The Marx Brothers

The Marx Brothers


Click on the picture to find out more:


The Marx Brothers

A family of Jewish-American comics whose zany humour convulsed minority audiences in its time and influenced later comedy writing to an enormous extent.

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.


Andrew Davison
Listing Three /* Simplified version of mapper 1.2 ** Based on work by: Kevin Hughes, ** Eric Haines, Rob McCool, Chris Hyams, Rick Troth, ** Craig Milo Rogers, Carlos Varela ** Original version at ** http://hoohoo.ncsa.uiuc.edu/docs/setup/admin/NewImagemap.html ** Andrew Davison (ad@cs.mu.oz.au) January 1995 ** Available at http://www.cs.mu.oz.au/~ad/code/visuals/mapper.c ** Object code should go in: /local/dept/wwwd/scripts/mapper */ #include #include #include #include #define MAXLINE 500 /* max length of line in image map file */ #define MAXVERTS 100 /* max num of coords in a shape */ #define NUMLEN 10 /* max num of digits in a X or Y number */ #define LF 10 #define X 0 #define Y 1 void get_map(char map[]); void get_clickpt(char *arg, double clickpt[]); void process_map(FILE *fp, double clickpt[]); void get_word(char *input, int *pi, char *word); void get_num(char *input, int *pi, char *num); void get_coords(char *input, int *pi, double coords[][2], int size, FILE *fp); void servererr(char *msg); void sendmesg(char *url); double sdist_apart(double clickpt[], double coords[][2]); int clickpt_in_rect(double clickpt[], double coords[][2]); int clickpt_in_circle(double clickpt[], double coords[][2]); int clickpt_in_poly(double clickpt[], double pgon[][2]); int main(int argc, char *argv[]) { char map[MAXLINE]; /* name of image map file with full path */ double clickpt[2]; /* for the (X,Y) coord clicked upon */ FILE *fp; if (argc != 2) servererr("Wrong number of arguments, client may not support ISMAP."); get_map(map); if((fp = fopen(map,"r")) == NULL) servererr(strcat("Couldn't open image map file:", map)); else { get_clickpt(argv[1], clickpt); process_map(fp, clickpt); fclose(fp); } return 0; } void get_map(char map[]) /* obtain the image map file name with a full UNIX path */ { char *name; /* name of image map file with partial path */ name = getenv("PATH_INFO"); if((!name) || (!name[0])) servererr("No image map name given. Please read the instructions.

"); 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("Mapping Server Error"); printf("

Mapping Server Error

"); printf("This server encountered an error:

"); 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: The Marx Brothers (image as anchor label)

The Marx Brothers (image as anchor label)


Click on the picture for more on the Marx Brothers.


Andrew Davison
Example 2: The Marx Brothers (using forms)

The Marx Brothers (using forms)


Click on the picture to find out more:


Andrew Davison
Example 3: # image map for Marx Brothers image default /~ad/code/visuals/mgm.html # left head circle /~ad/code/visuals/harpo.html 52,33 52,10 # middle head circle /~ad/code/visuals/groucho.html 142,33 142,10 #right head circle /~ad/code/visuals/chico.html 230,46 230,26 # blondes suitcase poly /~ad/code/visuals/blondes.html 19,74 92,62 101,101 31,109 # gags suitcase poly /~ad/code/visuals/gags.html 219,86 309,44 310,87 251,110