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 "" if there
- isn't one). Example:
- "hiya <!-- <foo>there</foo> -- --whatever-- > there"
- pass this -^ return this -^
- */
- char *FindEndComment( char *ptr )
- {
- char c, *s;
- for(;;)
- {
- ptr += 2; /* first character after opening "--" */
- if(!((s = strstr(ptr, "--")))) break;
- ptr = s + 1; /* second "-" -- ++ will put us on the next character */
- /* Skip past the optional white space (<= ' ' from GetToken) */
- while((c=*(++ptr)) && c <= ' ');
- if(c == '>')
- {
- return ptr; /* comment terminated correctly */
- }
- if(!strncmp(ptr, "--", 2))
- {
- /* comment is something like "<!--fine-- wrong>" */
- if(s=strchr(ptr,'>')) return s;
- break;
- }
- }
- /* Document ends in unfinished comment -- seek for '0' */
- if(*ptr) while(*(++ptr));
- return ptr;
- }
- /*
- char *tag points to start of tag string which is terminated
- by whitespace (including EOF) or a '>' character.
- return tag code or 0 if unknown.
- */
- int RecogniseTag(void)
- {
- int c, len;
- char *s;
- s = bufptr + 1;
-
- /* handle comments correctly -- code by mlvanbie@valeyard.uwaterloo.ca */
- if (*s == '!' && (*(s+1) == '-') && (*(s+2) == '-'))
- {
- bufptr += 4; /* eat "<!--" */
- EndTag = 0;
- TagLen = 0; /* we will be manipulating bufptr directly */
- TokenClass = EN_UNKNOWN;
- bufptr = FindEndComment( bufptr + 2 ); /* +2: eat "<!" */
- #if 0
- while ((s = strstr(bufptr, "--")))
- {
- bufptr = s + 1; /* stay on second "-" */
- /* Skip past the optional white space (<= ' ' from GetToken) */
- while((c=*(++bufptr)) && c <= ' ');
- if(c == '>')
- {
- return UNKNOWN; /* pretend we have an unknown tag */
- }
- bufptr = s + 1; /* handles "<!-- ... --->" (nonoptimal) */
- }
- /* Document ends in unfinished comment -- seek for '0' */
- if(*bufptr) while(*(++bufptr));
- #endif
- return UNKNOWN; /* unknown tag */
- }
- if (*s == '/')
- {
- EndTag = 1;
- ++s;
- }
- else
- EndTag = 0;
- if ((c = *s) == '!' || c == '?')
- ++s;
- else if (c != '>' && !isalpha(c))
- return PCDATA;
- /* find end of tag to allow use of strncasecmp */
- while ((c = *s, isalpha(c)) || isdigit(c))
- ++s;
- TagLen = s - bufptr; /* how far to next char after tag name */
- len = TagLen - EndTag - 1; /* number of chars in tag name itself */
- s -= len;
- c = TOLOWER(*s);
- if (isalpha(c))
- {
- if (c == 'a')
- {
- if (len == 1 && strncasecmp(s, "a", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_ANCHOR;
- }
- if (len == 3 && strncasecmp(s, "alt", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_ALT;
- }
- if (len == 5 && strncasecmp(s, "added", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_ADDED;
- }
- if (len == 7 && strncasecmp(s, "address", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_ADDRESS;
- }
- if (len == 8 && strncasecmp(s, "abstract", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_ABSTRACT;
- }
- }
- else if (c == 'b')
- {
- if (len == 1)
- {
- TokenClass = EN_TEXT;
- return TAG_BOLD;
- }
- if (len == 2 && strncasecmp(s, "br", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_BR;
- }
- if (len == 4 && strncasecmp(s, "body", len) == 0)
- {
- TokenClass = EN_MAIN;
- return TAG_BODY;
- }
- if (len == 10 && strncasecmp(s, "blockquote", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_QUOTE;
- }
- if (len == 4 && strncasecmp(s, "base", len) == 0)
- {
- TokenClass = EN_SETUP;
- return TAG_BASE;
- }
- }
- else if (c == 'c')
- {
- if (len == 4)
- {
- if (strncasecmp(s, "code", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_CODE;
- }
- if (strncasecmp(s, "cite", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_CITE;
- }
- }
- else if (len == 7 && (strncasecmp(s, "caption", len) == 0))/* howcome 3/2/95: = -> == after hint from P.M.Hounslow@reading.ac.uk */
- {
- TokenClass = EN_BLOCK;
- return TAG_CAPTION;
- }
- }
- else if (c == 'd')
- {
- if (len == 3 && strncasecmp(s, "dfn", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_DFN;
- }
- /* howcome 11/8/95: added upport for DIR */
- if (len == 3 && strncasecmp(s, "dir", len) == 0)
- {
- TokenClass = EN_LIST;
- return TAG_UL;
- }
- if (len != 2)
- return 0;
- if (strncasecmp(s, "dl", len) == 0)
- {
- TokenClass = EN_LIST;
- return TAG_DL;
- }
- if (strncasecmp(s, "dt", len) == 0)
- {
- TokenClass = EL_DEFLIST;
- return TAG_DT;
- }
- if (strncasecmp(s, "dd", len) == 0)
- {
- TokenClass = EL_DEFLIST;
- return TAG_DD;
- }
- }
- else if (c == 'e')
- {
- if (len == 2 && strncasecmp(s, "em", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_EM;
- }
- }
- else if (c == 'f')
- {
- if (len == 3 && strncasecmp(s, "fig", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_FIG;
- }
-
- /* --Spif 10/10/95 Form tag must be checked ! */
- if (len == 4 && strncasecmp(s, "form", len) == 0)
- {
- TokenClass = EN_TEXT /*EN_BLOCK*/;
- return TAG_FORM;
- };
- }
- else if (c == 'h')
- {
- if (len == 4 && strncasecmp(s, "head", len) == 0)
- {
- TokenClass = EN_SETUP;
- return TAG_HEAD;
- }
- if (len != 2)
- return 0;
- TokenClass = EN_HEADER;
- c = TOLOWER(s[1]);
- switch (c)
- {
- case '1':
- return TAG_H1;
- case '2':
- return TAG_H2;
- case '3':
- return TAG_H3;
- case '4':
- return TAG_H4;
- case '5':
- return TAG_H5;
- case '6':
- return TAG_H6;
- case 'r':
- TokenClass = EN_BLOCK;
- return TAG_HR;
- }
- }
- else if (c == 'i')
- {
- if (len == 1)
- {
- TokenClass = EN_TEXT;
- return TAG_ITALIC;
- }
- if (len == 3 && strncasecmp(s, "img", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_IMG;
- }
- if (len == 5 && strncasecmp(s, "input", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_INPUT;
- }
- if (len == 7 && strncasecmp(s, "isindex", len) == 0)
- {
- TokenClass = EN_SETUP;
- return TAG_ISINDEX;
- }
- }
- else if (c == 'k')
- {
- if (len == 3 && strncasecmp(s, "kbd", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_KBD;
- }
- }
- else if (c == 'l')
- {
- if (len == 2 && strncasecmp(s, "li", len) == 0)
- {
- TokenClass = EN_LIST;
- return TAG_LI;
- }
- if (len == 4 && strncasecmp(s, "link", len) == 0)
- {
- TokenClass = EN_SETUP;
- return TAG_LINK;
- }
- }
- else if (c == 'm')
- {
- if (len == 4 && strncasecmp(s, "math", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_MATH;
- }
- if (len == 6 && strncasecmp(s, "margin", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_MARGIN;
- }
- /* howcome 11/8/95: added MENU to be compatible with HTML2 */
- if (len == 4 && strncasecmp(s, "menu", len) == 0)
- {
- TokenClass = EN_LIST;
- return TAG_UL;
- }
- }
- else if (c == 'n')
- {
- if (len == 4 && strncasecmp(s, "note", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_NOTE;
- }
- }
- else if (c == 'o')
- {
- if (len == 2 && strncasecmp(s, "ol", len) == 0)
- {
- TokenClass = EN_LIST;
- return TAG_OL;
- }
- if (len == 6 && strncasecmp(s, "option", len) == 0)
- {
- TokenClass = EN_TEXT; /* kludge for error recovery */
- return TAG_OPTION;
- }
- }
- else if (c == 'p')
- {
- if (len == 1)
- {
- TokenClass = EN_BLOCK;
- return TAG_P;
- }
- if (len == 3 && strncasecmp(s, "pre", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_PRE;
- }
- }
- else if (c == 'q')
- {
- if (len == 1)
- {
- TokenClass = EN_TEXT;
- return TAG_Q;
- }
- if (len == 5 && strncasecmp(s, "quote", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_QUOTE;
- }
- }
- else if (c == 'r')
- {
- if (len == 7 && strncasecmp(s, "removed", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_REMOVED;
- }
- }
- else if (c == 's')
- {
- if (len == 1)
- {
- TokenClass = EN_TEXT;
- return TAG_STRIKE;
- }
- if (len == 3 && strncasecmp(s, "sup", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_SUP;
- }
- if (len == 3 && strncasecmp(s, "sub", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_SUB;
- }
- if (len == 4 && strncasecmp(s, "samp", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_SAMP;
- }
- if (len == 5 && strncasecmp(s, "small", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_SMALL;
- }
- if (len == 6 && strncasecmp(s, "strong", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_STRONG;
- }
- if (len == 6 && strncasecmp(s, "select", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_SELECT;
- }
- if (len == 6 && strncasecmp(s, "strike", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_STRIKE;
- }
- /* howcome 26/2/95 */
- if (len == 5 && strncasecmp(s, "style", len) == 0)
- {
- TokenClass = EN_SETUP;
- return TAG_STYLE;
- }
- }
- else if (c == 't')
- {
- if (len == 5 && strncasecmp(s, "title", len) == 0)
- {
- TokenClass = EN_SETUP;
- return TAG_TITLE;
- }
- if (len == 2 && strncasecmp(s, "tt", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_TT;
- }
- if (len == 2 && strncasecmp(s, "tr", len) == 0)
- {
- TokenClass = EN_TABLE;
- return TAG_TR;
- }
- if (len == 2 && strncasecmp(s, "th", len) == 0)
- {
- TokenClass = EN_TABLE;
- return TAG_TH;
- }
- if (len == 2 && strncasecmp(s, "td", len) == 0)
- {
- TokenClass = EN_TABLE;
- return TAG_TD;
- }
- if (len == 5 && strncasecmp(s, "table", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_TABLE;
- }
- if (len == 8 && strncasecmp(s, "textarea", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_TEXTAREA;
- }
- }
- else if (c == 'u')
- {
- if (len == 1)
- {
- TokenClass = EN_TEXT;
- return TAG_UNDERLINE;
- }
- if (len == 2 && strncasecmp(s, "ul", len) == 0)
- {
- TokenClass = EN_LIST;
- return TAG_UL;
- }
- }
- else if (c == 'v')
- {
- if (len == 3 && strncasecmp(s, "var", len) == 0)
- {
- TokenClass = EN_TEXT;
- return TAG_VAR;
- }
- }
- else if (c == 'x')
- {
- if (len == 3 && strncasecmp(s, "xmp", len) == 0)
- {
- TokenClass = EN_BLOCK;
- return TAG_PRE;
- }
- }
- }
- TokenClass = EN_UNKNOWN;
- return UNKNOWN; /* unknown tag */
- }
- void UnGetToken(void)
- {
- bufptr = LastBufPtr;
- }
- /*
- The token type is returned in the global token.
- Characters are returned in TokenValue while TokenClass
- is used to return a class value e.g. EN_SETUP or EN_BLOCK.
- Entity definitions are pointed to by EntityValue.
- The bufptr is moved past the token, except at the end
- of the buffer - as a safety precaution.
- */
- int GetToken(void)
- {
- int c, k, n;
- LastBufPtr = bufptr;
- c = *(unsigned char *)bufptr;
- TokenValue = c;
- if (bufptr <= targetptr)
- ViewOffset = PixOffset;
- if (c == '<' && (Token = RecogniseTag()) != PCDATA)
- {
- bufptr += TagLen; /* to first char after tag name */
- return Token;
- }
- TokenClass = EN_TEXT;
- EndTag = 0;
- if (c == '&' && (isalpha(bufptr[1]) || bufptr[1] == '#'))
- {
- n = entity(bufptr + 1, &k);
- if (n)
- {
- bufptr += k;
- TokenValue = n;
- Token = PCDATA;
- return Token;
- }
- }
- if (c <= ' ')
- {
- if (c == '')
- {
- Token = ENDDATA;
- TokenClass = EN_UNKNOWN;
- return Token;
- }
-
- ++bufptr;
- Token = WHITESPACE;
- return Token;
- }
- ++bufptr;
- Token = PCDATA;
- return Token;
- }
- /* void ParseAnchorAttrs(char **href, int *hreflen, char **name, int *namelen, char **class_p, int *class_len_p);*/
- /* get token, skipping white space and unknown tokens */
- int SkipSpace(void)
- {
- for (;;)
- {
- while (GetToken() == WHITESPACE);
- if (Token == UNKNOWN)
- {
- SwallowAttributes();
- continue;
- }
- break;
- }
- return Token;
- }
- /* assumes bufptr points to start of attribute */
- char *ParseAttribute(int *len)
- {
- int c;
- char *attr;
- *len = 0;
- attr = bufptr;
- IdAttributeFlag = 0;
- for (;;)
- {
- c = *bufptr;
- if (c == '>' || c == '')
- return attr;
- if (c == '=' || IsWhite(c))
- break;
- ++(*len);
- ++bufptr;
- }
- if (*len == 2 && strncasecmp(attr, "id", 2) ==0)
- IdAttributeFlag = 1;
- return attr;
- }
- /* values start with "=" or " = " etc. */
- char *ParseValue(int *len)
- {
- int c, delim;
- char *value;
- *len = 0;
- while (c = *bufptr, IsWhite(c))
- ++bufptr;
- if (c != '=')
- return 0;
- ++bufptr; /* past the = sign */
- while (c = *bufptr, IsWhite(c))
- ++bufptr;
- if (c == '"' || c == ''')
- {
- delim = c;
- ++bufptr;
- }
- else
- delim = 0;
- value = bufptr;
- for (;;)
- {
- c = *bufptr;
- if (c == '')
- if(delim)
- return 0; /* a big and dirty hack --Spif 27-Oct-95 */
- else
- break;
- if (delim)
- {
- if (c == delim)
- {
- ++bufptr;
- break;
- }
- }
- else if (c == '>' || IsWhite(c))
- break;
- ++(*len);
- ++bufptr;
- }
- if (IdAttributeFlag && value && targetId)
- {
- if (strlen(targetId) == *len &&
- strncasecmp(value, targetId, *len) == 0)
- {
- IdOffset = PixOffset;
- }
- }
- IdAttributeFlag = 0;
- return value;
- }
- /*
- HREF attribute defines original document URL and is added by
- the browser when making a local copy of a document so that
- relative references can be deferenced to their original links
- */
- void ParseBase(Frame *frame)
- {
- char *href, *name;
- int hreflen, namelen;
- ParseAnchorAttrs(&href, &hreflen, &name, &namelen, &class, &class_len);
- if(href)
- CurrentDoc->base = strndup(href, hreflen);
- }
- void ParseLink(Frame *frame)
- {
- char *href=NULL, *rel=NULL;
- int hreflen = 0, rellen = 0;
- int c, n, m;
- char *attr, *value;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- value = ParseValue(&m);
- if (n == 4 && strncasecmp(attr, "href", n) == 0)
- {
- href = value;
- hreflen = m;
- continue;
- }
- if (n == 3 && strncasecmp(attr, "rel", n) == 0)
- {
- rel = value;
- rellen = m;
- continue;
- }
- }
- if (href && rel) {
- if (!NoStyle && !CurrentDoc->link_style && (strncasecmp(rel, "style", 5) == 0))
- CurrentDoc->link_style = (char *)StyleLoad(href, hreflen, CurrentDoc->pending_reload);
- /* (char *) because StyleLoad not declared -> int implied , must add include files */
- }
- }
- void ParseTitle(int implied, Frame *frame)
- {
- if (EndTag)
- {
- SwallowAttributes();
- return;
- }
- if (!implied)
- SwallowAttributes();
- /* skip leading white space - subsequently contigous
- white space is compressed to a single space */
- while (GetToken() == WHITESPACE);
- UnGetToken();
- LineLen = 0;
- for (;;)
- {
- GetToken();
- if (Token == TAG_TITLE && EndTag)
- {
- SwallowAttributes();
- break;
- }
- if (Token == UNKNOWN)
- {
- SwallowAttributes();
- continue;
- }
- if (Token == WHITESPACE)
- {
- while (GetToken() == WHITESPACE);
- UnGetToken();
- if (LineLen < LBUFSIZE - 1)
- LineBuf[LineLen++] = ' ';
- continue;
- }
- if (Token != PCDATA)
- {
- UnGetToken();
- break;
- }
- if (LineLen < LBUFSIZE - 1)
- LineBuf[LineLen++] = TokenValue;
- }
- LineBuf[LineLen] = '';
- SetBanner(LineBuf);
- }
- /* howcome 26/2/95 */
- void ParseStyle(Frame *frame)
- {
- if (EndTag)
- {
- SwallowAttributes();
- return;
- }
- SwallowAttributes();
- /* skip leading white space - subsequently contigous
- white space is compressed to a single space */
- while (GetToken() == WHITESPACE);
- UnGetToken();
- LineLen = 0;
- for (;;)
- {
- GetToken();
- if (Token == TAG_STYLE && EndTag)
- {
- SwallowAttributes();
- break;
- }
- if (Token == UNKNOWN)
- {
- SwallowAttributes();
- continue;
- }
- if (LineLen < LBUFSIZE - 1)
- LineBuf[LineLen++] = TokenValue;
- }
- LineBuf[LineLen] = '';
- if (!NoStyle && !CurrentDoc->head_style)
- CurrentDoc->head_style = strdup (LineBuf);
- }
- void ParseSetUp(int implied, Frame *frame)
- {
- if (EndTag)
- {
- SwallowAttributes();
- return;
- }
- if (!implied)
- SwallowAttributes();
- for (;;)
- {
- while (GetToken() == WHITESPACE);
- /* UnGetToken(); */ /* howcome 10/7/95 part of comment handling */
- if (Token == TAG_HEAD && EndTag)
- {
- SwallowAttributes();
- break;
- }
- if (Token == TAG_TITLE)
- {
- UnGetToken();
- ParseTitle(0, frame);
- continue;
- }
- if (Token == TAG_ISINDEX)
- {
- SwallowAttributes();
- IsIndex = 1;
- ClearStatus();
- continue;
- }
- if (Token == TAG_BASE)
- {
- UnGetToken();
- ParseBase(frame);
- continue;
- }
- /* howcome 26/2/95 */
- if (Token == TAG_STYLE)
- {
- UnGetToken();
- ParseStyle(frame);
- continue;
- }
- /* howcome 25/4/95 */
- if (Token == TAG_LINK)
- {
- UnGetToken();
- ParseLink(frame);
- continue;
- }
- if (Token == UNKNOWN)
- {
- SwallowAttributes();
- continue;
- }
- if (Token == PCDATA || Token == ENTITY)
- {
- UnGetToken();
- break;
- }
- if (Token == ENDDATA || TokenClass != EN_SETUP)
- {
- UnGetToken();
- break;
- }
- }
- }
- void ParseAnchorAttrs(char **href, int *hreflen, char **name, int *namelen, char **class_p, int *class_len_p)
- {
- int c, n, m;
- char *attr, *value;
- *href = 0;
- *name = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- value = ParseValue(&m);
- if (n == 4 && strncasecmp(attr, "href", n) == 0)
- {
- *href = value;
- *hreflen = m;
- continue;
- }
- if (n == 4 && strncasecmp(attr, "name", n) == 0)
- {
- *name = value;
- *namelen = m;
- continue;
- }
- if (n == 5 && strncasecmp(attr, "class", n) == 0)
- {
- if (STYLE_TRACE) {
- char *s = strndup(attr, n);
- fprintf(stderr,"style_class %sn",s);
- Free(s);
- }
- *class_p = value;
- *class_len_p = m;
- }
- }
- if (*href == NULL)
- if (TAG_TRACE)
- fprintf(stderr,"ParseAnchorAttrs: *href == NULL, hreflen = %dn", *hreflen);
- }
- /* howcome30/5/95: addded support for widht and height */
- void ParseImageAttrs(char **href, int *hreflen, int *align, int *ismap, int *width, int *height)
- {
- int c, n, m;
- char *attr, *value;
- *href = NULL; /* howcome: NULL !! */
- *align = ALIGN_BOTTOM;
- *ismap = 0;
- *width = 0; *height = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- value = ParseValue(&m);
- if (n == 3 && strncasecmp(attr, "src", n) == 0)
- {
- *href = value;
- *hreflen = m;
- continue;
- }
- if (n == 5 && strncasecmp(attr, "width", n) == 0)
- {
- *width = atoi(value);
- continue;
- }
- if (n == 6 && strncasecmp(attr, "height", n) == 0)
- {
- *height = atoi(value);
- continue;
- }
- if (n == 5 && strncasecmp(attr, "align", n) == 0)
- {
- if (m == 3 && strncasecmp(value, "top", m) == 0)
- *align = ALIGN_TOP;
- else if (m == 6 && strncasecmp(value, "middle", m) == 0)
- *align = ALIGN_MIDDLE;
- else if (m == 6 && strncasecmp(value, "bottom", m) == 0)
- *align = ALIGN_BOTTOM;
- continue;
- }
- if (n == 5 && strncasecmp(attr, "ismap", n) == 0)
- *ismap = 1;
- }
- }
- void ParseFigureAttrs(char **href, int *hreflen, int *align, int *width, int *height)
- {
- int c, n, m;
- char *attr, *value;
- *href = 0;
- *align = ALIGN_CENTER;
- *width = 0; *height = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- value = ParseValue(&m);
- if (n == 3 && strncasecmp(attr, "src", n) == 0)
- {
- *href = value;
- *hreflen = m;
- continue;
- }
- if (n == 5 && strncasecmp(attr, "width", n) == 0)
- {
- *width = atoi(value);
- continue;
- }
- if (n == 6 && strncasecmp(attr, "height", n) == 0)
- {
- *height = atoi(value);
- continue;
- }
- if (n == 5 && strncasecmp(attr, "align", n) == 0)
- {
- if (m == 4 && strncasecmp(value, "left", m) == 0)
- *align = ALIGN_LEFT;
- else if (m == 6 && strncasecmp(value, "center", m) == 0)
- *align = ALIGN_CENTER;
- else if (m == 5 && strncasecmp(value, "right", m) == 0)
- *align = ALIGN_RIGHT;
- else if (m == 9 && strncasecmp(value, "bleedleft", m) == 0)
- *align = ALIGN_BLEEDLEFT;
- else if (m == 10 && strncasecmp(value, "bleedright", m) == 0)
- *align = ALIGN_BLEEDRIGHT;
- continue;
- }
- }
- }
- void /* wm 19.Jan.95 */
- ParseTextAreaAttrs(int *type, char **name, int *nlen,
- char **value, int *vlen, int *rows, int *cols, int *flags)
- {
- int c, n, m; /* janet: not used: checked */
- char *attr, *attrval;
- *type = TEXTFIELD;
- *rows = 4;
- *cols = 20;
- *flags = 0;
- *name = *value = "";
- *nlen = *vlen = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 4 && strncasecmp(attr, "type", n) == 0)
- {
- if (m == 4 && strncasecmp(attrval, "text", m) == 0)
- *type = TEXTFIELD;
- else if (m == 8 && strncasecmp(attrval, "checkbox", m) == 0)
- *type = CHECKBOX;
- else if (m == 5 && strncasecmp(attrval, "radio", m) == 0)
- *type = RADIOBUTTON;
- continue;
- }
- if (n == 4 && strncasecmp(attr, "name", n) == 0)
- {
- *name = attrval;
- *nlen = m;
- continue;
- }
- if (n == 5 && strncasecmp(attr, "value", n) == 0)
- {
- *value = attrval;
- *vlen = m;
- continue;
- }
- if (n == 4 && strncasecmp(attr, "rows", n) == 0)
- {
- sscanf(attrval, "%d", rows);
- continue;
- }
- if (n == 4 && strncasecmp(attr, "cols", n) == 0)
- {
- sscanf(attrval, "%d", cols);
- continue;
- }
- if (n == 5 && strncasecmp(attr, "error", n) == 0)
- {
- *flags |= IN_ERROR;
- continue;
- }
- if (n == 8 && strncasecmp(attr, "disabled", n) == 0)
- {
- *flags |= DISABLED;
- continue;
- }
- if (n == 7 && strncasecmp(attr, "checked", n) == 0)
- *flags |= CHECKED;
- }
- }
- void /* --Spif 11-Oct-95 */
- ParseFormAttrs(int *method, char **action, int *alen)
- {
- int c, n, m;
- char *attr, *attrval;
-
- *action = NULL;
- *method = GET; /* implied must add encoded-type.. */
- for (;;)
- {
- c= *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 6 && strncasecmp(attr, "method", n) == 0)
- {
- if ( m == 3 && strncasecmp(attrval, "get", m) ==0)
- *method = GET;
- else if ( m == 4 && strncasecmp(attrval, "post", m) ==0)
- *method = POST;
- }
- if ( n == 6 && strncasecmp(attr, "action", n) == 0)
- {
- *action = attrval;
- *alen = m;
- continue;
- };
- };
- }
- void /* wm 19.Jan.95 */
- ParseInputAttrs(int *type, char **name, int *nlen,
- char **value, int *vlen, int *size, int *flags, Image **image)
- {
- int c, n, m; /* janet: not used: checked */
- char *attr, *attrval, *href = NULL;
- int hreflen = 0; /* --SPif */
- *type = TEXTFIELD;
- *size = 20;
- *flags = 0;
- *name = *value = "";
- *nlen = *vlen = 0;
- hreflen = 0;
- *image=NULL;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 4 && strncasecmp(attr, "type", n) == 0)
- {
- if (m == 4 && strncasecmp(attrval, "text", m) == 0)
- *type = TEXTFIELD;
- else if (m == 8 && strncasecmp(attrval, "checkbox", m) == 0)
- *type = CHECKBOX;
- else if (m == 5 && strncasecmp(attrval, "radio", m) == 0)
- *type = RADIOBUTTON;
- else if (m == 6 && strncasecmp(attrval, "submit", m) == 0)
- *type = SUBMITBUTTON;
- else if (m == 5 && strncasecmp(attrval, "reset", m) == 0)
- *type = RESETBUTTON;
- else if (m == 5 && strncasecmp(attrval, "image", m) ==0)
- *type = SUBMITBUTTON; /* --Spif image in html2 = Submit */
- else if (m == 6 && strncasecmp(attrval, "hidden", m) ==0)
- *type = HIDDEN;
- else if (m == 6 && strncasecmp(attrval, "passwd", m) ==0)
- *type = PASSWD;
- continue;
- }
- if (n == 4 && strncasecmp(attr, "name", n) == 0)
- {
- *name = attrval;
- *nlen = m;
- continue;
- }
- if (n == 5 && strncasecmp(attr, "value", n) == 0)
- {
- *value = attrval;
- *vlen = m;
- continue;
- }
- if (n == 4 && strncasecmp(attr, "size", n) == 0)
- {
- sscanf(attrval, "%d", size);
- continue;
- }
- if (n == 5 && strncasecmp(attr, "error", n) == 0)
- {
- *flags |= IN_ERROR;
- continue;
- }
- if (n == 8 && strncasecmp(attr, "disabled", n) == 0)
- {
- *flags |= DISABLED;
- continue;
- }
- if (n == 7 && strncasecmp(attr, "checked", n) == 0)
- *flags |= CHECKED;
- if (n == 8 && strncasecmp(attr, "multiple", n) == 0)
- *flags |= MULTIPLE;
- /* --Spif 9-Oct-1995 */
- if (n == 3 && strncasecmp(attr, "src", n) == 0)
- {
- href = attrval;
- hreflen = m;
- };
- }
- /* --Spif 9-Oct-1995 */
- if (hreflen > 0)
- *image = GetImage(href, hreflen, CurrentDoc->pending_reload);
- }
- void /* wm 19.Jan.95 */
- ParseCellAttrs(int *rowspan, int *colspan, int *align, int *nowrap)
- {
- int c, n, m;
- char *attr, *attrval;
- *rowspan = *colspan = 1;
- *align = ALIGN_CENTER;
- *nowrap = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 7 && strncasecmp(attr, "rowspan", n) == 0)
- {
- sscanf(attrval, "%d", rowspan);
- continue;
- }
- if (n == 7 && strncasecmp(attr, "colspan", n) == 0)
- {
- sscanf(attrval, "%d", colspan);
- continue;
- }
- if (n == 5 && strncasecmp(attr, "align", n) == 0)
- {
- if (m == 6 && strncasecmp(attrval, "center", m) == 0)
- *align = ALIGN_CENTER;
- else if (m == 5 && strncasecmp(attrval, "right", m) == 0)
- *align = ALIGN_RIGHT;
- else if (m == 4 && strncasecmp(attrval, "left", m) == 0)
- *align = ALIGN_LEFT;
- continue;
- }
- if (n == 6 && strncasecmp(attr, "nowrap", n) == 0)
- *nowrap = 1;
- }
- }
- void /* wm 19.Jan.95 */
- ParseTableAttrs(int *border)
- {
- int c, n, m;
- char *attr, *attrval;
- *border = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 6 && strncasecmp(attr, "border", n) == 0)
- {
- int bd=1; /* DJB 17-Jan-96 */
-
- if (attrval)
- sscanf(attrval, "%d", &bd);
-
- *border = bd ? 1: 0; /* Restrict to 1 and 0 ? */
- continue;
- }
- }
- }
- void
- ParseClassAttrs(char **class_p, int *class_len_p)
- {
- int c, n, m;
- char *attr, *attrval;
- *class_p = NULL;
- *class_len_p = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 5 && strncasecmp(attr, "class", n) == 0)
- {
- if (STYLE_TRACE) {
- char *s = strndup(attrval, m);
- fprintf(stderr,"style_class %sn",s);
- Free(s);
- }
- *class_p = attrval;
- *class_len_p = m;
- }
- }
- }
- void /* wm 19.Jan.95 */
- ParseParaAttrs(int *align, char **class_p, int *class_len_p)
- {
- int c, n, m;
- char *attr, *attrval;
- *class_p = NULL;
- *class_len_p = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 5 && strncasecmp(attr, "align", n) == 0)
- {
- if (m == 6 && strncasecmp(attrval, "center", m) == 0)
- *align = ALIGN_CENTER;
- else if (m == 5 && strncasecmp(attrval, "right", m) == 0)
- *align = ALIGN_RIGHT;
- else if (m == 4 && strncasecmp(attrval, "left", m) == 0)
- *align = ALIGN_LEFT;
- else if (m == 7 && strncasecmp(attrval, "justify", m) == 0)
- *align = ALIGN_JUSTIFY;
- }
- if (n == 5 && strncasecmp(attr, "class", n) == 0)
- {
- if (STYLE_TRACE) {
- char *s = strndup(attrval, m);
- fprintf(stderr,"style_class %sn",s);
- Free(s);
- }
- *class_p = attrval;
- *class_len_p = m;
- }
- }
- }
- #ifdef HTML3_HAS_EXPIRED
- ParseBodyAttrs(char **bg_img, int *bg_len)
- {
- int c, n, m;
- char *attr, *attrval;
- *bg_img = NULL;
- *bg_len = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if (n == 10 && strncasecmp(attr, "background", n) == 0)
- {
- *bg_img = attrval;
- *bg_len = m;
- }
- }
- }
- #endif
- Image *ParseNoteAttrs(void)
- {
- int c, n, m, hreflen;
- char *attr, *attrval, *href = NULL;
- Image *image;
- image = NULL;
- hreflen = 0;
- for (;;)
- {
- c = *bufptr++;
- if (c == '')
- break;
- if (c == '>')
- break;
- if (IsWhite(c))
- continue;
- --bufptr;
- attr = ParseAttribute(&n);
- attrval = ParseValue(&m);
- if ((n == 4 && strncasecmp(attr, "role", n) == 0) || (n == 5 && strncasecmp(attr, "class", n) == 0))
- {
- if (m == 4 && strncasecmp(attrval, "note", m) == 0)
- image = note_image;
- else if (m == 3 && strncasecmp(attrval, "tip", m) == 0)
- image = note_image;
- else if (m == 7 && strncasecmp(attrval, "caution", m) == 0)
- image = caution_image;
- else if (m == 7 && strncasecmp(attrval, "warning", m) == 0)
- image = warning_image;
- }
- if (n == 3 && strncasecmp(attr, "src", n) == 0)
- {
- href = attrval;
- hreflen = m;
- }
- }
- if (hreflen > 0)
- image = GetImage(href, hreflen, CurrentDoc->pending_reload);
- return image;
- }
- void ParseOption(int implied, Frame *frame, Field *field, int font)
- {
- /* janet: not used: int width; */
- if (EndTag)
- {
- SwallowAttributes();
- return;
- }
- if (!implied)
- SwallowAttributes();
- LineLen = 0;
- for (;;)
- {
- GetToken();
- if (Token == TAG_OPTION && EndTag)
- {
- SwallowAttributes();
- break;
- }
- if (Token == UNKNOWN)
- {
- SwallowAttributes();
- continue;
- }
- /* condense whitespace */
- if (Token == WHITESPACE)
- {
- while (GetToken() == WHITESPACE);
- UnGetToken();
- if (LineLen < LBUFSIZE - 1)
- LineBuf[LineLen++] = ' ';
- continue;
- }
- if (Token == PCDATA)
- {
- if (LineLen < LBUFSIZE - 1)
- LineBuf[LineLen++] = TokenValue;
- continue;
- }
- /* unexpected tag so terminate element */
- UnGetToken();
- break;
- }
- LineBuf[LineLen] = '';
- if (LineLen > 0)
- AddOption(field, font, LineBuf, LineLen);
- }