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