diff options
Diffstat (limited to 'WWW/Library/Implementation/HTStyle.c')
-rw-r--r-- | WWW/Library/Implementation/HTStyle.c | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/WWW/Library/Implementation/HTStyle.c b/WWW/Library/Implementation/HTStyle.c new file mode 100644 index 0000000..54c0bc5 --- /dev/null +++ b/WWW/Library/Implementation/HTStyle.c @@ -0,0 +1,378 @@ +/* + * $LynxId: HTStyle.c,v 1.16 2009/11/27 13:01:48 tom Exp $ + * + * Style Implementation for Hypertext HTStyle.c + * ================================== + * + * Styles allow the translation between a logical property + * of a piece of text and its physical representation. + * + * A StyleSheet is a collection of styles, defining the + * translation necessary to + * represent a document. It is a linked list of styles. + */ + +#include <HTUtils.h> +#include <HTStyle.h> + +#include <LYLeaks.h> + +/* Create a new style +*/ +HTStyle *HTStyleNew(void) +{ + HTStyle *self = typecalloc(HTStyle); + + if (self == NULL) + outofmem(__FILE__, "HTStyleNew"); + return self; +} + +/* Create a new style with a name +*/ +HTStyle *HTStyleNewNamed(const char *name) +{ + HTStyle *self = HTStyleNew(); + + StrAllocCopy(self->w_name, name); + self->id = -1; /* <0 */ + return self; +} + +/* Free a style +*/ +HTStyle *HTStyleFree(HTStyle *self) +{ + FREE(self->w_name); + FREE(self->w_SGMLTag); + FREE(self); + return NULL; +} + +#ifdef SUPPRESS /* Only on the NeXT */ +/* Read a style from a stream (without its name) + * -------------------------- + * + * Reads a style with paragraph information from a stream. + * The style name is not read or written by these routines. + */ +#define NONE_STRING "(None)" +#define HTStream NXStream + +HTStyle *HTStyleRead(HTStyle *style, HTStream *stream) +{ + char myTag[STYLE_NAME_LENGTH]; + char fontName[STYLE_NAME_LENGTH]; + NXTextStyle *p; + int tab; + int gotpara; /* flag: have we got a paragraph definition? */ + + NXScanf(stream, "%s%s%f%d", + myTag, + fontName, + &style->fontSize, + &gotpara); + if (gotpara) { + if (!style->paragraph) { + style->paragraph = malloc(sizeof(*(style->paragraph))); + if (!style->paragraph) + outofmem(__FILE__, "HTStyleRead"); + style->paragraph->tabs = 0; + } + p = style->paragraph; + NXScanf(stream, "%f%f%f%f%hd%f%f%hd", + &p->indent1st, + &p->indent2nd, + &p->lineHt, + &p->descentLine, + &p->alignment, + &style->spaceBefore, + &style->spaceAfter, + &p->numTabs); + FREE(p->tabs); + p->tabs = malloc(p->numTabs * sizeof(p->tabs[0])); + if (!p->tabs) + outofmem(__FILE__, "HTStyleRead"); + for (tab = 0; tab < p->numTabs; tab++) { + NXScanf(stream, "%hd%f", + &p->tabs[tab].kind, + &p->tabs[tab].x); + } + } else { /* No paragraph */ + FREE(style->paragraph); + } /* if no paragraph */ + StrAllocCopy(style->SGMLTag, myTag); + if (strcmp(fontName, NONE_STRING) == 0) + style->font = 0; + else + style->font =[Font newFont: fontName size:style->fontSize]; + return NULL; +} + +/* Write a style to a stream in a compatible way +*/ +HTStyle *HTStyleWrite(HTStyle *style, NXStream * stream) +{ + int tab; + NXTextStyle *p = style->paragraph; + + NXPrintf(stream, "%s %s %f %d\n", + style->SGMLTag, + style->font ?[style->font name] : NONE_STRING, + style->fontSize, + p != 0); + + if (p) { + NXPrintf(stream, "\t%f %f %f %f %d %f %f\t%d\n", + p->indent1st, + p->indent2nd, + p->lineHt, + p->descentLine, + p->alignment, + style->spaceBefore, + style->spaceAfter, + p->numTabs); + + for (tab = 0; tab < p->numTabs; tab++) + NXPrintf(stream, "\t%d %f\n", + p->tabs[tab].kind, + p->tabs[tab].x); + } + return style; +} + +/* Write a style to stdout for diagnostics +*/ +HTStyle *HTStyleDump(HTStyle *style) +{ + int tab; + NXTextStyle *p = style->paragraph; + + printf(STYLE_DUMP_FONT, + style, + style->name, + style->SGMLTag, + [style->font name], + style->fontSize); + if (p) { + printf(STYLE_DUMP_IDENT, + p->indent1st, + p->indent2nd, + p->lineHt, + p->descentLine); + printf(STYLE_DUMP_ALIGN, + p->alignment, + p->numTabs, + style->spaceBefore, + style->spaceAfter); + + for (tab = 0; tab < p->numTabs; tab++) { + printf(STYLE_DUMP_TAB, + p->tabs[tab].kind, + p->tabs[tab].x); + } + printf("\n"); + } /* if paragraph */ + return style; +} +#endif /* SUPPRESS */ + +/* StyleSheet Functions + * ==================== + */ + +/* Searching for styles: +*/ +HTStyle *HTStyleNamed(HTStyleSheet *self, const char *name) +{ + HTStyle *scan; + + for (scan = self->styles; scan; scan = scan->next) + if (0 == strcmp(GetHTStyleName(scan), name)) + return scan; + CTRACE((tfp, "StyleSheet: No style named `%s'\n", name)); + return NULL; +} + +#ifdef NEXT_SUPRESS /* Not in general common code */ + +HTStyle *HTStyleMatching(HTStyleSheet *self, HTStyle *style) +{ + HTStyle *scan; + + for (scan = self->styles; scan; scan = scan->next) + if (scan->paragraph == para) + return scan; + return NULL; +} + +/* Find the style which best fits a given run + * ------------------------------------------ + * + * This heuristic is used for guessing the style for a run of + * text which has been pasted in. In order, we try: + * + * A style whose paragraph structure is actually used by the run. + * A style matching in font + * A style matching in paragraph style exactly + * A style matching in paragraph to a degree + */ + +HTStyle *HTStyleForRun(HTStyleSheet *self, NXRun * run) +{ + HTStyle *scan; + HTStyle *best = 0; + int bestMatch = 0; + NXTextStyle *rp = run->paraStyle; + + for (scan = self->styles; scan; scan = scan->next) + if (scan->paragraph == run->paraStyle) + return scan; /* Exact */ + + for (scan = self->styles; scan; scan = scan->next) { + NXTextStyle *sp = scan->paragraph; + + if (sp) { + int match = 0; + + if (sp->indent1st == rp->indent1st) + match = match + 1; + if (sp->indent2nd == rp->indent2nd) + match = match + 2; + if (sp->lineHt == rp->lineHt) + match = match + 1; + if (sp->numTabs == rp->numTabs) + match = match + 1; + if (sp->alignment == rp->alignment) + match = match + 3; + if (scan->font == run->font) + match = match + 10; + if (match > bestMatch) { + best = scan; + bestMatch = match; + } + } + } + CTRACE((tfp, "HTStyleForRun: Best match for style is %d out of 18\n", + bestMatch)); + return best; +} +#endif /* NEXT_SUPRESS */ + +/* Add a style to a sheet + * ---------------------- + */ +HTStyleSheet *HTStyleSheetAddStyle(HTStyleSheet *self, HTStyle *style) +{ + style->next = 0; /* The style will go on the end */ + if (!self->styles) { + self->styles = style; + } else { + HTStyle *scan; + + for (scan = self->styles; scan->next; scan = scan->next) ; /* Find end */ + scan->next = style; + } + return self; +} + +/* Remove the given object from a style sheet if it exists +*/ +HTStyleSheet *HTStyleSheetRemoveStyle(HTStyleSheet *self, HTStyle *style) +{ + if (self->styles == style) { + self->styles = style->next; + return self; + } else { + HTStyle *scan; + + for (scan = self->styles; scan; scan = scan->next) { + if (scan->next == style) { + scan->next = style->next; + return self; + } + } + } + return NULL; +} + +/* Create new style sheet +*/ + +HTStyleSheet *HTStyleSheetNew(void) +{ + HTStyleSheet *self = typecalloc(HTStyleSheet); + + if (self == NULL) + outofmem(__FILE__, "HTStyleSheetNew"); + return self; +} + +/* Free off a style sheet pointer +*/ +HTStyleSheet *HTStyleSheetFree(HTStyleSheet *self) +{ + HTStyle *style; + + while ((style = self->styles) != 0) { + self->styles = style->next; + HTStyleFree(style); + } + FREE(self); + return NULL; +} + +/* Read a stylesheet from a typed stream + * ------------------------------------- + * + * Reads a style sheet from a stream. If new styles have the same names + * as existing styles, they replace the old ones without changing the ids. + */ + +#ifdef NEXT_SUPRESS /* Only on the NeXT */ +HTStyleSheet *HTStyleSheetRead(HTStyleSheet *self, NXStream * stream) +{ + int numStyles; + int i; + HTStyle *style; + char styleName[80]; + + NXScanf(stream, " %d ", &numStyles); + CTRACE((tfp, "Stylesheet: Reading %d styles\n", numStyles)); + for (i = 0; i < numStyles; i++) { + NXScanf(stream, "%s", styleName); + style = HTStyleNamed(self, styleName); + if (!style) { + style = HTStyleNewNamed(styleName); + (void) HTStyleSheetAddStyle(self, style); + } + (void) HTStyleRead(style, stream); + if (TRACE) + HTStyleDump(style); + } + return self; +} + +/* Write a stylesheet to a typed stream + * ------------------------------------ + * + * Writes a style sheet to a stream. + */ + +HTStyleSheet *HTStyleSheetWrite(HTStyleSheet *self, NXStream * stream) +{ + int numStyles = 0; + HTStyle *style; + + for (style = self->styles; style; style = style->next) + numStyles++; + NXPrintf(stream, "%d\n", numStyles); + + CTRACE((tfp, "StyleSheet: Writing %d styles\n", numStyles)); + for (style = self->styles; style; style = style->next) { + NXPrintf(stream, "%s ", style->name); + (void) HTStyleWrite(style, stream); + } + return self; +} +#endif /* NEXT_SUPRESS */ |