/** * Add an imagemap to the hashtable, creating it if it doesn't exist * * \param c The containing content * \param key The name of the imagemap * \param list List of map regions * \return true on succes, false otherwise */ bool imagemap_add(html_content *c, const char *key, struct mapentry *list) { struct imagemap *map; unsigned int slot; assert(c != NULL); assert(key != NULL); assert(list != NULL); if (imagemap_create(c) == false) return false; map = calloc(1, sizeof(*map)); if (map == NULL) return false; map->key = strdup(key); if (map->key == NULL) { free(map); return false; } map->list = list; slot = imagemap_hash(key); map->next = c->imagemaps[slot]; c->imagemaps[slot] = map; return true; }
/** * Add an imagemap to the hashtable, creating it if it doesn't exist * * \param c The containing content * \param key The name of the imagemap * \param list List of map regions * \return true on succes, false otherwise */ static bool imagemap_add(html_content *c, dom_string *key, struct mapentry *list) { struct imagemap *map; unsigned int slot; assert(c != NULL); assert(key != NULL); assert(list != NULL); if (imagemap_create(c) == false) return false; map = calloc(1, sizeof(*map)); if (map == NULL) return false; /* \todo Stop relying on NULL termination of dom_string */ map->key = strdup(dom_string_data(key)); if (map->key == NULL) { free(map); return false; } map->list = list; slot = imagemap_hash(map->key); map->next = c->imagemaps[slot]; c->imagemaps[slot] = map; return true; }
/** * Retrieve url associated with imagemap entry * * \param h The containing content * \param key The map name to search for * \param x The left edge of the containing box * \param y The top edge of the containing box * \param click_x The horizontal location of the click * \param click_y The vertical location of the click * \param target Pointer to location to receive target pointer (if any) * \return The url associated with this area, or NULL if not found */ nsurl *imagemap_get(struct html_content *c, const char *key, unsigned long x, unsigned long y, unsigned long click_x, unsigned long click_y, const char **target) { unsigned int slot = 0; struct imagemap *map; struct mapentry *entry; unsigned long cx, cy; assert(c != NULL); if (key == NULL) return NULL; if (c->imagemaps == NULL) return NULL; slot = imagemap_hash(key); for (map = c->imagemaps[slot]; map != NULL; map = map->next) { if (map->key != NULL && strcasecmp(map->key, key) == 0) break; } if (map == NULL || map->list == NULL) return NULL; for (entry = map->list; entry; entry = entry->next) { switch (entry->type) { case IMAGEMAP_DEFAULT: /* just return the URL. no checks required */ if (target) *target = entry->target; return entry->url; break; case IMAGEMAP_RECT: if (click_x >= x + entry->bounds.rect.x0 && click_x <= x + entry->bounds.rect.x1 && click_y >= y + entry->bounds.rect.y0 && click_y <= y + entry->bounds.rect.y1) { if (target) *target = entry->target; return entry->url; } break; case IMAGEMAP_CIRCLE: cx = x + entry->bounds.circle.x - click_x; cy = y + entry->bounds.circle.y - click_y; if ((cx * cx + cy * cy) <= (unsigned long) (entry->bounds.circle.r * entry->bounds.circle.r)) { if (target) *target = entry->target; return entry->url; } break; case IMAGEMAP_POLY: if (imagemap_point_in_poly(entry->bounds.poly.num, entry->bounds.poly.xcoords, entry->bounds.poly.ycoords, x, y, click_x, click_y)) { if (target) *target = entry->target; return entry->url; } break; } } if (target) *target = NULL; return NULL; }