int cur_line, cur_char, cur_shift;
int cur_line, cur_shift;
PUBLIC void HText_trimHightext ARGS2(	HText *,	text,	BOOLEAN,	final){    int cur_line, cur_char, cur_shift;    TextAnchor *anchor_ptr;    TextAnchor *prev_a = NULL;    HTLine *line_ptr;    unsigned char ch;    if (!text)	return;    CTRACE(tfp,"Gridtext: Entering HText_trimHightext %s\n",	       final ? "(final)" : "(partial)");    /*     *  Get the first line.     */    line_ptr = text->last_line->next;    cur_char = line_ptr->size;    cur_line = 0;    /*     *  Fix up the anchor structure values and     *  create the hightext strings. - FM     */    for (anchor_ptr = text->first_anchor;	anchor_ptr;	prev_a = anchor_ptr, anchor_ptr=anchor_ptr->next) {re_parse:	/*	 *  Find the right line.	 */	for (; anchor_ptr->start > cur_char;	       line_ptr = line_ptr->next,	       cur_char += line_ptr->size+1,	       cur_line++) {	    ; /* null body */	}	if (!final) {	    /*	     *  If this is not the final call, stop when we have reached	     *  the last line, or the very end of preceding line.	     *  The last line is probably still not finished. - kw	     */	    if (cur_line >= text->Lines)		break;	    if (anchor_ptr->start >= text->chars - 1)		break;	    /*	     *  Also skip this anchor if it looks like HText_endAnchor	     *  is not yet done with it. - kw	     */	    if (!anchor_ptr->extent && anchor_ptr->number &&		(anchor_ptr->link_type & HYPERTEXT_ANCHOR) &&		!anchor_ptr->show_anchor &&		anchor_ptr->number == text->last_anchor_number)		continue;	}	/*	 *  If hightext has already been set, then we must have already	 *  done the trimming & adjusting for this anchor, so avoid	 *  doing it a second time. - kw	 */	if (anchor_ptr->hightext)	    continue;	if (anchor_ptr->start == cur_char) {	    anchor_ptr->line_pos = line_ptr->size;	} else {	    anchor_ptr->line_pos = anchor_ptr->start -				   (cur_char - line_ptr->size);	}	if (anchor_ptr->line_pos < 0) {	    anchor_ptr->start -= anchor_ptr->line_pos;	    anchor_ptr->line_pos = 0;	    anchor_ptr->line_num = cur_line;	}	CTRACE(tfp,	       "Gridtext: Anchor found on line:%d col:%d [%d] ext:%d\n",	       cur_line, anchor_ptr->line_pos,	       anchor_ptr->number, anchor_ptr->extent);	cur_shift = 0;	/*	 *  Strip off any spaces or SpecialAttrChars at the beginning,	 *  if they exist, but only on HYPERTEXT_ANCHORS.	 */	if (anchor_ptr->link_type & HYPERTEXT_ANCHOR) {	    ch = (unsigned char)line_ptr->data[anchor_ptr->line_pos];	    while (isspace(ch) ||		   IsSpecialAttrChar(ch)) {		anchor_ptr->line_pos++;		anchor_ptr->extent--;		cur_shift++;		ch = (unsigned char)line_ptr->data[anchor_ptr->line_pos];	    }	}	if (anchor_ptr->extent < 0) {	    anchor_ptr->extent = 0;	}	anchor_ptr->start += cur_shift;	CTRACE(tfp, "anchor text: '%s'\n",					   line_ptr->data);	/*	 *  If the link begins with an end of line and we have more	 *  lines, then start the highlighting on the next line. - FM	 *  But if an empty anchor is at the end of line and empty,	 *  keep it where it is, unless the previous anchor in the list	 *  (if any) already starts later. - kw	 */	if ((unsigned)anchor_ptr->line_pos >= strlen(line_ptr->data)) {	    if (cur_line < text->Lines &&		(anchor_ptr->extent ||		 anchor_ptr->line_pos != (int)line_ptr->size ||		 (prev_a && prev_a->start > anchor_ptr->start))) {		anchor_ptr->start++;		CTRACE(tfp, "found anchor at end of line\n");		goto re_parse;	    } else {		CTRACE(tfp, "found anchor at end of line, leaving it there\n");	    }	}	/*	 *  Copy the link name into the data structure.	 */	if (line_ptr->data &&	    anchor_ptr->extent > 0 && anchor_ptr->line_pos >= 0) {	    StrnAllocCopy(anchor_ptr->hightext,			  &line_ptr->data[anchor_ptr->line_pos],			  anchor_ptr->extent);	} else {	    StrAllocCopy(anchor_ptr->hightext, "");	}	/*	 *  If true the anchor extends over two lines,	 *  copy that into the data structure.	 */	if ((unsigned)anchor_ptr->extent > strlen(anchor_ptr->hightext)) {	    HTLine *line_ptr2 = line_ptr->next;	    if (!final) {		if (cur_line + 1 >= text->Lines) {		    FREE(anchor_ptr->hightext); /* bail out */		    break;		}	    }	    /*	     *  Double check that we have a line pointer,	     *  and if so, copy into hightext2.	     */	    if (line_ptr2) {		StrnAllocCopy(anchor_ptr->hightext2,			      line_ptr2->data,			      (anchor_ptr->extent -			       strlen(anchor_ptr->hightext)));		anchor_ptr->hightext2offset = line_ptr2->offset;		remove_special_attr_chars(anchor_ptr->hightext2);		if (anchor_ptr->link_type & HYPERTEXT_ANCHOR) {		    LYTrimTrailing(anchor_ptr->hightext2);		    if (anchor_ptr->hightext2[0] == '\0') {			FREE(anchor_ptr->hightext2);			anchor_ptr->hightext2offset = 0;		    }		}	    }	}	remove_special_attr_chars(anchor_ptr->hightext);	if (anchor_ptr->link_type & HYPERTEXT_ANCHOR) {	    LYTrimTrailing(anchor_ptr->hightext);	}	/*	 *  Subtract any formatting characters from the x position	 *  of the link.	 */	if (anchor_ptr->line_pos > 0) {	    register int offset = 0, i = 0;	    for (; i < anchor_ptr->line_pos; i++)		if (IS_UTF_EXTRA(line_ptr->data[i]) ||		    IsSpecialAttrChar(line_ptr->data[i]))		    offset++;	    anchor_ptr->line_pos -= offset;	}	/*	 *  Add the offset, and set the line number.	 */	anchor_ptr->line_pos += line_ptr->offset;	anchor_ptr->line_num  = cur_line;	CTRACE(tfp, "GridText:     add link on line %d col %d [%d] %s\n",	       cur_line, anchor_ptr->line_pos,	       anchor_ptr->number, "in HText_trimHightext");	/*	 *  If this is the last anchor, we're done!	 */	if (anchor_ptr == text->last_anchor)	    break;    }}