Annotation of Amaya/amaya/styleparser.c, revision 1.115
1.1 cvs 1: /*
2: *
1.113 quint 3: * (c) COPYRIGHT MIT and INRIA, 1996-2002
1.1 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.53 cvs 7:
1.1 cvs 8: /*
9: * Everything directly linked to the CSS syntax should now hopefully
10: * be contained in this module.
11: *
12: * Author: I. Vatton
13: *
14: */
15:
16: /* Included headerfiles */
17: #define THOT_EXPORT extern
18: #include "amaya.h"
19: #include "css.h"
1.25 cvs 20: #include "fetchHTMLname.h"
1.100 vatton 21: #include "SVG.h"
1.107 cvs 22: #include "XML.h"
1.1 cvs 23:
24: typedef struct _BackgroundImageCallbackBlock
25: {
26: Element el;
27: PSchema tsch;
28: union
29: {
30: PresentationContextBlock specific;
31: GenericContextBlock generic;
32: } context;
33: }
34: BackgroundImageCallbackBlock, *BackgroundImageCallbackPtr;
35:
36: #include "AHTURLTools_f.h"
37: #include "HTMLpresentation_f.h"
38: #include "HTMLimage_f.h"
39: #include "UIcss_f.h"
40: #include "css_f.h"
1.24 cvs 41: #include "fetchHTMLname_f.h"
1.91 cvs 42: #include "fetchXMLname_f.h"
1.1 cvs 43: #include "html2thot_f.h"
1.91 cvs 44: #include "init_f.h"
1.1 cvs 45: #include "styleparser_f.h"
46:
47: #define MAX_BUFFER_LENGTH 200
48: /*
49: * A PropertyParser is a function used to parse the
50: * description substring associated to a given style attribute
1.59 cvs 51: * e.g.: "red" for a color attribute or "12pt bold helvetica"
1.1 cvs 52: * for a font attribute.
53: */
1.79 cvs 54: typedef char *(*PropertyParser) (Element element,
1.56 cvs 55: PSchema tsch,
56: PresentationContext context,
1.79 cvs 57: char *cssRule,
1.56 cvs 58: CSSInfoPtr css,
59: ThotBool isHTML);
1.1 cvs 60:
61: /* Description of the set of CSS properties supported */
62: typedef struct CSSProperty
63: {
1.79 cvs 64: char *name;
1.25 cvs 65: PropertyParser parsing_function;
1.1 cvs 66: }
67: CSSProperty;
68:
69: struct unit_def
70: {
1.79 cvs 71: char *sign;
1.1 cvs 72: unsigned int unit;
73: };
74:
75: static struct unit_def CSSUnitNames[] =
76: {
1.82 cvs 77: {"pt", STYLE_UNIT_PT},
78: {"pc", STYLE_UNIT_PC},
79: {"in", STYLE_UNIT_IN},
80: {"cm", STYLE_UNIT_CM},
81: {"mm", STYLE_UNIT_MM},
82: {"em", STYLE_UNIT_EM},
83: {"px", STYLE_UNIT_PX},
84: {"ex", STYLE_UNIT_XHEIGHT},
85: {"%", STYLE_UNIT_PERCENT}
1.1 cvs 86: };
87:
88: #define NB_UNITS (sizeof(CSSUnitNames) / sizeof(struct unit_def))
1.86 cvs 89: static char *DocURL = NULL; /* The parsed CSS file */
90: static Document ParsedDoc; /* The document to which CSS are to be applied */
91: static int LineNumber = -1; /* The line where the error occurs */
1.93 vatton 92: static int NewLineSkipped = 0;
1.1 cvs 93:
94: /*----------------------------------------------------------------------
95: SkipWord:
96: ----------------------------------------------------------------------*/
1.79 cvs 97: static char *SkipWord (char *ptr)
1.1 cvs 98: {
1.50 cvs 99: # ifdef _WINDOWS
100: /* iswalnum is supposed to be supported by the i18n veriosn of libc
101: use it when available */
1.82 cvs 102: while (iswalnum (*ptr) || *ptr == '-' || *ptr == '%')
1.50 cvs 103: # else /* !_WINDOWS */
1.82 cvs 104: while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '%')
1.50 cvs 105: # endif /* !_WINDOWS */
106: ptr++;
1.1 cvs 107: return (ptr);
108: }
109:
110: /*----------------------------------------------------------------------
1.13 cvs 111: SkipBlanksAndComments:
112: ----------------------------------------------------------------------*/
1.82 cvs 113: char *SkipBlanksAndComments (char *ptr)
1.13 cvs 114: {
1.93 vatton 115: /* skip spaces */
116: while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
117: *ptr == TAB || *ptr == __CR__)
118: {
119: if (*ptr == EOL)
120: /* increment the number of newline skipped */
121: NewLineSkipped++;
122: ptr++;
123: }
1.13 cvs 124: while (ptr[0] == '/' && ptr[1] == '*')
125: {
126: /* look for the end of the comment */
127: ptr = &ptr[2];
128: while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
129: ptr++;
130: if (ptr[0] != EOS)
131: ptr = &ptr[2];
1.93 vatton 132: /* skip spaces */
133: while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
134: *ptr == TAB || *ptr == __CR__)
135: {
136: if (*ptr == EOL)
137: /* increment the number of newline skipped */
138: NewLineSkipped++;
139: ptr++;
140: }
1.13 cvs 141: }
142: return (ptr);
143: }
144:
1.49 cvs 145:
146: /*----------------------------------------------------------------------
1.1 cvs 147: SkipQuotedString:
148: ----------------------------------------------------------------------*/
1.79 cvs 149: static char *SkipQuotedString (char *ptr, char quote)
1.1 cvs 150: {
1.14 cvs 151: ThotBool stop;
1.1 cvs 152:
153: stop = FALSE;
154: while (!stop)
155: {
156: if (*ptr == quote)
157: {
158: ptr++;
159: stop = TRUE;
160: }
1.82 cvs 161: else if (*ptr == EOS)
1.1 cvs 162: stop = TRUE;
1.82 cvs 163: else if (*ptr == '\\')
1.1 cvs 164: /* escape character */
165: {
166: ptr++;
1.82 cvs 167: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
168: (*ptr >= 'a' && *ptr <= 'f'))
1.1 cvs 169: {
170: ptr++;
1.82 cvs 171: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
172: (*ptr >= 'a' && *ptr <= 'f'))
1.1 cvs 173: ptr++;
174: }
175: else
176: ptr++;
177: }
178: else
179: ptr++;
180: }
181: return (ptr);
182: }
183:
184: /*----------------------------------------------------------------------
1.86 cvs 185: CSSParseError
186: print the error message msg on stderr.
187: When the line is 0 ask to expat the current line number
188: ----------------------------------------------------------------------*/
189: static void CSSParseError (char *msg, char *value)
190: {
191: if (!TtaIsPrinting () && ParsedDoc > 0)
192: {
193: if (!ErrFile)
194: {
1.90 cvs 195: if (OpenParsingErrors (ParsedDoc) == FALSE)
1.86 cvs 196: return;
197: }
198:
199: if (DocURL != NULL)
200: {
1.94 cvs 201: fprintf (ErrFile, "*** Errors/warnings in %s\n", DocURL);
1.86 cvs 202: /* set to NULL as long as the CSS file doesn't change */
203: DocURL = NULL;
204: }
1.89 cvs 205: CSSErrorsFound = TRUE;
1.86 cvs 206: if (LineNumber < 0)
1.99 vatton 207: fprintf (ErrFile, " In Style attribute %s %s\"\n", msg, value);
1.86 cvs 208: else
1.99 vatton 209: fprintf (ErrFile, " line %d: %s %s\"\n", LineNumber + NewLineSkipped,
1.93 vatton 210: msg, value);
1.86 cvs 211: }
212: }
213:
1.89 cvs 214:
1.86 cvs 215: /*----------------------------------------------------------------------
216: SkipProperty:
217: ----------------------------------------------------------------------*/
218: static char *SkipProperty (char *ptr)
219: {
220: char *deb;
221: char c;
222:
223: deb = ptr;
224: while (*ptr != EOS && *ptr != ';' && *ptr != '}')
225: ptr++;
1.95 cvs 226: /* print the skipped property */
1.86 cvs 227: c = *ptr;
228: *ptr = EOS;
1.95 cvs 229: #ifdef CSS_WARNING
1.86 cvs 230: if (*deb != EOS)
1.99 vatton 231: CSSParseError ("CSS property ignored \"", deb);
1.95 cvs 232: #endif /* CSS_WARNING */
1.86 cvs 233: *ptr = c;
234: return (ptr);
235: }
236:
237: /*----------------------------------------------------------------------
1.1 cvs 238: SkipProperty:
239: ----------------------------------------------------------------------*/
1.99 vatton 240: static char *SkipValue (char *ptr, ThotBool error)
1.1 cvs 241: {
1.86 cvs 242: char *deb;
243: char c;
244:
245: deb = ptr;
1.82 cvs 246: while (*ptr != EOS && *ptr != ';' && *ptr != '}')
1.1 cvs 247: ptr++;
1.95 cvs 248: /* print the skipped property */
1.86 cvs 249: c = *ptr;
250: *ptr = EOS;
1.99 vatton 251: if (*deb != EOS && *deb != ',')
252: {
253: if (error)
254: CSSParseError ("invalid CSS value \"", deb);
1.95 cvs 255: #ifdef CSS_WARNING
1.99 vatton 256: else
257: CSSParseError ("CSS value ignored \"", deb);
1.95 cvs 258: #endif /* CSS_WARNING */
1.99 vatton 259: }
1.86 cvs 260: *ptr = c;
1.1 cvs 261: return (ptr);
262: }
263:
264: /*----------------------------------------------------------------------
1.64 cvs 265: ParseNumber:
266: parse a number and returns the corresponding value.
1.1 cvs 267: ----------------------------------------------------------------------*/
1.79 cvs 268: char *ParseNumber (char *cssRule, PresentationValue *pval)
1.1 cvs 269: {
270: int val = 0;
271: int minus = 0;
272: int valid = 0;
273: int f = 0;
1.14 cvs 274: ThotBool real = FALSE;
1.1 cvs 275:
276: pval->typed_data.unit = STYLE_UNIT_REL;
277: pval->typed_data.real = FALSE;
1.82 cvs 278: cssRule = SkipBlanksAndComments (cssRule);
279: if (*cssRule == '-')
1.1 cvs 280: {
281: minus = 1;
282: cssRule++;
1.82 cvs 283: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 284: }
285:
1.82 cvs 286: if (*cssRule == '+')
1.1 cvs 287: {
288: cssRule++;
1.82 cvs 289: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 290: }
291:
1.82 cvs 292: while ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 293: {
294: val *= 10;
1.82 cvs 295: val += *cssRule - '0';
1.1 cvs 296: cssRule++;
297: valid = 1;
298: }
299:
1.82 cvs 300: if (*cssRule == '.')
1.1 cvs 301: {
302: real = TRUE;
303: f = val;
304: val = 0;
305: cssRule++;
306: /* keep only 3 digits */
1.82 cvs 307: if (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 308: {
1.82 cvs 309: val = (*cssRule - '0') * 100;
1.1 cvs 310: cssRule++;
1.82 cvs 311: if (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 312: {
1.82 cvs 313: val += (*cssRule - '0') * 10;
1.1 cvs 314: cssRule++;
1.82 cvs 315: if ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 316: {
1.82 cvs 317: val += *cssRule - '0';
1.1 cvs 318: cssRule++;
319: }
320: }
321:
1.82 cvs 322: while (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 323: cssRule++;
324: valid = 1;
325: }
326: }
327:
328: if (!valid)
329: {
330: pval->typed_data.unit = STYLE_UNIT_INVALID;
331: pval->typed_data.value = 0;
332: }
333: else
334: {
335: pval->typed_data.real = real;
336: if (real)
337: {
338: if (minus)
339: pval->typed_data.value = -(f * 1000 + val);
340: else
341: pval->typed_data.value = f * 1000 + val;
342: }
343: else
344: {
345: if (minus)
346: pval->typed_data.value = -val;
347: else
348: pval->typed_data.value = val;
349: }
1.64 cvs 350: }
351: return (cssRule);
352: }
353:
354: /*----------------------------------------------------------------------
355: ParseCSSUnit:
356: parse a CSS Unit substring and returns the corresponding
357: value and its unit.
358: ----------------------------------------------------------------------*/
1.82 cvs 359: char *ParseCSSUnit (char *cssRule, PresentationValue *pval)
1.64 cvs 360: {
361: unsigned int uni;
362:
363: pval->typed_data.unit = STYLE_UNIT_REL;
364: cssRule = ParseNumber (cssRule, pval);
365: if (pval->typed_data.unit == STYLE_UNIT_INVALID)
366: cssRule = SkipWord (cssRule);
367: else
368: {
1.82 cvs 369: cssRule = SkipBlanksAndComments (cssRule);
1.64 cvs 370: for (uni = 0; uni < NB_UNITS; uni++)
371: {
1.82 cvs 372: if (!strncasecmp (CSSUnitNames[uni].sign, cssRule,
373: strlen (CSSUnitNames[uni].sign)))
1.64 cvs 374: {
375: pval->typed_data.unit = CSSUnitNames[uni].unit;
1.82 cvs 376: return (cssRule + strlen (CSSUnitNames[uni].sign));
1.64 cvs 377: }
378: }
379: /* not in the list of predefined units */
380: pval->typed_data.unit = STYLE_UNIT_PX;
1.1 cvs 381: }
382: return (cssRule);
383: }
384:
1.43 cvs 385: /*----------------------------------------------------------------------
386: ParseBorderValue
387: ----------------------------------------------------------------------*/
1.79 cvs 388: static char *ParseBorderValue (char *cssRule, PresentationValue *border)
1.43 cvs 389: {
390: /* first parse the attribute string */
391: border->typed_data.value = 0;
1.44 cvs 392: border->typed_data.unit = STYLE_UNIT_INVALID;
1.43 cvs 393: border->typed_data.real = FALSE;
1.82 cvs 394: if (!strncasecmp (cssRule, "thin", 4))
1.43 cvs 395: {
1.44 cvs 396: border->typed_data.unit = STYLE_UNIT_PX;
1.43 cvs 397: border->typed_data.value = 1;
398: cssRule = SkipWord (cssRule);
399: }
1.82 cvs 400: else if (!strncasecmp (cssRule, "medium", 6))
1.43 cvs 401: {
1.44 cvs 402: border->typed_data.unit = STYLE_UNIT_PX;
1.43 cvs 403: border->typed_data.value = 3;
404: cssRule = SkipWord (cssRule);
405: }
1.82 cvs 406: else if (!strncasecmp (cssRule, "thick", 5))
1.43 cvs 407: {
1.44 cvs 408: border->typed_data.unit = STYLE_UNIT_PX;
1.43 cvs 409: border->typed_data.value = 5;
410: cssRule = SkipWord (cssRule);
411: }
1.110 vatton 412: else if (isdigit (*cssRule) || *cssRule == '.')
1.43 cvs 413: cssRule = ParseCSSUnit (cssRule, border);
414: return (cssRule);
415: }
416:
417: /*----------------------------------------------------------------------
418: ParseBorderStyle
419: ----------------------------------------------------------------------*/
1.79 cvs 420: static char *ParseBorderStyle (char *cssRule, PresentationValue *border)
1.43 cvs 421: {
422: /* first parse the attribute string */
423: border->typed_data.value = 0;
424: border->typed_data.unit = STYLE_UNIT_PX;
425: border->typed_data.real = FALSE;
1.82 cvs 426: if (!strncasecmp (cssRule, "none", 4))
1.43 cvs 427: border->typed_data.value = STYLE_BORDERNONE;
1.82 cvs 428: else if (!strncasecmp (cssRule, "hidden", 6))
1.43 cvs 429: border->typed_data.value = STYLE_BORDERHIDDEN;
1.82 cvs 430: else if (!strncasecmp (cssRule, "dotted", 6))
1.43 cvs 431: border->typed_data.value = STYLE_BORDERDOTTED;
1.82 cvs 432: else if (!strncasecmp (cssRule, "dashed", 6))
1.43 cvs 433: border->typed_data.value = STYLE_BORDERDASHED;
1.82 cvs 434: else if (!strncasecmp (cssRule, "solid", 5))
1.43 cvs 435: border->typed_data.value = STYLE_BORDERSOLID;
1.82 cvs 436: else if (!strncasecmp (cssRule, "double", 6))
1.43 cvs 437: border->typed_data.value = STYLE_BORDERDOUBLE;
1.82 cvs 438: else if (!strncasecmp (cssRule, "groove", 6))
1.43 cvs 439: border->typed_data.value = STYLE_BORDERGROOVE;
1.82 cvs 440: else if (!strncasecmp (cssRule, "ridge", 5))
1.43 cvs 441: border->typed_data.value = STYLE_BORDERRIDGE;
1.82 cvs 442: else if (!strncasecmp (cssRule, "inset", 5))
1.43 cvs 443: border->typed_data.value = STYLE_BORDERINSET;
1.82 cvs 444: else if (!strncasecmp (cssRule, "outset", 6))
1.43 cvs 445: border->typed_data.value = STYLE_BORDEROUTSET;
446: else
1.44 cvs 447: {
448: /* invalid style */
449: border->typed_data.unit = STYLE_UNIT_INVALID;
450: return (cssRule);
451: }
1.43 cvs 452: /* the value is parsed now */
453: cssRule = SkipWord (cssRule);
454: return (cssRule);
455: }
456:
457: /*----------------------------------------------------------------------
1.59 cvs 458: ParseCSSColor: parse a CSS color attribute string
1.43 cvs 459: we expect the input string describing the attribute to be
460: either a color name, a 3 tuple or an hexadecimal encoding.
461: The color used will be approximed from the current color
462: table
463: ----------------------------------------------------------------------*/
1.79 cvs 464: static char *ParseCSSColor (char *cssRule, PresentationValue * val)
1.43 cvs 465: {
1.79 cvs 466: char *ptr;
1.43 cvs 467: unsigned short redval = (unsigned short) -1;
468: unsigned short greenval = 0; /* composant of each RGB */
469: unsigned short blueval = 0; /* default to red if unknown ! */
470: int best = 0; /* best color in list found */
471:
1.82 cvs 472: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 473: val->typed_data.unit = STYLE_UNIT_INVALID;
474: val->typed_data.real = FALSE;
475: val->typed_data.value = 0;
1.57 cvs 476: ptr = TtaGiveRGB (cssRule, &redval, &greenval, &blueval);
477: if (ptr == cssRule)
1.43 cvs 478: {
1.99 vatton 479: cssRule = SkipValue (cssRule, TRUE);
1.43 cvs 480: val->typed_data.value = 0;
481: val->typed_data.unit = STYLE_UNIT_INVALID;
482: }
483: else
484: {
485: best = TtaGetThotColor (redval, greenval, blueval);
486: val->typed_data.value = best;
487: val->typed_data.unit = STYLE_UNIT_REL;
1.57 cvs 488: cssRule = ptr;
1.43 cvs 489: }
490: val->typed_data.real = FALSE;
1.65 cvs 491: return (cssRule);
1.43 cvs 492: }
1.1 cvs 493:
494: /*----------------------------------------------------------------------
1.59 cvs 495: ParseCSSBorderTopWidth: parse a CSS BorderTopWidth
1.1 cvs 496: attribute string.
497: ----------------------------------------------------------------------*/
1.79 cvs 498: static char *ParseCSSBorderTopWidth (Element element, PSchema tsch,
499: PresentationContext context,
500: char *cssRule, CSSInfoPtr css,
501: ThotBool isHTML)
1.1 cvs 502: {
1.41 cvs 503: PresentationValue border;
504:
1.82 cvs 505: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 506: cssRule = ParseBorderValue (cssRule, &border);
507: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 508: {
509: TtaSetStylePresentation (PRBorderTopWidth, element, tsch, context, border);
510: border.typed_data.value = 1;
511: border.typed_data.unit = STYLE_UNIT_REL;
512: }
1.1 cvs 513: return (cssRule);
514: }
515:
516: /*----------------------------------------------------------------------
1.59 cvs 517: ParseCSSBorderBottomWidth: parse a CSS BorderBottomWidth
1.1 cvs 518: attribute string.
519: ----------------------------------------------------------------------*/
1.79 cvs 520: static char *ParseCSSBorderBottomWidth (Element element, PSchema tsch,
521: PresentationContext context,
522: char *cssRule, CSSInfoPtr css,
523: ThotBool isHTML)
1.1 cvs 524: {
1.41 cvs 525: PresentationValue border;
526:
1.82 cvs 527: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 528: /* first parse the attribute string */
1.43 cvs 529: cssRule = ParseBorderValue (cssRule, &border);
530: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 531: {
532: TtaSetStylePresentation (PRBorderBottomWidth, element, tsch, context, border);
533: border.typed_data.value = 1;
534: border.typed_data.unit = STYLE_UNIT_REL;
535: }
1.1 cvs 536: return (cssRule);
537: }
538:
539: /*----------------------------------------------------------------------
1.59 cvs 540: ParseCSSBorderLeftWidth: parse a CSS BorderLeftWidth
1.1 cvs 541: attribute string.
542: ----------------------------------------------------------------------*/
1.79 cvs 543: static char *ParseCSSBorderLeftWidth (Element element, PSchema tsch,
544: PresentationContext context,
545: char *cssRule, CSSInfoPtr css,
546: ThotBool isHTML)
1.1 cvs 547: {
1.41 cvs 548: PresentationValue border;
549:
1.82 cvs 550: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 551: /* first parse the attribute string */
1.43 cvs 552: cssRule = ParseBorderValue (cssRule, &border);
553: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 554: {
555: TtaSetStylePresentation (PRBorderLeftWidth, element, tsch, context, border);
556: border.typed_data.value = 1;
557: border.typed_data.unit = STYLE_UNIT_REL;
558: }
1.1 cvs 559: return (cssRule);
560: }
561:
562: /*----------------------------------------------------------------------
1.59 cvs 563: ParseCSSBorderRightWidth: parse a CSS BorderRightWidth
1.1 cvs 564: attribute string.
565: ----------------------------------------------------------------------*/
1.79 cvs 566: static char *ParseCSSBorderRightWidth (Element element, PSchema tsch,
567: PresentationContext context,
568: char *cssRule, CSSInfoPtr css,
569: ThotBool isHTML)
1.1 cvs 570: {
1.41 cvs 571: PresentationValue border;
572:
1.82 cvs 573: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 574: /* first parse the attribute string */
1.43 cvs 575: cssRule = ParseBorderValue (cssRule, &border);
576: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 577: {
578: TtaSetStylePresentation (PRBorderRightWidth, element, tsch, context, border);
579: border.typed_data.value = 1;
580: border.typed_data.unit = STYLE_UNIT_REL;
581: }
1.1 cvs 582: return (cssRule);
583: }
584:
585: /*----------------------------------------------------------------------
1.59 cvs 586: ParseCSSBorderWidth: parse a CSS BorderWidth
1.1 cvs 587: attribute string.
588: ----------------------------------------------------------------------*/
1.79 cvs 589: static char *ParseCSSBorderWidth (Element element, PSchema tsch,
590: PresentationContext context,
591: char *cssRule, CSSInfoPtr css,
592: ThotBool isHTML)
1.1 cvs 593: {
1.79 cvs 594: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 595: int skippedNL;
1.41 cvs 596:
1.82 cvs 597: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 598: /* First parse Border-Top */
599: ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 600: ptrR = SkipBlanksAndComments (ptrR);
601: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 602: {
1.93 vatton 603: skippedNL = NewLineSkipped;
1.42 cvs 604: cssRule = ptrR;
605: /* apply the Border-Top to all */
606: ptrR = ParseCSSBorderRightWidth (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 607: NewLineSkipped = skippedNL;
1.42 cvs 608: ptrR = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 609: NewLineSkipped = skippedNL;
1.42 cvs 610: ptrR = ParseCSSBorderLeftWidth (element, tsch, context, ptrT, css, isHTML);
611: }
612: else
613: {
614: /* parse Border-Right */
615: ptrB = ParseCSSBorderRightWidth (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 616: ptrB = SkipBlanksAndComments (ptrB);
617: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 618: {
1.93 vatton 619: skippedNL = NewLineSkipped;
1.42 cvs 620: cssRule = ptrB;
621: /* apply the Border-Top to Border-Bottom */
622: ptrB = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 623: NewLineSkipped = skippedNL;
1.42 cvs 624: /* apply the Border-Right to Border-Left */
625: ptrB = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
626: }
627: else
628: {
629: /* parse Border-Bottom */
630: ptrL = ParseCSSBorderBottomWidth (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 631: ptrL = SkipBlanksAndComments (ptrL);
632: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 633: {
634: cssRule = ptrL;
635: /* apply the Border-Right to Border-Left */
636: ptrL = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
637: }
638: else
639: /* parse Border-Left */
640: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 641: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 642: }
643: }
1.1 cvs 644: return (cssRule);
645: }
646:
647: /*----------------------------------------------------------------------
1.59 cvs 648: ParseCSSBorderColorTop: parse a CSS BorderColorTop
1.1 cvs 649: attribute string.
650: ----------------------------------------------------------------------*/
1.79 cvs 651: static char *ParseCSSBorderColorTop (Element element, PSchema tsch,
652: PresentationContext context,
653: char *cssRule, CSSInfoPtr css,
654: ThotBool isHTML)
1.1 cvs 655: {
1.43 cvs 656: PresentationValue best;
657:
658: cssRule = ParseCSSColor (cssRule, &best);
659: if (best.typed_data.unit != STYLE_UNIT_INVALID)
660: /* install the new presentation */
661: TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
1.65 cvs 662: return (cssRule);
1.1 cvs 663: }
664:
665: /*----------------------------------------------------------------------
1.59 cvs 666: ParseCSSBorderColorLeft: parse a CSS BorderColorLeft
1.42 cvs 667: attribute string.
668: ----------------------------------------------------------------------*/
1.79 cvs 669: static char *ParseCSSBorderColorLeft (Element element, PSchema tsch,
670: PresentationContext context,
671: char *cssRule, CSSInfoPtr css,
672: ThotBool isHTML)
1.42 cvs 673: {
1.43 cvs 674: PresentationValue best;
675:
676: cssRule = ParseCSSColor (cssRule, &best);
677: if (best.typed_data.unit != STYLE_UNIT_INVALID)
678: /* install the new presentation */
679: TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
1.65 cvs 680: return (cssRule);
1.42 cvs 681: }
682:
683: /*----------------------------------------------------------------------
1.59 cvs 684: ParseCSSBorderColorBottom: parse a CSS BorderColorBottom
1.42 cvs 685: attribute string.
686: ----------------------------------------------------------------------*/
1.79 cvs 687: static char *ParseCSSBorderColorBottom (Element element, PSchema tsch,
688: PresentationContext context,
689: char *cssRule, CSSInfoPtr css,
690: ThotBool isHTML)
1.42 cvs 691: {
1.43 cvs 692: PresentationValue best;
693:
694: cssRule = ParseCSSColor (cssRule, &best);
695: if (best.typed_data.unit != STYLE_UNIT_INVALID)
696: /* install the new presentation */
697: TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
1.65 cvs 698: return (cssRule);
1.42 cvs 699: }
700:
701: /*----------------------------------------------------------------------
1.59 cvs 702: ParseCSSBorderColorRight: parse a CSS BorderColorRight
1.1 cvs 703: attribute string.
704: ----------------------------------------------------------------------*/
1.79 cvs 705: static char *ParseCSSBorderColorRight (Element element, PSchema tsch,
706: PresentationContext context,
707: char *cssRule, CSSInfoPtr css,
708: ThotBool isHTML)
1.1 cvs 709: {
1.43 cvs 710: PresentationValue best;
711:
712: cssRule = ParseCSSColor (cssRule, &best);
713: if (best.typed_data.unit != STYLE_UNIT_INVALID)
714: /* install the new presentation */
715: TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
1.65 cvs 716: return (cssRule);
1.1 cvs 717: }
718:
719: /*----------------------------------------------------------------------
1.59 cvs 720: ParseCSSBorderColor: parse a CSS border-color
1.42 cvs 721: attribute string.
722: ----------------------------------------------------------------------*/
1.79 cvs 723: static char *ParseCSSBorderColor (Element element, PSchema tsch,
724: PresentationContext context,
725: char *cssRule, CSSInfoPtr css,
726: ThotBool isHTML)
1.42 cvs 727: {
1.79 cvs 728: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 729: int skippedNL;
1.42 cvs 730:
1.82 cvs 731: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 732: /* First parse Border-Top */
1.43 cvs 733: ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 734: ptrR = SkipBlanksAndComments (ptrR);
735: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 736: {
1.93 vatton 737: skippedNL = NewLineSkipped;
1.42 cvs 738: cssRule = ptrR;
739: /* apply the Border-Top to all */
1.43 cvs 740: ptrR = ParseCSSBorderColorRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 741: NewLineSkipped = skippedNL;
1.43 cvs 742: ptrR = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 743: NewLineSkipped = skippedNL;
1.43 cvs 744: ptrR = ParseCSSBorderColorLeft (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 745: }
746: else
747: {
748: /* parse Border-Right */
1.43 cvs 749: ptrB = ParseCSSBorderColorRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 750: ptrB = SkipBlanksAndComments (ptrB);
751: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 752: {
1.93 vatton 753: skippedNL = NewLineSkipped;
1.42 cvs 754: cssRule = ptrB;
755: /* apply the Border-Top to Border-Bottom */
1.43 cvs 756: ptrB = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 757: NewLineSkipped = skippedNL;
1.42 cvs 758: /* apply the Border-Right to Border-Left */
1.43 cvs 759: ptrB = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 760: }
761: else
762: {
1.93 vatton 763: skippedNL = NewLineSkipped;
1.42 cvs 764: /* parse Border-Bottom */
1.43 cvs 765: ptrL = ParseCSSBorderColorBottom (element, tsch, context, ptrB, css, isHTML);
1.93 vatton 766: NewLineSkipped = skippedNL;
1.82 cvs 767: ptrL = SkipBlanksAndComments (ptrL);
768: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 769: {
770: cssRule = ptrL;
771: /* apply the Border-Right to Border-Left */
1.43 cvs 772: ptrL = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 773: }
774: else
775: /* parse Border-Left */
1.43 cvs 776: cssRule = ParseCSSBorderColorLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 777: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 778: }
779: }
780: return (cssRule);
781: }
782:
783: /*----------------------------------------------------------------------
1.59 cvs 784: ParseCSSBorderStyleTop: parse a CSS BorderStyleTop
1.42 cvs 785: attribute string.
786: ----------------------------------------------------------------------*/
1.79 cvs 787: static char *ParseCSSBorderStyleTop (Element element, PSchema tsch,
788: PresentationContext context,
789: char *cssRule, CSSInfoPtr css,
790: ThotBool isHTML)
1.42 cvs 791: {
1.43 cvs 792: PresentationValue border;
793:
1.82 cvs 794: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 795: cssRule = ParseBorderStyle (cssRule, &border);
796: if (border.typed_data.unit != STYLE_UNIT_INVALID)
797: TtaSetStylePresentation (PRBorderTopStyle, element, tsch, context, border);
1.42 cvs 798: return (cssRule);
799: }
800:
801: /*----------------------------------------------------------------------
1.59 cvs 802: ParseCSSBorderStyleLeft: parse a CSS BorderStyleLeft
1.42 cvs 803: attribute string.
804: ----------------------------------------------------------------------*/
1.79 cvs 805: static char *ParseCSSBorderStyleLeft (Element element, PSchema tsch,
806: PresentationContext context,
807: char *cssRule, CSSInfoPtr css,
808: ThotBool isHTML)
1.42 cvs 809: {
1.43 cvs 810: PresentationValue border;
811:
1.82 cvs 812: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 813: cssRule = ParseBorderStyle (cssRule, &border);
814: if (border.typed_data.unit != STYLE_UNIT_INVALID)
815: TtaSetStylePresentation (PRBorderLeftStyle, element, tsch, context, border);
1.42 cvs 816: return (cssRule);
817: }
818:
819: /*----------------------------------------------------------------------
1.59 cvs 820: ParseCSSBorderStyleBottom: parse a CSS BorderStyleBottom
1.1 cvs 821: attribute string.
822: ----------------------------------------------------------------------*/
1.79 cvs 823: static char *ParseCSSBorderStyleBottom (Element element, PSchema tsch,
824: PresentationContext context,
825: char *cssRule, CSSInfoPtr css,
826: ThotBool isHTML)
1.1 cvs 827: {
1.43 cvs 828: PresentationValue border;
829:
1.82 cvs 830: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 831: cssRule = ParseBorderStyle (cssRule, &border);
832: if (border.typed_data.unit != STYLE_UNIT_INVALID)
833: TtaSetStylePresentation (PRBorderBottomStyle, element, tsch, context, border);
1.1 cvs 834: return (cssRule);
835: }
836:
837: /*----------------------------------------------------------------------
1.59 cvs 838: ParseCSSBorderStyleRight: parse a CSS BorderStyleRight
1.1 cvs 839: attribute string.
840: ----------------------------------------------------------------------*/
1.79 cvs 841: static char *ParseCSSBorderStyleRight (Element element, PSchema tsch,
842: PresentationContext context,
843: char *cssRule, CSSInfoPtr css,
844: ThotBool isHTML)
1.1 cvs 845: {
1.43 cvs 846: PresentationValue border;
847:
1.82 cvs 848: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 849: cssRule = ParseBorderStyle (cssRule, &border);
850: if (border.typed_data.unit != STYLE_UNIT_INVALID)
851: TtaSetStylePresentation (PRBorderRightStyle, element, tsch, context, border);
1.1 cvs 852: return (cssRule);
853: }
854:
855: /*----------------------------------------------------------------------
1.59 cvs 856: ParseCSSBorderStyleStyle: parse a CSS border-style
1.1 cvs 857: attribute string.
858: ----------------------------------------------------------------------*/
1.79 cvs 859: static char *ParseCSSBorderStyle (Element element, PSchema tsch,
860: PresentationContext context,
861: char *cssRule, CSSInfoPtr css,
862: ThotBool isHTML)
1.1 cvs 863: {
1.79 cvs 864: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 865: int skippedNL;
1.42 cvs 866:
1.82 cvs 867: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 868: /* First parse Border-Top */
1.43 cvs 869: ptrR = ParseCSSBorderStyleTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 870: ptrR = SkipBlanksAndComments (ptrR);
871: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 872: {
1.93 vatton 873: skippedNL = NewLineSkipped;
1.42 cvs 874: cssRule = ptrR;
875: /* apply the Border-Top to all */
1.43 cvs 876: ptrR = ParseCSSBorderStyleRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 877: NewLineSkipped = skippedNL;
1.43 cvs 878: ptrR = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 879: NewLineSkipped = skippedNL;
1.43 cvs 880: ptrR = ParseCSSBorderStyleLeft (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 881: }
882: else
883: {
884: /* parse Border-Right */
1.43 cvs 885: ptrB = ParseCSSBorderStyleRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 886: ptrB = SkipBlanksAndComments (ptrB);
887: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 888: {
1.93 vatton 889: skippedNL = NewLineSkipped;
1.42 cvs 890: cssRule = ptrB;
891: /* apply the Border-Top to Border-Bottom */
1.43 cvs 892: ptrB = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 893: NewLineSkipped = skippedNL;
1.42 cvs 894: /* apply the Border-Right to Border-Left */
1.43 cvs 895: ptrB = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 896: }
897: else
898: {
899: /* parse Border-Bottom */
1.43 cvs 900: ptrL = ParseCSSBorderStyleBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 901: ptrL = SkipBlanksAndComments (ptrL);
902: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 903: {
904: cssRule = ptrL;
905: /* apply the Border-Right to Border-Left */
1.43 cvs 906: ptrL = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 907: }
908: else
909: /* parse Border-Left */
1.43 cvs 910: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 911: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 912: }
913: }
914: return (cssRule);
915: }
916:
917: /*----------------------------------------------------------------------
1.59 cvs 918: ParseCSSBorderTop: parse a CSS BorderTop
1.42 cvs 919: attribute string.
920: ----------------------------------------------------------------------*/
1.79 cvs 921: static char *ParseCSSBorderTop (Element element, PSchema tsch,
922: PresentationContext context, char *cssRule,
923: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 924: {
1.79 cvs 925: char *ptr;
1.43 cvs 926:
1.82 cvs 927: cssRule = SkipBlanksAndComments (cssRule);
928: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 929: {
930: ptr = cssRule;
931: cssRule = ParseCSSBorderStyleTop (element, tsch, context, cssRule, css, isHTML);
932: if (ptr == cssRule)
933: cssRule = ParseCSSBorderTopWidth (element, tsch, context, cssRule, css, isHTML);
934: if (ptr == cssRule)
935: cssRule = ParseCSSBorderColorTop (element, tsch, context, cssRule, css, isHTML);
936: if (ptr == cssRule)
937: /* rule not found */
1.99 vatton 938: cssRule = SkipValue (cssRule, TRUE);
1.82 cvs 939: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 940: }
1.42 cvs 941: return (cssRule);
942: }
943:
944: /*----------------------------------------------------------------------
1.59 cvs 945: ParseCSSBorderLeft: parse a CSS BorderLeft
1.42 cvs 946: attribute string.
947: ----------------------------------------------------------------------*/
1.79 cvs 948: static char *ParseCSSBorderLeft (Element element, PSchema tsch,
949: PresentationContext context, char *cssRule,
950: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 951: {
1.79 cvs 952: char *ptr;
1.43 cvs 953:
1.82 cvs 954: cssRule = SkipBlanksAndComments (cssRule);
955: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 956: {
957: ptr = cssRule;
958: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, cssRule, css, isHTML);
959: if (ptr == cssRule)
960: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, cssRule, css, isHTML);
961: if (ptr == cssRule)
962: cssRule = ParseCSSBorderColorLeft (element, tsch, context, cssRule, css, isHTML);
963: if (ptr == cssRule)
964: /* rule not found */
1.99 vatton 965: cssRule = SkipValue (cssRule, TRUE);
1.82 cvs 966: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 967: }
1.1 cvs 968: return (cssRule);
969: }
970:
971: /*----------------------------------------------------------------------
1.59 cvs 972: ParseCSSBorderBottom: parse a CSS BorderBottom
1.1 cvs 973: attribute string.
974: ----------------------------------------------------------------------*/
1.79 cvs 975: static char *ParseCSSBorderBottom (Element element, PSchema tsch,
976: PresentationContext context, char *cssRule,
977: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 978: {
1.79 cvs 979: char *ptr;
1.43 cvs 980:
1.82 cvs 981: cssRule = SkipBlanksAndComments (cssRule);
982: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 983: {
984: ptr = cssRule;
985: cssRule = ParseCSSBorderStyleBottom (element, tsch, context, cssRule, css, isHTML);
986: if (ptr == cssRule)
987: cssRule = ParseCSSBorderBottomWidth (element, tsch, context, cssRule, css, isHTML);
988: if (ptr == cssRule)
989: cssRule = ParseCSSBorderColorBottom (element, tsch, context, cssRule, css, isHTML);
990: if (ptr == cssRule)
991: /* rule not found */
1.99 vatton 992: cssRule = SkipValue (cssRule, TRUE);
1.82 cvs 993: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 994: }
1.1 cvs 995: return (cssRule);
996: }
997:
998: /*----------------------------------------------------------------------
1.59 cvs 999: ParseCSSBorderRight: parse a CSS BorderRight
1.1 cvs 1000: attribute string.
1001: ----------------------------------------------------------------------*/
1.79 cvs 1002: static char *ParseCSSBorderRight (Element element, PSchema tsch,
1003: PresentationContext context, char *cssRule,
1004: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1005: {
1.79 cvs 1006: char *ptr;
1.43 cvs 1007:
1.82 cvs 1008: cssRule = SkipBlanksAndComments (cssRule);
1009: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1010: {
1011: ptr = cssRule;
1012: cssRule = ParseCSSBorderStyleRight (element, tsch, context, cssRule, css, isHTML);
1013: if (ptr == cssRule)
1014: cssRule = ParseCSSBorderRightWidth (element, tsch, context, cssRule, css, isHTML);
1015: if (ptr == cssRule)
1016: cssRule = ParseCSSBorderColorRight (element, tsch, context, cssRule, css, isHTML);
1017: if (ptr == cssRule)
1018: /* rule not found */
1.99 vatton 1019: cssRule = SkipValue (cssRule, TRUE);
1.82 cvs 1020: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1021: }
1.1 cvs 1022: return (cssRule);
1023: }
1024:
1025: /*----------------------------------------------------------------------
1.59 cvs 1026: ParseCSSBorder: parse a CSS border
1.42 cvs 1027: attribute string.
1028: ----------------------------------------------------------------------*/
1.79 cvs 1029: static char *ParseCSSBorder (Element element, PSchema tsch,
1030: PresentationContext context, char *cssRule,
1031: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1032: {
1.79 cvs 1033: char *ptrT, *ptrR;
1.93 vatton 1034: int skippedNL;
1.42 cvs 1035:
1.82 cvs 1036: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 1037: /* First parse Border-Top */
1038: ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 1039: ptrR = SkipBlanksAndComments (ptrR);
1040: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 1041: {
1.93 vatton 1042: skippedNL = NewLineSkipped;
1.42 cvs 1043: cssRule = ptrR;
1044: /* apply the Border-Top to all */
1045: ptrR = ParseCSSBorderRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 1046: NewLineSkipped = skippedNL;
1.42 cvs 1047: ptrR = ParseCSSBorderBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 1048: NewLineSkipped = skippedNL;
1.42 cvs 1049: ptrR = ParseCSSBorderLeft (element, tsch, context, ptrT, css, isHTML);
1050: }
1051: return (cssRule);
1052: }
1053:
1054: /*----------------------------------------------------------------------
1.59 cvs 1055: ParseCSSClear: parse a CSS clear attribute string
1.1 cvs 1056: ----------------------------------------------------------------------*/
1.79 cvs 1057: static char *ParseCSSClear (Element element, PSchema tsch,
1058: PresentationContext context, char *cssRule,
1059: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1060: {
1.99 vatton 1061: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1062: return (cssRule);
1063: }
1064:
1065: /*----------------------------------------------------------------------
1.59 cvs 1066: ParseCSSDisplay: parse a CSS display attribute string
1.1 cvs 1067: ----------------------------------------------------------------------*/
1.79 cvs 1068: static char *ParseCSSDisplay (Element element, PSchema tsch,
1069: PresentationContext context, char *cssRule,
1070: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1071: {
1072: PresentationValue pval;
1073:
1074: pval.typed_data.unit = STYLE_UNIT_REL;
1075: pval.typed_data.real = FALSE;
1.82 cvs 1076: cssRule = SkipBlanksAndComments (cssRule);
1077: if (!strncasecmp (cssRule, "block", 5))
1.1 cvs 1078: {
1.79 cvs 1079: /* pval.typed_data.value = STYLE_INLINE;
1.93 vatton 1080: TtaSetStylePresentation (PRLine, element, tsch, context, pval); */
1081: cssRule = SkipWord (cssRule);
1.1 cvs 1082: }
1.82 cvs 1083: else if (!strncasecmp (cssRule, "inline", 6))
1.1 cvs 1084: {
1.79 cvs 1085: /* pval.typed_data.value = STYLE_INLINE;
1.93 vatton 1086: TtaSetStylePresentation (PRLine, element, tsch, context, pval); */
1087: cssRule = SkipWord (cssRule);
1.1 cvs 1088: }
1.82 cvs 1089: else if (!strncasecmp (cssRule, "none", 4))
1.1 cvs 1090: {
1091: pval.typed_data.value = STYLE_HIDE;
1092: TtaSetStylePresentation (PRVisibility, element, tsch, context, pval);
1093: cssRule = SkipWord (cssRule);
1094: }
1.82 cvs 1095: else if (!strncasecmp (cssRule, "list-item", 9))
1.99 vatton 1096: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1097: else
1.86 cvs 1098: CSSParseError ("Invalid display value", cssRule);
1.34 cvs 1099:
1.1 cvs 1100: return (cssRule);
1101: }
1102:
1103: /*----------------------------------------------------------------------
1.59 cvs 1104: ParseCSSFloat: parse a CSS float attribute string
1.1 cvs 1105: ----------------------------------------------------------------------*/
1.79 cvs 1106: static char *ParseCSSFloat (Element element, PSchema tsch,
1107: PresentationContext context, char *cssRule,
1108: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1109: {
1.99 vatton 1110: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1111: return (cssRule);
1112: }
1113:
1114: /*----------------------------------------------------------------------
1.59 cvs 1115: ParseCSSLetterSpacing: parse a CSS letter-spacing
1.1 cvs 1116: attribute string.
1117: ----------------------------------------------------------------------*/
1.79 cvs 1118: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
1119: PresentationContext context, char *cssRule,
1120: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1121: {
1.99 vatton 1122: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1123: return (cssRule);
1124: }
1125:
1126: /*----------------------------------------------------------------------
1.59 cvs 1127: ParseCSSListStyleType: parse a CSS list-style-type
1.1 cvs 1128: attribute string.
1129: ----------------------------------------------------------------------*/
1.79 cvs 1130: static char *ParseCSSListStyleType (Element element, PSchema tsch,
1131: PresentationContext context, char *cssRule,
1132: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1133: {
1.99 vatton 1134: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1135: return (cssRule);
1136: }
1137:
1138: /*----------------------------------------------------------------------
1.59 cvs 1139: ParseCSSListStyleImage: parse a CSS list-style-image
1.1 cvs 1140: attribute string.
1141: ----------------------------------------------------------------------*/
1.79 cvs 1142: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1143: PresentationContext context, char *cssRule,
1144: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1145: {
1.99 vatton 1146: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1147: return (cssRule);
1148: }
1149:
1150: /*----------------------------------------------------------------------
1.59 cvs 1151: ParseCSSListStylePosition: parse a CSS list-style-position
1.1 cvs 1152: attribute string.
1153: ----------------------------------------------------------------------*/
1.79 cvs 1154: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
1155: PresentationContext context,
1156: char *cssRule, CSSInfoPtr css,
1157: ThotBool isHTML)
1.1 cvs 1158: {
1.99 vatton 1159: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1160: return (cssRule);
1161: }
1162:
1163: /*----------------------------------------------------------------------
1.59 cvs 1164: ParseCSSListStyle: parse a CSS list-style
1.1 cvs 1165: attribute string.
1166: ----------------------------------------------------------------------*/
1.79 cvs 1167: static char *ParseCSSListStyle (Element element, PSchema tsch,
1168: PresentationContext context, char *cssRule,
1169: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1170: {
1.99 vatton 1171: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1172: return (cssRule);
1173: }
1174:
1175: /*----------------------------------------------------------------------
1.59 cvs 1176: ParseCSSTextAlign: parse a CSS text-align
1.1 cvs 1177: attribute string.
1178: ----------------------------------------------------------------------*/
1.79 cvs 1179: static char *ParseCSSTextAlign (Element element, PSchema tsch,
1180: PresentationContext context, char *cssRule,
1181: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1182: {
1183: PresentationValue align;
1184:
1185: align.typed_data.value = 0;
1186: align.typed_data.unit = STYLE_UNIT_REL;
1187: align.typed_data.real = FALSE;
1188:
1.82 cvs 1189: cssRule = SkipBlanksAndComments (cssRule);
1190: if (!strncasecmp (cssRule, "left", 4))
1.1 cvs 1191: {
1192: align.typed_data.value = AdjustLeft;
1193: cssRule = SkipWord (cssRule);
1194: }
1.82 cvs 1195: else if (!strncasecmp (cssRule, "right", 5))
1.1 cvs 1196: {
1197: align.typed_data.value = AdjustRight;
1198: cssRule = SkipWord (cssRule);
1199: }
1.82 cvs 1200: else if (!strncasecmp (cssRule, "center", 6))
1.1 cvs 1201: {
1202: align.typed_data.value = Centered;
1203: cssRule = SkipWord (cssRule);
1204: }
1.82 cvs 1205: else if (!strncasecmp (cssRule, "justify", 7))
1.1 cvs 1206: {
1.81 cvs 1207: align.typed_data.value = Justify;
1.1 cvs 1208: cssRule = SkipWord (cssRule);
1209: }
1210: else
1211: {
1.86 cvs 1212: CSSParseError ("Invalid align value", cssRule);
1.1 cvs 1213: return (cssRule);
1214: }
1215:
1216: /*
1217: * install the new presentation.
1218: */
1219: if (align.typed_data.value)
1.81 cvs 1220: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
1.1 cvs 1221: return (cssRule);
1222: }
1223:
1224: /*----------------------------------------------------------------------
1.112 quint 1225: ParseCSSDirection: parse a CSS direction property
1226: ----------------------------------------------------------------------*/
1227: static char *ParseCSSDirection (Element element, PSchema tsch,
1228: PresentationContext context, char *cssRule,
1229: CSSInfoPtr css, ThotBool isHTML)
1230: {
1231: PresentationValue direction;
1232:
1233: direction.typed_data.value = 0;
1234: direction.typed_data.unit = STYLE_UNIT_REL;
1235: direction.typed_data.real = FALSE;
1236:
1237: cssRule = SkipBlanksAndComments (cssRule);
1238: if (!strncasecmp (cssRule, "ltr", 3))
1239: {
1240: direction.typed_data.value = STYLE_LEFTTORIGHT;
1241: cssRule = SkipWord (cssRule);
1242: }
1243: else if (!strncasecmp (cssRule, "rtl", 3))
1244: {
1245: direction.typed_data.value = STYLE_RIGHTTOLEFT;
1246: cssRule = SkipWord (cssRule);
1247: }
1248: else if (!strncasecmp (cssRule, "inherit", 7))
1249: {
1250: /* not implemented */
1251: cssRule = SkipWord (cssRule);
1252: return (cssRule);
1253: }
1254: else
1255: {
1256: CSSParseError ("Invalid direction value", cssRule);
1257: return (cssRule);
1258: }
1259:
1260: /*
1261: * install the new presentation.
1262: */
1263: if (direction.typed_data.value)
1264: TtaSetStylePresentation (PRDirection, element, tsch, context, direction);
1265: return (cssRule);
1266: }
1267:
1268: /*----------------------------------------------------------------------
1.113 quint 1269: ParseCSSUnicodeBidi: parse a CSS unicode-bidi property
1270: ----------------------------------------------------------------------*/
1271: static char *ParseCSSUnicodeBidi (Element element, PSchema tsch,
1272: PresentationContext context, char *cssRule,
1273: CSSInfoPtr css, ThotBool isHTML)
1274: {
1275: PresentationValue bidi;
1276:
1277: bidi.typed_data.value = 0;
1278: bidi.typed_data.unit = STYLE_UNIT_REL;
1279: bidi.typed_data.real = FALSE;
1280:
1281: cssRule = SkipBlanksAndComments (cssRule);
1282: if (!strncasecmp (cssRule, "normal", 6))
1283: {
1284: bidi.typed_data.value = STYLE_BIDINORMAL;
1285: cssRule = SkipWord (cssRule);
1286: }
1287: else if (!strncasecmp (cssRule, "embed", 5))
1288: {
1289: bidi.typed_data.value = STYLE_BIDIEMBED;
1290: cssRule = SkipWord (cssRule);
1291: }
1292: else if (!strncasecmp (cssRule, "override", 8))
1293: {
1294: bidi.typed_data.value = STYLE_BIDIOVERRIDE;
1295: cssRule = SkipWord (cssRule);
1296: }
1297: else if (!strncasecmp (cssRule, "inherit", 7))
1298: {
1299: /* not implemented */
1300: cssRule = SkipWord (cssRule);
1301: return (cssRule);
1302: }
1303: else
1304: {
1305: CSSParseError ("Invalid unicode-bidi value", cssRule);
1306: return (cssRule);
1307: }
1308:
1309: /*
1310: * install the new presentation.
1311: */
1312: if (bidi.typed_data.value)
1313: TtaSetStylePresentation (PRUnicodeBidi, element, tsch, context, bidi);
1314: return (cssRule);
1315: }
1316:
1317: /*----------------------------------------------------------------------
1.59 cvs 1318: ParseCSSTextIndent: parse a CSS text-indent
1.1 cvs 1319: attribute string.
1320: ----------------------------------------------------------------------*/
1.79 cvs 1321: static char *ParseCSSTextIndent (Element element, PSchema tsch,
1322: PresentationContext context, char *cssRule,
1323: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1324: {
1325: PresentationValue pval;
1326:
1.82 cvs 1327: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1328: cssRule = ParseCSSUnit (cssRule, &pval);
1329: if (pval.typed_data.unit == STYLE_UNIT_INVALID)
1330: return (cssRule);
1331: /* install the attribute */
1332: TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
1333: return (cssRule);
1334: }
1335:
1336: /*----------------------------------------------------------------------
1.59 cvs 1337: ParseCSSTextTransform: parse a CSS text-transform
1.1 cvs 1338: attribute string.
1339: ----------------------------------------------------------------------*/
1.79 cvs 1340: static char *ParseCSSTextTransform (Element element, PSchema tsch,
1341: PresentationContext context, char *cssRule,
1342: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1343: {
1.99 vatton 1344: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1345: return (cssRule);
1346: }
1347:
1348: /*----------------------------------------------------------------------
1.59 cvs 1349: ParseCSSVerticalAlign: parse a CSS vertical-align
1.1 cvs 1350: attribute string.
1351: ----------------------------------------------------------------------*/
1.79 cvs 1352: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
1353: PresentationContext context, char *cssRule,
1354: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1355: {
1.99 vatton 1356: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1357: return (cssRule);
1358: }
1359:
1360: /*----------------------------------------------------------------------
1.59 cvs 1361: ParseCSSWhiteSpace: parse a CSS white-space
1.1 cvs 1362: attribute string.
1363: ----------------------------------------------------------------------*/
1.79 cvs 1364: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
1365: PresentationContext context, char *cssRule,
1366: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1367: {
1.82 cvs 1368: cssRule = SkipBlanksAndComments (cssRule);
1369: if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1370: cssRule = SkipWord (cssRule);
1.82 cvs 1371: else if (!strncasecmp (cssRule, "pre", 3))
1.1 cvs 1372: cssRule = SkipWord (cssRule);
1373: else
1374: return (cssRule);
1375: return (cssRule);
1376: }
1377:
1378: /*----------------------------------------------------------------------
1.59 cvs 1379: ParseCSSWordSpacing: parse a CSS word-spacing
1.1 cvs 1380: attribute string.
1381: ----------------------------------------------------------------------*/
1.79 cvs 1382: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
1383: PresentationContext context, char *cssRule,
1384: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1385: {
1.99 vatton 1386: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1387: return (cssRule);
1388: }
1389:
1390: /*----------------------------------------------------------------------
1.59 cvs 1391: ParseCSSLineSpacing: parse a CSS font leading string
1.25 cvs 1392: we expect the input string describing the attribute to be
1393: value% or value
1394: ----------------------------------------------------------------------*/
1.79 cvs 1395: static char *ParseCSSLineSpacing (Element element, PSchema tsch,
1396: PresentationContext context, char *cssRule,
1397: CSSInfoPtr css, ThotBool isHTML)
1.25 cvs 1398: {
1399: PresentationValue lead;
1400:
1401: cssRule = ParseCSSUnit (cssRule, &lead);
1.93 vatton 1402: if (lead.typed_data.unit != STYLE_UNIT_INVALID)
1403: /* install the new presentation */
1404: TtaSetStylePresentation (PRLineSpacing, element, tsch, context, lead);
1.25 cvs 1405: return (cssRule);
1406: }
1407:
1408: /*----------------------------------------------------------------------
1.59 cvs 1409: ParseCSSFontSize: parse a CSS font size attr string
1.1 cvs 1410: we expect the input string describing the attribute to be
1411: xx-small, x-small, small, medium, large, x-large, xx-large
1412: or an absolute size, or an imcrement relative to the parent
1413: ----------------------------------------------------------------------*/
1.79 cvs 1414: static char *ParseCSSFontSize (Element element, PSchema tsch,
1415: PresentationContext context, char *cssRule,
1416: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1417: {
1418: PresentationValue pval;
1.79 cvs 1419: char *ptr = NULL;
1.14 cvs 1420: ThotBool real;
1.1 cvs 1421:
1422: pval.typed_data.real = FALSE;
1.82 cvs 1423: cssRule = SkipBlanksAndComments (cssRule);
1424: if (!strncasecmp (cssRule, "larger", 6))
1.1 cvs 1425: {
1426: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1427: pval.typed_data.value = 130;
1428: cssRule = SkipWord (cssRule);
1429: }
1.82 cvs 1430: else if (!strncasecmp (cssRule, "smaller", 7))
1.1 cvs 1431: {
1432: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1433: pval.typed_data.value = 80;
1434: cssRule = SkipWord (cssRule);
1435: }
1.82 cvs 1436: else if (!strncasecmp (cssRule, "xx-small", 8))
1.1 cvs 1437: {
1438: pval.typed_data.unit = STYLE_UNIT_REL;
1439: pval.typed_data.value = 1;
1440: cssRule = SkipWord (cssRule);
1441: }
1.82 cvs 1442: else if (!strncasecmp (cssRule, "x-small", 7))
1.1 cvs 1443: {
1444: pval.typed_data.unit = STYLE_UNIT_REL;
1445: pval.typed_data.value = 2;
1446: cssRule = SkipWord (cssRule);
1447: }
1.82 cvs 1448: else if (!strncasecmp (cssRule, "small", 5))
1.1 cvs 1449: {
1450: pval.typed_data.unit = STYLE_UNIT_REL;
1451: pval.typed_data.value = 3;
1452: cssRule = SkipWord (cssRule);
1453: }
1.82 cvs 1454: else if (!strncasecmp (cssRule, "medium", 6))
1.1 cvs 1455: {
1456: pval.typed_data.unit = STYLE_UNIT_REL;
1457: pval.typed_data.value = 4;
1458: cssRule = SkipWord (cssRule);
1459: }
1.82 cvs 1460: else if (!strncasecmp (cssRule, "large", 5))
1.1 cvs 1461: {
1462: pval.typed_data.unit = STYLE_UNIT_REL;
1463: pval.typed_data.value = 5;
1464: cssRule = SkipWord (cssRule);
1465: }
1.82 cvs 1466: else if (!strncasecmp (cssRule, "x-large", 7))
1.1 cvs 1467: {
1468: pval.typed_data.unit = STYLE_UNIT_REL;
1469: pval.typed_data.value = 6;
1470: cssRule = SkipWord (cssRule);
1471: }
1.82 cvs 1472: else if (!strncasecmp (cssRule, "xx-large", 8))
1.1 cvs 1473: {
1474: pval.typed_data.unit = STYLE_UNIT_REL;
1475: pval.typed_data.value = 7;
1476: cssRule = SkipWord (cssRule);
1477: }
1478: else
1479: {
1.25 cvs 1480: /* look for a '/' within the current cssRule */
1.82 cvs 1481: ptr = strchr (cssRule, '/');
1.25 cvs 1482: if (ptr != NULL)
1483: {
1484: /* keep the line spacing rule */
1.82 cvs 1485: ptr[0] = EOS;
1.25 cvs 1486: ptr = &ptr[1];
1487: }
1.1 cvs 1488: cssRule = ParseCSSUnit (cssRule, &pval);
1489: if (pval.typed_data.unit == STYLE_UNIT_INVALID ||
1490: pval.typed_data.value < 0)
1491: return (cssRule);
1492: if (pval.typed_data.unit == STYLE_UNIT_REL && pval.typed_data.value > 0)
1493: /* CSS relative sizes have to be higher than Thot ones */
1494: pval.typed_data.value += 1;
1495: else
1496: {
1497: real = pval.typed_data.real;
1498: if (pval.typed_data.unit == STYLE_UNIT_EM)
1499: {
1500: if (real)
1501: {
1502: pval.typed_data.value /= 10;
1.11 cvs 1503: pval.typed_data.real = FALSE;
1.1 cvs 1504: real = FALSE;
1505: }
1506: else
1507: pval.typed_data.value *= 100;
1508: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1509: }
1510: }
1.25 cvs 1511:
1.1 cvs 1512: }
1513:
1.25 cvs 1514: /* install the presentation style */
1.1 cvs 1515: TtaSetStylePresentation (PRSize, element, tsch, context, pval);
1.25 cvs 1516:
1517: if (ptr != NULL)
1518: cssRule = ParseCSSLineSpacing (element, tsch, context, ptr, css, isHTML);
1.1 cvs 1519: return (cssRule);
1520: }
1521:
1522: /*----------------------------------------------------------------------
1.59 cvs 1523: ParseCSSFontFamily: parse a CSS font family string
1.1 cvs 1524: we expect the input string describing the attribute to be
1525: a common generic font style name
1526: ----------------------------------------------------------------------*/
1.79 cvs 1527: static char *ParseCSSFontFamily (Element element, PSchema tsch,
1528: PresentationContext context, char *cssRule,
1529: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1530: {
1531: PresentationValue font;
1.79 cvs 1532: char quoteChar;
1.1 cvs 1533:
1534: font.typed_data.value = 0;
1535: font.typed_data.unit = STYLE_UNIT_REL;
1536: font.typed_data.real = FALSE;
1.82 cvs 1537: cssRule = SkipBlanksAndComments (cssRule);
1538: if (*cssRule == '"' || *cssRule == '\'')
1.1 cvs 1539: {
1540: quoteChar = *cssRule;
1541: cssRule++;
1542: }
1543: else
1.82 cvs 1544: quoteChar = EOS;
1.1 cvs 1545:
1.92 cvs 1546: if (!strncasecmp (cssRule, "times", 5) &&
1547: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 1548: {
1.1 cvs 1549: font.typed_data.value = STYLE_FONT_TIMES;
1.86 cvs 1550: cssRule += 5;
1551: }
1.92 cvs 1552: else if (!strncasecmp (cssRule, "serif", 5) &&
1553: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 1554: {
1.1 cvs 1555: font.typed_data.value = STYLE_FONT_TIMES;
1.86 cvs 1556: cssRule += 5;
1.92 cvs 1557: if (quoteChar != EOS)
1558: cssRule++;
1.86 cvs 1559: }
1.92 cvs 1560: else if (!strncasecmp (cssRule, "helvetica", 9) &&
1561: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 1562: {
1563: font.typed_data.value = STYLE_FONT_HELVETICA;
1564: cssRule += 9;
1.92 cvs 1565: if (quoteChar != EOS)
1566: cssRule++;
1.86 cvs 1567: }
1.92 cvs 1568: else if (!strncasecmp (cssRule, "verdana", 7) &&
1569: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 1570: {
1.1 cvs 1571: font.typed_data.value = STYLE_FONT_HELVETICA;
1.86 cvs 1572: cssRule += 7;
1.92 cvs 1573: if (quoteChar != EOS)
1574: cssRule++;
1.86 cvs 1575: }
1.92 cvs 1576: else if (!strncasecmp (cssRule, "sans-serif", 10) &&
1577: (quoteChar == EOS || quoteChar == cssRule[10]))
1.86 cvs 1578: {
1.1 cvs 1579: font.typed_data.value = STYLE_FONT_HELVETICA;
1.86 cvs 1580: cssRule += 10;
1.92 cvs 1581: if (quoteChar != EOS)
1582: cssRule++;
1.86 cvs 1583: }
1.92 cvs 1584: else if (!strncasecmp (cssRule, "courier", 7) &&
1585: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 1586: {
1.1 cvs 1587: font.typed_data.value = STYLE_FONT_COURIER;
1.86 cvs 1588: cssRule += 7;
1.92 cvs 1589: if (quoteChar != EOS)
1590: cssRule++;
1.86 cvs 1591: }
1.92 cvs 1592: else if (!strncasecmp (cssRule, "monospace", 9) &&
1593: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 1594: {
1.1 cvs 1595: font.typed_data.value = STYLE_FONT_COURIER;
1.86 cvs 1596: cssRule += 9;
1.92 cvs 1597: if (quoteChar != EOS)
1598: cssRule++;
1.86 cvs 1599: }
1.1 cvs 1600: else
1601: /* unknown font name. Skip it */
1602: {
1.92 cvs 1603: if (quoteChar != EOS)
1.54 cvs 1604: cssRule = SkipQuotedString (cssRule, quoteChar);
1.86 cvs 1605: else
1.1 cvs 1606: cssRule = SkipWord (cssRule);
1.82 cvs 1607: cssRule = SkipBlanksAndComments (cssRule);
1608: if (*cssRule == ',')
1.1 cvs 1609: {
1.86 cvs 1610: cssRule++;
1611: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1612: return (cssRule);
1.1 cvs 1613: }
1614: }
1615:
1616: if (font.typed_data.value != 0)
1617: {
1.93 vatton 1618: cssRule = SkipBlanksAndComments (cssRule);
1.99 vatton 1619: cssRule = SkipValue (cssRule, FALSE);
1.93 vatton 1620: /* install the new presentation */
1621: TtaSetStylePresentation (PRFont, element, tsch, context, font);
1.1 cvs 1622: }
1623: return (cssRule);
1624: }
1625:
1626: /*----------------------------------------------------------------------
1.59 cvs 1627: ParseCSSFontWeight: parse a CSS font weight string
1.1 cvs 1628: we expect the input string describing the attribute to be
1.20 cvs 1629: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 1630: ----------------------------------------------------------------------*/
1.79 cvs 1631: static char *ParseCSSFontWeight (Element element, PSchema tsch,
1632: PresentationContext context, char *cssRule,
1633: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1634: {
1.20 cvs 1635: PresentationValue weight;
1.1 cvs 1636:
1637: weight.typed_data.value = 0;
1638: weight.typed_data.unit = STYLE_UNIT_REL;
1639: weight.typed_data.real = FALSE;
1.82 cvs 1640: cssRule = SkipBlanksAndComments (cssRule);
1641: if (!strncasecmp (cssRule, "100", 3) && !isalpha (cssRule[3]))
1.1 cvs 1642: {
1643: weight.typed_data.value = -3;
1644: cssRule = SkipWord (cssRule);
1645: }
1.82 cvs 1646: else if (!strncasecmp (cssRule, "200", 3) && !isalpha (cssRule[3]))
1.1 cvs 1647: {
1648: weight.typed_data.value = -2;
1649: cssRule = SkipWord (cssRule);
1650: }
1.82 cvs 1651: else if (!strncasecmp (cssRule, "300", 3) && ! isalpha(cssRule[3]))
1.1 cvs 1652: {
1653: weight.typed_data.value = -1;
1654: cssRule = SkipWord (cssRule);
1655: }
1.82 cvs 1656: else if (!strncasecmp (cssRule, "normal", 6) || (!strncasecmp (cssRule, "400", 3) && !isalpha (cssRule[3])))
1.1 cvs 1657: {
1658: weight.typed_data.value = 0;
1659: cssRule = SkipWord (cssRule);
1660: }
1.82 cvs 1661: else if (!strncasecmp (cssRule, "500", 3) && !isalpha (cssRule[3]))
1.1 cvs 1662: {
1663: weight.typed_data.value = +1;
1664: cssRule = SkipWord (cssRule);
1665: }
1.82 cvs 1666: else if (!strncasecmp (cssRule, "600", 3) && !isalpha (cssRule[3]))
1.1 cvs 1667: {
1668: weight.typed_data.value = +2;
1669: cssRule = SkipWord (cssRule);
1670: }
1.82 cvs 1671: else if (!strncasecmp (cssRule, "bold", 4) || (!strncasecmp (cssRule, "700", 3) && !isalpha (cssRule[3])))
1.1 cvs 1672: {
1673: weight.typed_data.value = +3;
1674: cssRule = SkipWord (cssRule);
1675: }
1.82 cvs 1676: else if (!strncasecmp (cssRule, "800", 3) && !isalpha (cssRule[3]))
1.1 cvs 1677: {
1678: weight.typed_data.value = +4;
1679: cssRule = SkipWord (cssRule);
1680: }
1.82 cvs 1681: else if (!strncasecmp (cssRule, "900", 3) && !isalpha (cssRule[3]))
1.1 cvs 1682: {
1683: weight.typed_data.value = +5;
1684: cssRule = SkipWord (cssRule);
1685: }
1.82 cvs 1686: else if (!strncasecmp (cssRule, "inherit", 7) || !strncasecmp (cssRule, "bolder", 6) || !strncasecmp (cssRule, "lighter", 7))
1.1 cvs 1687: {
1688: /* not implemented */
1689: cssRule = SkipWord (cssRule);
1690: return (cssRule);
1691: }
1692: else
1693: return (cssRule);
1694:
1695: /*
1.20 cvs 1696: * Here we have to reduce since only two font weight values are supported
1.1 cvs 1697: * by the Thot presentation API.
1698: */
1.20 cvs 1699: if (weight.typed_data.value > 0)
1700: weight.typed_data.value = STYLE_WEIGHT_BOLD;
1701: else
1702: weight.typed_data.value = STYLE_WEIGHT_NORMAL;
1.1 cvs 1703:
1704: /* install the new presentation */
1.21 cvs 1705: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
1.1 cvs 1706: return (cssRule);
1707: }
1708:
1709: /*----------------------------------------------------------------------
1.59 cvs 1710: ParseCSSFontVariant: parse a CSS font variant string
1.1 cvs 1711: we expect the input string describing the attribute to be
1712: normal or small-caps
1713: ----------------------------------------------------------------------*/
1.79 cvs 1714: static char *ParseCSSFontVariant (Element element, PSchema tsch,
1715: PresentationContext context, char *cssRule,
1716: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1717: {
1718: PresentationValue style;
1719:
1720: style.typed_data.value = 0;
1721: style.typed_data.unit = STYLE_UNIT_REL;
1722: style.typed_data.real = FALSE;
1.82 cvs 1723: cssRule = SkipBlanksAndComments (cssRule);
1724: if (!strncasecmp (cssRule, "small-caps", 10))
1.1 cvs 1725: {
1726: /* Not supported yet */
1727: cssRule = SkipWord (cssRule);
1728: }
1.82 cvs 1729: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1730: {
1731: /* Not supported yet */
1732: cssRule = SkipWord (cssRule);
1733: }
1.82 cvs 1734: else if (!strncasecmp (cssRule, "inherit", 7))
1.1 cvs 1735: {
1736: /* Not supported yet */
1737: cssRule = SkipWord (cssRule);
1738: }
1739: else
1740: return (cssRule);
1741:
1742: return (cssRule);
1743: }
1744:
1745:
1746: /*----------------------------------------------------------------------
1.59 cvs 1747: ParseCSSFontStyle: parse a CSS font style string
1.1 cvs 1748: we expect the input string describing the attribute to be
1749: italic, oblique or normal
1750: ----------------------------------------------------------------------*/
1.79 cvs 1751: static char *ParseCSSFontStyle (Element element, PSchema tsch,
1752: PresentationContext context, char *cssRule,
1753: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1754: {
1755: PresentationValue style;
1756: PresentationValue size;
1757:
1758: style.typed_data.value = 0;
1759: style.typed_data.unit = STYLE_UNIT_REL;
1760: style.typed_data.real = FALSE;
1761: size.typed_data.value = 0;
1762: size.typed_data.unit = STYLE_UNIT_REL;
1763: size.typed_data.real = FALSE;
1.82 cvs 1764: cssRule = SkipBlanksAndComments (cssRule);
1765: if (!strncasecmp (cssRule, "italic", 6))
1.1 cvs 1766: {
1767: style.typed_data.value = STYLE_FONT_ITALICS;
1768: cssRule = SkipWord (cssRule);
1769: }
1.82 cvs 1770: else if (!strncasecmp (cssRule, "oblique", 7))
1.1 cvs 1771: {
1772: style.typed_data.value = STYLE_FONT_OBLIQUE;
1773: cssRule = SkipWord (cssRule);
1774: }
1.82 cvs 1775: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1776: {
1777: style.typed_data.value = STYLE_FONT_ROMAN;
1778: cssRule = SkipWord (cssRule);
1779: }
1.108 cvs 1780: else if (!strncasecmp (cssRule, "inherit", 7))
1781: {
1782: /* not implemented */
1783: cssRule = SkipWord (cssRule);
1784: return (cssRule);
1785: }
1.1 cvs 1786: else
1787: {
1788: /* invalid font style */
1.108 cvs 1789: return (cssRule);
1.1 cvs 1790: }
1791:
1792: /*
1793: * install the new presentation.
1794: */
1795: if (style.typed_data.value != 0)
1.20 cvs 1796: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.1 cvs 1797: if (size.typed_data.value != 0)
1798: {
1799: PresentationValue previous_size;
1800:
1801: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
1802: {
1803: /* !!!!!!!!!!!!!!!!!!!!!!!! Unite + relatif !!!!!!!!!!!!!!!! */
1804: size.typed_data.value += previous_size.typed_data.value;
1805: TtaSetStylePresentation (PRSize, element, tsch, context, size);
1806: }
1807: else
1808: {
1809: size.typed_data.value = 10;
1810: TtaSetStylePresentation (PRSize, element, tsch, context, size);
1811: }
1812: }
1813: return (cssRule);
1814: }
1815:
1816: /*----------------------------------------------------------------------
1.59 cvs 1817: ParseCSSFont: parse a CSS font attribute string
1818: we expect the input string describing the attribute to be
1819: !!!!!!
1.1 cvs 1820: ----------------------------------------------------------------------*/
1.79 cvs 1821: static char *ParseCSSFont (Element element, PSchema tsch,
1822: PresentationContext context, char *cssRule,
1823: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1824: {
1.79 cvs 1825: char *ptr;
1.93 vatton 1826: int skippedNL;
1.1 cvs 1827:
1.82 cvs 1828: cssRule = SkipBlanksAndComments (cssRule);
1829: if (!strncasecmp (cssRule, "caption", 7))
1.1 cvs 1830: ;
1.82 cvs 1831: else if (!strncasecmp (cssRule, "icon", 4))
1.1 cvs 1832: ;
1.82 cvs 1833: else if (!strncasecmp (cssRule, "menu", 4))
1.1 cvs 1834: ;
1.82 cvs 1835: else if (!strncasecmp (cssRule, "message-box", 11))
1.1 cvs 1836: ;
1.82 cvs 1837: else if (!strncasecmp (cssRule, "small-caption", 13))
1.1 cvs 1838: ;
1.82 cvs 1839: else if (!strncasecmp (cssRule, "status-bar", 10))
1.1 cvs 1840: ;
1841: else
1.43 cvs 1842: {
1.82 cvs 1843: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1844: {
1.72 cvs 1845: ptr = cssRule;
1.93 vatton 1846: skippedNL = NewLineSkipped;
1.72 cvs 1847: cssRule = ParseCSSFontStyle (element, tsch, context, cssRule, css, isHTML);
1848: if (ptr == cssRule)
1.93 vatton 1849: {
1850: NewLineSkipped = skippedNL;
1851: cssRule = ParseCSSFontVariant (element, tsch, context, cssRule, css, isHTML);
1852: }
1.72 cvs 1853: if (ptr == cssRule)
1.93 vatton 1854: {
1855: NewLineSkipped = skippedNL;
1856: cssRule = ParseCSSFontWeight (element, tsch, context, cssRule, css, isHTML);
1857: }
1.72 cvs 1858: if (ptr == cssRule)
1.93 vatton 1859: {
1860: NewLineSkipped = skippedNL;
1861: cssRule = ParseCSSFontSize (element, tsch, context, cssRule, css, isHTML);
1862: }
1.72 cvs 1863: if (ptr == cssRule)
1.93 vatton 1864: {
1865: NewLineSkipped = skippedNL;
1866: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1867: }
1.99 vatton 1868: if (ptr == cssRule)
1869: cssRule = SkipValue (cssRule, TRUE);
1.82 cvs 1870: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1871: }
1872: }
1873: return (cssRule);
1.1 cvs 1874: }
1875:
1876: /*----------------------------------------------------------------------
1.59 cvs 1877: ParseCSSTextDecoration: parse a CSS text decor string
1878: we expect the input string describing the attribute to be
1.109 cvs 1879: underline, overline, line-through, blink or none.
1.1 cvs 1880: ----------------------------------------------------------------------*/
1.79 cvs 1881: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
1882: PresentationContext context, char *cssRule,
1883: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1884: {
1885: PresentationValue decor;
1886:
1887: decor.typed_data.value = 0;
1888: decor.typed_data.unit = STYLE_UNIT_REL;
1889: decor.typed_data.real = FALSE;
1.82 cvs 1890: cssRule = SkipBlanksAndComments (cssRule);
1891: if (!strncasecmp (cssRule, "underline", strlen ("underline")))
1.1 cvs 1892: {
1893: decor.typed_data.value = Underline;
1894: cssRule = SkipWord (cssRule);
1895: }
1.82 cvs 1896: else if (!strncasecmp (cssRule, "overline", strlen ("overline")))
1.1 cvs 1897: {
1898: decor.typed_data.value = Overline;
1899: cssRule = SkipWord (cssRule);
1900: }
1.82 cvs 1901: else if (!strncasecmp (cssRule, "line-through", strlen ("line-through")))
1.1 cvs 1902: {
1903: decor.typed_data.value = CrossOut;
1904: cssRule = SkipWord (cssRule);
1905: }
1.82 cvs 1906: else if (!strncasecmp (cssRule, "blink", strlen ("blink")))
1.1 cvs 1907: {
1.109 cvs 1908: /* the blink text-decoration attribute is not supported */
1.1 cvs 1909: cssRule = SkipWord (cssRule);
1910: }
1.82 cvs 1911: else if (!strncasecmp (cssRule, "none", strlen ("none")))
1.1 cvs 1912: {
1913: decor.typed_data.value = NoUnderline;
1914: cssRule = SkipWord (cssRule);
1915: }
1916: else
1917: {
1.86 cvs 1918: CSSParseError ("Invalid text decoration", cssRule);
1.1 cvs 1919: return (cssRule);
1920: }
1921:
1922: /*
1923: * install the new presentation.
1924: */
1925: if (decor.typed_data.value)
1926: {
1927: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
1928: }
1929: return (cssRule);
1930: }
1931:
1932: /*----------------------------------------------------------------------
1.59 cvs 1933: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 1934: ----------------------------------------------------------------------*/
1.79 cvs 1935: static char *ParseCSSHeight (Element element, PSchema tsch,
1.93 vatton 1936: PresentationContext context, char *cssRule,
1937: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1938: {
1.93 vatton 1939: PresentationValue val;
1940:
1.82 cvs 1941: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1942: /* first parse the attribute string */
1.82 cvs 1943: if (!strcasecmp (cssRule, "auto"))
1.93 vatton 1944: cssRule = SkipWord (cssRule);
1945: else
1.1 cvs 1946: {
1.93 vatton 1947: cssRule = ParseCSSUnit (cssRule, &val);
1948: if (val.typed_data.unit != STYLE_UNIT_INVALID)
1949: /* install the new presentation */
1950: TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.1 cvs 1951: }
1952: return (cssRule);
1953: }
1954:
1955: /*----------------------------------------------------------------------
1.59 cvs 1956: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 1957: ----------------------------------------------------------------------*/
1.79 cvs 1958: static char *ParseCSSWidth (Element element, PSchema tsch,
1.78 cvs 1959: PresentationContext context,
1.79 cvs 1960: char *cssRule, CSSInfoPtr css,
1.78 cvs 1961: ThotBool isHTML)
1.1 cvs 1962: {
1.93 vatton 1963: PresentationValue val;
1964:
1.82 cvs 1965: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1966: /* first parse the attribute string */
1.82 cvs 1967: if (!strcasecmp (cssRule, "auto"))
1.93 vatton 1968: cssRule = SkipWord (cssRule);
1969: else
1.1 cvs 1970: {
1.93 vatton 1971: cssRule = ParseCSSUnit (cssRule, &val);
1972: if (val.typed_data.unit != STYLE_UNIT_INVALID)
1973: /* install the new presentation */
1974: TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.1 cvs 1975: }
1976: return (cssRule);
1977: }
1978:
1979: /*----------------------------------------------------------------------
1.59 cvs 1980: ParseCSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 1981: ----------------------------------------------------------------------*/
1.79 cvs 1982: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.78 cvs 1983: PresentationContext context,
1.79 cvs 1984: char *cssRule, CSSInfoPtr css,
1.78 cvs 1985: ThotBool isHTML)
1.1 cvs 1986: {
1987: PresentationValue margin;
1988:
1.82 cvs 1989: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1990: /* first parse the attribute string */
1991: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 1992: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1.98 vatton 1993: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
1.1 cvs 1994: return (cssRule);
1995: }
1996:
1997: /*----------------------------------------------------------------------
1.59 cvs 1998: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 1999: ----------------------------------------------------------------------*/
1.79 cvs 2000: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.78 cvs 2001: PresentationContext context,
1.79 cvs 2002: char *cssRule, CSSInfoPtr css,
1.78 cvs 2003: ThotBool isHTML)
1.1 cvs 2004: {
2005: PresentationValue margin;
2006:
1.82 cvs 2007: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2008: /* first parse the attribute string */
2009: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 2010: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
2011: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
1.1 cvs 2012: return (cssRule);
2013: }
2014:
2015: /*----------------------------------------------------------------------
1.59 cvs 2016: ParseCSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 2017: ----------------------------------------------------------------------*/
1.79 cvs 2018: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.78 cvs 2019: PresentationContext context,
1.79 cvs 2020: char *cssRule, CSSInfoPtr css,
1.78 cvs 2021: ThotBool isHTML)
1.1 cvs 2022: {
2023: PresentationValue margin;
2024:
1.82 cvs 2025: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2026: /* first parse the attribute string */
2027: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 2028: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1.98 vatton 2029: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
1.1 cvs 2030: return (cssRule);
2031: }
2032:
2033: /*----------------------------------------------------------------------
1.59 cvs 2034: ParseCSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 2035: ----------------------------------------------------------------------*/
1.79 cvs 2036: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.78 cvs 2037: PresentationContext context,
1.79 cvs 2038: char *cssRule, CSSInfoPtr css,
1.78 cvs 2039: ThotBool isHTML)
1.1 cvs 2040: {
2041: PresentationValue margin;
2042:
1.82 cvs 2043: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2044: /* first parse the attribute string */
2045: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 2046: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
2047: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
1.1 cvs 2048: return (cssRule);
2049: }
2050:
2051: /*----------------------------------------------------------------------
1.59 cvs 2052: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 2053: ----------------------------------------------------------------------*/
1.79 cvs 2054: static char *ParseCSSMargin (Element element, PSchema tsch,
1.78 cvs 2055: PresentationContext context,
1.79 cvs 2056: char *cssRule, CSSInfoPtr css,
1.78 cvs 2057: ThotBool isHTML)
1.1 cvs 2058: {
1.79 cvs 2059: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2060: int skippedNL;
1.1 cvs 2061:
1.82 cvs 2062: ptrT = SkipBlanksAndComments (cssRule);
1.1 cvs 2063: /* First parse Margin-Top */
2064: ptrR = ParseCSSMarginTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2065: ptrR = SkipBlanksAndComments (ptrR);
2066: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.1 cvs 2067: {
1.93 vatton 2068: skippedNL = NewLineSkipped;
1.1 cvs 2069: cssRule = ptrR;
2070: /* apply the Margin-Top to all */
2071: ptrR = ParseCSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2072: NewLineSkipped = skippedNL;
1.1 cvs 2073: ptrR = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2074: NewLineSkipped = skippedNL;
1.1 cvs 2075: ptrR = ParseCSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
2076: }
2077: else
2078: {
2079: /* parse Margin-Right */
2080: ptrB = ParseCSSMarginRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2081: ptrB = SkipBlanksAndComments (ptrB);
2082: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.1 cvs 2083: {
1.93 vatton 2084: skippedNL = NewLineSkipped;
1.1 cvs 2085: cssRule = ptrB;
2086: /* apply the Margin-Top to Margin-Bottom */
2087: ptrB = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2088: NewLineSkipped = skippedNL;
1.1 cvs 2089: /* apply the Margin-Right to Margin-Left */
2090: ptrB = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2091: }
2092: else
2093: {
2094: /* parse Margin-Bottom */
2095: ptrL = ParseCSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2096: ptrL = SkipBlanksAndComments (ptrL);
2097: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.1 cvs 2098: {
2099: cssRule = ptrL;
2100: /* apply the Margin-Right to Margin-Left */
2101: ptrL = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2102: }
2103: else
2104: /* parse Margin-Left */
2105: cssRule = ParseCSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2106: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2107: }
2108: }
2109: return (cssRule);
2110: }
2111:
2112: /*----------------------------------------------------------------------
1.59 cvs 2113: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 2114: ----------------------------------------------------------------------*/
1.79 cvs 2115: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.78 cvs 2116: PresentationContext context,
1.79 cvs 2117: char *cssRule, CSSInfoPtr css,
1.78 cvs 2118: ThotBool isHTML)
1.1 cvs 2119: {
1.43 cvs 2120: PresentationValue padding;
2121:
1.82 cvs 2122: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2123: /* first parse the attribute string */
2124: cssRule = ParseCSSUnit (cssRule, &padding);
2125: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
2126: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
1.1 cvs 2127: return (cssRule);
2128: }
2129:
2130: /*----------------------------------------------------------------------
1.59 cvs 2131: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 2132: ----------------------------------------------------------------------*/
1.79 cvs 2133: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.78 cvs 2134: PresentationContext context,
1.79 cvs 2135: char *cssRule, CSSInfoPtr css,
1.78 cvs 2136: ThotBool isHTML)
1.1 cvs 2137: {
1.43 cvs 2138: PresentationValue padding;
2139:
1.82 cvs 2140: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2141: /* first parse the attribute string */
2142: cssRule = ParseCSSUnit (cssRule, &padding);
2143: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
2144: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
1.1 cvs 2145: return (cssRule);
2146: }
2147:
2148: /*----------------------------------------------------------------------
1.59 cvs 2149: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 2150: ----------------------------------------------------------------------*/
1.79 cvs 2151: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.78 cvs 2152: PresentationContext context,
1.79 cvs 2153: char *cssRule, CSSInfoPtr css,
1.78 cvs 2154: ThotBool isHTML)
1.1 cvs 2155: {
1.43 cvs 2156: PresentationValue padding;
2157:
1.82 cvs 2158: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2159: /* first parse the attribute string */
2160: cssRule = ParseCSSUnit (cssRule, &padding);
2161: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
2162: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.1 cvs 2163: return (cssRule);
2164: }
2165:
2166: /*----------------------------------------------------------------------
1.59 cvs 2167: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 2168: ----------------------------------------------------------------------*/
1.79 cvs 2169: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.78 cvs 2170: PresentationContext context,
1.79 cvs 2171: char *cssRule, CSSInfoPtr css,
1.78 cvs 2172: ThotBool isHTML)
1.1 cvs 2173: {
1.43 cvs 2174: PresentationValue padding;
2175:
1.82 cvs 2176: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2177: /* first parse the attribute string */
2178: cssRule = ParseCSSUnit (cssRule, &padding);
2179: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
2180: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.1 cvs 2181: return (cssRule);
2182: }
2183:
2184: /*----------------------------------------------------------------------
1.59 cvs 2185: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 2186: ----------------------------------------------------------------------*/
1.79 cvs 2187: static char *ParseCSSPadding (Element element, PSchema tsch,
1.78 cvs 2188: PresentationContext context,
1.79 cvs 2189: char *cssRule, CSSInfoPtr css,
1.78 cvs 2190: ThotBool isHTML)
1.1 cvs 2191: {
1.79 cvs 2192: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2193: int skippedNL;
1.43 cvs 2194:
1.82 cvs 2195: ptrT = SkipBlanksAndComments (cssRule);
1.43 cvs 2196: /* First parse Padding-Top */
2197: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2198: ptrR = SkipBlanksAndComments (ptrR);
2199: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.43 cvs 2200: {
1.93 vatton 2201: skippedNL = NewLineSkipped;
1.43 cvs 2202: cssRule = ptrR;
2203: /* apply the Padding-Top to all */
2204: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2205: NewLineSkipped = skippedNL;
1.43 cvs 2206: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2207: NewLineSkipped = skippedNL;
1.43 cvs 2208: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
2209: }
2210: else
2211: {
2212: /* parse Padding-Right */
2213: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2214: ptrB = SkipBlanksAndComments (ptrB);
2215: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.43 cvs 2216: {
1.93 vatton 2217: skippedNL = NewLineSkipped;
1.43 cvs 2218: cssRule = ptrB;
2219: /* apply the Padding-Top to Padding-Bottom */
2220: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2221: NewLineSkipped = skippedNL;
1.43 cvs 2222: /* apply the Padding-Right to Padding-Left */
2223: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2224: }
2225: else
2226: {
2227: /* parse Padding-Bottom */
2228: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2229: ptrL = SkipBlanksAndComments (ptrL);
2230: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.43 cvs 2231: {
2232: cssRule = ptrL;
2233: /* apply the Padding-Right to Padding-Left */
2234: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2235: }
2236: else
2237: /* parse Padding-Left */
2238: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2239: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2240: }
2241: }
1.1 cvs 2242: return (cssRule);
2243: }
2244:
2245: /*----------------------------------------------------------------------
1.59 cvs 2246: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 2247: ----------------------------------------------------------------------*/
1.79 cvs 2248: static char *ParseCSSForeground (Element element, PSchema tsch,
1.78 cvs 2249: PresentationContext context,
1.79 cvs 2250: char *cssRule,
1.78 cvs 2251: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2252: {
2253: PresentationValue best;
2254:
2255: cssRule = ParseCSSColor (cssRule, &best);
1.25 cvs 2256: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2257: /* install the new presentation */
2258: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.1 cvs 2259: return (cssRule);
2260: }
2261:
2262: /*----------------------------------------------------------------------
1.59 cvs 2263: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 2264: ----------------------------------------------------------------------*/
1.79 cvs 2265: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.78 cvs 2266: PresentationContext context,
1.79 cvs 2267: char *cssRule,
1.78 cvs 2268: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2269: {
2270: PresentationValue best;
2271: unsigned int savedtype = 0;
1.14 cvs 2272: ThotBool moved;
1.1 cvs 2273:
2274: /* move the BODY rule to the HTML element */
2275: moved = (context->type == HTML_EL_BODY && isHTML);
2276: if (moved)
2277: {
2278: if (element)
2279: element = TtaGetMainRoot (context->doc);
2280: else
2281: {
2282: savedtype = context->type;
1.83 cvs 2283: context->type = HTML_EL_Document;
1.1 cvs 2284: }
2285: }
2286:
2287: best.typed_data.unit = STYLE_UNIT_INVALID;
2288: best.typed_data.real = FALSE;
1.82 cvs 2289: if (!strncasecmp (cssRule, "transparent", strlen ("transparent")))
1.1 cvs 2290: {
2291: best.typed_data.value = STYLE_PATTERN_NONE;
2292: best.typed_data.unit = STYLE_UNIT_REL;
2293: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 2294: cssRule = SkipWord (cssRule);
1.1 cvs 2295: }
2296: else
2297: {
2298: cssRule = ParseCSSColor (cssRule, &best);
2299: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2300: {
2301: /* install the new presentation. */
2302: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59 cvs 2303: /* thot specificity: need to set fill pattern for background color */
1.1 cvs 2304: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2305: best.typed_data.unit = STYLE_UNIT_REL;
2306: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2307: best.typed_data.value = 1;
2308: best.typed_data.unit = STYLE_UNIT_REL;
2309: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
2310: }
2311: }
2312:
2313: /* restore the refered element */
2314: if (moved && !element)
2315: context->type = savedtype;
2316: return (cssRule);
2317: }
2318:
1.63 cvs 2319:
2320: /*----------------------------------------------------------------------
1.65 cvs 2321: ParseSVGStroke: parse a SVG stroke property
2322: ----------------------------------------------------------------------*/
1.79 cvs 2323: static char *ParseSVGStroke (Element element, PSchema tsch,
2324: PresentationContext context, char *cssRule,
2325: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 2326: {
2327: PresentationValue best;
2328:
2329: best.typed_data.unit = STYLE_UNIT_INVALID;
2330: best.typed_data.real = FALSE;
1.82 cvs 2331: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 2332: {
2333: best.typed_data.value = -2; /* -2 means transparent */
2334: best.typed_data.unit = STYLE_UNIT_REL;
2335: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2336: cssRule = SkipWord (cssRule);
2337: }
2338: else
2339: {
2340: cssRule = ParseCSSColor (cssRule, &best);
2341: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2342: /* install the new presentation */
2343: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2344: }
2345: return (cssRule);
2346: }
2347:
2348: /*----------------------------------------------------------------------
1.63 cvs 2349: ParseSVGFill: parse a SVG fill property
2350: ----------------------------------------------------------------------*/
1.79 cvs 2351: static char *ParseSVGFill (Element element, PSchema tsch,
2352: PresentationContext context, char *cssRule,
2353: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 2354: {
2355: PresentationValue best;
2356:
2357: best.typed_data.unit = STYLE_UNIT_INVALID;
2358: best.typed_data.real = FALSE;
1.82 cvs 2359: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 2360: {
2361: best.typed_data.value = STYLE_PATTERN_NONE;
2362: best.typed_data.unit = STYLE_UNIT_REL;
2363: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 2364: cssRule = SkipWord (cssRule);
1.63 cvs 2365: }
2366: else
2367: {
2368: cssRule = ParseCSSColor (cssRule, &best);
2369: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2370: {
2371: /* install the new presentation. */
2372: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
2373: /* thot specificity: need to set fill pattern for background color */
2374: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2375: best.typed_data.unit = STYLE_UNIT_REL;
2376: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2377: }
2378: }
2379: return (cssRule);
2380: }
2381:
1.1 cvs 2382: /*----------------------------------------------------------------------
1.59 cvs 2383: ParseCSSBackgroundImageCallback: Callback called asynchronously by
2384: FetchImage when a background image has been fetched.
1.1 cvs 2385: ----------------------------------------------------------------------*/
1.82 cvs 2386: void ParseCSSBackgroundImageCallback (Document doc, Element element,
2387: char *file, void *extra)
1.1 cvs 2388: {
1.82 cvs 2389: DisplayMode dispMode;
2390: BackgroundImageCallbackPtr callblock;
2391: Element el;
2392: PSchema tsch;
2393: PresentationContext context;
2394: PresentationValue image;
2395: PresentationValue value;
1.1 cvs 2396:
1.82 cvs 2397: callblock = (BackgroundImageCallbackPtr) extra;
1.34 cvs 2398: if (callblock == NULL)
2399: return;
1.1 cvs 2400:
1.34 cvs 2401: /* avoid too many redisplay */
2402: dispMode = TtaGetDisplayMode (doc);
2403: if (dispMode == DisplayImmediately)
2404: TtaSetDisplayMode (doc, DeferredDisplay);
2405:
2406: el = callblock->el;
2407: tsch = callblock->tsch;
2408: context = &callblock->context.specific;
2409:
2410: /* Ok the image was fetched, finish the background-image handling */
2411: image.pointer = file;
2412: TtaSetStylePresentation (PRBackgroundPicture, el, tsch, context, image);
1.1 cvs 2413:
1.70 cvs 2414: /* enforce the showbox */
1.34 cvs 2415: value.typed_data.value = 1;
2416: value.typed_data.unit = STYLE_UNIT_REL;
2417: value.typed_data.real = FALSE;
2418: TtaSetStylePresentation (PRShowBox, el, tsch, context, value);
2419:
2420: TtaFreeMemory (callblock);
2421: /* restore the display mode */
2422: if (dispMode == DisplayImmediately)
2423: TtaSetDisplayMode (doc, dispMode);
1.1 cvs 2424: }
2425:
2426:
2427: /*----------------------------------------------------------------------
2428: GetCSSBackgroundURL searches a CSS BackgroundImage url within
2429: the styleString.
2430: Returns NULL or a new allocated url string.
2431: ----------------------------------------------------------------------*/
1.79 cvs 2432: char *GetCSSBackgroundURL (char *styleString)
1.1 cvs 2433: {
1.79 cvs 2434: char *b, *e, *ptr;
2435: int len;
1.1 cvs 2436:
2437: ptr = NULL;
1.82 cvs 2438: b = strstr (styleString, "url");
1.1 cvs 2439: if (b != NULL)
2440: {
2441: b += 3;
1.82 cvs 2442: b = SkipBlanksAndComments (b);
2443: if (*b == '(')
1.1 cvs 2444: {
2445: b++;
1.82 cvs 2446: b = SkipBlanksAndComments (b);
1.1 cvs 2447: /*** Caution: Strings can either be written with double quotes or
2448: with single quotes. Only double quotes are handled here.
2449: Escaped quotes are not handled. See function SkipQuotedString */
1.82 cvs 2450: if (*b == '"')
1.1 cvs 2451: {
2452: b++;
2453: /* search the url end */
2454: e = b;
1.82 cvs 2455: while (*e != EOS && *e != '"')
1.1 cvs 2456: e++;
2457: }
2458: else
2459: {
2460: /* search the url end */
2461: e = b;
1.82 cvs 2462: while (*e != EOS && *e != ')')
1.1 cvs 2463: e++;
2464: }
1.82 cvs 2465: if (*e != EOS)
1.1 cvs 2466: {
2467: len = (int)(e - b);
1.82 cvs 2468: ptr = (char*) TtaGetMemory (len+1);
2469: strncpy (ptr, b, len);
2470: ptr[len] = EOS;
1.1 cvs 2471: }
2472: }
2473: }
2474: return (ptr);
2475: }
2476:
2477:
2478: /*----------------------------------------------------------------------
1.59 cvs 2479: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 2480: ----------------------------------------------------------------------*/
1.79 cvs 2481: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
2482: PresentationContext context,
2483: char *cssRule, CSSInfoPtr css,
2484: ThotBool isHTML)
1.1 cvs 2485: {
1.49 cvs 2486: Element el;
2487: GenericContext gblock;
1.71 cvs 2488: PresentationContext sblock;
1.1 cvs 2489: BackgroundImageCallbackPtr callblock;
1.49 cvs 2490: PresentationValue image, value;
1.79 cvs 2491: char *url;
1.82 cvs 2492: char *bg_image;
1.79 cvs 2493: char saved;
2494: char *base;
2495: char tempname[MAX_LENGTH];
2496: char imgname[MAX_LENGTH];
1.49 cvs 2497: unsigned int savedtype = 0;
2498: ThotBool moved;
1.1 cvs 2499:
2500: /* default element for FetchImage */
2501: el = TtaGetMainRoot (context->doc);
2502: /* move the BODY rule to the HTML element */
2503: moved = (context->type == HTML_EL_BODY && isHTML);
2504: if (moved)
2505: {
2506: if (element)
2507: element = el;
2508: else
2509: {
2510: savedtype = context->type;
1.83 cvs 2511: context->type = HTML_EL_Document;
1.1 cvs 2512: }
2513: }
2514: else if (element)
2515: el = element;
2516:
2517: url = NULL;
1.82 cvs 2518: cssRule = SkipBlanksAndComments (cssRule);
2519: if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 2520: {
2521: cssRule += 3;
1.82 cvs 2522: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2523: if (*cssRule == '(')
2524: {
2525: cssRule++;
1.82 cvs 2526: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2527: /*** Caution: Strings can either be written with double quotes or
2528: with single quotes. Only double quotes are handled here.
2529: Escaped quotes are not handled. See function SkipQuotedString */
2530: if (*cssRule == '"')
2531: {
2532: cssRule++;
2533: base = cssRule;
1.82 cvs 2534: while (*cssRule != EOS && *cssRule != '"')
1.1 cvs 2535: cssRule++;
2536: }
2537: else
2538: {
2539: base = cssRule;
2540: while (*cssRule != EOS && *cssRule != ')')
2541: cssRule++;
2542: }
2543: saved = *cssRule;
1.82 cvs 2544: *cssRule = EOS;
2545: url = TtaStrdup (base);
1.1 cvs 2546: *cssRule = saved;
2547: if (saved == '"')
2548: /* we need to skip two characters */
2549: cssRule++;
2550: }
2551: cssRule++;
2552:
2553: if (context->destroy)
2554: {
2555: /* remove the background image PRule */
2556: image.pointer = NULL;
2557: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, context, image);
2558: if (TtaGetStylePresentation (PRFillPattern, element, tsch, context, &value) < 0)
2559: {
2560: /* there is no FillPattern rule -> remove ShowBox rule */
2561: value.typed_data.value = 1;
2562: value.typed_data.unit = STYLE_UNIT_REL;
2563: value.typed_data.real = FALSE;
2564: TtaSetStylePresentation (PRShowBox, element, tsch, context, value);
2565: }
2566: }
2567: else if (url)
2568: {
1.30 cvs 2569: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
1.82 cvs 2570: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
1.1 cvs 2571: {
2572: callblock = (BackgroundImageCallbackPtr) TtaGetMemory(sizeof(BackgroundImageCallbackBlock));
2573: if (callblock != NULL)
2574: {
2575: callblock->el = element;
2576: callblock->tsch = tsch;
2577: if (element == NULL)
1.18 cvs 2578: {
2579: gblock = (GenericContext) context;
2580: memcpy (&callblock->context.generic, gblock,
2581: sizeof (GenericContextBlock));
2582: }
2583: else
2584: {
2585: sblock = context;
2586: memcpy (&callblock->context.specific, sblock,
2587: sizeof(PresentationContextBlock));
2588: }
2589:
2590: /* check if the image url is related to an external CSS */
2591: if (css != NULL && css->category == CSS_EXTERNAL_STYLE)
2592: {
2593: NormalizeURL (url, 0, tempname, imgname, css->url);
2594: /* fetch and display background image of element */
1.49 cvs 2595: FetchImage (context->doc, el, tempname, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2596: }
2597: else
1.49 cvs 2598: FetchImage (context->doc, el, url, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2599: }
2600: }
2601:
2602: if (url)
2603: TtaFreeMemory (url);
2604: }
2605: }
2606:
2607: /* restore the refered element */
2608: if (moved && !element)
2609: context->type = savedtype;
2610: return (cssRule);
2611: }
2612:
2613: /*----------------------------------------------------------------------
1.59 cvs 2614: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 2615: ----------------------------------------------------------------------*/
1.79 cvs 2616: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.97 vatton 2617: PresentationContext context,
2618: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2619: {
2620: PresentationValue repeat;
2621: unsigned int savedtype = 0;
2622: ThotBool moved;
2623:
2624: /* move the BODY rule to the HTML element */
2625: moved = (context->type == HTML_EL_BODY && isHTML);
2626: if (moved)
2627: {
2628: if (element)
2629: element = TtaGetMainRoot (context->doc);
2630: else
2631: {
2632: savedtype = context->type;
1.83 cvs 2633: context->type = HTML_EL_Document;
1.18 cvs 2634: }
2635: }
2636:
2637: repeat.typed_data.value = STYLE_REALSIZE;
2638: repeat.typed_data.unit = STYLE_UNIT_REL;
2639: repeat.typed_data.real = FALSE;
1.82 cvs 2640: cssRule = SkipBlanksAndComments (cssRule);
2641: if (!strncasecmp (cssRule, "no-repeat", 9))
1.18 cvs 2642: repeat.typed_data.value = STYLE_REALSIZE;
1.82 cvs 2643: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.18 cvs 2644: repeat.typed_data.value = STYLE_VREPEAT;
1.82 cvs 2645: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.18 cvs 2646: repeat.typed_data.value = STYLE_HREPEAT;
1.82 cvs 2647: else if (!strncasecmp (cssRule, "repeat", 6))
1.18 cvs 2648: repeat.typed_data.value = STYLE_REPEAT;
2649: else
2650: return (cssRule);
2651:
2652: /* install the new presentation */
2653: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
2654: cssRule = SkipWord (cssRule);
2655:
2656: /* restore the refered element */
2657: if (moved && !element)
2658: context->type = savedtype;
2659: return (cssRule);
2660: }
2661:
2662: /*----------------------------------------------------------------------
1.59 cvs 2663: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18 cvs 2664: attribute string.
2665: ----------------------------------------------------------------------*/
1.79 cvs 2666: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
2667: PresentationContext context,
2668: char *cssRule, CSSInfoPtr css,
2669: ThotBool isHTML)
1.18 cvs 2670: {
2671: unsigned int savedtype = 0;
2672: ThotBool moved;
1.1 cvs 2673:
1.18 cvs 2674: /* move the BODY rule to the HTML element */
2675: moved = (context->type == HTML_EL_BODY && isHTML);
2676: if (moved)
2677: {
2678: if (element)
2679: element = TtaGetMainRoot (context->doc);
2680: else
2681: {
2682: savedtype = context->type;
1.83 cvs 2683: context->type = HTML_EL_Document;
1.1 cvs 2684: }
2685: }
2686:
1.82 cvs 2687: cssRule = SkipBlanksAndComments (cssRule);
2688: if (!strncasecmp (cssRule, "scroll", 6))
1.18 cvs 2689: cssRule = SkipWord (cssRule);
1.82 cvs 2690: else if (!strncasecmp (cssRule, "fixed", 5))
1.18 cvs 2691: cssRule = SkipWord (cssRule);
2692:
1.1 cvs 2693: /* restore the refered element */
2694: if (moved && !element)
2695: context->type = savedtype;
1.18 cvs 2696: return (cssRule);
1.1 cvs 2697: }
2698:
2699: /*----------------------------------------------------------------------
1.59 cvs 2700: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
1.1 cvs 2701: attribute string.
2702: ----------------------------------------------------------------------*/
1.79 cvs 2703: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
2704: PresentationContext context,
2705: char *cssRule, CSSInfoPtr css,
2706: ThotBool isHTML)
1.1 cvs 2707: {
1.18 cvs 2708: PresentationValue repeat;
2709: unsigned int savedtype = 0;
2710: ThotBool moved;
2711: ThotBool ok;
1.1 cvs 2712:
2713: /* move the BODY rule to the HTML element */
2714: moved = (context->type == HTML_EL_BODY && isHTML);
2715: if (moved)
2716: {
2717: if (element)
2718: element = TtaGetMainRoot (context->doc);
2719: else
2720: {
2721: savedtype = context->type;
1.83 cvs 2722: context->type = HTML_EL_Document;
1.1 cvs 2723: }
2724: }
2725:
1.82 cvs 2726: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 2727: ok = TRUE;
1.82 cvs 2728: if (!strncasecmp (cssRule, "left", 4))
1.18 cvs 2729: cssRule = SkipWord (cssRule);
1.82 cvs 2730: else if (!strncasecmp (cssRule, "right", 5))
1.18 cvs 2731: cssRule = SkipWord (cssRule);
1.82 cvs 2732: else if (!strncasecmp (cssRule, "center", 6))
1.18 cvs 2733: cssRule = SkipWord (cssRule);
1.82 cvs 2734: else if (!strncasecmp (cssRule, "top", 3))
1.18 cvs 2735: cssRule = SkipWord (cssRule);
1.82 cvs 2736: else if (!strncasecmp (cssRule, "bottom", 6))
1.18 cvs 2737: cssRule = SkipWord (cssRule);
1.110 vatton 2738: else if (isdigit (*cssRule) || *cssRule == '.')
1.18 cvs 2739: cssRule = SkipWord (cssRule);
2740: else
2741: ok = FALSE;
2742:
2743: if (ok)
2744: {
2745: /* force realsize for the background image */
2746: repeat.typed_data.value = STYLE_REALSIZE;
2747: repeat.typed_data.unit = STYLE_UNIT_REL;
2748: repeat.typed_data.real = FALSE;
2749: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
2750: }
2751:
2752: /* restore the refered element */
2753: if (moved && !element)
2754: context->type = savedtype;
2755: return (cssRule);
2756: }
2757:
2758: /*----------------------------------------------------------------------
1.59 cvs 2759: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 2760: ----------------------------------------------------------------------*/
1.79 cvs 2761: static char *ParseCSSBackground (Element element, PSchema tsch,
2762: PresentationContext context, char *cssRule,
2763: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2764: {
1.79 cvs 2765: char *ptr;
1.93 vatton 2766: int skippedNL;
1.18 cvs 2767:
1.82 cvs 2768: cssRule = SkipBlanksAndComments (cssRule);
2769: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 2770: {
1.71 cvs 2771: /* perhaps a Background Image */
1.82 cvs 2772: if (!strncasecmp (cssRule, "url", 3))
1.63 cvs 2773: cssRule = ParseCSSBackgroundImage (element, tsch, context, cssRule,
2774: css, isHTML);
1.18 cvs 2775: /* perhaps a Background Attachment */
1.82 cvs 2776: else if (!strncasecmp (cssRule, "scroll", 6) ||
2777: !strncasecmp (cssRule, "fixed", 5))
1.63 cvs 2778: cssRule = ParseCSSBackgroundAttachment (element, tsch, context,
2779: cssRule, css, isHTML);
1.18 cvs 2780: /* perhaps a Background Repeat */
1.82 cvs 2781: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
2782: !strncasecmp (cssRule, "repeat-y", 8) ||
2783: !strncasecmp (cssRule, "repeat-x", 8) ||
2784: !strncasecmp (cssRule, "repeat", 6))
2785: cssRule = ParseCSSBackgroundRepeat (element, tsch, context,
2786: cssRule, css, isHTML);
1.18 cvs 2787: /* perhaps a Background Position */
1.82 cvs 2788: else if (!strncasecmp (cssRule, "left", 4) ||
2789: !strncasecmp (cssRule, "right", 5) ||
2790: !strncasecmp (cssRule, "center", 6) ||
2791: !strncasecmp (cssRule, "top", 3) ||
2792: !strncasecmp (cssRule, "bottom", 6) ||
1.110 vatton 2793: isdigit (*cssRule) || *cssRule == '.')
1.63 cvs 2794: cssRule = ParseCSSBackgroundPosition (element, tsch, context,
2795: cssRule, css, isHTML);
1.18 cvs 2796: /* perhaps a Background Color */
2797: else
2798: {
1.93 vatton 2799: skippedNL = NewLineSkipped;
1.18 cvs 2800: /* check if the rule has been found */
2801: ptr = cssRule;
1.82 cvs 2802: cssRule = ParseCSSBackgroundColor (element, tsch, context,
2803: cssRule, css, isHTML);
1.43 cvs 2804: if (ptr == cssRule)
1.93 vatton 2805: {
2806: NewLineSkipped = skippedNL;
2807: /* rule not found */
2808: cssRule = SkipProperty (cssRule);
2809: }
1.18 cvs 2810: }
1.82 cvs 2811: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 2812: }
2813: return (cssRule);
2814: }
2815:
1.59 cvs 2816: /*----------------------------------------------------------------------
1.60 cvs 2817: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 2818: ----------------------------------------------------------------------*/
1.79 cvs 2819: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
2820: PresentationContext context, char *cssRule,
2821: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 2822: {
2823: PresentationValue page;
2824:
2825: page.typed_data.unit = STYLE_UNIT_INVALID;
2826: page.typed_data.real = FALSE;
1.82 cvs 2827: cssRule = SkipBlanksAndComments (cssRule);
2828: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 2829: {
2830: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2831: page.typed_data.value = STYLE_AUTO;
2832: }
1.82 cvs 2833: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 2834: {
2835: page.typed_data.unit = STYLE_UNIT_REL;
2836: page.typed_data.value = STYLE_ALWAYS;
2837: }
1.82 cvs 2838: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 2839: {
2840: page.typed_data.unit = STYLE_UNIT_REL;
2841: page.typed_data.value = STYLE_AVOID;
2842: }
1.82 cvs 2843: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 2844: {
2845: page.typed_data.unit = STYLE_UNIT_REL;
2846: page.typed_data.value = STYLE_PAGELEFT;
2847: }
1.82 cvs 2848: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 2849: {
2850: page.typed_data.unit = STYLE_UNIT_REL;
2851: page.typed_data.value = STYLE_PAGERIGHT;
2852: }
1.82 cvs 2853: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 2854: {
2855: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2856: page.typed_data.value = STYLE_INHERIT;
2857: }
2858: cssRule = SkipWord (cssRule);
2859: /* install the new presentation */
2860: if (page.typed_data.unit == STYLE_UNIT_REL &&
2861: page.typed_data.value == STYLE_ALWAYS)
2862: TtaSetStylePresentation (PRPageBefore, element, tsch, context, page);
2863: return (cssRule);
2864: }
2865:
2866: /*----------------------------------------------------------------------
1.60 cvs 2867: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 2868: ----------------------------------------------------------------------*/
1.79 cvs 2869: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
2870: PresentationContext context,
2871: char *cssRule, CSSInfoPtr css,
2872: ThotBool isHTML)
1.59 cvs 2873: {
2874: PresentationValue page;
2875:
2876: page.typed_data.unit = STYLE_UNIT_INVALID;
2877: page.typed_data.real = FALSE;
1.82 cvs 2878: cssRule = SkipBlanksAndComments (cssRule);
2879: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 2880: {
2881: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2882: page.typed_data.value = STYLE_AUTO;
2883: }
1.82 cvs 2884: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 2885: {
2886: page.typed_data.unit = STYLE_UNIT_REL;
2887: page.typed_data.value = STYLE_ALWAYS;
2888: }
1.82 cvs 2889: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 2890: {
2891: page.typed_data.unit = STYLE_UNIT_REL;
2892: page.typed_data.value = STYLE_AVOID;
2893: }
1.82 cvs 2894: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 2895: {
2896: page.typed_data.unit = STYLE_UNIT_REL;
2897: page.typed_data.value = STYLE_PAGELEFT;
2898: }
1.82 cvs 2899: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 2900: {
2901: page.typed_data.unit = STYLE_UNIT_REL;
2902: page.typed_data.value = STYLE_PAGERIGHT;
2903: }
1.82 cvs 2904: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 2905: {
2906: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2907: page.typed_data.value = STYLE_INHERIT;
2908: }
2909: cssRule = SkipWord (cssRule);
2910: /* install the new presentation */
2911: /*if (page.typed_data.unit == STYLE_UNIT_REL)
2912: TtaSetStylePresentation (PRPageAfter, element, tsch, context, page);*/
2913: return (cssRule);
2914: }
2915:
2916: /*----------------------------------------------------------------------
1.60 cvs 2917: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 2918: ----------------------------------------------------------------------*/
1.79 cvs 2919: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
2920: PresentationContext context,
2921: char *cssRule, CSSInfoPtr css,
2922: ThotBool isHTML)
1.59 cvs 2923: {
2924: PresentationValue page;
2925:
2926: page.typed_data.unit = STYLE_UNIT_INVALID;
2927: page.typed_data.real = FALSE;
1.82 cvs 2928: cssRule = SkipBlanksAndComments (cssRule);
2929: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 2930: {
2931: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2932: page.typed_data.value = STYLE_AUTO;
2933: }
1.82 cvs 2934: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 2935: {
2936: page.typed_data.unit = STYLE_UNIT_REL;
2937: page.typed_data.value = STYLE_AVOID;
2938: }
1.82 cvs 2939: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 2940: {
2941: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2942: page.typed_data.value = STYLE_INHERIT;
2943: }
2944: cssRule = SkipWord (cssRule);
2945: /* install the new presentation */
1.96 vatton 2946: /*if (page.typed_data.unit == STYLE_UNIT_REL &&
1.59 cvs 2947: page.typed_data.value == STYLE_AVOID)
1.96 vatton 2948: TtaSetStylePresentation (PRPageInside, element, tsch, context, page);*/
1.59 cvs 2949: return (cssRule);
2950: }
1.18 cvs 2951:
2952:
1.60 cvs 2953: /*----------------------------------------------------------------------
1.63 cvs 2954: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 2955: ----------------------------------------------------------------------*/
1.79 cvs 2956: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
2957: PresentationContext context, char *cssRule,
2958: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 2959: {
2960: PresentationValue width;
2961:
1.82 cvs 2962: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 2963: width.typed_data.value = 0;
2964: width.typed_data.unit = STYLE_UNIT_INVALID;
2965: width.typed_data.real = FALSE;
1.110 vatton 2966: if (isdigit (*cssRule) || *cssRule == '.')
1.60 cvs 2967: cssRule = ParseCSSUnit (cssRule, &width);
2968: if (width.typed_data.unit != STYLE_UNIT_INVALID)
2969: {
2970: TtaSetStylePresentation (PRLineWeight, element, tsch, context, width);
2971: width.typed_data.value = 1;
2972: width.typed_data.unit = STYLE_UNIT_REL;
2973: }
2974: return (cssRule);
2975: }
2976:
1.18 cvs 2977: /************************************************************************
2978: * *
2979: * FUNCTIONS STYLE DECLARATIONS *
2980: * *
2981: ************************************************************************/
2982: /*
1.59 cvs 2983: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 2984: * e.g. "FONT-SIZE" must be placed before "FONT"
2985: */
2986: static CSSProperty CSSProperties[] =
2987: {
1.82 cvs 2988: {"font-family", ParseCSSFontFamily},
2989: {"font-style", ParseCSSFontStyle},
2990: {"font-variant", ParseCSSFontVariant},
2991: {"font-weight", ParseCSSFontWeight},
2992: {"font-size", ParseCSSFontSize},
2993: {"font", ParseCSSFont},
2994:
2995: {"color", ParseCSSForeground},
2996: {"background-color", ParseCSSBackgroundColor},
2997: {"background-image", ParseCSSBackgroundImage},
2998: {"background-repeat", ParseCSSBackgroundRepeat},
2999: {"background-attachment", ParseCSSBackgroundAttachment},
3000: {"background-position", ParseCSSBackgroundPosition},
3001: {"background", ParseCSSBackground},
3002:
3003: {"word-spacing", ParseCSSWordSpacing},
3004: {"letter-spacing", ParseCSSLetterSpacing},
3005: {"text-decoration", ParseCSSTextDecoration},
3006: {"vertical-align", ParseCSSVerticalAlign},
3007: {"text-transform", ParseCSSTextTransform},
3008: {"text-align", ParseCSSTextAlign},
3009: {"text-indent", ParseCSSTextIndent},
3010: {"line-height", ParseCSSLineSpacing},
3011:
1.112 quint 3012: {"direction", ParseCSSDirection},
1.113 quint 3013: {"unicode-bidi", ParseCSSUnicodeBidi},
1.112 quint 3014:
1.82 cvs 3015: {"margin-top", ParseCSSMarginTop},
3016: {"margin-right", ParseCSSMarginRight},
3017: {"margin-bottom", ParseCSSMarginBottom},
3018: {"margin-left", ParseCSSMarginLeft},
3019: {"margin", ParseCSSMargin},
3020:
3021: {"padding-top", ParseCSSPaddingTop},
3022: {"padding-right", ParseCSSPaddingRight},
3023: {"padding-bottom", ParseCSSPaddingBottom},
3024: {"padding-left", ParseCSSPaddingLeft},
3025: {"padding", ParseCSSPadding},
3026:
3027: {"border-top-width", ParseCSSBorderTopWidth},
3028: {"border-right-width", ParseCSSBorderRightWidth},
3029: {"border-bottom-width", ParseCSSBorderBottomWidth},
3030: {"border-left-width", ParseCSSBorderLeftWidth},
3031: {"border-width", ParseCSSBorderWidth},
3032: {"border-top-color", ParseCSSBorderColorTop},
3033: {"border-right-color", ParseCSSBorderColorRight},
3034: {"border-bottom-color", ParseCSSBorderColorBottom},
3035: {"border-left-color", ParseCSSBorderColorLeft},
3036: {"border-color", ParseCSSBorderColor},
3037: {"border-top-style", ParseCSSBorderStyleTop},
3038: {"border-right-style", ParseCSSBorderStyleRight},
3039: {"border-bottom-style", ParseCSSBorderStyleBottom},
3040: {"border-left-style", ParseCSSBorderStyleLeft},
3041: {"border-style", ParseCSSBorderStyle},
3042: {"border-top", ParseCSSBorderTop},
3043: {"border-right", ParseCSSBorderRight},
3044: {"border-bottom", ParseCSSBorderBottom},
3045: {"border-left", ParseCSSBorderLeft},
3046: {"border", ParseCSSBorder},
3047:
3048: {"width", ParseCSSWidth},
3049: {"height", ParseCSSHeight},
3050: {"float", ParseCSSFloat},
3051: {"clear", ParseCSSClear},
3052:
3053: {"display", ParseCSSDisplay},
3054: {"white-space", ParseCSSWhiteSpace},
3055:
3056: {"list-style-type", ParseCSSListStyleType},
3057: {"list-style-image", ParseCSSListStyleImage},
3058: {"list-style-position", ParseCSSListStylePosition},
3059: {"list-style", ParseCSSListStyle},
3060:
3061: {"page-break-before", ParseCSSPageBreakBefore},
3062: {"page-break-after", ParseCSSPageBreakAfter},
3063: {"page-break-inside", ParseCSSPageBreakInside},
1.60 cvs 3064:
3065: /* SVG extensions */
1.82 cvs 3066: {"stroke-width", ParseSVGStrokeWidth},
3067: {"stroke", ParseSVGStroke},
3068: {"fill", ParseSVGFill}
1.18 cvs 3069: };
3070: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
3071:
3072: /*----------------------------------------------------------------------
1.59 cvs 3073: ParseCSSRule: parse a CSS Style string
1.18 cvs 3074: we expect the input string describing the style to be of the
1.59 cvs 3075: form: PRORPERTY: DESCRIPTION [ ; PROPERTY: DESCRIPTION ] *
1.18 cvs 3076: but tolerate incorrect or incomplete input
3077: ----------------------------------------------------------------------*/
1.79 cvs 3078: static void ParseCSSRule (Element element, PSchema tsch,
3079: PresentationContext context, char *cssRule,
3080: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3081: {
1.34 cvs 3082: DisplayMode dispMode;
1.79 cvs 3083: char *p = NULL;
1.18 cvs 3084: int lg;
1.34 cvs 3085: unsigned int i;
1.76 cvs 3086: ThotBool found;
1.18 cvs 3087:
1.34 cvs 3088: /* avoid too many redisplay */
3089: dispMode = TtaGetDisplayMode (context->doc);
3090: if (dispMode == DisplayImmediately)
3091: TtaSetDisplayMode (context->doc, DeferredDisplay);
3092:
1.82 cvs 3093: while (*cssRule != EOS)
1.18 cvs 3094: {
1.82 cvs 3095: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 3096: if (*cssRule == '{')
3097: {
3098: cssRule++;
3099: CSSParseError ("Invalid character", "{");
3100: cssRule = SkipBlanksAndComments (cssRule);
3101: }
1.18 cvs 3102:
3103: found = FALSE;
3104: /* look for the type of property */
3105: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
3106: {
1.82 cvs 3107: lg = strlen (CSSProperties[i].name);
3108: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
1.18 cvs 3109: {
1.86 cvs 3110: p = cssRule + lg;
1.18 cvs 3111: found = TRUE;
3112: i--;
3113: }
3114: }
3115:
3116: if (i == NB_CSSSTYLEATTRIBUTE)
3117: cssRule = SkipProperty (cssRule);
3118: else
3119: {
3120: /* update index and skip the ":" indicator if present */
1.86 cvs 3121: p = SkipBlanksAndComments (p);
3122: if (*p == ':')
1.18 cvs 3123: {
1.86 cvs 3124: p++;
3125: p = SkipBlanksAndComments (p);
1.74 cvs 3126: /* try to parse the value associated with this property */
3127: if (CSSProperties[i].parsing_function != NULL)
1.61 cvs 3128: {
1.75 cvs 3129: p = CSSProperties[i].parsing_function (element, tsch, context,
1.86 cvs 3130: p, css, isHTML);
1.74 cvs 3131: /* update index and skip the ";" separator if present */
3132: cssRule = p;
1.61 cvs 3133: }
1.18 cvs 3134: }
1.74 cvs 3135: else
3136: cssRule = SkipProperty (cssRule);
1.18 cvs 3137: }
1.89 cvs 3138:
1.18 cvs 3139: /* next property */
1.82 cvs 3140: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 3141: if (*cssRule == '}')
3142: {
3143: cssRule++;
3144: CSSParseError ("Invalid character", "}");
3145: cssRule = SkipBlanksAndComments (cssRule);
3146: }
1.82 cvs 3147: if (*cssRule == ',' || *cssRule == ';')
1.18 cvs 3148: {
3149: cssRule++;
1.82 cvs 3150: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3151: }
3152: }
1.34 cvs 3153:
3154: /* restore the display mode */
3155: if (dispMode == DisplayImmediately)
3156: TtaSetDisplayMode (context->doc, dispMode);
1.18 cvs 3157: }
1.1 cvs 3158:
1.111 cvs 3159: /*----------------------------------------------------------------------
3160: AddBorderStyleValue
3161: -----------------------------------------------------------------------*/
3162: static void AddBorderStyleValue (char *buffer, int value)
3163: {
3164: switch (value)
3165: {
3166: case STYLE_BORDERNONE:
3167: strcat (buffer, "none");
3168: break;
3169: case STYLE_BORDERHIDDEN:
3170: strcat (buffer, "hidden");
3171: break;
3172: case STYLE_BORDERDOTTED:
3173: strcat (buffer, "dotted");
3174: break;
3175: case STYLE_BORDERDASHED:
3176: strcat (buffer, "dashed");
3177: break;
3178: case STYLE_BORDERSOLID:
3179: strcat (buffer, "solid");
3180: break;
3181: case STYLE_BORDERDOUBLE:
3182: strcat (buffer, "double");
3183: break;
3184: case STYLE_BORDERGROOVE:
3185: strcat (buffer, "groove");
3186: break;
3187: case STYLE_BORDERRIDGE:
3188: strcat (buffer, "ridge");
3189: break;
3190: case STYLE_BORDERINSET:
3191: strcat (buffer, "inset");
3192: break;
3193: case STYLE_BORDEROUTSET:
3194: strcat (buffer, "outset");
3195: break;
3196: }
3197: }
1.1 cvs 3198:
3199: /*----------------------------------------------------------------------
1.59 cvs 3200: PToCss: translate a PresentationSetting to the
1.18 cvs 3201: equivalent CSS string, and add it to the buffer given as the
1.67 cvs 3202: argument. It is used when extracting the CSS string from actual
3203: presentation.
3204: el is the element for which the style rule is generated
1.18 cvs 3205:
3206: All the possible values returned by the presentation drivers are
3207: described in thotlib/include/presentation.h
3208: -----------------------------------------------------------------------*/
1.79 cvs 3209: void PToCss (PresentationSetting settings, char *buffer, int len, Element el)
1.1 cvs 3210: {
1.76 cvs 3211: ElementType elType;
1.18 cvs 3212: float fval = 0;
3213: unsigned short red, green, blue;
3214: int add_unit = 0;
3215: unsigned int unit, i;
3216: ThotBool real = FALSE;
3217:
1.82 cvs 3218: buffer[0] = EOS;
1.18 cvs 3219: if (len < 40)
3220: return;
3221:
3222: unit = settings->value.typed_data.unit;
3223: if (settings->value.typed_data.real)
3224: {
3225: real = TRUE;
3226: fval = (float) settings->value.typed_data.value;
3227: fval /= 1000;
3228: }
1.1 cvs 3229:
1.18 cvs 3230: switch (settings->type)
1.1 cvs 3231: {
1.18 cvs 3232: case PRVisibility:
3233: break;
1.111 cvs 3234: case PRHeight:
3235: if (real)
3236: sprintf (buffer, "height: %g", fval);
3237: else
3238: sprintf (buffer, "height: %d", settings->value.typed_data.value);
3239: add_unit = 1;
3240: break;
3241: case PRWidth:
3242: if (real)
3243: sprintf (buffer, "width: %g", fval);
3244: else
3245: sprintf (buffer, "width: %d", settings->value.typed_data.value);
3246: add_unit = 1;
3247: break;
3248: case PRMarginTop:
3249: if (real)
3250: sprintf (buffer, "margin-top: %g", fval);
3251: else
3252: sprintf (buffer, "margin-top: %d",settings->value.typed_data.value);
3253: add_unit = 1;
3254: break;
3255: case PRMarginBottom:
3256: if (real)
3257: sprintf (buffer, "margin-bottom: %g", fval);
3258: else
3259: sprintf (buffer, "margin-bottom: %d",
3260: settings->value.typed_data.value);
3261: add_unit = 1;
3262: break;
3263: case PRMarginLeft:
3264: if (real)
3265: sprintf (buffer, "margin-left: %g", fval);
3266: else
3267: sprintf (buffer, "margin-left: %d",
3268: settings->value.typed_data.value);
3269: add_unit = 1;
3270: break;
3271: case PRMarginRight:
3272: if (real)
3273: sprintf (buffer, "margin-right: %g", fval);
3274: else
3275: sprintf (buffer, "margin-right: %d",
3276: settings->value.typed_data.value);
3277: add_unit = 1;
3278: break;
3279: case PRPaddingTop:
3280: if (real)
3281: sprintf (buffer, "padding-top: %g", fval);
3282: else
3283: sprintf (buffer, "padding-top: %d",settings->value.typed_data.value);
3284: add_unit = 1;
3285: break;
3286: case PRPaddingBottom:
3287: if (real)
3288: sprintf (buffer, "padding-bottom: %g", fval);
3289: else
3290: sprintf (buffer, "padding-bottom: %d",
3291: settings->value.typed_data.value);
3292: add_unit = 1;
3293: break;
3294: case PRPaddingLeft:
3295: if (real)
3296: sprintf (buffer, "padding-left: %g", fval);
3297: else
3298: sprintf (buffer, "padding-left: %d",
3299: settings->value.typed_data.value);
3300: add_unit = 1;
3301: break;
3302: case PRPaddingRight:
3303: if (real)
3304: sprintf (buffer, "padding-right: %g", fval);
3305: else
3306: sprintf (buffer, "padding-right: %d",
3307: settings->value.typed_data.value);
3308: add_unit = 1;
3309: break;
3310: case PRBorderTopWidth:
3311: if (real)
3312: sprintf (buffer, "border-top-width: %g", fval);
3313: else
3314: sprintf (buffer, "border-top-width: %d",
3315: settings->value.typed_data.value);
3316: add_unit = 1;
3317: break;
3318: case PRBorderBottomWidth:
3319: if (real)
3320: sprintf (buffer, "border-bottom-width: %g", fval);
3321: else
3322: sprintf (buffer, "border-bottom-width: %d",
3323: settings->value.typed_data.value);
3324: add_unit = 1;
3325: break;
3326: case PRBorderLeftWidth:
3327: if (real)
3328: sprintf (buffer, "border-left-width: %g", fval);
3329: else
3330: sprintf (buffer, "border-left-width: %d",
3331: settings->value.typed_data.value);
3332: add_unit = 1;
3333: break;
3334: case PRBorderRightWidth:
3335: if (real)
3336: sprintf (buffer, "border-right-width: %g", fval);
3337: else
3338: sprintf (buffer, "border-right-width: %d",
3339: settings->value.typed_data.value);
3340: add_unit = 1;
3341: break;
3342: case PRBorderTopColor:
3343: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3344: elType = TtaGetElementType(el);
3345: sprintf (buffer, "border-top-color: #%02X%02X%02X", red, green, blue);
3346: break;
3347: case PRBorderRightColor:
3348: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3349: elType = TtaGetElementType(el);
3350: sprintf (buffer, "border-right-color: #%02X%02X%02X", red, green, blue);
3351: break;
3352: case PRBorderBottomColor:
3353: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3354: elType = TtaGetElementType(el);
3355: sprintf (buffer, "border-bottom-color: #%02X%02X%02X", red, green, blue);
1.18 cvs 3356: break;
1.111 cvs 3357: case PRBorderLeftColor:
3358: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3359: elType = TtaGetElementType(el);
3360: sprintf (buffer, "border-left-color: #%02X%02X%02X", red, green, blue);
1.20 cvs 3361: break;
1.111 cvs 3362: case PRBorderTopStyle:
3363: strcpy (buffer, "border-top-style: ");
3364: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3365: break;
3366: case PRBorderRightStyle:
3367: strcpy (buffer, "border-right-style: ");
3368: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3369: break;
3370: case PRBorderBottomStyle:
3371: strcpy (buffer, "border-bottom-style: ");
3372: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3373: break;
3374: case PRBorderLeftStyle:
3375: strcpy (buffer, "border-left-style: ");
3376: AddBorderStyleValue (buffer, settings->value.typed_data.value);
1.18 cvs 3377: break;
3378: case PRSize:
3379: if (unit == STYLE_UNIT_REL)
3380: {
3381: if (real)
3382: {
1.82 cvs 3383: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 3384: add_unit = 1;
3385: }
3386: else
3387: switch (settings->value.typed_data.value)
3388: {
3389: case 1:
1.82 cvs 3390: strcpy (buffer, "font-size: xx-small");
1.18 cvs 3391: break;
3392: case 2:
1.82 cvs 3393: strcpy (buffer, "font-size: x-small");
1.18 cvs 3394: break;
3395: case 3:
1.82 cvs 3396: strcpy (buffer, "font-size: small");
1.18 cvs 3397: break;
3398: case 4:
1.82 cvs 3399: strcpy (buffer, "font-size: medium");
1.18 cvs 3400: break;
3401: case 5:
1.82 cvs 3402: strcpy (buffer, "font-size: large");
1.18 cvs 3403: break;
3404: case 6:
1.82 cvs 3405: strcpy (buffer, "font-size: x-large");
1.18 cvs 3406: break;
3407: case 7:
3408: case 8:
3409: case 9:
3410: case 10:
3411: case 11:
3412: case 12:
1.82 cvs 3413: strcpy (buffer, "font-size: xx-large");
1.18 cvs 3414: break;
3415: }
3416: }
3417: else
3418: {
3419: if (real)
1.82 cvs 3420: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 3421: else
1.82 cvs 3422: sprintf (buffer, "font-size: %d",
1.67 cvs 3423: settings->value.typed_data.value);
1.18 cvs 3424: add_unit = 1;
3425: }
3426: break;
1.111 cvs 3427: case PRStyle:
3428: switch (settings->value.typed_data.value)
3429: {
3430: case STYLE_FONT_ROMAN:
3431: strcpy (buffer, "font-style: normal");
3432: break;
3433: case STYLE_FONT_ITALICS:
3434: strcpy (buffer, "font-style: italic");
3435: break;
3436: case STYLE_FONT_OBLIQUE:
3437: strcpy (buffer, "font-style: oblique");
3438: break;
3439: }
3440: break;
3441: case PRWeight:
3442: switch (settings->value.typed_data.value)
3443: {
3444: case STYLE_WEIGHT_BOLD:
3445: strcpy (buffer, "font-weight: bold");
3446: break;
3447: case STYLE_WEIGHT_NORMAL:
3448: strcpy (buffer, "font-weight: normal");
3449: break;
3450: }
3451: break;
3452: case PRFont:
3453: switch (settings->value.typed_data.value)
3454: {
3455: case STYLE_FONT_HELVETICA:
3456: strcpy (buffer, "font-family: helvetica");
3457: break;
3458: case STYLE_FONT_TIMES:
3459: strcpy (buffer, "font-family: times");
3460: break;
3461: case STYLE_FONT_COURIER:
3462: strcpy (buffer, "font-family: courier");
3463: break;
3464: }
3465: break;
1.18 cvs 3466: case PRUnderline:
3467: switch (settings->value.typed_data.value)
3468: {
3469: case STYLE_UNDERLINE:
1.82 cvs 3470: strcpy (buffer, "text-decoration: underline");
1.18 cvs 3471: break;
3472: case STYLE_OVERLINE:
1.82 cvs 3473: strcpy (buffer, "text-decoration: overline");
1.18 cvs 3474: break;
3475: case STYLE_CROSSOUT:
1.82 cvs 3476: strcpy (buffer, "text-decoration: line-through");
1.18 cvs 3477: break;
3478: }
3479: break;
1.111 cvs 3480: case PRThickness:
3481: break;
1.18 cvs 3482: case PRIndent:
3483: if (real)
1.82 cvs 3484: sprintf (buffer, "text-indent: %g", fval);
1.18 cvs 3485: else
1.82 cvs 3486: sprintf (buffer, "text-indent: %d",
1.67 cvs 3487: settings->value.typed_data.value);
1.18 cvs 3488: add_unit = 1;
3489: break;
3490: case PRLineSpacing:
3491: if (real)
1.82 cvs 3492: sprintf (buffer, "line-height: %g", fval);
1.1 cvs 3493: else
1.82 cvs 3494: sprintf (buffer, "line-height: %d",
1.67 cvs 3495: settings->value.typed_data.value);
1.18 cvs 3496: add_unit = 1;
3497: break;
1.111 cvs 3498: case PRDepth:
3499: break;
1.18 cvs 3500: case PRAdjust:
3501: switch (settings->value.typed_data.value)
1.1 cvs 3502: {
1.18 cvs 3503: case STYLE_ADJUSTLEFT:
1.82 cvs 3504: strcpy (buffer, "text-align: left");
1.18 cvs 3505: break;
3506: case STYLE_ADJUSTRIGHT:
1.82 cvs 3507: strcpy (buffer, "text-align: right");
1.18 cvs 3508: break;
3509: case STYLE_ADJUSTCENTERED:
1.82 cvs 3510: strcpy (buffer, "text-align: center");
1.18 cvs 3511: break;
3512: case STYLE_ADJUSTLEFTWITHDOTS:
1.82 cvs 3513: strcpy (buffer, "text-align: left");
1.81 cvs 3514: break;
3515: case STYLE_ADJUSTJUSTIFY:
1.82 cvs 3516: strcpy (buffer, "text-align: justify");
1.112 quint 3517: break;
3518: }
3519: break;
3520: case PRDirection:
3521: switch (settings->value.typed_data.value)
3522: {
3523: case STYLE_LEFTTORIGHT:
3524: strcpy (buffer, "direction: ltr");
3525: break;
3526: case STYLE_RIGHTTOLEFT:
3527: strcpy (buffer, "direction: rtl");
1.113 quint 3528: break;
3529: }
3530: break;
3531: case PRUnicodeBidi:
3532: switch (settings->value.typed_data.value)
3533: {
3534: case STYLE_BIDINORMAL:
3535: strcpy (buffer, "unicode-bidi: normal");
3536: break;
3537: case STYLE_BIDIEMBED:
3538: strcpy (buffer, "unicode-bidi: embed");
3539: break;
3540: case STYLE_BIDIOVERRIDE:
3541: strcpy (buffer, "unicode-bidi: bidi-override");
1.18 cvs 3542: break;
1.1 cvs 3543: }
1.18 cvs 3544: break;
1.111 cvs 3545: case PRLineStyle:
3546: break;
3547: case PRLineWeight:
3548: elType = TtaGetElementType(el);
3549: #ifdef _SVG
3550: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
3551: #endif /* _SVG */
3552: {
3553: if (real)
3554: sprintf (buffer, "stroke-width: %g", fval);
3555: else
3556: sprintf (buffer, "stroke-width: %d",
3557: settings->value.typed_data.value);
3558: }
3559: add_unit = 1;
1.18 cvs 3560: break;
3561: case PRFillPattern:
3562: break;
3563: case PRBackground:
3564: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3565: elType = TtaGetElementType(el);
1.100 vatton 3566: #ifdef _SVG
3567: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 3568: sprintf (buffer, "fill: #%02X%02X%02X", red, green, blue);
1.67 cvs 3569: else
1.100 vatton 3570: #endif /* _SVG */
1.82 cvs 3571: sprintf (buffer, "background-color: #%02X%02X%02X", red, green,
1.67 cvs 3572: blue);
1.18 cvs 3573: break;
3574: case PRForeground:
3575: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3576: elType = TtaGetElementType(el);
1.100 vatton 3577: #ifdef _SVG
3578: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 3579: sprintf (buffer, "stroke: #%02X%02X%02X", red, green, blue);
1.67 cvs 3580: else
1.100 vatton 3581: #endif /* _SVG */
1.82 cvs 3582: sprintf (buffer, "color: #%02X%02X%02X", red, green, blue);
1.67 cvs 3583: break;
1.111 cvs 3584: case PRHyphenate:
1.18 cvs 3585: break;
1.111 cvs 3586: case PRVertOverflow:
1.18 cvs 3587: break;
1.111 cvs 3588: case PRHorizOverflow:
1.18 cvs 3589: break;
3590: case PRLine:
3591: if (settings->value.typed_data.value == STYLE_INLINE)
1.82 cvs 3592: strcpy (buffer, "display: inline");
1.18 cvs 3593: else if (settings->value.typed_data.value == STYLE_NOTINLINE)
1.82 cvs 3594: strcpy (buffer, "display: block");
1.18 cvs 3595: break;
3596: case PRBackgroundPicture:
3597: if (settings->value.pointer != NULL)
1.82 cvs 3598: sprintf (buffer, "background-image: url(%s)",
1.67 cvs 3599: (char*)(settings->value.pointer));
1.1 cvs 3600: else
1.82 cvs 3601: sprintf (buffer, "background-image: none");
1.18 cvs 3602: break;
3603: case PRPictureMode:
3604: switch (settings->value.typed_data.value)
1.1 cvs 3605: {
1.18 cvs 3606: case STYLE_REALSIZE:
1.82 cvs 3607: sprintf (buffer, "background-repeat: no-repeat");
1.18 cvs 3608: break;
3609: case STYLE_REPEAT:
1.82 cvs 3610: sprintf (buffer, "background-repeat: repeat");
1.18 cvs 3611: break;
3612: case STYLE_VREPEAT:
1.82 cvs 3613: sprintf (buffer, "background-repeat: repeat-y");
1.18 cvs 3614: break;
3615: case STYLE_HREPEAT:
1.82 cvs 3616: sprintf (buffer, "background-repeat: repeat-x");
1.18 cvs 3617: break;
1.1 cvs 3618: }
1.18 cvs 3619: break;
3620: default:
3621: break;
1.1 cvs 3622: }
3623:
1.18 cvs 3624: if (add_unit)
1.1 cvs 3625: {
1.18 cvs 3626: /* add the unit string to the CSS string */
3627: for (i = 0; i < NB_UNITS; i++)
1.1 cvs 3628: {
1.18 cvs 3629: if (CSSUnitNames[i].unit == unit)
1.1 cvs 3630: {
1.82 cvs 3631: strcat (buffer, CSSUnitNames[i].sign);
1.18 cvs 3632: break;
1.1 cvs 3633: }
3634: }
3635: }
3636: }
3637:
3638: /*----------------------------------------------------------------------
1.59 cvs 3639: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18 cvs 3640: This function must be called when a specific style is applied to an
3641: element.
1.114 quint 3642: The parameter specificity is the specificity of the style, 0 if it is
3643: not really a CSS rule.
1.1 cvs 3644: ----------------------------------------------------------------------*/
1.79 cvs 3645: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.114 quint 3646: int specificity, ThotBool destroy)
1.1 cvs 3647: {
3648: PresentationContext context;
3649: ElementType elType;
1.14 cvs 3650: ThotBool isHTML;
1.1 cvs 3651:
3652: /* A rule applying to BODY is really meant to address HTML */
3653: elType = TtaGetElementType (el);
1.89 cvs 3654:
1.86 cvs 3655: /* store the current line for eventually reported errors */
3656: LineNumber = TtaGetElementLineNumber (el);
1.89 cvs 3657: if (destroy)
3658: /* no reported errors */
3659: ParsedDoc = 0;
3660: else if (ParsedDoc != doc)
3661: {
3662: /* update the context for reported errors */
3663: ParsedDoc = doc;
3664: DocURL = DocumentURLs[doc];
3665: }
1.82 cvs 3666: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
1.1 cvs 3667: /* create the context of the Specific presentation driver */
3668: context = TtaGetSpecificStyleContext (doc);
3669: if (context == NULL)
3670: return;
3671: context->type = elType.ElTypeNum;
1.114 quint 3672: context->cssSpecificity = specificity;
1.1 cvs 3673: context->destroy = destroy;
3674: /* Call the parser */
3675: ParseCSSRule (el, NULL, (PresentationContext) context, cssRule, NULL, isHTML);
3676: /* free the context */
3677: TtaFreeMemory(context);
3678: }
3679:
1.68 cvs 3680:
1.1 cvs 3681: /*----------------------------------------------------------------------
1.59 cvs 3682: ParseGenericSelector: Create a generic context for a given
1.1 cvs 3683: selector string. If the selector is made of multiple comma-
3684: separated selector items, it parses them one at a time and
3685: return the end of the selector string to be handled or NULL
3686: ----------------------------------------------------------------------*/
1.79 cvs 3687: static char *ParseGenericSelector (char *selector, char *cssRule,
3688: GenericContext ctxt, Document doc,
3689: CSSInfoPtr css)
3690: {
3691: ElementType elType;
3692: PSchema tsch;
1.105 cvs 3693: /*AttributeType attrType;*/
1.79 cvs 3694: char sel[MAX_ANCESTORS * 50];
3695: char *deb, *cur;
3696: char *structName;
3697: char *names[MAX_ANCESTORS];
3698: char *ids[MAX_ANCESTORS];
3699: char *classes[MAX_ANCESTORS];
3700: char *pseudoclasses[MAX_ANCESTORS];
3701: char *attrs[MAX_ANCESTORS];
3702: char *attrvals[MAX_ANCESTORS];
1.91 cvs 3703: char *ptr;
3704: int i, j, k, max;
3705: int att, maxAttr;
1.79 cvs 3706: ThotBool isHTML;
3707: ThotBool level;
1.1 cvs 3708:
1.82 cvs 3709: sel[0] = EOS;
1.1 cvs 3710: for (i = 0; i < MAX_ANCESTORS; i++)
3711: {
1.25 cvs 3712: names[i] = NULL;
3713: ids[i] = NULL;
3714: classes[i] = NULL;
3715: pseudoclasses[i] = NULL;
3716: attrs[i] = NULL;
3717: attrvals[i] = NULL;
3718:
3719: ctxt->name[i] = 0;
3720: ctxt->names_nb[i] = 0;
3721: ctxt->attrType[i] = 0;
3722: ctxt->attrText[i] = NULL;
1.1 cvs 3723: }
1.25 cvs 3724: ctxt->box = 0;
3725: ctxt->type = 0;
1.114 quint 3726: /* the specificity of the rule depends on the selector */
3727: ctxt->cssSpecificity = 0;
1.25 cvs 3728:
1.82 cvs 3729: selector = SkipBlanksAndComments (selector);
1.27 cvs 3730: cur = &sel[0];
1.25 cvs 3731: max = 0; /* number of loops */
1.1 cvs 3732: while (1)
3733: {
1.85 cvs 3734: /* point to the following word in sel[] */
1.27 cvs 3735: deb = cur;
1.25 cvs 3736: /* copy an item of the selector into sel[] */
1.1 cvs 3737: /* put one word in the sel buffer */
1.82 cvs 3738: while (*selector != EOS && *selector != ',' &&
3739: *selector != '.' && *selector != ':' &&
3740: *selector != '#' && !TtaIsBlank (selector))
1.50 cvs 3741: *cur++ = *selector++;
1.82 cvs 3742: *cur++ = EOS; /* close the first string in sel[] */
3743: if (deb[0] != EOS)
1.27 cvs 3744: names[0] = deb;
1.25 cvs 3745: else
1.27 cvs 3746: names[0] = NULL;
3747: classes[0] = NULL;
3748: pseudoclasses[0] = NULL;
3749: ids[0] = NULL;
3750: attrs[0] = NULL;
3751: attrvals[0] = NULL;
1.25 cvs 3752:
1.27 cvs 3753: /* now names[0] points to the beginning of the parsed item
1.25 cvs 3754: and cur to the next chain to be parsed */
1.82 cvs 3755: if (*selector == ':' || *selector == '.' || *selector == '#')
1.85 cvs 3756: /* point to the following word in sel[] */
3757: deb = cur;
1.1 cvs 3758:
1.82 cvs 3759: if (*selector == '.')
1.1 cvs 3760: {
3761: selector++;
1.82 cvs 3762: while (*selector != EOS && *selector != ',' &&
3763: *selector != '.' && *selector != ':' &&
3764: !TtaIsBlank (selector))
1.1 cvs 3765: *cur++ = *selector++;
1.86 cvs 3766: /* close the word */
3767: *cur++ = EOS;
1.85 cvs 3768: /* point to the class in sel[] if it's valid name */
1.86 cvs 3769: if (deb[0] <= 64)
3770: CSSParseError ("Invalid class", deb);
3771: else
1.85 cvs 3772: classes[0] = deb;
1.1 cvs 3773: }
1.82 cvs 3774: else if (*selector == ':')
1.1 cvs 3775: {
3776: selector++;
1.82 cvs 3777: while (*selector != EOS && *selector != ',' &&
3778: *selector != '.' && *selector != ':' &&
3779: !TtaIsBlank (selector))
1.50 cvs 3780: *cur++ = *selector++;
1.86 cvs 3781: /* close the word */
3782: *cur++ = EOS;
1.85 cvs 3783: /* point to the pseudoclass in sel[] if it's valid name */
1.86 cvs 3784: if (deb[0] <= 64)
3785: CSSParseError ("Invalid pseudoclass", deb);
3786: else
1.85 cvs 3787: pseudoclasses[0]= deb;
1.1 cvs 3788: }
1.82 cvs 3789: else if (*selector == '#')
1.1 cvs 3790: {
3791: selector++;
1.82 cvs 3792: while (*selector != EOS && *selector != ',' &&
3793: *selector != '.' && *selector != ':' &&
3794: !TtaIsBlank (selector))
1.50 cvs 3795: *cur++ = *selector++;
1.86 cvs 3796: /* close the word */
3797: *cur++ = EOS;
1.85 cvs 3798: /* point to the attribute in sel[] if it's valid name */
1.86 cvs 3799: if (deb[0] <= 64)
3800: CSSParseError ("Invalid id", deb);
3801: else
1.85 cvs 3802: ids[0] = deb;
1.1 cvs 3803: }
1.82 cvs 3804: else if (*selector == '[')
1.1 cvs 3805: {
1.25 cvs 3806: selector++;
1.85 cvs 3807: while (*selector != EOS && *selector != ']' &&
3808: *selector != '=' && *selector != '~')
1.25 cvs 3809: *cur++ = *selector++;
1.86 cvs 3810: /* close the word */
3811: *cur++ = EOS;
1.85 cvs 3812: /* point to the attribute in sel[] if it's valid name */
1.86 cvs 3813: if (deb[0] <= 64)
3814: CSSParseError ("Invalid attribute", deb);
3815: else
1.85 cvs 3816: attrs[0] = deb;
3817: if (*selector == '=')
1.25 cvs 3818: {
1.85 cvs 3819: /* look for a value "xxxx" */
1.82 cvs 3820: while (*selector != EOS && *selector != ']' && *selector != '"')
1.85 cvs 3821: *cur++ = *selector++;
3822: /* there is a value */
1.86 cvs 3823: if (*selector == EOS)
3824: CSSParseError ("Invalid attribute value", deb);
3825: else
1.25 cvs 3826: {
3827: /* we are now parsing the attribute value */
1.27 cvs 3828: attrvals[0] = cur;
1.25 cvs 3829: selector++;
1.82 cvs 3830: while (*selector != EOS && *selector != '"')
1.25 cvs 3831: *cur++ = *selector++;
1.82 cvs 3832: if (*selector != EOS)
1.25 cvs 3833: selector++;
3834: }
3835: }
1.82 cvs 3836: *cur++ = EOS;
1.1 cvs 3837: }
3838:
1.82 cvs 3839: selector = SkipBlanksAndComments (selector);
1.25 cvs 3840: /* is it a multi-level selector? */
1.82 cvs 3841: if (*selector == EOS)
1.1 cvs 3842: /* end of the selector */
3843: break;
1.82 cvs 3844: else if (*selector == ',')
1.1 cvs 3845: {
3846: /* end of the current selector */
3847: selector++;
3848: break;
3849: }
1.25 cvs 3850: else
3851: {
3852: /* shifts the list to make room for the new name */
3853: max++; /* a new level in ancestor tables */
3854: if (max == MAX_ANCESTORS)
3855: /* abort the CSS parsing */
3856: return (selector);
3857: for (i = max; i > 0; i--)
3858: {
3859: names[i] = names[i - 1];
3860: ids[i] = ids[i - 1];
3861: classes[i] = classes[i - 1];
3862: attrs[i] = attrs[i - 1];
3863: attrvals[i] = attrvals[i - 1];
3864: pseudoclasses[i] = pseudoclasses[i - 1];
3865: }
3866: }
1.1 cvs 3867: }
3868:
3869: /* Now set up the context block */
1.25 cvs 3870: i = 0;
3871: k = 0;
3872: j = 0;
1.35 cvs 3873: maxAttr = 0;
1.91 cvs 3874: /* default schema name */
3875: ptr = "HTML";
1.25 cvs 3876: while (i <= max)
3877: {
3878: if (names[i])
3879: {
3880: /* get the new element type of this name */
3881: GIType (names[i], &elType, doc);
3882: if (i == 0)
3883: {
3884: /* Store the element type */
1.106 cvs 3885: #ifdef XML_GENERIC
3886: if (elType.ElSSchema == NULL)
3887: {
3888: /* Search in the list of loaded genereric schemas */
3889: TtaGetXmlElementType (names[i], &elType, NULL, doc);
3890: if (elType.ElSSchema == NULL)
3891: {
3892: char *mappedName, *schemaName;
3893: /* Creation of a new element type in the main schema */
3894: elType.ElSSchema = TtaGetDocumentSSchema (doc);
3895: schemaName = TtaGetSSchemaName(elType.ElSSchema);
3896: if (strcmp (schemaName, "HTML") &&
3897: strcmp (schemaName, "MathML") &&
3898: strcmp (schemaName, "SVG") &&
3899: strcmp (schemaName, "XLink") &&
3900: strcmp (schemaName, "Annot"))
3901: TtaAppendXmlElement (names[i], &elType,
3902: &mappedName, doc);
3903: }
3904: }
3905: #endif /* XML_GENERIC */
1.25 cvs 3906: ctxt->type = elType.ElTypeNum;
1.32 cvs 3907: ctxt->name[0] = elType.ElTypeNum;
3908: ctxt->names_nb[0] = 0;
1.25 cvs 3909: ctxt->schema = elType.ElSSchema;
1.91 cvs 3910: ptr = TtaGetSSchemaName (elType.ElSSchema);
1.27 cvs 3911: k++;
1.25 cvs 3912: }
3913: else if (elType.ElTypeNum != 0)
3914: {
3915: /* look at the current context to see if the type is already
3916: stored */
3917: j = 0;
1.32 cvs 3918: while (j < k && ctxt->name[j] != elType.ElTypeNum)
1.25 cvs 3919: j++;
3920: if (j == k)
3921: {
3922: /* add a new entry */
3923: k++;
3924: ctxt->name[j] = elType.ElTypeNum;
3925: if (j != 0)
3926: ctxt->names_nb[j] = 1;
3927: }
3928: else
3929: /* increment the number of ancestor levels */
3930: ctxt->names_nb[j]++;
3931: }
3932: else
3933: {
3934: /* add a new entry */
3935: j = k;
3936: k++;
3937: }
3938: }
1.1 cvs 3939:
1.25 cvs 3940: /* store attributes information */
3941: if (classes[i])
3942: {
3943: ctxt->attrText[j] = classes[i];
1.100 vatton 3944: if (!strcmp (ptr, "SVG"))
3945: ctxt->attrType[j] = SVG_ATTR_class;
1.91 cvs 3946: else if (!strcmp (ptr, "MathML"))
3947: ctxt->attrType[j] = MathML_ATTR_class;
1.107 cvs 3948: #ifdef XML_GENERIC
3949: else if (!strcmp (ptr, "HTML"))
3950: ctxt->attrType[j] = HTML_ATTR_Class;
3951: else
3952: ctxt->attrType[j] = XML_ATTR_class;
3953: #else /* XML_GENERIC */
1.91 cvs 3954: else
3955: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 3956: #endif /* XML_GENERIC */
1.79 cvs 3957: /* add a new entry */
1.80 cvs 3958: maxAttr = i + 1;
1.25 cvs 3959: }
1.79 cvs 3960: if (pseudoclasses[i])
1.25 cvs 3961: {
3962: ctxt->attrText[j] = pseudoclasses[i];
1.100 vatton 3963: if (!strcmp (ptr, "SVG"))
3964: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
1.91 cvs 3965: else if (!strcmp (ptr, "MathML"))
3966: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
1.107 cvs 3967: #ifdef XML_GENERIC
3968: else if (!strcmp (ptr, "HTML"))
3969: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
3970: else
3971: ctxt->attrType[j] = XML_ATTR_PseudoClass;
3972: #else /* XML_GENERIC */
1.91 cvs 3973: else
3974: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 3975: #endif /* XML_GENERIC */
1.79 cvs 3976: /* add a new entry */
1.80 cvs 3977: maxAttr = i + 1;
1.25 cvs 3978: }
1.79 cvs 3979: if (ids[i])
1.25 cvs 3980: {
3981: ctxt->attrText[j] = ids[i];
1.100 vatton 3982: if (!strcmp (ptr, "SVG"))
3983: ctxt->attrType[j] = SVG_ATTR_id;
1.91 cvs 3984: else if (!strcmp (ptr, "MathML"))
3985: ctxt->attrType[j] = MathML_ATTR_id;
1.107 cvs 3986: #ifdef XML_GENERIC
3987: else if (!strcmp (ptr, "HTML"))
3988: ctxt->attrType[j] = HTML_ATTR_ID;
3989: else
3990: ctxt->attrType[j] = XML_ATTR_id;
3991: #else /* XML_GENERIC */
1.91 cvs 3992: else
3993: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 3994: #endif /* XML_GENERIC */
1.80 cvs 3995: /* add a new entry */
3996: maxAttr = i + 1;
1.25 cvs 3997: }
1.79 cvs 3998: if (attrs[i])
1.25 cvs 3999: {
1.100 vatton 4000: if (!strcmp (ptr, "SVG"))
1.101 cvs 4001: MapXMLAttribute (SVG_TYPE, attrs[i], names[i], &level, doc, &att);
1.91 cvs 4002: else if (!strcmp (ptr, "MathML"))
4003: MapXMLAttribute (MATH_TYPE, attrs[i], names[i], &level, doc, &att);
4004: else
4005: MapXMLAttribute (XHTML_TYPE, attrs[i], names[i], &level, doc, &att);
1.25 cvs 4006: ctxt->attrText[j] = attrvals[i];
1.91 cvs 4007: /* we should pass also the attribute schema in the context */
4008: ctxt->attrType[j] = att;
1.80 cvs 4009: maxAttr = i + 1;
1.25 cvs 4010: }
4011: i++;
1.1 cvs 4012: }
4013:
1.25 cvs 4014: /* sort the list of ancestors by name order */
4015: max = k;
4016: i = 1;
4017: while (i < max)
1.28 cvs 4018: {
4019: for (k = i + 1; k < max; k++)
4020: if (ctxt->name[i] > ctxt->name[k])
4021: {
4022: j = ctxt->name[i];
4023: ctxt->name[i] = ctxt->name[k];
4024: ctxt->name[k] = j;
4025: j = ctxt->names_nb[i];
4026: ctxt->names_nb[i] = ctxt->names_nb[k];
4027: ctxt->names_nb[k] = j;
4028: j = ctxt->attrType[i];
4029: ctxt->attrType[i] = ctxt->attrType[k];
4030: ctxt->attrType[k] = j;
4031: cur = ctxt->attrText[i];
4032: ctxt->attrText[i] = ctxt->attrText[k];
4033: ctxt->attrText[k] = cur;
4034: }
4035: i++;
4036: }
1.84 cvs 4037:
1.25 cvs 4038: /* Get the schema name of the main element */
1.105 cvs 4039: if (ctxt->schema != NULL)
4040: {
4041: isHTML = (strcmp (TtaGetSSchemaName (ctxt->schema), "HTML") == 0);
4042: tsch = GetPExtension (doc, ctxt->schema, css);
4043: structName = TtaGetSSchemaName (ctxt->schema);
4044: if (tsch && cssRule)
4045: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
4046: }
1.1 cvs 4047: return (selector);
4048: }
4049:
4050: /*----------------------------------------------------------------------
1.73 cvs 4051: ParseStyleDeclaration: parse a style declaration
4052: stored in the style element of a document
1.59 cvs 4053: We expect the style string to be of the form:
1.1 cvs 4054: [
4055: e.g: pinky, awful { color: pink, font-family: helvetica }
4056: ----------------------------------------------------------------------*/
1.79 cvs 4057: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
4058: CSSInfoPtr css, ThotBool destroy)
1.1 cvs 4059: {
1.79 cvs 4060: GenericContext ctxt;
4061: char *decl_end;
4062: char *sel_end;
4063: char *selector;
4064: char saved1;
4065: char saved2;
1.1 cvs 4066:
4067: /* separate the selectors string */
1.82 cvs 4068: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 4069: decl_end = cssRule;
1.82 cvs 4070: while (*decl_end != EOS && *decl_end != '{')
1.1 cvs 4071: decl_end++;
1.82 cvs 4072: if (*decl_end == EOS)
1.86 cvs 4073: {
4074: CSSParseError ("Invalid selector", cssRule);
4075: return;
4076: }
1.1 cvs 4077: /* verify and clean the selector string */
4078: sel_end = decl_end - 1;
1.82 cvs 4079: while (*sel_end == SPACE || *sel_end == BSPACE ||
4080: *sel_end == EOL || *sel_end == CR)
1.1 cvs 4081: sel_end--;
4082: sel_end++;
4083: saved1 = *sel_end;
1.82 cvs 4084: *sel_end = EOS;
1.1 cvs 4085: selector = cssRule;
4086:
4087: /* now, deal with the content ... */
4088: decl_end++;
4089: cssRule = decl_end;
1.82 cvs 4090: while (*decl_end != EOS && *decl_end != '}')
1.1 cvs 4091: decl_end++;
1.82 cvs 4092: if (*decl_end == EOS)
1.1 cvs 4093: {
1.86 cvs 4094: CSSParseError ("Invalid selector", cssRule);
1.1 cvs 4095: return;
4096: }
4097: saved2 = *decl_end;
1.82 cvs 4098: *decl_end = EOS;
1.1 cvs 4099:
4100: /*
4101: * parse the style attribute string and install the corresponding
4102: * presentation attributes on the new element
4103: */
4104: ctxt = TtaGetGenericStyleContext (doc);
4105: if (ctxt == NULL)
4106: return;
4107: ctxt->destroy = destroy;
4108:
1.82 cvs 4109: while ((selector != NULL) && (*selector != EOS))
1.25 cvs 4110: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css);
1.1 cvs 4111: TtaFreeMemory (ctxt);
4112:
4113: /* restore the string to its original form ! */
4114: *sel_end = saved1;
4115: *decl_end = saved2;
4116: }
4117:
4118: /************************************************************************
4119: * *
4120: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
4121: * *
4122: ************************************************************************/
4123:
4124: /*----------------------------------------------------------------------
1.59 cvs 4125: IsImplicitClassName: return wether the Class name is an
1.1 cvs 4126: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
4127: or an HTML context name.
4128: ----------------------------------------------------------------------*/
1.79 cvs 4129: int IsImplicitClassName (char *class, Document doc)
1.1 cvs 4130: {
1.79 cvs 4131: char name[200];
4132: char *cur = name;
4133: char *first;
4134: char save;
4135: SSchema schema;
1.1 cvs 4136:
4137: /* make a local copy */
1.82 cvs 4138: strncpy (name, class, 199);
1.1 cvs 4139: name[199] = 0;
4140:
4141: /* loop looking if each word is a GI */
4142: while (*cur != 0)
4143: {
4144: first = cur;
4145: cur = SkipWord (cur);
4146: save = *cur;
4147: *cur = 0;
4148: schema = NULL;
4149: if (MapGI (first, &schema, doc) == -1)
4150: {
4151: return (0);
4152: }
4153: *cur = save;
1.82 cvs 4154: cur = SkipBlanksAndComments (cur);
1.1 cvs 4155: }
4156: return (1);
4157: }
4158:
4159: /************************************************************************
4160: * *
1.114 quint 4161: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 4162: * *
4163: ************************************************************************/
4164:
4165: /*----------------------------------------------------------------------
1.59 cvs 4166: HTMLSetBackgroundColor:
1.1 cvs 4167: ----------------------------------------------------------------------*/
1.79 cvs 4168: void HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1 cvs 4169: {
1.79 cvs 4170: char css_command[100];
1.1 cvs 4171:
1.82 cvs 4172: sprintf (css_command, "background-color: %s", color);
1.114 quint 4173: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4174: }
4175:
4176: /*----------------------------------------------------------------------
1.59 cvs 4177: HTMLSetBackgroundImage:
1.1 cvs 4178: repeat = repeat value
4179: image = url of background image
4180: ----------------------------------------------------------------------*/
1.79 cvs 4181: void HTMLSetBackgroundImage (Document doc, Element el, int repeat, char *image)
1.1 cvs 4182: {
1.79 cvs 4183: char css_command[400];
1.1 cvs 4184:
4185: /******* check buffer overflow ********/
1.82 cvs 4186: sprintf (css_command, "background-image: url(%s); background-repeat: ", image);
1.1 cvs 4187: if (repeat == STYLE_REPEAT)
1.82 cvs 4188: strcat (css_command, "repeat");
1.1 cvs 4189: else if (repeat == STYLE_HREPEAT)
1.82 cvs 4190: strcat (css_command, "repeat-x");
1.1 cvs 4191: else if (repeat == STYLE_VREPEAT)
1.82 cvs 4192: strcat (css_command, "repeat-y");
1.1 cvs 4193: else
1.82 cvs 4194: strcat (css_command, "no-repeat");
1.114 quint 4195: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4196: }
4197:
4198: /*----------------------------------------------------------------------
1.59 cvs 4199: HTMLSetForegroundColor:
1.1 cvs 4200: ----------------------------------------------------------------------*/
1.97 vatton 4201: void HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1 cvs 4202: {
1.79 cvs 4203: char css_command[100];
1.1 cvs 4204:
1.82 cvs 4205: sprintf (css_command, "color: %s", color);
1.114 quint 4206: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4207: }
4208:
4209: /*----------------------------------------------------------------------
1.59 cvs 4210: HTMLResetBackgroundColor:
1.1 cvs 4211: ----------------------------------------------------------------------*/
1.97 vatton 4212: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 4213: {
1.79 cvs 4214: char css_command[100];
1.1 cvs 4215:
1.82 cvs 4216: sprintf (css_command, "background: red");
1.114 quint 4217: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4218: }
4219:
4220: /*----------------------------------------------------------------------
1.59 cvs 4221: HTMLResetBackgroundImage:
1.1 cvs 4222: ----------------------------------------------------------------------*/
1.97 vatton 4223: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 4224: {
1.79 cvs 4225: char css_command[1000];
1.1 cvs 4226:
1.82 cvs 4227: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.114 quint 4228: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4229: }
4230:
4231: /*----------------------------------------------------------------------
1.59 cvs 4232: HTMLResetForegroundColor:
1.1 cvs 4233: ----------------------------------------------------------------------*/
1.97 vatton 4234: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 4235: {
1.79 cvs 4236: char css_command[100];
1.1 cvs 4237:
1.36 cvs 4238: /* it's not necessary to well know the current color but it must be valid */
1.82 cvs 4239: sprintf (css_command, "color: red");
1.114 quint 4240: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4241: }
4242:
4243: /*----------------------------------------------------------------------
1.59 cvs 4244: HTMLSetAlinkColor:
1.1 cvs 4245: ----------------------------------------------------------------------*/
1.97 vatton 4246: void HTMLSetAlinkColor (Document doc, char *color)
1.1 cvs 4247: {
1.79 cvs 4248: char css_command[100];
1.1 cvs 4249:
1.82 cvs 4250: sprintf (css_command, "a:link { color: %s }", color);
1.1 cvs 4251: ApplyCSSRules (NULL, css_command, doc, FALSE);
4252: }
4253:
4254: /*----------------------------------------------------------------------
1.59 cvs 4255: HTMLSetAactiveColor:
1.1 cvs 4256: ----------------------------------------------------------------------*/
1.97 vatton 4257: void HTMLSetAactiveColor (Document doc, char *color)
1.1 cvs 4258: {
1.79 cvs 4259: char css_command[100];
1.1 cvs 4260:
1.82 cvs 4261: sprintf (css_command, "a:active { color: %s }", color);
1.1 cvs 4262: ApplyCSSRules (NULL, css_command, doc, FALSE);
4263: }
4264:
4265: /*----------------------------------------------------------------------
1.59 cvs 4266: HTMLSetAvisitedColor:
1.1 cvs 4267: ----------------------------------------------------------------------*/
1.79 cvs 4268: void HTMLSetAvisitedColor (Document doc, char *color)
1.1 cvs 4269: {
1.79 cvs 4270: char css_command[100];
1.1 cvs 4271:
1.82 cvs 4272: sprintf (css_command, "a:visited { color: %s }", color);
1.1 cvs 4273: ApplyCSSRules (NULL, css_command, doc, FALSE);
4274: }
4275:
4276: /*----------------------------------------------------------------------
1.59 cvs 4277: HTMLResetAlinkColor:
1.1 cvs 4278: ----------------------------------------------------------------------*/
4279: void HTMLResetAlinkColor (Document doc)
4280: {
1.79 cvs 4281: char css_command[100];
1.1 cvs 4282:
1.82 cvs 4283: sprintf (css_command, "a:link { color: red }");
1.1 cvs 4284: ApplyCSSRules (NULL, css_command, doc, TRUE);
4285: }
4286:
4287: /*----------------------------------------------------------------------
1.59 cvs 4288: HTMLResetAactiveColor:
1.1 cvs 4289: ----------------------------------------------------------------------*/
4290: void HTMLResetAactiveColor (Document doc)
4291: {
1.79 cvs 4292: char css_command[100];
1.1 cvs 4293:
1.82 cvs 4294: sprintf (css_command, "a:active { color: red }");
1.1 cvs 4295: ApplyCSSRules (NULL, css_command, doc, TRUE);
4296: }
4297:
4298: /*----------------------------------------------------------------------
1.59 cvs 4299: HTMLResetAvisitedColor:
1.1 cvs 4300: ----------------------------------------------------------------------*/
4301: void HTMLResetAvisitedColor (Document doc)
4302: {
1.79 cvs 4303: char css_command[100];
1.1 cvs 4304:
1.82 cvs 4305: sprintf (css_command, "a:visited { color: red }");
1.1 cvs 4306: ApplyCSSRules (NULL, css_command, doc, TRUE);
4307: }
4308:
4309: /*----------------------------------------------------------------------
1.73 cvs 4310: ApplyCSSRules: parse a CSS Style description stored in the
1.1 cvs 4311: header of a HTML document.
4312: ----------------------------------------------------------------------*/
1.79 cvs 4313: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 4314: {
4315: CSSInfoPtr css;
4316:
4317: css = SearchCSS (doc, NULL);
4318: if (css == NULL)
4319: /* create the document css */
4320: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, NULL, NULL);
4321: ParseStyleDeclaration (el, cssRule, doc, css, destroy);
4322: }
4323:
4324: /*----------------------------------------------------------------------
1.59 cvs 4325: ReadCSSRules: is the front-end function called by the HTML parser
1.1 cvs 4326: when detecting a <STYLE TYPE="text/css"> indicating it's the
4327: beginning of a CSS fragment or when reading a file .css.
4328:
4329: The CSS parser has to handle <!-- ... --> constructs used to
4330: prevent prehistoric browser from displaying the CSS as a text
4331: content. It will stop on any sequence "<x" where x is different
4332: from ! and will return x as to the caller. Theorically x should
4333: be equal to / for the </STYLE> end of style.
4334:
4335: The parameter doc gives the document tree that contains CSS information.
4336: The parameter docRef gives the document to which CSS are to be applied.
4337: This function uses the current css context or creates it. It's able
1.23 cvs 4338: to work on the given buffer or call GetNextChar to read the parsed
1.1 cvs 4339: file.
1.86 cvs 4340: Parameter numberOfLinesRead indicates the number of lines already
4341: read in the file.
1.1 cvs 4342: Parameter withUndo indicates whether the changes made in the document
4343: structure and content have to be registered in the Undo queue or not
4344: ----------------------------------------------------------------------*/
1.86 cvs 4345: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer,
4346: int numberOfLinesRead, ThotBool withUndo)
1.1 cvs 4347: {
1.6 cvs 4348: DisplayMode dispMode;
1.82 cvs 4349: char c;
4350: char *cssRule, *base;
1.19 cvs 4351: int index;
1.1 cvs 4352: int CSSindex;
4353: int CSScomment;
4354: int import;
4355: int openRule;
1.93 vatton 4356: int newlines;
1.14 cvs 4357: ThotBool HTMLcomment;
1.102 vatton 4358: ThotBool toParse, eof, quoted;
1.36 cvs 4359: ThotBool ignoreMedia, media;
1.88 cvs 4360: ThotBool noRule, ignoreImport;
1.1 cvs 4361:
4362: CSScomment = MAX_CSS_LENGTH;
4363: HTMLcomment = FALSE;
4364: CSSindex = 0;
4365: toParse = FALSE;
4366: noRule = FALSE;
1.36 cvs 4367: media = FALSE;
1.88 cvs 4368: ignoreImport = FALSE;
1.1 cvs 4369: ignoreMedia = FALSE;
4370: import = MAX_CSS_LENGTH;
4371: eof = FALSE;
4372: openRule = 0;
1.82 cvs 4373: c = SPACE;
1.1 cvs 4374: index = 0;
1.93 vatton 4375: /* number of new lines parsed */
4376: newlines = 0;
1.6 cvs 4377: /* avoid too many redisplay */
4378: dispMode = TtaGetDisplayMode (docRef);
4379: if (dispMode == DisplayImmediately)
4380: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 4381:
4382: /* look for the CSS context */
4383: if (css == NULL)
4384: css = SearchCSS (docRef, NULL);
4385: if (css == NULL)
4386: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, NULL, NULL);
1.1 cvs 4387:
1.86 cvs 4388: /* register parsed CSS file and the document to which CSS are to be applied */
4389: ParsedDoc = docRef;
4390: if (css->url)
4391: DocURL = css->url;
4392: else
4393: /* the CSS source in within the document itself */
4394: DocURL = DocumentURLs[docRef];
4395: LineNumber = numberOfLinesRead + 1;
1.93 vatton 4396: NewLineSkipped = 0;
1.82 cvs 4397: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
4398: {
4399: c = buffer[index++];
4400: eof = (c == EOS);
4401: CSSbuffer[CSSindex] = c;
4402: if (CSScomment == MAX_CSS_LENGTH ||
4403: c == '*' || c == '/' || c == '<')
4404: {
4405: /* we're not within a comment or we're parsing * or / */
4406: switch (c)
4407: {
4408: case '@': /* perhaps an import primitive */
4409: import = CSSindex;
4410: break;
4411: case ';':
4412: if (import != MAX_CSS_LENGTH && !media)
4413: {
4414: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
4415: /* it's not an import */
4416: import = MAX_CSS_LENGTH;
4417: /* save the text */
4418: noRule = TRUE;
4419: }
4420: break;
4421: case '*':
4422: if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
4423: CSSbuffer[CSSindex - 1] == '/')
4424: /* start a comment */
4425: CSScomment = CSSindex - 1;
4426: break;
4427: case '/':
4428: if (CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
4429: CSSbuffer[CSSindex - 1] == '*')
4430: {
4431: /* close a comment:and ignore its contents */
4432: CSSindex = CSScomment - 1; /* will be incremented later */
4433: CSScomment = MAX_CSS_LENGTH;
1.93 vatton 4434: /* clean up the buffer */
1.103 vatton 4435: if (newlines && CSSindex > 0)
4436: while (CSSindex > 0 &&
4437: (CSSbuffer[CSSindex] == SPACE ||
4438: CSSbuffer[CSSindex] == BSPACE ||
4439: CSSbuffer[CSSindex] == EOL ||
4440: CSSbuffer[CSSindex] == TAB ||
4441: CSSbuffer[CSSindex] == __CR__))
1.93 vatton 4442: {
4443: if ( CSSbuffer[CSSindex] == EOL)
4444: {
4445: LineNumber ++;
4446: newlines --;
4447: }
4448: CSSindex--;
4449: }
1.82 cvs 4450: }
4451: else if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
4452: CSSbuffer[CSSindex - 1] == '<')
4453: {
4454: /* this is the closing tag ! */
4455: CSSindex -= 2; /* remove </ from the CSS string */
4456: noRule = TRUE;
4457: }
4458: break;
4459: case '<':
4460: if (CSScomment == MAX_CSS_LENGTH)
4461: {
4462: /* only if we're not parsing a comment */
4463: c = buffer[index++];
4464: eof = (c == EOS);
4465: if (c == '!')
4466: {
4467: /* CSS within an HTML comment */
4468: HTMLcomment = TRUE;
4469: CSSindex++;
4470: CSSbuffer[CSSindex] = c;
4471: }
4472: else if (c == EOS)
4473: CSSindex++;
4474: }
4475: break;
4476: case '-':
4477: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
4478: HTMLcomment)
4479: /* CSS within an HTML comment */
4480: noRule = TRUE;
4481: break;
4482: case '>':
4483: if (HTMLcomment)
4484: noRule = TRUE;
4485: break;
4486: case ' ':
4487: if (import != MAX_CSS_LENGTH && openRule == 0)
4488: media = !strncmp (&CSSbuffer[import+1], "media", 5);
4489: break;
4490: case '{':
4491: openRule++;
4492: if (import != MAX_CSS_LENGTH && openRule == 1 && media)
4493: {
4494: /* is it the screen concerned? */
4495: CSSbuffer[CSSindex+1] = EOS;
4496: if (TtaIsPrinting ())
4497: base = strstr (&CSSbuffer[import], "print");
4498: else
4499: base = strstr (&CSSbuffer[import], "screen");
4500: if (base == NULL)
4501: ignoreMedia = TRUE;
4502: noRule = TRUE;
4503: }
4504: break;
4505: case '}':
4506: openRule--;
4507: if (import != MAX_CSS_LENGTH && openRule == 0)
4508: {
4509: import = MAX_CSS_LENGTH;
4510: noRule = TRUE;
4511: ignoreMedia = FALSE;
4512: media = FALSE;
4513: }
4514: else
4515: toParse = TRUE;
4516: break;
4517: default:
1.86 cvs 4518: if (c == EOL)
1.93 vatton 4519: newlines++;
1.82 cvs 4520: break;
4521: }
4522: }
1.93 vatton 4523: else if (c == EOL)
4524: LineNumber++;
1.82 cvs 4525: if (c != CR)
4526: CSSindex++;
4527:
4528: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
4529: /* we're still parsing a comment: remove the text comment */
4530: CSSindex = CSScomment;
4531:
4532: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
4533: {
4534: CSSbuffer[CSSindex] = EOS;
4535: /* parse a not empty string */
4536: if (CSSindex > 0)
4537: {
1.50 cvs 4538: /* apply CSS rule if it's not just a saving of text */
4539: if (!noRule && !ignoreMedia)
1.88 cvs 4540: {
4541: /* future import rules must be ignored */
4542: ignoreImport = TRUE;
4543: ParseStyleDeclaration (NULL, CSSbuffer, docRef, css, FALSE);
1.93 vatton 4544: LineNumber += newlines;
4545: newlines = 0;
4546: NewLineSkipped = 0;
1.88 cvs 4547: }
1.82 cvs 4548: else if (import != MAX_CSS_LENGTH &&
4549: !strncasecmp (&CSSbuffer[import+1], "import", 6))
4550: {
4551: /* import section */
4552: cssRule = &CSSbuffer[import+7];
4553: cssRule = TtaSkipBlanks (cssRule);
1.93 vatton 4554: /* save the current line number */
4555: newlines += LineNumber;
1.82 cvs 4556: if (!strncasecmp (cssRule, "url", 3))
4557: {
1.50 cvs 4558: cssRule = &cssRule[3];
1.82 cvs 4559: cssRule = TtaSkipBlanks (cssRule);
4560: if (*cssRule == '(')
4561: {
4562: cssRule++;
4563: cssRule = TtaSkipBlanks (cssRule);
1.102 vatton 4564: quoted = (*cssRule == '"' || *cssRule == '\'');
4565: if (quoted)
4566: cssRule++;
1.82 cvs 4567: base = cssRule;
4568: while (*cssRule != EOS && *cssRule != ')')
4569: cssRule++;
1.102 vatton 4570: if (quoted)
4571: cssRule--;
1.82 cvs 4572: *cssRule = EOS;
1.88 cvs 4573: if (!ignoreImport)
1.115 ! quint 4574: LoadStyleSheet (base, docRef, NULL, css,
! 4575: css->media[docRef],
! 4576: css->category == CSS_USER_STYLE);
1.82 cvs 4577: }
4578: }
1.87 cvs 4579: else if (*cssRule == '"')
4580: {
1.88 cvs 4581: /*
4582: Do we have to accept single quotes?
4583: Double quotes are acceted here.
4584: Escaped quotes are not handled. See function SkipQuotedString
4585: */
1.87 cvs 4586: cssRule++;
4587: cssRule = TtaSkipBlanks (cssRule);
4588: base = cssRule;
4589: while (*cssRule != EOS && *cssRule != '"')
4590: cssRule++;
4591: *cssRule = EOS;
1.88 cvs 4592: if (!ignoreImport)
1.115 ! quint 4593: LoadStyleSheet (base, docRef, NULL, css,
! 4594: css->media[docRef],
! 4595: css->category == CSS_USER_STYLE);
1.82 cvs 4596: }
1.93 vatton 4597: /* restore the number of lines */
4598: LineNumber = newlines;
4599: newlines = 0;
1.82 cvs 4600: import = MAX_CSS_LENGTH;
4601: }
1.93 vatton 4602:
1.82 cvs 4603: }
4604: toParse = FALSE;
4605: noRule = FALSE;
4606: CSSindex = 0;
1.50 cvs 4607: }
1.82 cvs 4608: }
1.6 cvs 4609: /* restore the display mode */
4610: if (dispMode == DisplayImmediately)
1.82 cvs 4611: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 4612:
4613: /* Prepare the context for style attributes */
4614: DocURL = DocumentURLs[docRef];
4615: LineNumber = -1;
1.1 cvs 4616: return (c);
4617: }
1.89 cvs 4618:
Webmaster