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