Index: text.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/text.c,v
retrieving revision 1.7
diff -u -r1.7 text.c
--- text.c	16 Sep 2003 21:05:38 -0000	1.7
+++ text.c	23 Mar 2004 11:01:26 -0000
@@ -364,23 +364,113 @@
 html_a11y_text_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type,
 				      gint *start_offset, gint *end_offset)
 {
+	HTMLEngine * e;
+	GtkHTML * html;
+	HTMLCursor orig_cursor;
 	HTMLText *to = HTML_TEXT (HTML_A11Y_HTML (text));
 
-	gail_text_util_text_setup (HTML_A11Y_TEXT (text)->util, to->text);
-	return gail_text_util_get_text (HTML_A11Y_TEXT (text)->util, NULL, GAIL_AFTER_OFFSET, boundary_type, offset, 
+	g_return_val_if_fail (to, NULL);
+	g_return_val_if_fail (start_offset && end_offset, NULL);
+
+	html = GTK_HTML_A11Y_GTKHTML (html_a11y_get_gtkhtml_parent(HTML_A11Y(text)));
+	g_return_val_if_fail (html && GTK_IS_HTML(html) && html->engine, NULL);
+
+	e = html_engine_get_top_html_engine (html->engine);
+
+	switch (boundary_type) {
+	case ATK_TEXT_BOUNDARY_LINE_START:
+		html_cursor_copy (&orig_cursor, e->cursor);
+		html_cursor_down (e->cursor, e);
+		if (e->cursor->object != orig_cursor.object) { /* we are on the last line. */
+			*start_offset = *end_offset = html_a11y_text_get_character_count (text);
+		} else {
+			html_cursor_beginning_of_line (e->cursor, e);
+			*start_offset = e->cursor->offset;
+			html_cursor_down (e->cursor, e);
+			if (e->cursor->object != orig_cursor.object) { 
+				*end_offset = html_a11y_text_get_character_count (text);
+			} else {
+				html_cursor_beginning_of_line (e->cursor, e);
+				*end_offset = e->cursor->offset;
+			}
+		}
+		html_cursor_copy (e->cursor, &orig_cursor); 
+		return html_a11y_text_get_text (text, *start_offset, *end_offset);
+
+	case ATK_TEXT_BOUNDARY_LINE_END:
+		html_cursor_copy (&orig_cursor, e->cursor);
+		html_cursor_end_of_line (e->cursor, e);
+		*start_offset = e->cursor->offset;
+		html_cursor_down (e->cursor, e);
+		if (e->cursor->object != orig_cursor.object) { 
+			*end_offset = *start_offset;
+		} else {
+			html_cursor_end_of_line (e->cursor, e);
+			*end_offset = e->cursor->offset;
+		}
+		html_cursor_copy (e->cursor, &orig_cursor); 
+		return html_a11y_text_get_text (text, *start_offset, *end_offset);
+
+	default:
+		gail_text_util_text_setup (HTML_A11Y_TEXT (text)->util, to->text);
+		return gail_text_util_get_text (HTML_A11Y_TEXT (text)->util, NULL, GAIL_AFTER_OFFSET, boundary_type, offset, 
 					start_offset, end_offset);
+	}
 }
 
 static gchar *
 html_a11y_text_get_text_at_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type,
 				   gint *start_offset, gint *end_offset)
 {
-	gchar * ret;
+	HTMLEngine * e;
+	GtkHTML * html;
+	HTMLCursor orig_cursor;
 	HTMLText *to = HTML_TEXT (HTML_A11Y_HTML (text));
 
-	gail_text_util_text_setup (HTML_A11Y_TEXT (text)->util, to->text);
-	return gail_text_util_get_text (HTML_A11Y_TEXT (text)->util, NULL, GAIL_AT_OFFSET, boundary_type, offset, 
+	g_return_val_if_fail (to, NULL);
+	g_return_val_if_fail (start_offset && end_offset, NULL);
+
+	html = GTK_HTML_A11Y_GTKHTML (html_a11y_get_gtkhtml_parent(HTML_A11Y(text)));
+	g_return_val_if_fail (html && GTK_IS_HTML(html) && html->engine, NULL);
+	
+	e = html_engine_get_top_html_engine (html->engine);
+
+	switch (boundary_type) {
+	case ATK_TEXT_BOUNDARY_LINE_START:
+		html_cursor_copy (&orig_cursor, e->cursor);
+		html_cursor_beginning_of_line (e->cursor, e);
+		*start_offset = e->cursor->offset;
+		html_cursor_down (e->cursor, e);
+		if (e->cursor->object != orig_cursor.object) { /* move to the last line */
+			html_cursor_copy (e->cursor, &orig_cursor); 
+			html_cursor_end_of_line (e->cursor, e);
+		} else {
+			html_cursor_beginning_of_line (e->cursor, e);
+		}
+		*end_offset = e->cursor->offset;
+		html_cursor_copy (e->cursor, &orig_cursor); 
+		return html_a11y_text_get_text (text, *start_offset, *end_offset);
+
+	case ATK_TEXT_BOUNDARY_LINE_END:
+		html_cursor_copy (&orig_cursor, e->cursor);
+		html_cursor_end_of_line (e->cursor, e);
+		*end_offset = e->cursor->offset;
+		html_cursor_up (e->cursor, e);
+		if (e->cursor->object != orig_cursor.object) { /* move to the first line */
+			html_cursor_copy (e->cursor, &orig_cursor); 
+			html_cursor_beginning_of_line (e->cursor, e);
+		} else {
+			html_cursor_end_of_line (e->cursor, e);
+		}
+		*start_offset = e->cursor->offset;
+		html_cursor_copy (e->cursor, &orig_cursor); 
+		return html_a11y_text_get_text (text, *start_offset, *end_offset);
+
+	default:
+		gail_text_util_text_setup (HTML_A11Y_TEXT (text)->util, to->text);
+		return gail_text_util_get_text (HTML_A11Y_TEXT (text)->util, NULL, GAIL_AT_OFFSET, boundary_type, offset, 
 					start_offset, end_offset);
+	}
 	
 }
 
@@ -398,14 +488,58 @@
 html_a11y_text_get_text_before_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type,
 				       gint *start_offset, gint *end_offset)
 {
+	HTMLEngine * e;
+	GtkHTML * html;
+	HTMLCursor orig_cursor;
 	HTMLText *to = HTML_TEXT (HTML_A11Y_HTML (text));
 
 	g_return_val_if_fail (to, NULL);
+	g_return_val_if_fail (start_offset && end_offset, NULL);
 
-	gail_text_util_text_setup (HTML_A11Y_TEXT (text)->util, to->text);
-	
-	return gail_text_util_get_text (HTML_A11Y_TEXT (text)->util, NULL, GAIL_BEFORE_OFFSET, boundary_type, offset, 
+	html = GTK_HTML_A11Y_GTKHTML (html_a11y_get_gtkhtml_parent(HTML_A11Y(text)));
+	g_return_val_if_fail (html && GTK_IS_HTML(html) && html->engine, NULL);
+
+	e = html_engine_get_top_html_engine (html->engine);
+
+	switch (boundary_type) {
+	case ATK_TEXT_BOUNDARY_LINE_START:
+		html_cursor_copy (&orig_cursor, e->cursor);
+		html_cursor_beginning_of_line (e->cursor, e);
+		*end_offset = e->cursor->offset;
+		html_cursor_up (e->cursor, e);
+		if (e->cursor->object != orig_cursor.object) { 
+			*start_offset = *end_offset;
+		} else {
+			html_cursor_beginning_of_line (e->cursor, e);
+			*start_offset = e->cursor->offset;
+		}
+		html_cursor_copy (e->cursor, &orig_cursor); 
+		return html_a11y_text_get_text (text, *start_offset, *end_offset);
+
+	case ATK_TEXT_BOUNDARY_LINE_END:
+		html_cursor_copy (&orig_cursor, e->cursor);
+		html_cursor_up (e->cursor, e);
+		if (e->cursor->object != orig_cursor.object) { /* on the first line */
+			*start_offset = *end_offset = 0;
+		} else {
+			html_cursor_end_of_line (e->cursor, e);
+			*end_offset = e->cursor->offset;
+			html_cursor_up (e->cursor, e);
+			if (e->cursor->object != orig_cursor.object) { /* on the second line */
+				*start_offset = 0;
+			} else {
+				html_cursor_end_of_line (e->cursor, e);
+				*start_offset = e->cursor->offset;
+			}
+		}
+		html_cursor_copy (e->cursor, &orig_cursor); 
+		return html_a11y_text_get_text (text, *start_offset, *end_offset);
+
+	default:
+		gail_text_util_text_setup (HTML_A11Y_TEXT (text)->util, to->text);
+		return gail_text_util_get_text (HTML_A11Y_TEXT (text)->util, NULL, GAIL_BEFORE_OFFSET, boundary_type, offset, 
 					start_offset, end_offset);
+	}
 }
 
 static gint
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/ChangeLog,v
retrieving revision 1.6
diff -u -r1.6 ChangeLog
--- ChangeLog	8 Sep 2003 09:02:55 -0000	1.6
+++ ChangeLog	23 Mar 2004 11:08:42 -0000
@@ -1,3 +1,13 @@
+2004-03-23  Eric Zhao  <eric.zhao@sun.com>
+
+	fixed #55250.
+
+	* text.c: (html_a11y_text_get_text_after_offset),
+	(html_a11y_text_get_text_at_offset),
+	(html_a11y_text_get_text_before_offset): the gail_text_util doesn't
+	know how we break lines in gtkhtml, so we should implement them by
+	ourselves.
+
 2003-09-05  Yuedong Du  <yuedong.du@sun.com>
 
 	* text.c: (html_a11y_text_get_text_after_offset),
