Index: src/dw_gtk_viewport.c =================================================================== RCS file: /sfhome/cvs/dillo/dillo/src/dw_gtk_viewport.c,v retrieving revision 1.44 diff -p -u -r1.44 dw_gtk_viewport.c --- src/dw_gtk_viewport.c 17 Oct 2004 13:39:51 -0000 1.44 +++ src/dw_gtk_viewport.c 19 Oct 2004 18:49:19 -0000 @@ -803,35 +803,40 @@ DwWidget* Dw_gtk_viewport_widget_at_poin /* * Add an anchor, and assign a position for it. For all widgets * directly or indirectly assigned to a viewports, anchors must be - * unique, this is tested. + * unique, this is tested. "name" is copied, so no strdup is + * neccessary for the caller. * - * The viewport gets the responsibility to free "name", so the caller - * does not have to pass a copy, neither, the caller must free it. + * Return the copy on success, or NULL, when this anchor had already + * been added to the widget tree. + * + * The viewport gets the responsibility to free "name". */ -void p_Dw_gtk_viewport_add_anchor (DwWidget *widget, - gchar *name, - gint32 y) +gchar* p_Dw_gtk_viewport_add_anchor (DwWidget *widget, + const gchar *name, + gint32 y) { GtkDwViewport *viewport; GtkDwViewportAnchor *anchor; - gboolean exists; _MSG("new anchor %p/'%s' -> %d\n", widget, name, y); - g_return_if_fail (widget->viewport != NULL); + g_return_val_if_fail (widget->viewport != NULL, NULL); viewport = GTK_DW_VIEWPORT (widget->viewport); - exists = - g_hash_table_lookup_extended (viewport->anchors_table, name, NULL, NULL); - g_return_if_fail(!exists); - - anchor = g_new (GtkDwViewportAnchor, 1); - anchor->name = name; - anchor->widget = widget; - anchor->y = y; - - g_hash_table_insert (viewport->anchors_table, name, anchor); - Dw_gtk_viewport_update_anchor (viewport); + if(g_hash_table_lookup_extended (viewport->anchors_table, name, NULL, NULL)) + /* Anchor does already exist. */ + return NULL; + else { + anchor = g_new (GtkDwViewportAnchor, 1); + anchor->name = g_strdup (name); + anchor->widget = widget; + anchor->y = y; + + g_hash_table_insert (viewport->anchors_table, anchor->name, anchor); + Dw_gtk_viewport_update_anchor (viewport); + + return anchor->name; + } } @@ -852,7 +857,7 @@ void p_Dw_gtk_viewport_change_anchor (Dw g_return_if_fail (widget->viewport != NULL); viewport = GTK_DW_VIEWPORT (widget->viewport); - exists = + exists = g_hash_table_lookup_extended (viewport->anchors_table, name, NULL, &tmp_anchor); g_return_if_fail(exists); Index: src/dw_gtk_viewport.h =================================================================== RCS file: /sfhome/cvs/dillo/dillo/src/dw_gtk_viewport.h,v retrieving revision 1.21 diff -p -u -r1.21 dw_gtk_viewport.h --- src/dw_gtk_viewport.h 17 Oct 2004 13:39:51 -0000 1.21 +++ src/dw_gtk_viewport.h 19 Oct 2004 18:49:20 -0000 @@ -90,8 +90,8 @@ DwWidget* a_Dw_gtk_viewport_widget_ gint32 vx, gint32 vy); -void p_Dw_gtk_viewport_add_anchor (DwWidget *widget, - gchar *name, +gchar* p_Dw_gtk_viewport_add_anchor (DwWidget *widget, + const gchar* name, gint32 y); void p_Dw_gtk_viewport_change_anchor (DwWidget *widget, gchar *name, Index: src/dw_page.c =================================================================== RCS file: /sfhome/cvs/dillo/dillo/src/dw_page.c,v retrieving revision 1.133 diff -p -u -r1.133 dw_page.c --- src/dw_page.c 17 Oct 2004 13:39:51 -0000 1.133 +++ src/dw_page.c 19 Oct 2004 18:49:50 -0000 @@ -2042,24 +2042,40 @@ void a_Dw_page_add_widget (DwPage *page, /* - * Add an anchor to the page. name is copied, so no strdup is neccessary for + * Add an anchor to the page. "name" is copied, so no strdup is neccessary for * the caller. + * + * Return TRUE on success, and FALSE, when this anchor had already been + * added to the widget tree. */ -void a_Dw_page_add_anchor (DwPage *page, const char *name, DwStyle *style) +gboolean a_Dw_page_add_anchor (DwPage *page, const gchar *name, DwStyle *style) { DwPageWord *word; + char *copy; + gint32 y; - word = Dw_page_add_word (page, 0, 0, 0, style); - word->content.type = DW_CONTENT_ANCHOR; - word->content.data.anchor = g_strdup (name); - Dw_page_word_wrap (page, page->num_words - 1); + if(page->num_lines == 0) + y = 0; + else + y = Dw_page_line_total_y_offset_i (page, page->num_lines - 1); - DBG_OBJ_ARRSET_STR (page, "words.%d.content.anchor", page->num_words - 1, - word->content.data.anchor); + /* + * Since an anchor does not take any space, it is safe to call + * p_Dw_gtk_viewport_add_anchor already here. + */ + if((copy = p_Dw_gtk_viewport_add_anchor (DW_WIDGET(page), name, y)) == NULL) + return FALSE; + else { + word = Dw_page_add_word (page, 0, 0, 0, style); + word->content.type = DW_CONTENT_ANCHOR; + word->content.data.anchor = copy; + Dw_page_word_wrap (page, page->num_words - 1); + + DBG_OBJ_ARRSET_STR (page, "words.%d.content.anchor", page->num_words - 1, + word->content.data.anchor); - p_Dw_gtk_viewport_add_anchor - (DW_WIDGET(page), word->content.data.anchor, - Dw_page_line_total_y_offset_i (page, page->num_lines - 1)); + return TRUE; + } } Index: src/dw_page.h =================================================================== RCS file: /sfhome/cvs/dillo/dillo/src/dw_page.h,v retrieving revision 1.45 diff -p -u -r1.45 dw_page.h --- src/dw_page.h 13 Mar 2004 17:53:28 -0000 1.45 +++ src/dw_page.h 19 Oct 2004 18:49:51 -0000 @@ -158,7 +158,7 @@ void a_Dw_page_add_text (DwPage *page, c void a_Dw_page_add_widget (DwPage *page, DwWidget *widget, DwStyle *style); -void a_Dw_page_add_anchor (DwPage *page, const char *name, DwStyle *style); +gboolean a_Dw_page_add_anchor (DwPage *page, const gchar *name, DwStyle *style); void a_Dw_page_add_space(DwPage *page, DwStyle *style); void a_Dw_page_add_parbreak (DwPage *page, gint space, DwStyle *style); void a_Dw_page_add_linebreak (DwPage *page, DwStyle *style); Index: src/html.c =================================================================== RCS file: /sfhome/cvs/dillo/dillo/src/html.c,v retrieving revision 1.217 diff -p -u -r1.217 html.c --- src/html.c 15 Oct 2004 15:50:41 -0000 1.217 +++ src/html.c 19 Oct 2004 18:50:50 -0000 @@ -2604,7 +2604,9 @@ static void Html_tag_open_a(DilloHtml *h if ((attrbuf = Html_get_attr(html, tag, tagsize, "name"))) { pname = a_Url_decode_hex_str(attrbuf); if (Html_check_name_val(html, pname, "name")) { - a_Dw_page_add_anchor(page, pname, html->stack[html->stack_top].style); + if(!a_Dw_page_add_anchor(page, pname, + html->stack[html->stack_top].style)) + MSG_HTML("Value of 'name' must be unique within the document\n"); _MSG("Registering ANCHOR: %s\n", pname); } g_free(pname); @@ -4494,8 +4496,9 @@ static void Html_process_tag(DilloHtml * HTML_LeftTrim | HTML_RightTrim)) && Html_check_name_val(html, attrbuf, "id")) { - a_Dw_page_add_anchor(DW_PAGE (html->dw), attrbuf, - html->stack[html->stack_top].style); + if(!a_Dw_page_add_anchor(DW_PAGE (html->dw), attrbuf, + html->stack[html->stack_top].style)) + MSG_HTML("Value of 'id' must be unique within the document\n"); } /* let the parser know this was an open tag */