1
/* Style Implementation for Hypertext HTStyle.c
2
** ==================================
4
** Styles allow the translation between a logical property
5
** of a piece of text and its physical representation.
7
** A StyleSheet is a collection of styles, defining the
8
** translation necessary to
9
** represent a document. It is a linked list of styles.
19
PUBLIC HTStyle* HTStyleNew NOARGS
21
HTStyle * self = typecalloc(HTStyle);
23
outofmem(__FILE__, "HTStyleNew");
27
/* Create a new style with a name
29
PUBLIC HTStyle* HTStyleNewNamed ARGS1 (CONST char *,name)
31
HTStyle * self = HTStyleNew();
32
StrAllocCopy(self->name, name);
33
self->id = -1; /* <0 */
40
PUBLIC HTStyle * HTStyleFree ARGS1 (HTStyle *,self)
49
#ifdef SUPPRESS /* Only on the NeXT */
50
/* Read a style from a stream (without its name)
51
** --------------------------
53
** Reads a style with paragraph information from a stream.
54
** The style name is not read or written by these routines.
56
#define NONE_STRING "(None)"
57
#define HTStream NXStream
59
HTStyle * HTStyleRead (HTStyle * style, HTStream * stream)
61
char myTag[STYLE_NAME_LENGTH];
62
char fontName[STYLE_NAME_LENGTH];
65
int gotpara; /* flag: have we got a paragraph definition? */
67
NXScanf(stream, "%s%s%f%d",
73
if (!style->paragraph) {
74
style->paragraph = malloc(sizeof(*(style->paragraph)));
75
if (!style->paragraph)
76
outofmem(__FILE__, "HTStyleRead");
77
style->paragraph->tabs = 0;
80
NXScanf(stream, "%f%f%f%f%hd%f%f%hd",
90
p->tabs = malloc(p->numTabs * sizeof(p->tabs[0]));
92
outofmem(__FILE__, "HTStyleRead");
93
for (tab=0; tab < p->numTabs; tab++) {
94
NXScanf(stream, "%hd%f",
98
} else { /* No paragraph */
99
FREE(style->paragraph);
100
} /* if no paragraph */
101
StrAllocCopy(style->SGMLTag, myTag);
102
if (strcmp(fontName, NONE_STRING)==0)
105
style->font = [Font newFont:fontName size:style->fontSize];
110
/* Write a style to a stream in a compatible way
112
HTStyle * HTStyleWrite (HTStyle * style, NXStream * stream)
115
NXTextStyle *p = style->paragraph;
116
NXPrintf(stream, "%s %s %f %d\n",
118
style->font ? [style->font name] : NONE_STRING,
123
NXPrintf(stream, "\t%f %f %f %f %d %f %f\t%d\n",
133
for (tab=0; tab < p->numTabs; tab++)
134
NXPrintf(stream, "\t%d %f\n",
142
/* Write a style to stdout for diagnostics
144
HTStyle * HTStyleDump (HTStyle * style)
147
NXTextStyle *p = style->paragraph;
148
printf(STYLE_DUMP_FONT,
155
printf(STYLE_DUMP_IDENT,
160
printf(STYLE_DUMP_ALIGN,
166
for (tab=0; tab < p->numTabs; tab++) {
167
printf(STYLE_DUMP_TAB,
175
#endif /* SUPPRESS */
178
/* StyleSheet Functions
179
** ====================
182
/* Searching for styles:
184
HTStyle * HTStyleNamed ARGS2 (HTStyleSheet *,self, CONST char *,name)
187
for (scan=self->styles; scan; scan=scan->next)
188
if (0==strcmp(scan->name, name)) return scan;
189
CTRACE((tfp, "StyleSheet: No style named `%s'\n", name));
193
#ifdef NEXT_SUPRESS /* Not in general common code */
195
HTStyle * HTStyleMatching (HTStyleSheet * self, HTStyle *style)
198
for (scan=self->styles; scan; scan=scan->next)
199
if (scan->paragraph == para) return scan;
203
/* Find the style which best fits a given run
204
** ------------------------------------------
206
** This heuristic is used for guessing the style for a run of
207
** text which has been pasted in. In order, we try:
209
** A style whose paragraph structure is actually used by the run.
210
** A style matching in font
211
** A style matching in paragraph style exactly
212
** A style matching in paragraph to a degree
215
HTStyle * HTStyleForRun (HTStyleSheet *self, NXRun *run)
220
NXTextStyle * rp = run->paraStyle;
221
for (scan=self->styles; scan; scan=scan->next)
222
if (scan->paragraph == run->paraStyle) return scan; /* Exact */
224
for (scan=self->styles; scan; scan=scan->next){
225
NXTextStyle * sp = scan->paragraph;
228
if (sp->indent1st == rp->indent1st) match = match+1;
229
if (sp->indent2nd == rp->indent2nd) match = match+2;
230
if (sp->lineHt == rp->lineHt) match = match+1;
231
if (sp->numTabs == rp->numTabs) match = match+1;
232
if (sp->alignment == rp->alignment) match = match+3;
233
if (scan->font == run->font) match = match+10;
234
if (match>bestMatch) {
240
CTRACE((tfp, "HTStyleForRun: Best match for style is %d out of 18\n",
244
#endif /* NEXT_SUPRESS */
247
/* Add a style to a sheet
248
** ----------------------
250
HTStyleSheet * HTStyleSheetAddStyle ARGS2
251
(HTStyleSheet *,self, HTStyle *,style)
253
style->next = 0; /* The style will go on the end */
255
self->styles = style;
258
for(scan=self->styles; scan->next; scan=scan->next); /* Find end */
265
/* Remove the given object from a style sheet if it exists
267
HTStyleSheet * HTStyleSheetRemoveStyle ARGS2
268
(HTStyleSheet *,self, HTStyle *,style)
270
if (self->styles == style) {
271
self->styles = style->next;
275
for(scan = self->styles; scan; scan = scan->next) {
276
if (scan->next == style) {
277
scan->next = style->next;
285
/* Create new style sheet
288
HTStyleSheet * HTStyleSheetNew NOARGS
290
HTStyleSheet * self = typecalloc(HTStyleSheet);
292
outofmem(__FILE__, "HTStyleSheetNew");
297
/* Free off a style sheet pointer
299
HTStyleSheet * HTStyleSheetFree ARGS1 (HTStyleSheet *,self)
302
while((style=self->styles)!=0) {
303
self->styles = style->next;
311
/* Read a stylesheet from a typed stream
312
** -------------------------------------
314
** Reads a style sheet from a stream. If new styles have the same names
315
** as existing styles, they replace the old ones without changing the ids.
318
#ifdef NEXT_SUPRESS /* Only on the NeXT */
319
HTStyleSheet * HTStyleSheetRead(HTStyleSheet * self, NXStream * stream)
325
NXScanf(stream, " %d ", &numStyles);
326
CTRACE((tfp, "Stylesheet: Reading %d styles\n", numStyles));
327
for (i=0; i<numStyles; i++) {
328
NXScanf(stream, "%s", styleName);
329
style = HTStyleNamed(self, styleName);
331
style = HTStyleNewNamed(styleName);
332
(void) HTStyleSheetAddStyle(self, style);
334
(void) HTStyleRead(style, stream);
335
if (TRACE) HTStyleDump(style);
340
/* Write a stylesheet to a typed stream
341
** ------------------------------------
343
** Writes a style sheet to a stream.
346
HTStyleSheet * HTStyleSheetWrite(HTStyleSheet * self, NXStream * stream)
351
for(style=self->styles; style; style=style->next) numStyles++;
352
NXPrintf(stream, "%d\n", numStyles);
354
CTRACE((tfp, "StyleSheet: Writing %d styles\n", numStyles));
355
for (style=self->styles; style; style=style->next) {
356
NXPrintf(stream, "%s ", style->name);
357
(void) HTStyleWrite(style, stream);
361
#endif /* NEXT_SUPRESS */