📄 gridtext.c
字号:
last_nlinks = nlinks; /* * If Anchor_ptr is not NULL and is not pointing to the last * anchor, then there are anchors farther down in the document, * and we need to flag this for traversals. */ more_links = FALSE; if (traversal && Anchor_ptr) { if (Anchor_ptr->next) more_links = TRUE; } if (!display_flag) { /* * Nothing on the page. */ addstr("\n Document is empty"); } if (HTCJK != NOCJK || text->T.output_utf8 || TRACE) { /* * For non-multibyte curses. */ lynx_force_repaint(); } refresh();}/* Object Building methods** -----------------------**** These are used by a parser to build the text in an object*/PUBLIC void HText_beginAppend ARGS1( HText *, text){ text->permissible_split = 0; text->in_line_1 = YES;}/* Add a new line of text** ----------------------**** On entry,**** split is zero for newline function, else number of characters** before split.** text->display_on_the_fly** may be set to indicate direct output of the finished line.** On exit,** A new line has been made, justified according to the** current style. Text after the split (if split nonzero)** is taken over onto the next line.**** If display_on_the_fly is set, then it is decremented and** the finished line is displayed.*/#define new_line(text) split_line(text, 0)PRIVATE void split_line ARGS2( HText *, text, int, split){ HTStyle * style = text->style; HTLine * temp; int spare;#if defined(USE_COLOR_STYLE) int inew;#endif int indent = text->in_line_1 ? text->style->indent1st : text->style->leftIndent; TextAnchor * a; int CurLine = text->Lines; int HeadTrim = 0; int SpecialAttrChars = 0; int TailTrim = 0; /* * Make new line. */ HTLine * previous = text->last_line; int ctrl_chars_on_previous_line = 0; char * cp; HTLine * line = (HTLine *)LY_CALLOC(1, LINE_SIZE(MAX_LINE)); if (line == NULL) outofmem(__FILE__, "split_line_1"); ctrl_chars_on_this_line = 0; /*reset since we are going to a new line*/ text->LastChar = ' '; if (TRACE) fprintf(stderr,"GridText: split_line called\n"); text->Lines++; previous->next->prev = line; line->prev = previous; line->next = previous->next;#if defined(USE_COLOR_STYLE)#define LastStyle (previous->numstyles-1) line->numstyles = 0; inew = MAX_STYLES_ON_LINE - 1; spare = previous->numstyles; while (previous->numstyles && inew >= 0) { if (previous->numstyles >= 2 && previous->styles[LastStyle].style == previous->styles[previous->numstyles-2].style && previous->styles[LastStyle].horizpos == previous->styles[previous->numstyles-2].horizpos && ((previous->styles[LastStyle].direction == STACK_OFF && previous->styles[previous->numstyles-2].direction == STACK_ON) || (previous->styles[LastStyle].direction == ABS_OFF && previous->styles[previous->numstyles-2].direction == ABS_ON) || (previous->styles[LastStyle].direction == ABS_ON && previous->styles[previous->numstyles-2].direction == ABS_OFF) )) { /* * Discard pairs of ON/OFF for the same color style, but only * if they appear at the same position. - kw */ previous->numstyles -= 2; if (spare > previous->numstyles) spare = previous->numstyles; } else if (spare > 0 && previous->styles[spare - 1].direction && previous->numstyles < MAX_STYLES_ON_LINE) { /* * The index variable spare walks backwards through the * list of color style changes on the previous line, trying * to find an ON change which isn't followed by a * corresponding OFF. When it finds one, the missing OFF * change is appended to the end, and an ON change is added * at the beginning of the current line. The OFF change * appended to the previous line may get removed again in * the next iteration. - kw */ line->styles[inew].horizpos = 0; line->styles[inew].direction = ON; line->styles[inew].style = previous->styles[spare - 1].style; inew --; line->numstyles ++; previous->styles[previous->numstyles].style = line->styles[inew + 1].style; previous->styles[previous->numstyles].direction = ABS_OFF; previous->styles[previous->numstyles].horizpos = previous->size; previous->numstyles++; spare --; } else if (spare >= 2 && previous->styles[spare - 1].style == previous->styles[spare - 2].style && ((previous->styles[spare - 1].direction == STACK_OFF && previous->styles[spare - 2].direction == STACK_ON) || (previous->styles[spare - 1].direction == ABS_OFF && previous->styles[spare - 2].direction == ABS_ON) || (previous->styles[spare - 1].direction == STACK_ON && previous->styles[spare - 2].direction == STACK_OFF) || (previous->styles[spare - 1].direction == ABS_ON && previous->styles[spare - 2].direction == ABS_OFF) )) { /* * Skip pairs of adjacent ON/OFF or OFF/ON changes. */ spare -= 2; } else if (spare && !previous->styles[spare - 1].direction) { /* * Found an OFF change not part of a matched pair. * Assume it is safer to leave whatever comes before * it on the previous line alone. Setting spare to 0 * ensures that it won't be used in a following * iteration. - kw */ spare = 0; } else { /* * Nothing applied, so we are done with the loop. - kw */ break; } } if (previous->numstyles > 0 && previous->styles[LastStyle].direction) { if (TRACE) fprintf(stderr, "%s\n%s%s\n", "........... Too many character styles on line:", "........... ", previous->data); } if (line->numstyles > 0 && line->numstyles < MAX_STYLES_ON_LINE) { int n; inew ++; for (n = line->numstyles; n >= 0; n--) line->styles[n + inew] = line->styles[n]; } else if (line->numstyles == 0) /* FIXME: RJP - shouldn't use 0xffffffff for largest integer */ line->styles[0].horizpos = 0xffffffff; if (previous->numstyles == 0) previous->styles[0].horizpos = 0xffffffff;#endif previous->next = line; text->last_line = line; line->size = 0; line->offset = 0; text->permissible_split = 0; /* 12/13/93 */ line->data[0] = '\0'; /* * If we are not splitting and need an underline char, add it now. - FM */ if ((split < 1) && !(dump_output_immediately && use_underscore) && underline_on) { line->data[line->size++] = LY_UNDERLINE_START_CHAR; line->data[line->size] = '\0'; ctrl_chars_on_this_line++; } /* * If we are not splitting and need a bold char, add it now. - FM */ if ((split < 1) && bold_on) { line->data[line->size++] = LY_BOLD_START_CHAR; line->data[line->size] = '\0'; ctrl_chars_on_this_line++; } /* * Split at required point */ if (split > 0) { /* Delete space at "split" splitting line */ char *p, *prevdata = previous->data, *linedata = line->data; unsigned int plen; int i; /* * Split the line. - FM */ prevdata[previous->size] = '\0'; previous->size = split; /* * Trim any spaces or soft hyphens from the beginning * of our new line. - FM */ p = prevdata + split; while (*p == ' ' || *p == LY_SOFT_HYPHEN) { p++; HeadTrim++; } plen = strlen(p); /* * Add underline char if needed. - FM */ if (!(dump_output_immediately && use_underscore)) { /* * Make sure our global flag is correct. - FM */ underline_on = NO; for (i = (split-1); i >= 0; i--) { if (prevdata[i] == LY_UNDERLINE_END_CHAR) { break; } if (prevdata[i] == LY_UNDERLINE_START_CHAR) { underline_on = YES; break; } } /* * Act on the global flag if set above. - FM */ if (underline_on && *p != LY_UNDERLINE_END_CHAR) { linedata[line->size++] = LY_UNDERLINE_START_CHAR; linedata[line->size] = '\0'; ctrl_chars_on_this_line++; SpecialAttrChars++; } for (i = (plen - 1); i >= 0; i--) { if (p[i] == LY_UNDERLINE_START_CHAR) { underline_on = YES; break; } if (p[i] == LY_UNDERLINE_END_CHAR) { underline_on = NO; break; } } for (i = (plen - 1); i >= 0; i--) { if (p[i] == LY_UNDERLINE_START_CHAR || p[i] == LY_UNDERLINE_END_CHAR) { ctrl_chars_on_this_line++; } } } /* * Add bold char if needed, first making * sure that our global flag is correct. - FM */ bold_on = NO; for (i = (split - 1); i >= 0; i--) { if (prevdata[i] == LY_BOLD_END_CHAR) { break; } if (prevdata[i] == LY_BOLD_START_CHAR) { bold_on = YES; break; } } /* * Act on the global flag if set above. - FM */ if (bold_on && *p != LY_BOLD_END_CHAR) { linedata[line->size++] = LY_BOLD_START_CHAR; linedata[line->size] = '\0'; ctrl_chars_on_this_line++; SpecialAttrChars++;; } for (i = (plen - 1); i >= 0; i--) { if (p[i] == LY_BOLD_START_CHAR) { bold_on = YES; break; } if (p[i] == LY_BOLD_END_CHAR) { bold_on = NO; break; } } for (i = (plen - 1); i >= 0; i--) { if (p[i] == LY_BOLD_START_CHAR || p[i] == LY_BOLD_END_CHAR || IS_UTF_EXTRA(p[i]) || p[i] == LY_SOFT_HYPHEN) { ctrl_chars_on_this_line++; } if (p[i] == LY_SOFT_HYPHEN && text->permissible_split < i) { text->permissible_split = i + 1; } } /* * Add the data to the new line. - FM */ strcat(linedata, p); line->size += plen; } /* * Economize on space. */ while ((previous->size > 0) && (previous->data[previous->size-1] == ' ')) { /* * Strip trailers. */ previous->data[previous->size-1] = '\0'; previous->size--; TailTrim++; } temp = (HTLine *)LY_CALLOC(1, LINE_SIZE(previous->size)); if (temp == NULL) outofmem(__FILE__, "split_line_2"); memcpy(temp, previous, LINE_SIZE(previous->size)); FREE(previous); previous = temp; previous->prev->next = previous; /* Link in new line */ previous->next->prev = previous; /* Could be same node of course */ /* * Terminate finished line for printing. */ previous->data[previous->size] = '\0'; /* * Align left, right or center. */ for (cp = previous->data; *cp; cp++) { if (*cp == LY_UNDERLINE_START_CHAR || *cp == LY_UNDERLINE_END_CHAR || *cp == LY_BOLD_START_CHAR || *cp == LY_BOLD_END_CHAR || IS_UTF_EXTRA(*cp) || *cp == LY_SOFT_HYPHEN) ctrl_chars_on_previous_line++; } /* @@ first line indent */ spare = (LYcols-1) - (int)style->rightIndent - indent + ctrl_chars_on_previous_line - previous->size - ((previous->size > 0) && (int)(previous->data[previous->size-1] == LY_SOFT_HYPHEN ? 1 : 0)); switch (style->alignment) { case HT_CENTER : previous->offset = previous->offset + indent + spare/2; break; case HT_RIGHT : previous->offset = previous->offset + indent + spare; break; case HT_LEFT : case HT_JUSTIFY : /* Not implemented */ default: previous->offset = previous->offset + indent; break; } /* switch */ text->chars = text->chars + previous->size + 1; /* 1 for the line */ text->in_line_1 = NO; /* unless caller sets it otherwise */ /* * If we split the line, adjust the anchor * structure values for the new line. - FM */ if (split > 0) { for (a = text->first_anchor; a; a = a->next) { if (a->line_num == CurLine) { if (a->line_pos >= split) { a->start += (1 + SpecialAttrChars - HeadTrim - TailTrim); a->line_pos -= (split - SpecialAttrChars + HeadTrim); a->line_num = text->Lines; } else if ((a->link_type & HYPERTEXT_ANCHOR) && (a->line_pos + a->extent) >= split) { a->extent -= (TailTrim + HeadTrim); if (a->extent < 0) { a->extent = 0; } } } } }} /* split_line *//* Allow vertical blank space** --------------------------*/PRIVATE void blank_lines ARGS2( HText *, text, int, newlines){ BOOL IgnoreSpaces = FALSE; if (!HText_LastLineSize(text, IgnoreSpaces)) { /* No text on current line */ HTLine * line = text->last_line->prev; while ((line != text->last_line) && (HText_TrueLineSize(line, text, IgnoreSpaces) == 0)) { if (newlines == 0) break; newlines--; /* Don't bother: already blank */ line = line->prev; } } else { newlines++; /* Need also to finish this line */ } for (; newlines; newlines--) { new_line(text); } text->in_line_1 = YES;}/* New paragraph in current style** ------------------------------** See also: setStyle.*/PUBLIC void HText_appendParagraph ARGS1( HText *, text){ int after = text->style->spaceAfter; int before = text->style->spaceBefore; blank_lines(text, ((after > before) ? after : before));}/* Set Style** ---------**** Does not filter unnecessary style changes.*/PUBLIC void HText_setStyle ARGS2( HText *, text, HTStyle *, style){ int after, before; if (!style) return; /* Safety */ after = text->style->spaceAfter; before = style->spaceBefore; if (TRACE) fprintf(stderr, "GridText: Change to style %s\n", style->name); blank_lines (text, ((after > before) ? after : before)); text->style = style;}/* Append a character to the text object** -------------------------------------*/PUBLIC void HText_appendCharacter ARGS2( HText *, text,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -