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