parsehtml.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:164k
- /* parsehtml.c - display code for html
- ParseHTML() parses the HTML elements and generates a stream of commands for
- displaying the document in the Paint buffer. The paint commands specify the
- appearence of the document as a sequence of text, lines, and images. Each
- command includes the position as a pixel offset from the start of the
- document. This makes it easy to scroll efficiently in either direction.
- The paint buffer must be freed and recreated if the window is resized.
- The model needs to switch to relative offsets to enable the transition
- to an wysiwyg editor for html+. Relative values for pixel offsets and
- pointers to the html+ source would make it much easier to edit documents
- as it would limit revisions to the paint stream to the region changed.
- */
- /*
- Janne Saarela
- janne.saarela@hut.fi
- 28.7.1995
- PrintSeqText() and PutText() now use PushValue() to place
- the emph attribute to the PaintStream. The function prototypes
- now have emph added as unsigned int.
- */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include "www.h"
- #include "tools.h"
- #include "style.h"
- #define LBUFSIZE 1024
- extern Display *display;
- extern int screen;
- extern Window win;
- extern GC disp_gc, gc_fill;
- extern Cursor hourglass;
- extern int UsePaper;
- extern int debug; /* controls display of errors */
- extern int document; /* HTMLDOCUMENT or TEXTDOCUMENT */
- extern int busy;
- extern int OpenURL;
- extern int IsIndex;
- extern int FindStr;
- extern char *FindNextStr;
- extern int SaveFile;
- extern int sbar_width;
- extern int statusHeight;
- extern int ToolBarHeight;
- extern unsigned long windowColor;
- extern unsigned int win_width, win_height, tileWidth, tileHeight;
- extern BOOL NoStyle;
- extern Context *context;
- extern unsigned long textColor, labelColor, windowTopShadow,
- strikeColor, windowBottomShadow, windowShadow, windowColor;
- /*
- The current top line is displayed at the top of the window,the pixel
- offset is the number of pixels from the start of the document.
- */
- extern char *buffer; /* the start of the document buffer */
- extern long PixelOffset; /* the pixel offset to top of window */
- extern int hdrlen; /* MIME header length at start of buffer */
- extern long buf_height;
- extern long lineHeight;
- extern long chDescent;
- extern int buf_width;
- extern int PixelIndent;
- extern int chStrike;
- extern int spWidth; /* width of space char */
- extern int chWidth; /* width of average char */
- /*extern Doc NewDoc, CurrentDoc;*/
- extern XFontStruct *pFontInfo;
- extern XFontStruct *Fonts[FONTS];
- extern int LineSpacing[FONTS], BaseLine[FONTS], StrikeLine[FONTS];
- extern int ListIndent1, ListIndent2;
- extern Frame background;
- extern Image *images, *note_image, *caution_image, *warning_image;
- extern Form *forms;
- extern Doc *CurrentDoc;
- char *bufptr; /* parse position in the HTML buffer */
- char *lastbufptr; /* keep track of last position to store delta's */
- Byte *TopObject; /* first visible object in window */
- Byte *paint; /* holds the sequence of paint commands */
- int paintbufsize; /* size of buffer, not its contents */
- int paintlen; /* where to add next entry */
- int paintStartLine; /* where line starts in the paint stream */
- int above; /* above baseline */
- int below; /* below baseline */
- int voffset; /* if positive then above baseline */
- int IdAttributeFlag; /* signals attribute is ID value */
- int error; /* set by parser */
- int prepass; /* true during table prepass */
- int html_width; /* tracks maximum width */
- int min_width, max_width; /* table cell width */
- int list_indent;
- int damn_table=0; /* to debug table formatter */
- extern int preformatted;
- extern int font; /* index into Fonts[] array */
- static int EndTag, TagLen;
- static int TokenClass, TokenValue, Token;
- /* janet: not used: static char *EntityValue; */
- unsigned int ui_n;
- unsigned long ul_n;
- int baseline; /* from top of line */
- long TermTop, TermBottom;
- long PixOffset; /* current offset from start of document */
- long PrevOffset; /* keep track for saving delta's */
- long LastLIoffset; /* kludge for <LI><LI> line spacing */
- long ViewOffset; /* for toggling between HTML/TEXT views */
- extern long IdOffset; /* offset for targetId */
- extern char *targetptr; /* for toggling view between HTML/TEXT views */
- extern char *targetId; /* for locating named Id during ParseHTML() */
- int Here, TextLineWidth;
- int HTMLInit = 0;
- Image *start_figure, *figure;
- long figEnd;
- Form *form;
- int LeftFlowMargin, RightFlowMargin;
- int LeftMarginIndent = 0, RightMarginIndent = 0;
- long FigureEnd = 0;
- int class_len = 0;
- char *class = NULL;
- /* BOOL initial_cap = FALSE;*/
- char *LastBufPtr, *StartOfLine, *StartOfWord; /* in HTML document */
- static int LineLen, LineWidth, WordStart, WordWidth;
- static char LineBuf[LBUFSIZE]; /* line buffer */
- static char *Ones[] = {"i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"};
- static char *Tens[] = {"x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"};
- static char *Hundreds[] = {"c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"};
- char small_caps[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
- 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255 };
- /* push 16 bit value onto paint buffer */
- #define PushValue(p, value) ui_n = (unsigned int)value; *p++ = ui_n & 0xFF; *p++ = (ui_n >> 8) & 0xFF
- #define Push32(p, value) ul_n = (unsigned long)value; *p++ = ul_n & 0xFF; *p++ = (ul_n >> 8) & 0xFF; *p++ = (ul_n >> 16) & 0xFF; *p++ = (ul_n >> 24) & 0xFF
- /* expand paint stream to fit len bytes */
- Byte *MakeRoom(int len)
- {
- Byte *p;
- if (paintlen > paintbufsize - len)
- {
- paintbufsize = paintbufsize << 1;
- paint = (Byte *)realloc(paint, paintbufsize);
- }
- p = paint + paintlen;
- paintlen += len;
- return p;
- }
- void PrintBeginFrame(Frame *frame)
- {
- Byte *p;
- /* janet: not used: unsigned int len; */
- long offset;
- if (!prepass)
- {
- p = MakeRoom(FRAMESTLEN);
- frame->info = (p - paint);
- offset = frame->offset;
- *p++ = BEGIN_FRAME;
- PushValue(p, offset & 0xFFFF);
- PushValue(p, (offset >> 16) & 0xFFFF);
- PushValue(p, frame->indent);
- PushValue(p, frame->width);
- PushValue(p, 0); /* subsequently filled in with height(1) */
- PushValue(p, 0); /* subsequently filled in with height(2) */
- *p++ = frame->style; /* frame's background style */
- *p++ = frame->border; /* frame's border style */
- #ifdef STYLE_COLOR_BORDER
- *p++ = frame->cb_ix; /* frame's foreground color index */
- #endif
- #ifdef STYLE_BACKGROUND
- PutPointer(&p,(void *)StyleGet(S_BACKGROUND));
- #endif
- PushValue(p, 0); /* subsequently filled in with length */
- }
- }
- /* the size field after end of frame contents */
- void PrintFrameLength(Frame *frame)
- {
- Byte *p;
- unsigned int len;
- if (!prepass)
- {
- /* write the length field in frame's header */
- p = paint + frame->info + FRAMESTLEN - 2 ; /* --Spif 19-Oct-95 grmph !!! position of lenght in the paint stream */
- PushValue(p, frame->length);
- /* write the size field after frame's contents */
- p = MakeRoom(2);
- len = p - paint - frame->info; /* --Spif 19-Oct-95 must see this */
- PushValue(p, len);
- }
- }
- /* marker for pixel offset to end of frame */
- void PrintEndFrame(Frame *parent, Frame *frame)
- {
- Byte *p;
- unsigned int len;
- if (!prepass)
- {
- p = MakeRoom(FRAMENDLEN);
- len = p - (paint + frame->info);
- *p++ = END_FRAME;
- PushValue(p, len);
- PushValue(p, FRAMENDLEN-2);
- /* increase width of parent frame if necessary */
- if (parent)
- {
- len = frame->indent + frame->width + 2;
- if (parent->width < len)
- parent->width = len;
- /* and restore parent frame margins if this frame
- was involved in a text flow indent and is not
- obstructed by a subsequent text flow frame */
- /* howcome 7/10/94: prolonged the "if parent" block */
- if (frame->flow == ALIGN_LEFT)
- {
- if (frame->pushcount == parent->leftcount)
- {
- parent->leftcount -= 1;
- parent->leftmargin = frame->oldmargin;
- }
- }
- else if (frame->flow == ALIGN_RIGHT)
- {
- if (frame->pushcount == parent->rightcount)
- {
- parent->rightcount -= 1;
- parent->rightmargin = frame->oldmargin;
- }
- }
- else if (frame->flow == ALIGN_NOTE)
- {
- if (frame->pushcount == parent->leftcount)
- parent->leftcount -= 1;
- }
- }
- }
- }
- /* Write end markers for all peer frames and children.
- Note that the lists are flushed in the same order
- that items were pushed onto the list */
- void FlushAllFrames(Frame *parent, Frame *frame)
- {
- if (frame)
- {
- FlushAllFrames(parent, frame->next);
- FlushAllFrames(frame, frame->child);
- PrintEndFrame(parent, frame);
- FreeFrames(frame);
- }
- }
- /*
- Write end markers for any frames in peer list which have a
- finishing offset <= PixOffset. For any such frames, all
- descendant frames are flushed first. The process frees
- frames and removes them from the list of peers.
- If frame is the current frame then this procedure
- should be invoked as:
- frame->child = FlushFrames(frame, frame->child);
- This procedure assumes that BeginFrame() pushes
- new frames onto the front of the list of children,
- and guarantees that frames with the same offset are
- flushed to the paint stream in the order they were
- created. This property is needed for display purposes.
- */
- Frame *FlushFrames(Frame *parent, Frame *frame)
- {
- Frame *next;
- if (frame)
- {
- next = FlushFrames(parent, frame->next);
- if (frame->offset <= PixOffset)
- {
- /* first flush frame's children */
- FlushAllFrames(frame, frame->child);
- /* and now the frame itself */
- PrintEndFrame(parent, frame);
- free(frame);
- return next;
- }
- frame->next = next;
- }
- return frame;
- }
- void FlushPending(Frame *frame)
- {
- if (frame && frame->child)
- frame->child = FlushFrames(frame, frame->child);
- }
- /*
- The frame is created here, the new frame is returned so that the
- parser can later call EndFrame() at the end of the frame. Any frames
- which end before PixOffset are first flushed.
- */
- Frame *BeginFrame(Frame *parent, int style, int border, int left, int right, BG_Style *bg)
- {
- Frame *frame;
- FlushPending(parent);
- /* create frame and write begin frame marker */
- frame = (Frame *)calloc(1, sizeof(Frame));
- memset(frame, 0, sizeof(Frame));
- frame->offset = PixOffset;
- frame->indent = (parent ? parent->leftmargin + left : left);
- frame->width = right - left;
- frame->style = style;
- frame->border = border;
- #ifdef STYLE_COLOR_BORDER
- frame->cb_ix = (int)bg;
- #else
- frame->cb_ix = 0;
- #endif
- frame->flow = ALIGN_CENTER; /* implies this is a figure frame */
- frame->next = frame->child = NULL;
- frame->box_list = NULL;
- PrintBeginFrame(frame);
- return frame;
- }
- /* This writes the frame's height in the frame's header.
- Here we need to push the frame onto the front of the
- list of the parent frame's children so that FlushFrames()
- can write the end frame marker to the paint queue */
- void EndFrame(Frame *parent, Frame *frame)
- {
- Byte *p;
- /* janet: not used: Frame *next, *prev; */
- /* update background.height if needed */
- if (PixOffset > background.height)
- background.height = PixOffset;
- /* write height into paint struct for frame */
- frame->height = PixOffset - frame->offset;
- p = paint + frame->info + 9; /* --Spif 19-Oct-95 offset in frame to height(1) and (2) */
- PushValue(p, frame->height & 0xFFFF);
- PushValue(p, (frame->height >> 16) & 0xFFFF);
- /* change frame->offset to end of frame */
- frame->offset = PixOffset;
- /* and now push onto list of children */
- frame->next = parent->child;
- parent->child = frame;
- }
- int ListCells(Frame *cells)
- {
- int n;
- for (n = 0; cells != NULL; ++n)
- {
- #if defined PRINTF_HAS_PFORMAT
- printf("address = %p, indent = %d, width = %d, height = %ldn",
- cells, cells->indent, cells->width, cells->height);
- #else
- printf("address = %lx, indent = %d, width = %d, height = %ldn",
- cells, cells->indent, cells->width, cells->height);
- #endif /* POINTER_IS_64BIT */
- cells = cells ->next;
- }
- return n;
- }
- /*
- Insert cell at end of list of cells
- */
- void /* wm 19.Jan.95 */
- InsertCell(Frame **cells, Frame *cell)
- {
- Frame *frame, *next;
- frame = *cells;
- cell->next = NULL;
- if (frame == NULL)
- *cells = cell;
- else
- {
- for (frame = *cells;;)
- {
- next = frame->next;
- if (next == NULL)
- {
- frame->next = cell;
- break;
- }
- frame = next;
- }
- }
- }
- /*
- This routine adjusts height of all table cells which end
- on this row and then calls EndFrame() to move them to
- the list of frames awaiting PrintEndFrame()
- */
- void FlushCells(Frame *parent, int row, Frame **cells)
- {
- Frame *prev, *frame, *next;
- prev = NULL;
- frame = *cells;
- while (frame)
- {
- if (frame->lastrow <= row)
- {
- next = frame->next;
- if (prev)
- prev->next = next;
- else
- *cells = next;
- frame->height = PixOffset - frame->offset;
- frame->next = NULL;
- EndFrame(parent, frame);
- frame = next;
- continue;
- }
- prev = frame;
- frame = frame->next;
- }
- }
- /* insert TEXTLINE container */
- void TextLineFrame(Frame *frame)
- {
- Byte *p;
- if (prepass)
- {
- paintStartLine = 0;
- TextLineWidth = 0;
- }
- else
- {
- FlushPending(frame);
- TextLineWidth = 0;
- p = MakeRoom(TXTLINLEN);
- paintStartLine = p - paint;
- *p++ = TEXTLINE;
-
- PushValue(p, PixOffset & 0xFFFF);
- PushValue(p, (PixOffset >> 16) & 0xFFFF);
- /* baseline & indent set at end of line by EndOfLine() */
- *p++ = 0; *p++ = 0;
- *p++ = 0; *p++ = 0;
- *p++ = 0; *p++ = 0;
- }
- }
- /*
- This procedure writes the end of text line element
- and the baseline, line height and indent as appropriate
- for the frame's current margin settings. This handles
- horizontal alignment in the face of changing margins.
- */
- void EndOfLine(Frame *frame, int align)
- {
- unsigned int n, height, w;
- int indent, delta = 0, len;
- Byte *p;
- if (!prepass)
- StyleSetFlag(S_LEADING_FLAG,FALSE);
- if (paintStartLine >= 0)
- {
- /* fill in baseline for current line */
- if (!prepass)
- {
- if (frame == &background)
- {
- /* w = background.width - background.rightmargin;*/
- w = background.width - background.rightmargin - (int)StyleGet(S_MARGIN_RIGHT); /* howcome 26/2/95 */
- if (w > WinWidth - 4)
- w = WinWidth - 4;
- /* w -= background.leftmargin;*/
- w -= background.leftmargin;
- if (align == ALIGN_LEFT)
- delta = 0;
- else if (align == ALIGN_CENTER)
- delta = (w - TextLineWidth) / 2;
- else if (align == ALIGN_RIGHT)
- delta = w - TextLineWidth;
- else if (align == ALIGN_JUSTIFY)
- delta = 0;
- }
- else
- {
- if (align == ALIGN_LEFT)
- delta = 0;
- else if (align == ALIGN_CENTER)
- delta = (frame->width /* - frame->leftmargin
- - frame->rightmargin*/ - TextLineWidth) / 2;
- else if (align == ALIGN_RIGHT)
- delta = frame->width/* - frame->leftmargin
- - frame->rightmargin*/ - TextLineWidth;
- else if (align == ALIGN_JUSTIFY)
- delta = 0;
- }
- indent = (delta > 0 ? frame->leftmargin + delta : frame->leftmargin);
- height = above + below;
- paint[paintStartLine + 5] = (above & 0xFF);
- paint[paintStartLine + 6] = (above >> 8) & 0xFF;
- paint[paintStartLine + 7] = (indent & 0xFF);
- paint[paintStartLine + 8] = (indent >> 8) & 0xFF;
- paint[paintStartLine + 9] = (height & 0xFF);
- paint[paintStartLine + 10] = (height >> 8) & 0xFF;
- p = MakeRoom(3);
- *p++ = ' '; /* push end of elements marker */
- /* and write text line frame length */
- n = p - paint - paintStartLine;
- PushValue(p, n);
- }
-
- if(frame->flow == ALIGN_JUSTIFY)
- len = LineWidth + frame->leftmargin;
- else
- len = TextLineWidth + frame->leftmargin;
-
- if (len > frame->width)
- frame->width = len;
- PixOffset += above + below;
- paintStartLine = -1;
- above = 0;
- below = 0;
- TextLineWidth = 0;
- #if 0
- EndFigure();
- #endif
- }
- #if 0
- if (start_figure)
- PrintFigure(BEGIN_FIG);
- #endif
- }
- /* push horizontal rule onto paint stream */
- void PrintRule(Frame *frame, int type, int left, int right, int dy)
- {
- Byte *p;
- /* not used: int x; */
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (type == HLINE)
- {
- if (!prepass)
- {
- p = MakeRoom(RULEFLEN);
- *p++ = (RULE | type);
- PushValue(p, left);
- PushValue(p, right);
- PushValue(p, dy);
- #ifdef STYLE_COLOR
- *p++ = (Byte) StyleGet(S_COLOR);
- #endif
- #ifdef STYLE_BACKGROUND
- PutPointer(&p,(void *)StyleGet(S_BACKGROUND)); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- above = max(above, 2);
- below = max(below, 2);
- }
- }
- else
- {
- if (frame == &background)
- {
- if (background.width - right > WinWidth - right)
- right += background.width - WinWidth;
- }
- right += frame->rightmargin;
- if (frame->width - right > TextLineWidth)
- TextLineWidth = frame->width - right;
- /*
- above = max(above, 3);
- below = max(below, 5);
- */
- above = max(above, (int)StyleGet(S_MARGIN_TOP));
- below = max(below, (int)StyleGet(S_MARGIN_BOTTOM));
- if (!prepass)
- {
- p = MakeRoom(RULEFLEN);
- *p++ = (RULE | type);
- PushValue(p, left);
- PushValue(p, (frame->width - right));
- PushValue(p, dy);
- #ifdef STYLE_COLOR
- *p++ = (Byte) StyleGet(S_COLOR);
- #endif
- #ifdef STYLE_BACKGROUND
- PutPointer(&p, (void *)StyleGet(S_BACKGROUND)); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- }
- }
- }
- void PrintLine(Frame *frame, int left, int right, int top, int bottom) /* staalesc 13/12/95 */
- {
- Byte *p;
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (!prepass)
- {
- p = MakeRoom(LINEFLEN);
- *p++ = (LINE);
- PushValue(p, left);
- PushValue(p, right);
- PushValue(p, top);
- PushValue(p, bottom);
- #ifdef STYLE_COLOR
- *p++ = (Byte) StyleGet(S_COLOR);
- #endif
- #ifdef STYLE_BACKGROUND
- PutPointer(&p, (void *)StyleGet(S_BACKGROUND));
- #endif
- above = max(above, 2); /* staalesc: Are these correct??? */
- below = max(below, 2);
- }
- }
- /* push bullet onto paint stream */
- void PrintBullet(Frame *frame, int depth, int font, int size)
- {
- Byte *p;
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (Here + B_SIZE> TextLineWidth)
- TextLineWidth = Here + B_SIZE;
- above = max(above, ASCENT(font));
- below = max(below, DESCENT(font));
- if (!prepass)
- {
- p = MakeRoom(BULLETFLEN);
- *p++ = BULLET;
- PushValue(p, Here);
- PushValue(p, depth);
- *p++ = font; /*StyleGet(S_FONT);*/ /* howcome 25/4/95: adding vertical position of bullet item */
- *p++ = size; /*StyleGet(S_FONT_SIZE);*/ /* spif 8/1/96: size... */
- *p++ = (Byte) StyleGet(S_COLOR);
- #ifdef STYLE_BACKGROUND
- PutPointer(&p, (void *)StyleGet(S_BACKGROUND)); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- }
- }
- void WrapImageIfNeeded(Frame *frame, int align,
- int left, int right, int width, int up, int down)
- {
- if (!preformatted)
- {
- if (Here > left && Here + width + 2 > frame->width - frame->rightmargin - right)
- {
- EndOfLine(frame, align);
- Here = left;
- above = up;
- below = down;
- }
- else
- {
- if (up > above)
- above = up;
- if (down > below)
- below = down;
- }
- }
- else
- {
- if (up > above)
- above = up;
- if (down > below)
- below = down;
- }
- }
- void WrapFieldIfNeeded(Field *field, Frame *frame, int align, int left, int right)
- {
- if (!preformatted)
- {
- if (Here > left && field->x + field->width > frame->width - frame->rightmargin - right)
- {
- EndOfLine(frame, align);
- Here = left;
- field->x = Here;
- above = field->above;
- below = field->height - above;
- }
- else
- {
- if (above < field->above)
- above = field->above;
- if (below < field->height - field->above)
- below = field->height - above;
- }
- }
- else
- {
- if (above < field->above)
- above = field->above;
- if (below < field->height - field->above)
- below = field->height - field->above;
- }
- }
- /* push text input field */
- void PrintInputField(Frame *frame, Field *field)
- {
- Byte *p;
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (field->x + field->width > TextLineWidth)
- TextLineWidth = field->x + field->width;
- if (!prepass)
- {
- p = MakeRoom(INPUTFLEN);
- field->object = p - paint;
- *p++ = INPUT;
- PutPointer(&p,(void *)field);
- #ifdef STYLE_BACKGROUND
- PutPointer(&p, (void *)StyleGet(S_BACKGROUND)); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- }
- }
- /* push normal or preformatted string */
- /* emph contains font and emphasis */
- void RealPrintString(Frame *frame, unsigned int emph, int font,
- int delta, char *ref, char *buf, int len, int width, BOOL tight_font, Byte text_color, BG_Style *text_background)
- {
- Byte *p;
- /* int indent; */
- /* indent = Here + LeftMarginIndent;*/ /* figures on LHS */
- /* indent = Here + style->margin_left;*/ /* howcome 21/2/95 */
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (!prepass)
- p = MakeRoom(STRINGFLEN);
- if (Here + width > TextLineWidth)
- TextLineWidth = Here + width;
- /* In the case of a big initial, the descent should be calculated
- specifically for the character in question */
- if (tight_font) {
- above = max(above, Fonts[font]->per_char[*buf].ascent);
- /*
- if (above == 0)
- above = max(above, ASCENT(font));
- */
- below = max(below, Fonts[font]->per_char[*buf].descent);
- /*
- if (below == 0)
- below = max(below, DESCENT(font));
- */
- } else {
- if (!StyleGetFlag(S_LEADING_FLAG))
- above = max(above, ASCENT(font) + (int)StyleGet(S_FONT_LEADING));
- else
- above = max(above, ASCENT(font));
- below = max(below, DESCENT(font)); /* howcome 28/8/95: is this the right place to add leading? */
- } /* --Spif 13-Nov-95 this was not the right place ;) */
- if (!prepass)
- {
- *p++ = (preformatted ? (STRING | PRE_TEXT) : STRING);
- PushValue (p, emph);
- *p++ = font;
- if ( StyleGetFlag(S_INDENT_FLAG))
- {
- /* Here += StyleGet(S_INDENT); */
- Here += StyleGetFlag(S_INDENT_FLAG); /* flag carrying a value... hum... --Spif 14-Nov-95 */
- StyleSetFlag(S_INDENT_FLAG,FALSE);
- };
- if (StyleGetFlag(S_MARGIN_TOP_FLAG)) /* this is the right place for this, but it doesn't work... yet ;) --Spif 16-Jan-96 */
- {
- PixOffset += StyleGetFlag(S_MARGIN_TOP_FLAG);
- StyleSetFlag(S_MARGIN_TOP_FLAG, FALSE);
- };
- #ifdef STYLE_COLOR
- *p++ = text_color;
- #endif
- #ifdef STYLE_BACKGROUND
- PutPointer(&p,(void *)text_background); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- *p++ = delta + 128; /* baseline offset 128 is zero, 255 is +127, 0 is -128 */
- /*
- if (frame->leftcount) {
- PushValue(p, Here - style->margin_left);
- } else {
- */
- PushValue(p, Here);
- /* }*/
- PushValue(p, len);
- PushValue(p, width);
- PutPointer(&p, (void *)buf);
- PutPointer(&p, (void *)ref);
- }
- }
- void PrintString(Frame *frame, unsigned int emph, int font,
- int delta, char *buf, int len, int width, int wrapped)
- {
- int i, j, k, fix, index, icw = 0;
- int sc_width,dumpint; /* --Spif 5/10/95 small caps fix */
- int OldTextLineWidth, OldHere;
- BOOL emph_set = FALSE;
- BOOL ok;
- char dump_char[2];
- fix = (int)StyleGet(S_FONT);
- if ( ((int)StyleGet(S_TEXT_EFFECT) == TEXT_EFFECT_INITIAL_CAP) && (StyleGetFlag(S_INITIAL_FLAG)) ) {
- int alt_fix = (int)StyleGet(S_ALT_FONT);
-
- RealPrintString(frame, (emph_set ? 0 : emph), alt_fix, delta, buf, buf, 1, width,
- TRUE, (Byte) StyleGet(S_ALT_COLOR), (BG_Style *)StyleGet(S_ALT_BACKGROUND) );
- emph_set = TRUE;
- icw = XTextWidth(Fonts[alt_fix], buf, 1);
- Here += icw;
- StyleSetFlag(S_INITIAL_FLAG, False);
- buf++; len--;
- }
-
- StyleSetFlag(S_FONT_LEADING,FALSE);
- if ((int)StyleGet(S_FONT_STYLE) == FONT_STYLE_SMALL_CAPS) {
- int sc_fix = (int)StyleGet(S_SMALL_CAPS_FONT);
- for(i=k=0; k<len; i++, k++) {
- sc_width=CompoundTextWidth(buf + i, 0, 1,&dumpint) + (int)StyleGet(S_TEXT_SPACING); /* a hack... rename this stuff */
- OldTextLineWidth = TextLineWidth ; /* --Spif 6-Oct-95 keep this to update TextLineWidth with the right width */
- OldHere = Here;
- /* we must give the entire width if it is emphasized, to tell the paint stream to display a beeautiful box around
- the text, but the real TextLineWidth must be calculated with the width of only ONE character at a time */
- if (buf[i]=='&') {
- for(ok= FALSE,j=i; !ok && j<len; j++)
- ok = ((buf[j]==';') || (buf[j]==' ')); /* ' ' is here for dummy html writers ;) */
- index = *dump_char = (char)entity(buf+i+1, &j);
- if (index < 0)
- index+=256;
- dump_char[1]=0;
- RealPrintString(frame, (emph_set ? 0 : emph), sc_fix, delta, buf, &small_caps[index], 1, width, /* how can we capitalize entities? */
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- if(((index + small_caps[index]) % 256))
- Here += XTextWidth(Fonts[sc_fix], dump_char,1) + (int)StyleGet(S_TEXT_SPACING);
- else
- Here += XTextWidth(Fonts[fix], dump_char,1) + (int)StyleGet(S_TEXT_SPACING);
- i += j -1;
- } else if (islower(buf[i])) {
- RealPrintString(frame, (emph_set ? 0 : emph), sc_fix, delta, buf, &small_caps[buf[i]], 1, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- Here += XTextWidth(Fonts[sc_fix], &small_caps[buf[i]], 1) + (int)StyleGet(S_TEXT_SPACING);
- } else if (isdigit(buf[i])) {
- RealPrintString(frame, (emph_set ? 0 : emph), sc_fix, delta, buf, &small_caps[buf[i]], 1, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- Here += XTextWidth(Fonts[sc_fix], &small_caps[buf[i]], 1) + (int)StyleGet(S_TEXT_SPACING);
- } else {
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, &small_caps[buf[i]], 1, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- Here += XTextWidth(Fonts[fix], &small_caps[buf[i]], 1) + (int)StyleGet(S_TEXT_SPACING);
- }
- if( OldHere + sc_width > OldTextLineWidth) /* -- Spif: 6-Oct-95 small caps fix */
- TextLineWidth = OldHere + sc_width;
- };
- TextLineWidth -= (int)StyleGet(S_TEXT_SPACING);
- Here -= (int)StyleGet(S_TEXT_SPACING);
- } else if(StyleGet(S_TEXT_SPACING))
- {
- for(i=k=0; k<len; i++, k++) {
- sc_width=CompoundTextWidth(buf + i, 0, 1,&dumpint) + (int)StyleGet(S_TEXT_SPACING); /* a hack... rename this stuff */
- OldTextLineWidth = TextLineWidth ;
- OldHere = Here;
- /* we must give the entire width if it is emphasized, to tell the paint stream to display a beautiful box around
- the text, but the real TextLineWidth must be calculated with the width of only ONE character at a time */
-
- if (buf[i]=='&') {
- for(ok= FALSE,j=i; !ok && j<len; j++)
- ok = ((buf[j]==';') || (buf[j]==' ')); /* ' ' is here for dummy html writers ;) */
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, buf + i, 1, width, /* how can we capitalize entities? */
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- *dump_char = entity(buf+i+1, &j);
- dump_char[1]=0;
- Here += XTextWidth(Fonts[fix], dump_char,1) + (int)StyleGet(S_TEXT_SPACING);
- i += j -1;
- }
- else {
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, buf + i, 1, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- Here += XTextWidth(Fonts[fix], buf + i, 1) + (int)StyleGet(S_TEXT_SPACING);
- }
- if( OldHere + sc_width > OldTextLineWidth)
- TextLineWidth = OldHere + sc_width;
- };
- TextLineWidth -= (int)StyleGet(S_TEXT_SPACING);
- Here -= + (int)StyleGet(S_TEXT_SPACING);
- } else {
- if(frame->flow != ALIGN_JUSTIFY)
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, buf, len, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- else
- {
- int nb_space = 0;
- int remaining_space;
-
-
- for(k=0; k<len; k++)
- nb_space += (buf[k]==' ')||(buf[k]=='n');
- if(!nb_space || !wrapped){
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, buf, len, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- }
- else
- {
- remaining_space = frame->width - width - Here - StyleGetFlag(S_INDENT_FLAG);
- #if 1
- /* printf("len %d :nbspace %d : remaining_space %dn", len, nb_space, remaining_space);
- * printf("width %d, frame->width %d, frame->indent %d, Here %dn", width, frame->width, frame->indent, Here);
- */
- for(i=k=0; k<len; i++, k++) {
- if(buf[i]=='n')
- sc_width=XTextWidth(Fonts[fix], " ", 1) + (remaining_space/(nb_space ? nb_space :1));
- else
- sc_width=CompoundTextWidth(buf + i, 0, 1,&dumpint) + (*(buf+i)==' ')*(remaining_space/(nb_space ? nb_space :1));
- OldTextLineWidth = TextLineWidth ;
- OldHere = Here;
- /* we must give the entire width if it is emphasized, to tell the paint stream to display a beeautiful box around
- the text, but the real TextLineWidth must be calculated with the width of only ONE character at a time */
-
- if (buf[i]=='&') {
- for(ok= FALSE,j=i; !ok && j<len; j++)
- ok = ((buf[j]==';') || (buf[j]==' ')); /* ' ' is here for dummy html writers ;) */
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, buf + i, 1, width, /* how can we capitalize entities? */
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- *dump_char = entity(buf+i+1, &j);
- dump_char[1]=0;
- Here += XTextWidth(Fonts[fix], dump_char,1);
- i += j -1;
- }
- else {
- if(buf[i]=='n')
- {
- emph_set = TRUE;
- Here += XTextWidth(Fonts[fix], " ", 1) + (remaining_space/(nb_space ? nb_space :1));
- remaining_space -= (remaining_space/(nb_space ? nb_space :1));
- nb_space--;
- }
- else
- {
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, buf + i, 1, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- emph_set = TRUE;
- Here += XTextWidth(Fonts[fix], buf + i, 1) + (*(buf+i)==' ')*(remaining_space/(nb_space ? nb_space :1));
- if(*(buf+i)==' ')
- {
- remaining_space -= (remaining_space/(nb_space ? nb_space :1));
- nb_space--;
- }
- }
- }
- if( OldHere + sc_width > OldTextLineWidth)
- TextLineWidth = OldHere + sc_width;
- }
- #else
- RealPrintString(frame, (emph_set ? 0 : emph), fix, delta, buf, buf, len, width,
- FALSE, (Byte) StyleGet(S_COLOR), (BG_Style *)StyleGet(S_BACKGROUND));
- #endif
- }
- }
- emph_set = TRUE;
- Here += (width - icw);
- }
- }
- int CompoundTextWidth(char *s, int start, int len, int *space_p)
- {
- int width = 0, i, k, j, ok;
- int fix = (int)StyleGet(S_FONT);
- char dump_char[2];
- if (((int)StyleGet(S_TEXT_EFFECT) == TEXT_EFFECT_INITIAL_CAP) && (StyleGetFlag(S_INITIAL_FLAG))) {
- int alt_fix = (int)StyleGet(S_ALT_FONT);
- width += XTextWidth(Fonts[alt_fix], s, 1);
- start++; len--;
- }
- if ((int)StyleGet(S_FONT_STYLE) == FONT_STYLE_SMALL_CAPS) {
- for(i=k=start; k < (len + start); i++,k++) {
- width += (int)StyleGet(S_TEXT_SPACING);
- if (islower(s[i]))
- width += XTextWidth(Fonts[(int)StyleGet(S_SMALL_CAPS_FONT)], &small_caps[s[i]], 1);
- else if (s[i]=='&') {
- for(ok= FALSE,j=i; !ok && j<(len+start); j++)
- ok = ((s[j]==';') || (s[j]==' '));
- *dump_char = entity(s+i+1, &j);
- dump_char[1]=0;
- i+=j-1;
- width += XTextWidth(Fonts[(int)StyleGet(S_SMALL_CAPS_FONT)], dump_char, 1);
- } else if (isdigit(s[i])) {
- width += XTextWidth(Fonts[(int)StyleGet(S_SMALL_CAPS_FONT)], s + i, 1);
- } else
- width += XTextWidth(Fonts[fix], s + i, 1);
- }
- *space_p = XTextWidth(Fonts[(int)StyleGet(S_SMALL_CAPS_FONT)], " ", 1) + (int)StyleGet(S_TEXT_SPACING);
- return width;
- } else if(StyleGet(S_TEXT_SPACING)) {
- for(i=k=start; k < (len + start); i++,k++) {
- width += (int)StyleGet(S_TEXT_SPACING);
- if (s[i]=='&') {
- for(ok= FALSE,j=i; !ok && j<(len+start); j++)
- ok = ((s[j]==';') || (s[j]==' '));
- *dump_char = entity(s+i+1, &j);
- dump_char[1]=0;
- i+=j-1;
- width += XTextWidth(Fonts[fix], dump_char, 1);
- } else
- width += XTextWidth(Fonts[fix], s + i, 1);
- }
- *space_p = XTextWidth(Fonts[fix], " ", 1) + (int)StyleGet(S_TEXT_SPACING); /* WORD_SPACING instead */
- return width;
- } else {
- *space_p = XTextWidth(Fonts[fix], " ", 1);
- return (width + XTextWidth(Fonts[fix], s + start, len));
- }
- }
- /* Push explicit text onto paint stream */
- void PrintSeqText(Frame *frame, unsigned int emph, int font, char *s, int width)
- {
- Byte *p;
- int len;
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (!prepass)
- {
- len = strlen(s);
- p = MakeRoom(SEQTEXTFLEN(len));
- if (Here + width > TextLineWidth)
- TextLineWidth = Here + width;
- above = max(above, ASCENT(font));
- below = max(below, DESCENT(font));
- *p++ = SEQTEXT;
- PushValue (p, emph);
- *p++ = font;
- #ifdef STYLE_COLOR
- *p++ = (Byte) StyleGet(S_COLOR);
- #endif
- #ifdef STYLE_BACKGROUND
- PutPointer(&p, (void *)StyleGet(S_BACKGROUND)); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- PushValue(p, Here);
- PushValue(p, 0);
- *p++ = len;
- memcpy(p, s, len);
- }
- }
- /* for use by html-math parser */
- int TextWidth(int font, char *str, int len, int *up, int *down)
- {
- *up = Fonts[font]->max_bounds.ascent;
- *down = Fonts[font]->max_bounds.descent;
- return XTextWidth(Fonts[font], str, len);
- }
- /* for use by html-math parser */
- void FontSize(int font, int *ascent, int *descent)
- {
- *ascent = Fonts[font]->max_bounds.ascent;
- *descent = Fonts[font]->max_bounds.descent;
- }
- box *CreateBox(int x, int y, int width, int height)
- {
- box *new_box;
-
- new_box = (box *)malloc(sizeof(box));
-
- if(!new_box)
- {
- fprintf(stderr, "Ran Out of memory in CreateBox, Exitingn");
- exit(1);
- }
- new_box->x = x;
- new_box->y = y;
- new_box->width = width;
- new_box->height = height;
-
- return new_box;
- }
- void AddBox(Frame *frame, int x, int y, int width, int height)
- {
- box_link *new_link;
- box *new_box;
- if(!frame)
- return;
- #if 0
- printf("Adding Box %d,%d -> %d,%dn", x, y, width, height);
- #endif
- new_link = (box_link *)malloc(sizeof(box_link));
- if(!new_link)
- {
- fprintf(stderr, "Ran Out of memory in AddBox, Exitingn");
- exit(1);
- }
- new_link->box = CreateBox(x, y, width, height);
- new_link->next = frame->box_list; /* we add the box in first position */
- frame->box_list = new_link;
- }
- box *IsInBox(Frame *frame, int x, int y)
- {
- box_link *curr_box;
- box_link *is_in;
- if(!frame)
- return 0;
- for(is_in=NULL, curr_box = frame->box_list;!is_in && curr_box; curr_box = curr_box->next)
- if((x >= curr_box->box->x) && (x <= curr_box->box->x + curr_box->box->width)
- && (y >= curr_box->box->y) && (y <= curr_box->box->y + curr_box->box->height))
- is_in = curr_box;
- return (is_in) ? is_in->box : NULL;
- }
- void CopyBoxList(Frame *dest_frame, Frame *frame)
- {
- box_link *curr_box;
- if(!(dest_frame && frame))
- return;
-
- for(curr_box = frame->box_list;curr_box; curr_box = curr_box->next)
- AddBox(dest_frame, curr_box->box->x, curr_box->box->y, curr_box->box->width, curr_box->box->height);
- }
- int RightMargin(Frame *frame, int right, int voffset)
- {
- int rightMargin;
- box *thebox;
- if (frame == &background)
- {
- rightMargin = background.width - background.rightmargin - right;
- if (rightMargin > WinWidth - 4)
- rightMargin = WinWidth - 4;
- rightMargin -= frame->leftmargin;
- }
- else
- rightMargin = frame->width - right /*- frame->leftmargin - frame->rightmargin*/;
- if(frame)
- {
- thebox = IsInBox(frame, rightMargin, voffset);
- while(thebox)
- {
- rightMargin = thebox->x - 1;
- thebox = IsInBox(frame, rightMargin, voffset);
- }
- }
- return rightMargin;
- }
- int LeftMargin(Frame *frame, int left, int voffset)
- {
- int current_left;
- box *thebox;
- current_left = left;
- if(frame)
- {
- thebox = IsInBox(frame, current_left, voffset);
- while(thebox)
- {
- current_left = thebox->x + thebox->width + 1;
- thebox = IsInBox(frame, current_left, voffset);
- }
- }
- return current_left;
- }
- int Width(Frame *frame, int voffset)
- {
- return frame->width;
- }
- void PutText(Frame *frame, unsigned int emph, int font, char *s, int len, int x, int y)
- {
- Byte *p;
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (!prepass)
- {
- p = MakeRoom(SEQTEXTFLEN(len));
- *p++ = SEQTEXT;
- PushValue (p, emph);
- *p++ = font;
- #ifdef STYLE_COLOR
- *p++ = (Byte) StyleGet(S_COLOR);
- #endif
- #ifdef STYLE_BACKGROUND
- PutPointer(&p, (void *)StyleGet(S_BACKGROUND)); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- PushValue(p, x);
- PushValue(p, y);
- *p++ = len;
- memcpy(p, s, len);
- }
- }
- /* buf points to start of element in html source iff ismap is present */
- void PrintImage(Frame *frame, int delta, unsigned int emph,
- char *buf, Image *image, unsigned int width, unsigned int height)
- {
- Byte *p;
- Pixmap pixmap = 0;
- if (image)
- pixmap = image->pixmap;
- if (paintStartLine < 0)
- TextLineFrame(frame);
- if (Here + width > TextLineWidth)
- TextLineWidth = Here + width;
- if (prepass) /* just update min/max widths */
- {
- if (width > min_width)
- min_width = width;
- }
- else
- {
- p = MakeRoom(IMAGEFLEN);
- *p++ = (IMAGE & 0xF) | (emph & (ISMAP | EMPH_ANCHOR | EMPH_INPUT ));
- PushValue(p, delta);
- PushValue(p, Here);
- PushValue(p, width);
- PushValue(p, height);
- PutPointer(&p,(void *)pixmap);
- PutPointer(&p, (void *)buf);
- #ifdef STYLE_BACKGROUND
- PutPointer(&p, (void *)StyleGet(S_BACKGROUND)); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
- #endif
- }
- }
- #define NOBREAK 0
- #define BREAK 1
- /* check if current word forces word wrap and flush line as needed */
- void WrapIfNeeded(Frame *frame, int align, unsigned int emph, int font, int left, int right)
- {
- int WordLen, space, rightMargin;
- long line;
- if (paintStartLine < 0)
- TextLineFrame(frame); /* alters the flow margins, if a figure just ended */
-
- #ifdef OLD
- if (frame == &background)
- {
- rightMargin = background.width - background.rightmargin - right;
- if (rightMargin > WinWidth - 4)
- rightMargin = WinWidth - 4;
- rightMargin -= frame->leftmargin;
- }
- else
- rightMargin = frame->width - right /*- frame->leftmargin - frame->rightmargin*/;
- #else
- rightMargin = RightMargin(frame, right, PixOffset);
- #endif
- if(StyleGetFlag(S_INDENT_FLAG))
- rightMargin -= StyleGetFlag(S_INDENT_FLAG);
- LineBuf[LineLen] = ' '; /* debug*/
- WordLen = LineLen - WordStart;
- /* WordWidth = XTextWidth(Fonts[font], LineBuf+WordStart, WordLen);*/
- WordWidth = CompoundTextWidth(LineBuf, WordStart, WordLen, &space);
- /* space = XTextWidth(Fonts[StyleGet(S_FONT)], " ", 1);*/ /* width of a space char */
- /* space = XTextWidth(Fonts[font], " ", 1); */ /* width of a space char */
- line = LineSpacing[font]; /* height of a line */
- if (WordWidth > min_width) /* for tables */
- min_width = WordWidth;
- if (prepass)
- {
- TextLineWidth += WordWidth;
- LineWidth = LineLen = WordStart = 0;
- StartOfLine = bufptr;
- }
- else if (WordStart == 0 && Here + WordWidth > rightMargin)
- {
- /* word wider than window */
- if (left + WordWidth > rightMargin)
- {
- if (emph & EMPH_ANCHOR)
- WordWidth += 2;
- PrintString(frame, emph, font, voffset, StartOfLine, WordLen, WordWidth, FALSE);
- EndOfLine(frame, align);
- LineWidth = LineLen = WordStart = 0;
- StartOfLine = bufptr;
- }
- else /* wrap to next line */
- {
- EndOfLine(frame, align);
- LineWidth = WordWidth;
- LineLen = WordLen;
- WordStart = LineLen;
- StartOfLine = StartOfWord;
- }
- Here = LeftMargin(frame, left, PixOffset);
- }
- else if (WordStart > 0 && Here + LineWidth + space + WordWidth > rightMargin)
- {
- if (emph & EMPH_ANCHOR)
- LineWidth += 2;
- PrintString(frame, emph, font, voffset, StartOfLine, WordStart-1, LineWidth, TRUE);
- EndOfLine(frame, align);
- Here = left;
- /* was memmove(LineBuf, LineBuf+WordStart, WordLen);
- but memmove not available for SUNs and
- memcpy screws up for overlapping copies */
- {
- int n;
- char *p, *q;
- n = WordLen;
- p = LineBuf;
- q = LineBuf+WordStart;
- while (n-- > 0)
- *p++ = *q++;
- }
- LineWidth = WordWidth;
- LineLen = WordLen;
- WordStart = LineLen;
- StartOfLine = StartOfWord;
- }
- else /* word will fit on end of current line */
- {
- if (WordStart > 0)
- LineWidth += space;
- if (WordWidth > 0)
- LineWidth += WordWidth;
- WordStart = LineLen;
- }
- }
- void FlushLine(int linebreak, Frame *frame, int align,
- unsigned int emph, int font, int left, int right)
- {
- int WordLen, space; /* janet: not used: delta, rightMargin */
- /* *StartOfLine = toupper(*StartOfLine);*//* howcome playing 5/5/95 */
- if (preformatted)
- {
- WordLen = LineLen - WordStart;
- /* LineWidth = XTextWidth(Fonts[font], LineBuf+WordStart, WordLen);*/
- LineWidth = CompoundTextWidth(LineBuf, WordStart, WordLen, &space);
- }
- else if (LineLen > 1 || (LineLen == 1 && LineBuf[0] != ' '))
- WrapIfNeeded(frame, align, emph, font, left, right);
- if (LineLen > 0)
- {
- if (emph & EMPH_ANCHOR)
- LineWidth += 2;
- /* watch out for single space as leading spaces
- are stripped by CopyLine */
- if (LineLen > 1 || LineBuf[0] != ' ')
- PrintString(frame, emph, font, voffset, StartOfLine, LineLen, LineWidth, FALSE);
- if (linebreak)
- {
- EndOfLine(frame, align);
- Here = left;
- }
- /*
- else
- Here += LineWidth;
- */
- LineWidth = LineLen = WordStart = 0;
- }
- else if (linebreak)
- {
- /* watch out for empty preformatted lines */
- if (preformatted && TextLineWidth == 0)
- PixOffset += ASCENT(font) + DESCENT(font);
- if (paintStartLine >= 0) /* was if (Here > left) */
- {
- EndOfLine(frame, align);
- Here = left;
- }
- }
- StartOfLine = StartOfWord = bufptr;
- }
- /* needs to cope with > in quoted text for ' and " */
- void SwallowAttributes(void)
- {
- int c;
- while ((c = *bufptr) && c != '>')
- {
- ++bufptr;
- }
- if (c == '>')
- ++bufptr;
- }
- /*
- Return a pointer to the ">" in an end comment (or to "