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