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