Annotation of Amaya/amaya/styleparser.c, revision 1.251
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.79 cvs 1975: char quoteChar;
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.92 cvs 2046: if (quoteChar != EOS)
1.54 cvs 2047: cssRule = SkipQuotedString (cssRule, quoteChar);
1.86 cvs 2048: else
1.1 cvs 2049: cssRule = SkipWord (cssRule);
1.82 cvs 2050: cssRule = SkipBlanksAndComments (cssRule);
2051: if (*cssRule == ',')
1.1 cvs 2052: {
1.239 vatton 2053: /* recursive call to ParseCSSFontFamily */
1.86 cvs 2054: cssRule++;
2055: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
2056: return (cssRule);
1.1 cvs 2057: }
2058: }
2059:
1.239 vatton 2060: /* skip other values */
2061: cssRule = SkipBlanksAndComments (cssRule);
2062: while (*cssRule == ',')
2063: {
2064: cssRule++;
2065: cssRule = SkipValue (NULL, cssRule);
2066: cssRule = SkipBlanksAndComments (cssRule);
2067: }
2068:
1.1 cvs 2069: if (font.typed_data.value != 0)
2070: {
1.93 vatton 2071: /* install the new presentation */
1.116 vatton 2072: if (DoApply)
1.117 vatton 2073: {
2074: if (tsch)
2075: cssRule = CheckImportantRule (cssRule, context);
2076: TtaSetStylePresentation (PRFont, element, tsch, context, font);
2077: }
1.1 cvs 2078: }
2079: return (cssRule);
2080: }
2081:
2082: /*----------------------------------------------------------------------
1.59 cvs 2083: ParseCSSFontWeight: parse a CSS font weight string
1.1 cvs 2084: we expect the input string describing the attribute to be
1.20 cvs 2085: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 2086: ----------------------------------------------------------------------*/
1.79 cvs 2087: static char *ParseCSSFontWeight (Element element, PSchema tsch,
2088: PresentationContext context, char *cssRule,
2089: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2090: {
1.20 cvs 2091: PresentationValue weight;
1.1 cvs 2092:
2093: weight.typed_data.value = 0;
1.184 vatton 2094: weight.typed_data.unit = UNIT_REL;
1.1 cvs 2095: weight.typed_data.real = FALSE;
1.82 cvs 2096: cssRule = SkipBlanksAndComments (cssRule);
2097: if (!strncasecmp (cssRule, "100", 3) && !isalpha (cssRule[3]))
1.1 cvs 2098: {
2099: weight.typed_data.value = -3;
2100: cssRule = SkipWord (cssRule);
2101: }
1.82 cvs 2102: else if (!strncasecmp (cssRule, "200", 3) && !isalpha (cssRule[3]))
1.1 cvs 2103: {
2104: weight.typed_data.value = -2;
2105: cssRule = SkipWord (cssRule);
2106: }
1.82 cvs 2107: else if (!strncasecmp (cssRule, "300", 3) && ! isalpha(cssRule[3]))
1.1 cvs 2108: {
2109: weight.typed_data.value = -1;
2110: cssRule = SkipWord (cssRule);
2111: }
1.82 cvs 2112: else if (!strncasecmp (cssRule, "normal", 6) || (!strncasecmp (cssRule, "400", 3) && !isalpha (cssRule[3])))
1.1 cvs 2113: {
2114: weight.typed_data.value = 0;
2115: cssRule = SkipWord (cssRule);
2116: }
1.82 cvs 2117: else if (!strncasecmp (cssRule, "500", 3) && !isalpha (cssRule[3]))
1.1 cvs 2118: {
2119: weight.typed_data.value = +1;
2120: cssRule = SkipWord (cssRule);
2121: }
1.82 cvs 2122: else if (!strncasecmp (cssRule, "600", 3) && !isalpha (cssRule[3]))
1.1 cvs 2123: {
2124: weight.typed_data.value = +2;
2125: cssRule = SkipWord (cssRule);
2126: }
1.82 cvs 2127: else if (!strncasecmp (cssRule, "bold", 4) || (!strncasecmp (cssRule, "700", 3) && !isalpha (cssRule[3])))
1.1 cvs 2128: {
2129: weight.typed_data.value = +3;
2130: cssRule = SkipWord (cssRule);
2131: }
1.82 cvs 2132: else if (!strncasecmp (cssRule, "800", 3) && !isalpha (cssRule[3]))
1.1 cvs 2133: {
2134: weight.typed_data.value = +4;
2135: cssRule = SkipWord (cssRule);
2136: }
1.82 cvs 2137: else if (!strncasecmp (cssRule, "900", 3) && !isalpha (cssRule[3]))
1.1 cvs 2138: {
2139: weight.typed_data.value = +5;
2140: cssRule = SkipWord (cssRule);
2141: }
1.82 cvs 2142: else if (!strncasecmp (cssRule, "inherit", 7) || !strncasecmp (cssRule, "bolder", 6) || !strncasecmp (cssRule, "lighter", 7))
1.1 cvs 2143: {
2144: /* not implemented */
2145: cssRule = SkipWord (cssRule);
2146: return (cssRule);
2147: }
2148: else
2149: return (cssRule);
2150:
2151: /*
1.20 cvs 2152: * Here we have to reduce since only two font weight values are supported
1.1 cvs 2153: * by the Thot presentation API.
2154: */
1.20 cvs 2155: if (weight.typed_data.value > 0)
1.184 vatton 2156: weight.typed_data.value = WeightBold;
1.20 cvs 2157: else
1.184 vatton 2158: weight.typed_data.value = WeightNormal;
1.1 cvs 2159:
2160: /* install the new presentation */
1.116 vatton 2161: if (DoApply)
1.117 vatton 2162: {
2163: if (tsch)
2164: cssRule = CheckImportantRule (cssRule, context);
2165: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
2166: }
1.1 cvs 2167: return (cssRule);
2168: }
2169:
2170: /*----------------------------------------------------------------------
1.59 cvs 2171: ParseCSSFontVariant: parse a CSS font variant string
1.1 cvs 2172: we expect the input string describing the attribute to be
2173: normal or small-caps
2174: ----------------------------------------------------------------------*/
1.79 cvs 2175: static char *ParseCSSFontVariant (Element element, PSchema tsch,
2176: PresentationContext context, char *cssRule,
2177: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2178: {
2179: PresentationValue style;
2180:
2181: style.typed_data.value = 0;
1.184 vatton 2182: style.typed_data.unit = UNIT_REL;
1.1 cvs 2183: style.typed_data.real = FALSE;
1.82 cvs 2184: cssRule = SkipBlanksAndComments (cssRule);
2185: if (!strncasecmp (cssRule, "small-caps", 10))
1.1 cvs 2186: {
2187: /* Not supported yet */
2188: cssRule = SkipWord (cssRule);
2189: }
1.82 cvs 2190: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 2191: {
2192: /* Not supported yet */
2193: cssRule = SkipWord (cssRule);
2194: }
1.82 cvs 2195: else if (!strncasecmp (cssRule, "inherit", 7))
1.1 cvs 2196: {
2197: /* Not supported yet */
2198: cssRule = SkipWord (cssRule);
2199: }
2200: else
2201: return (cssRule);
2202:
2203: return (cssRule);
2204: }
2205:
2206:
2207: /*----------------------------------------------------------------------
1.59 cvs 2208: ParseCSSFontStyle: parse a CSS font style string
1.1 cvs 2209: we expect the input string describing the attribute to be
2210: italic, oblique or normal
2211: ----------------------------------------------------------------------*/
1.79 cvs 2212: static char *ParseCSSFontStyle (Element element, PSchema tsch,
2213: PresentationContext context, char *cssRule,
2214: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2215: {
2216: PresentationValue style;
2217: PresentationValue size;
2218:
2219: style.typed_data.value = 0;
1.184 vatton 2220: style.typed_data.unit = UNIT_REL;
1.1 cvs 2221: style.typed_data.real = FALSE;
2222: size.typed_data.value = 0;
1.184 vatton 2223: size.typed_data.unit = UNIT_REL;
1.1 cvs 2224: size.typed_data.real = FALSE;
1.82 cvs 2225: cssRule = SkipBlanksAndComments (cssRule);
2226: if (!strncasecmp (cssRule, "italic", 6))
1.1 cvs 2227: {
1.184 vatton 2228: style.typed_data.value = StyleItalics;
1.1 cvs 2229: cssRule = SkipWord (cssRule);
2230: }
1.82 cvs 2231: else if (!strncasecmp (cssRule, "oblique", 7))
1.1 cvs 2232: {
1.184 vatton 2233: style.typed_data.value = StyleOblique;
1.1 cvs 2234: cssRule = SkipWord (cssRule);
2235: }
1.82 cvs 2236: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 2237: {
1.184 vatton 2238: style.typed_data.value = StyleRoman;
1.1 cvs 2239: cssRule = SkipWord (cssRule);
2240: }
1.108 cvs 2241: else if (!strncasecmp (cssRule, "inherit", 7))
2242: {
2243: /* not implemented */
2244: cssRule = SkipWord (cssRule);
2245: return (cssRule);
2246: }
1.1 cvs 2247: else
2248: {
2249: /* invalid font style */
1.108 cvs 2250: return (cssRule);
1.1 cvs 2251: }
2252:
2253: /*
2254: * install the new presentation.
2255: */
1.116 vatton 2256: if (style.typed_data.value != 0 && DoApply)
1.117 vatton 2257: {
2258: if (tsch)
2259: cssRule = CheckImportantRule (cssRule, context);
1.20 cvs 2260: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.117 vatton 2261: }
1.116 vatton 2262: if (size.typed_data.value != 0 && DoApply)
1.1 cvs 2263: {
2264: PresentationValue previous_size;
2265:
2266: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
2267: {
2268: /* !!!!!!!!!!!!!!!!!!!!!!!! Unite + relatif !!!!!!!!!!!!!!!! */
2269: size.typed_data.value += previous_size.typed_data.value;
2270: TtaSetStylePresentation (PRSize, element, tsch, context, size);
2271: }
2272: else
2273: {
2274: size.typed_data.value = 10;
2275: TtaSetStylePresentation (PRSize, element, tsch, context, size);
2276: }
2277: }
2278: return (cssRule);
2279: }
2280:
2281: /*----------------------------------------------------------------------
1.59 cvs 2282: ParseCSSFont: parse a CSS font attribute string
2283: we expect the input string describing the attribute to be
2284: !!!!!!
1.1 cvs 2285: ----------------------------------------------------------------------*/
1.79 cvs 2286: static char *ParseCSSFont (Element element, PSchema tsch,
2287: PresentationContext context, char *cssRule,
2288: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2289: {
1.79 cvs 2290: char *ptr;
1.93 vatton 2291: int skippedNL;
1.1 cvs 2292:
1.82 cvs 2293: cssRule = SkipBlanksAndComments (cssRule);
2294: if (!strncasecmp (cssRule, "caption", 7))
1.1 cvs 2295: ;
1.82 cvs 2296: else if (!strncasecmp (cssRule, "icon", 4))
1.1 cvs 2297: ;
1.82 cvs 2298: else if (!strncasecmp (cssRule, "menu", 4))
1.1 cvs 2299: ;
1.82 cvs 2300: else if (!strncasecmp (cssRule, "message-box", 11))
1.1 cvs 2301: ;
1.82 cvs 2302: else if (!strncasecmp (cssRule, "small-caption", 13))
1.1 cvs 2303: ;
1.82 cvs 2304: else if (!strncasecmp (cssRule, "status-bar", 10))
1.1 cvs 2305: ;
2306: else
1.43 cvs 2307: {
1.133 vatton 2308: while (*cssRule != ';' && *cssRule != EOS)
1.43 cvs 2309: {
1.72 cvs 2310: ptr = cssRule;
1.93 vatton 2311: skippedNL = NewLineSkipped;
1.72 cvs 2312: cssRule = ParseCSSFontStyle (element, tsch, context, cssRule, css, isHTML);
2313: if (ptr == cssRule)
1.93 vatton 2314: {
2315: NewLineSkipped = skippedNL;
2316: cssRule = ParseCSSFontVariant (element, tsch, context, cssRule, css, isHTML);
2317: }
1.72 cvs 2318: if (ptr == cssRule)
1.93 vatton 2319: {
2320: NewLineSkipped = skippedNL;
2321: cssRule = ParseCSSFontWeight (element, tsch, context, cssRule, css, isHTML);
2322: }
1.72 cvs 2323: if (ptr == cssRule)
1.93 vatton 2324: {
2325: NewLineSkipped = skippedNL;
2326: cssRule = ParseCSSFontSize (element, tsch, context, cssRule, css, isHTML);
2327: }
1.72 cvs 2328: if (ptr == cssRule)
1.93 vatton 2329: {
2330: NewLineSkipped = skippedNL;
2331: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
2332: }
1.99 vatton 2333: if (ptr == cssRule)
1.168 vatton 2334: cssRule = SkipValue ("Invalid font value", cssRule);
1.82 cvs 2335: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2336: }
2337: }
2338: return (cssRule);
1.1 cvs 2339: }
2340:
2341: /*----------------------------------------------------------------------
1.59 cvs 2342: ParseCSSTextDecoration: parse a CSS text decor string
2343: we expect the input string describing the attribute to be
1.109 cvs 2344: underline, overline, line-through, blink or none.
1.1 cvs 2345: ----------------------------------------------------------------------*/
1.79 cvs 2346: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
2347: PresentationContext context, char *cssRule,
2348: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2349: {
2350: PresentationValue decor;
2351:
2352: decor.typed_data.value = 0;
1.184 vatton 2353: decor.typed_data.unit = UNIT_REL;
1.1 cvs 2354: decor.typed_data.real = FALSE;
1.82 cvs 2355: cssRule = SkipBlanksAndComments (cssRule);
1.211 vatton 2356: if (!strncasecmp (cssRule, "none", 4))
1.142 quint 2357: {
2358: decor.typed_data.value = NoUnderline;
2359: cssRule = SkipWord (cssRule);
2360: }
1.211 vatton 2361: else if (!strncasecmp (cssRule, "underline", 9))
1.1 cvs 2362: {
2363: decor.typed_data.value = Underline;
2364: cssRule = SkipWord (cssRule);
2365: }
1.211 vatton 2366: else if (!strncasecmp (cssRule, "overline", 8))
1.1 cvs 2367: {
2368: decor.typed_data.value = Overline;
2369: cssRule = SkipWord (cssRule);
2370: }
1.211 vatton 2371: else if (!strncasecmp (cssRule, "line-through", 12))
1.1 cvs 2372: {
2373: decor.typed_data.value = CrossOut;
2374: cssRule = SkipWord (cssRule);
2375: }
1.211 vatton 2376: else if (!strncasecmp (cssRule, "blink", 5))
1.1 cvs 2377: {
1.109 cvs 2378: /* the blink text-decoration attribute is not supported */
1.1 cvs 2379: cssRule = SkipWord (cssRule);
2380: }
1.142 quint 2381: else if (!strncasecmp (cssRule, "inherit", 7))
1.1 cvs 2382: {
1.142 quint 2383: cssRule = SkipWord (cssRule);
2384: return (cssRule);
1.1 cvs 2385: }
2386: else
2387: {
1.211 vatton 2388: cssRule = SkipValue ("Invalid text-decoration value", cssRule);
2389: return (cssRule);
1.1 cvs 2390: }
2391:
2392: /*
2393: * install the new presentation.
2394: */
1.116 vatton 2395: if (decor.typed_data.value && DoApply)
1.1 cvs 2396: {
1.117 vatton 2397: if (tsch)
2398: cssRule = CheckImportantRule (cssRule, context);
1.1 cvs 2399: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
2400: }
2401: return (cssRule);
2402: }
2403:
2404: /*----------------------------------------------------------------------
1.59 cvs 2405: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 2406: ----------------------------------------------------------------------*/
1.79 cvs 2407: static char *ParseCSSHeight (Element element, PSchema tsch,
1.93 vatton 2408: PresentationContext context, char *cssRule,
2409: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2410: {
1.117 vatton 2411: PresentationValue val;
1.168 vatton 2412: char *ptr;
1.93 vatton 2413:
1.117 vatton 2414: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2415: ptr = cssRule;
1.117 vatton 2416: /* first parse the attribute string */
1.164 quint 2417: if (!strncasecmp (cssRule, "auto", 4))
2418: {
1.184 vatton 2419: val.typed_data.unit = VALUE_AUTO;
1.164 quint 2420: val.typed_data.value = 0;
2421: val.typed_data.real = FALSE;
2422: cssRule = SkipWord (cssRule);
2423: }
1.117 vatton 2424: else
1.168 vatton 2425: cssRule = ParseCSSUnit (cssRule, &val);
2426: if (val.typed_data.value != 0 &&
1.184 vatton 2427: (val.typed_data.unit == UNIT_INVALID ||
2428: val.typed_data.unit == UNIT_BOX))
1.211 vatton 2429: {
2430: CSSParseError ("height value", ptr, cssRule);
1.212 cvs 2431: val.typed_data.unit = UNIT_PX;
1.211 vatton 2432: }
2433: if (DoApply)
1.117 vatton 2434: {
1.164 quint 2435: if (tsch)
2436: cssRule = CheckImportantRule (cssRule, context);
2437: /* install the new presentation */
2438: TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.117 vatton 2439: }
2440: return (cssRule);
1.1 cvs 2441: }
2442:
2443: /*----------------------------------------------------------------------
1.59 cvs 2444: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 2445: ----------------------------------------------------------------------*/
1.79 cvs 2446: static char *ParseCSSWidth (Element element, PSchema tsch,
1.78 cvs 2447: PresentationContext context,
1.79 cvs 2448: char *cssRule, CSSInfoPtr css,
1.78 cvs 2449: ThotBool isHTML)
1.1 cvs 2450: {
1.117 vatton 2451: PresentationValue val;
1.168 vatton 2452: char *ptr;
1.93 vatton 2453:
1.117 vatton 2454: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2455: ptr = cssRule;
1.117 vatton 2456: /* first parse the attribute string */
1.164 quint 2457: if (!strncasecmp (cssRule, "auto", 4))
2458: {
1.184 vatton 2459: val.typed_data.unit = VALUE_AUTO;
1.164 quint 2460: val.typed_data.value = 0;
2461: val.typed_data.real = FALSE;
2462: cssRule = SkipWord (cssRule);
2463: }
1.117 vatton 2464: else
1.164 quint 2465: cssRule = ParseCSSUnit (cssRule, &val);
1.168 vatton 2466: if (val.typed_data.value != 0 &&
1.184 vatton 2467: (val.typed_data.unit == UNIT_INVALID ||
2468: val.typed_data.unit == UNIT_BOX))
1.211 vatton 2469: {
2470: CSSParseError ("Invalid width value", ptr, cssRule);
1.212 cvs 2471: val.typed_data.unit = UNIT_PX;
1.211 vatton 2472: }
2473: if (DoApply)
1.117 vatton 2474: {
1.164 quint 2475: if (tsch)
2476: cssRule = CheckImportantRule (cssRule, context);
2477: /* install the new presentation */
2478: TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.117 vatton 2479: }
2480: return (cssRule);
1.1 cvs 2481: }
2482:
2483: /*----------------------------------------------------------------------
1.59 cvs 2484: ParseCSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 2485: ----------------------------------------------------------------------*/
1.79 cvs 2486: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.78 cvs 2487: PresentationContext context,
1.79 cvs 2488: char *cssRule, CSSInfoPtr css,
1.78 cvs 2489: ThotBool isHTML)
1.1 cvs 2490: {
2491: PresentationValue margin;
1.168 vatton 2492: char *ptr;
1.1 cvs 2493:
1.82 cvs 2494: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2495: ptr = cssRule;
1.1 cvs 2496: /* first parse the attribute string */
1.164 quint 2497: if (!strncasecmp (cssRule, "auto", 4))
2498: {
1.184 vatton 2499: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2500: margin.typed_data.value = 0;
2501: margin.typed_data.real = FALSE;
2502: cssRule = SkipWord (cssRule);
2503: }
2504: else
1.168 vatton 2505: cssRule = ParseCSSUnit (cssRule, &margin);
2506: if (margin.typed_data.value != 0 &&
1.184 vatton 2507: (margin.typed_data.unit == UNIT_INVALID ||
2508: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2509: CSSParseError ("Invalid margin-top value", ptr, cssRule);
1.168 vatton 2510: else if (DoApply)
1.117 vatton 2511: {
2512: if (tsch)
2513: cssRule = CheckImportantRule (cssRule, context);
2514: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
2515: }
1.1 cvs 2516: return (cssRule);
2517: }
2518:
2519: /*----------------------------------------------------------------------
1.59 cvs 2520: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 2521: ----------------------------------------------------------------------*/
1.79 cvs 2522: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.78 cvs 2523: PresentationContext context,
1.79 cvs 2524: char *cssRule, CSSInfoPtr css,
1.78 cvs 2525: ThotBool isHTML)
1.1 cvs 2526: {
2527: PresentationValue margin;
1.168 vatton 2528: char *ptr;
1.1 cvs 2529:
1.82 cvs 2530: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2531: ptr = cssRule;
1.1 cvs 2532: /* first parse the attribute string */
1.164 quint 2533: if (!strncasecmp (cssRule, "auto", 4))
2534: {
1.184 vatton 2535: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2536: margin.typed_data.value = 0;
2537: margin.typed_data.real = FALSE;
2538: cssRule = SkipWord (cssRule);
2539: }
2540: else
1.168 vatton 2541: cssRule = ParseCSSUnit (cssRule, &margin);
2542: if (margin.typed_data.value != 0 &&
1.184 vatton 2543: (margin.typed_data.unit == UNIT_INVALID ||
2544: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2545: CSSParseError ("Invalid margin-bottom value", ptr, cssRule);
1.168 vatton 2546: else if (DoApply)
1.117 vatton 2547: {
2548: if (tsch)
2549: cssRule = CheckImportantRule (cssRule, context);
2550: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
2551: }
1.1 cvs 2552: return (cssRule);
2553: }
2554:
2555: /*----------------------------------------------------------------------
1.59 cvs 2556: ParseCSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 2557: ----------------------------------------------------------------------*/
1.79 cvs 2558: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.78 cvs 2559: PresentationContext context,
1.79 cvs 2560: char *cssRule, CSSInfoPtr css,
1.78 cvs 2561: ThotBool isHTML)
1.1 cvs 2562: {
2563: PresentationValue margin;
1.168 vatton 2564: char *ptr;
1.1 cvs 2565:
1.82 cvs 2566: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2567: ptr = cssRule;
1.1 cvs 2568: /* first parse the attribute string */
1.164 quint 2569: if (!strncasecmp (cssRule, "auto", 4))
2570: {
1.184 vatton 2571: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2572: margin.typed_data.value = 0;
2573: margin.typed_data.real = FALSE;
2574: cssRule = SkipWord (cssRule);
2575: }
2576: else
1.168 vatton 2577: cssRule = ParseCSSUnit (cssRule, &margin);
2578: if (margin.typed_data.value != 0 &&
1.184 vatton 2579: (margin.typed_data.unit == UNIT_INVALID ||
2580: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2581: CSSParseError ("Invalid margin-left value", ptr, cssRule);
1.168 vatton 2582: else if (DoApply)
1.184 vatton 2583: if (margin.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 2584: {
2585: if (tsch)
2586: cssRule = CheckImportantRule (cssRule, context);
2587: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
2588: }
1.1 cvs 2589: return (cssRule);
2590: }
2591:
2592: /*----------------------------------------------------------------------
1.59 cvs 2593: ParseCSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 2594: ----------------------------------------------------------------------*/
1.79 cvs 2595: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.78 cvs 2596: PresentationContext context,
1.79 cvs 2597: char *cssRule, CSSInfoPtr css,
1.78 cvs 2598: ThotBool isHTML)
1.1 cvs 2599: {
2600: PresentationValue margin;
1.168 vatton 2601: char *ptr;
1.1 cvs 2602:
1.82 cvs 2603: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2604: ptr = cssRule;
1.1 cvs 2605: /* first parse the attribute string */
1.164 quint 2606: if (!strncasecmp (cssRule, "auto", 4))
2607: {
1.184 vatton 2608: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2609: margin.typed_data.value = 0;
2610: margin.typed_data.real = FALSE;
2611: cssRule = SkipWord (cssRule);
2612: }
2613: else
1.168 vatton 2614: cssRule = ParseCSSUnit (cssRule, &margin);
2615: if (margin.typed_data.value != 0 &&
1.184 vatton 2616: (margin.typed_data.unit == UNIT_INVALID ||
2617: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2618: CSSParseError ("Invalid margin-right value", ptr, cssRule);
1.168 vatton 2619: else if (DoApply)
1.117 vatton 2620: {
2621: if (tsch)
2622: cssRule = CheckImportantRule (cssRule, context);
2623: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
2624: }
1.1 cvs 2625: return (cssRule);
2626: }
2627:
2628: /*----------------------------------------------------------------------
1.59 cvs 2629: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 2630: ----------------------------------------------------------------------*/
1.79 cvs 2631: static char *ParseCSSMargin (Element element, PSchema tsch,
1.78 cvs 2632: PresentationContext context,
1.79 cvs 2633: char *cssRule, CSSInfoPtr css,
1.78 cvs 2634: ThotBool isHTML)
1.1 cvs 2635: {
1.79 cvs 2636: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2637: int skippedNL;
1.1 cvs 2638:
1.82 cvs 2639: ptrT = SkipBlanksAndComments (cssRule);
1.1 cvs 2640: /* First parse Margin-Top */
2641: ptrR = ParseCSSMarginTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2642: ptrR = SkipBlanksAndComments (ptrR);
2643: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.1 cvs 2644: {
1.93 vatton 2645: skippedNL = NewLineSkipped;
1.1 cvs 2646: cssRule = ptrR;
2647: /* apply the Margin-Top to all */
2648: ptrR = ParseCSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2649: NewLineSkipped = skippedNL;
1.1 cvs 2650: ptrR = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2651: NewLineSkipped = skippedNL;
1.1 cvs 2652: ptrR = ParseCSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
2653: }
2654: else
2655: {
2656: /* parse Margin-Right */
2657: ptrB = ParseCSSMarginRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2658: ptrB = SkipBlanksAndComments (ptrB);
2659: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.1 cvs 2660: {
1.93 vatton 2661: skippedNL = NewLineSkipped;
1.1 cvs 2662: cssRule = ptrB;
2663: /* apply the Margin-Top to Margin-Bottom */
2664: ptrB = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2665: NewLineSkipped = skippedNL;
1.1 cvs 2666: /* apply the Margin-Right to Margin-Left */
2667: ptrB = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2668: }
2669: else
2670: {
2671: /* parse Margin-Bottom */
2672: ptrL = ParseCSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2673: ptrL = SkipBlanksAndComments (ptrL);
2674: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.1 cvs 2675: {
2676: cssRule = ptrL;
2677: /* apply the Margin-Right to Margin-Left */
2678: ptrL = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2679: }
2680: else
2681: /* parse Margin-Left */
2682: cssRule = ParseCSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2683: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2684: }
2685: }
2686: return (cssRule);
2687: }
2688:
2689: /*----------------------------------------------------------------------
1.59 cvs 2690: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 2691: ----------------------------------------------------------------------*/
1.79 cvs 2692: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.78 cvs 2693: PresentationContext context,
1.79 cvs 2694: char *cssRule, CSSInfoPtr css,
1.78 cvs 2695: ThotBool isHTML)
1.1 cvs 2696: {
1.43 cvs 2697: PresentationValue padding;
1.168 vatton 2698: char *ptr;
1.43 cvs 2699:
1.82 cvs 2700: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2701: ptr = cssRule;
1.43 cvs 2702: /* first parse the attribute string */
2703: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2704: if (padding.typed_data.value != 0 &&
1.184 vatton 2705: (padding.typed_data.unit == UNIT_INVALID ||
2706: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2707: {
1.169 vatton 2708: CSSParseError ("Invalid padding-top value", ptr, cssRule);
1.168 vatton 2709: padding.typed_data.value = 0;
2710: }
2711: else if (DoApply)
1.117 vatton 2712: {
2713: if (tsch)
2714: cssRule = CheckImportantRule (cssRule, context);
2715: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
2716: }
1.1 cvs 2717: return (cssRule);
2718: }
2719:
2720: /*----------------------------------------------------------------------
1.59 cvs 2721: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 2722: ----------------------------------------------------------------------*/
1.79 cvs 2723: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.78 cvs 2724: PresentationContext context,
1.79 cvs 2725: char *cssRule, CSSInfoPtr css,
1.78 cvs 2726: ThotBool isHTML)
1.1 cvs 2727: {
1.43 cvs 2728: PresentationValue padding;
1.168 vatton 2729: char *ptr;
1.43 cvs 2730:
1.82 cvs 2731: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2732: ptr = cssRule;
1.43 cvs 2733: /* first parse the attribute string */
2734: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2735: if (padding.typed_data.value == 0)
1.184 vatton 2736: padding.typed_data.unit = UNIT_EM;
1.168 vatton 2737: if (padding.typed_data.value != 0 &&
1.184 vatton 2738: (padding.typed_data.unit == UNIT_INVALID ||
2739: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2740: {
1.169 vatton 2741: CSSParseError ("Invalid padding-bottom value", ptr, cssRule);
1.168 vatton 2742: padding.typed_data.value = 0;
2743: }
2744: else if (DoApply)
1.117 vatton 2745: {
2746: if (tsch)
2747: cssRule = CheckImportantRule (cssRule, context);
2748: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
2749: }
1.1 cvs 2750: return (cssRule);
2751: }
2752:
2753: /*----------------------------------------------------------------------
1.59 cvs 2754: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 2755: ----------------------------------------------------------------------*/
1.79 cvs 2756: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.78 cvs 2757: PresentationContext context,
1.79 cvs 2758: char *cssRule, CSSInfoPtr css,
1.78 cvs 2759: ThotBool isHTML)
1.1 cvs 2760: {
1.43 cvs 2761: PresentationValue padding;
1.168 vatton 2762: char *ptr;
1.43 cvs 2763:
1.82 cvs 2764: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2765: ptr = cssRule;
1.43 cvs 2766: /* first parse the attribute string */
2767: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2768: if (padding.typed_data.value == 0)
1.184 vatton 2769: padding.typed_data.unit = UNIT_EM;
1.168 vatton 2770: if (padding.typed_data.value != 0 &&
1.184 vatton 2771: (padding.typed_data.unit == UNIT_INVALID ||
2772: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2773: {
1.169 vatton 2774: CSSParseError ("Invalid padding-left value", ptr, cssRule);
1.168 vatton 2775: padding.typed_data.value = 0;
2776: }
2777: else if (DoApply)
1.117 vatton 2778: {
2779: if (tsch)
2780: cssRule = CheckImportantRule (cssRule, context);
1.43 cvs 2781: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.117 vatton 2782: }
1.1 cvs 2783: return (cssRule);
2784: }
2785:
2786: /*----------------------------------------------------------------------
1.59 cvs 2787: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 2788: ----------------------------------------------------------------------*/
1.79 cvs 2789: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.78 cvs 2790: PresentationContext context,
1.79 cvs 2791: char *cssRule, CSSInfoPtr css,
1.78 cvs 2792: ThotBool isHTML)
1.1 cvs 2793: {
1.43 cvs 2794: PresentationValue padding;
1.168 vatton 2795: char *ptr;
1.43 cvs 2796:
1.82 cvs 2797: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2798: ptr = cssRule;
1.43 cvs 2799: /* first parse the attribute string */
2800: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2801: if (padding.typed_data.value == 0)
1.184 vatton 2802: padding.typed_data.unit = UNIT_EM;
1.168 vatton 2803: if (padding.typed_data.value != 0 &&
1.184 vatton 2804: (padding.typed_data.unit == UNIT_INVALID ||
2805: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2806: {
1.169 vatton 2807: CSSParseError ("Invalid padding-right value", ptr, cssRule);
1.168 vatton 2808: padding.typed_data.value = 0;
2809: }
2810: else if (DoApply)
1.117 vatton 2811: {
2812: if (tsch)
2813: cssRule = CheckImportantRule (cssRule, context);
1.43 cvs 2814: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.117 vatton 2815: }
1.1 cvs 2816: return (cssRule);
2817: }
2818:
2819: /*----------------------------------------------------------------------
1.59 cvs 2820: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 2821: ----------------------------------------------------------------------*/
1.79 cvs 2822: static char *ParseCSSPadding (Element element, PSchema tsch,
1.78 cvs 2823: PresentationContext context,
1.79 cvs 2824: char *cssRule, CSSInfoPtr css,
1.78 cvs 2825: ThotBool isHTML)
1.1 cvs 2826: {
1.79 cvs 2827: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2828: int skippedNL;
1.43 cvs 2829:
1.82 cvs 2830: ptrT = SkipBlanksAndComments (cssRule);
1.43 cvs 2831: /* First parse Padding-Top */
2832: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2833: ptrR = SkipBlanksAndComments (ptrR);
2834: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.43 cvs 2835: {
1.93 vatton 2836: skippedNL = NewLineSkipped;
1.43 cvs 2837: cssRule = ptrR;
2838: /* apply the Padding-Top to all */
2839: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2840: NewLineSkipped = skippedNL;
1.43 cvs 2841: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2842: NewLineSkipped = skippedNL;
1.43 cvs 2843: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
2844: }
2845: else
2846: {
2847: /* parse Padding-Right */
2848: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2849: ptrB = SkipBlanksAndComments (ptrB);
2850: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.43 cvs 2851: {
1.93 vatton 2852: skippedNL = NewLineSkipped;
1.43 cvs 2853: cssRule = ptrB;
2854: /* apply the Padding-Top to Padding-Bottom */
2855: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2856: NewLineSkipped = skippedNL;
1.43 cvs 2857: /* apply the Padding-Right to Padding-Left */
2858: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2859: }
2860: else
2861: {
2862: /* parse Padding-Bottom */
2863: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2864: ptrL = SkipBlanksAndComments (ptrL);
2865: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.43 cvs 2866: {
2867: cssRule = ptrL;
2868: /* apply the Padding-Right to Padding-Left */
2869: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2870: }
2871: else
2872: /* parse Padding-Left */
2873: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2874: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2875: }
2876: }
1.1 cvs 2877: return (cssRule);
2878: }
2879:
2880: /*----------------------------------------------------------------------
1.59 cvs 2881: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 2882: ----------------------------------------------------------------------*/
1.79 cvs 2883: static char *ParseCSSForeground (Element element, PSchema tsch,
1.78 cvs 2884: PresentationContext context,
1.79 cvs 2885: char *cssRule,
1.78 cvs 2886: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2887: {
1.117 vatton 2888: PresentationValue best;
1.1 cvs 2889:
1.117 vatton 2890: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 2891: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 2892: {
2893: if (tsch)
2894: cssRule = CheckImportantRule (cssRule, context);
2895: /* install the new presentation */
2896: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2897: }
1.1 cvs 2898: return (cssRule);
2899: }
2900:
2901: /*----------------------------------------------------------------------
1.59 cvs 2902: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 2903: ----------------------------------------------------------------------*/
1.79 cvs 2904: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.78 cvs 2905: PresentationContext context,
1.79 cvs 2906: char *cssRule,
1.78 cvs 2907: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2908: {
2909: PresentationValue best;
2910:
1.184 vatton 2911: best.typed_data.unit = UNIT_INVALID;
1.1 cvs 2912: best.typed_data.real = FALSE;
1.198 vatton 2913: if (!strncasecmp (cssRule, "transparent", 11))
1.1 cvs 2914: {
1.184 vatton 2915: best.typed_data.value = PATTERN_NONE;
2916: best.typed_data.unit = UNIT_REL;
1.116 vatton 2917: if (DoApply)
1.117 vatton 2918: {
2919: if (tsch)
2920: cssRule = CheckImportantRule (cssRule, context);
2921: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2922: }
1.65 cvs 2923: cssRule = SkipWord (cssRule);
1.1 cvs 2924: }
2925: else
2926: {
2927: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 2928: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.1 cvs 2929: {
1.117 vatton 2930: if (tsch)
2931: cssRule = CheckImportantRule (cssRule, context);
1.1 cvs 2932: /* install the new presentation. */
2933: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59 cvs 2934: /* thot specificity: need to set fill pattern for background color */
1.184 vatton 2935: best.typed_data.value = PATTERN_BACKGROUND;
2936: best.typed_data.unit = UNIT_REL;
1.1 cvs 2937: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2938: best.typed_data.value = 1;
1.184 vatton 2939: best.typed_data.unit = UNIT_REL;
1.1 cvs 2940: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
2941: }
2942: }
2943: return (cssRule);
2944: }
2945:
1.63 cvs 2946: /*----------------------------------------------------------------------
1.245 quint 2947: ParseCSSUrl: parse an URL
2948: ----------------------------------------------------------------------*/
2949: static char *ParseCSSUrl (char *cssRule, char **url)
2950: {
2951: char saved;
2952: char *base, *ptr;
2953:
2954: cssRule = SkipBlanksAndComments (cssRule);
2955: saved = *cssRule;
2956: if (*cssRule == '(')
2957: {
2958: cssRule++;
2959: cssRule = SkipBlanksAndComments (cssRule);
2960: /*** Escaped quotes are not handled. See function SkipQuotedString */
2961: if (*cssRule == '"')
2962: {
2963: cssRule++;
2964: base = cssRule;
2965: while (*cssRule != EOS && *cssRule != '"')
2966: cssRule++;
2967: }
2968: else if (*cssRule == '\'')
2969: {
2970: cssRule++;
2971: base = cssRule;
2972: while (*cssRule != EOS && *cssRule != '\'')
2973: cssRule++;
2974: }
2975: else
2976: {
2977: base = cssRule;
2978: while (*cssRule != EOS && *cssRule != ')')
2979: cssRule++;
2980: }
2981: /* keep the current position */
2982: ptr = cssRule;
2983: if (saved == ')')
2984: {
2985: /* remove extra spaces */
2986: if (cssRule[-1] == SPACE)
2987: {
2988: *cssRule = SPACE;
2989: cssRule--;
2990: while (cssRule[-1] == SPACE)
2991: cssRule--;
2992: }
2993: }
2994: saved = *cssRule;
2995: *cssRule = EOS;
2996: *url = TtaStrdup (base);
2997: *cssRule = saved;
2998: if (saved == '"' || saved == '\'')
2999: /* we need to skip the quote character and possible spaces */
3000: {
3001: cssRule++;
3002: cssRule = SkipBlanksAndComments (cssRule);
3003: }
3004: else
3005: cssRule = ptr;
3006: }
3007: cssRule++;
3008: return cssRule;
3009: }
3010:
3011: /*----------------------------------------------------------------------
1.65 cvs 3012: ParseSVGStroke: parse a SVG stroke property
3013: ----------------------------------------------------------------------*/
1.79 cvs 3014: static char *ParseSVGStroke (Element element, PSchema tsch,
3015: PresentationContext context, char *cssRule,
3016: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 3017: {
3018: PresentationValue best;
1.245 quint 3019: char *url;
1.65 cvs 3020:
1.184 vatton 3021: best.typed_data.unit = UNIT_INVALID;
1.65 cvs 3022: best.typed_data.real = FALSE;
1.82 cvs 3023: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 3024: {
3025: best.typed_data.value = -2; /* -2 means transparent */
1.184 vatton 3026: best.typed_data.unit = UNIT_REL;
1.116 vatton 3027: if (DoApply)
1.117 vatton 3028: {
3029: if (tsch)
3030: cssRule = CheckImportantRule (cssRule, context);
3031: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
3032: }
1.65 cvs 3033: cssRule = SkipWord (cssRule);
3034: }
1.245 quint 3035: else if (!strncasecmp (cssRule, "currentColor", 12))
3036: {
3037: /* **** do something here to inherit color */;
3038: }
3039: else if (!strncasecmp (cssRule, "url", 3))
3040: {
3041: cssRule += 3;
3042: cssRule = ParseCSSUrl (cssRule, &url);
3043: /* **** do something with the url ***** */;
3044: TtaFreeMemory (url);
3045: /* **** caution: another color value may follow the uri (in case
3046: the uri could ne be dereferenced) *** */
3047: }
1.65 cvs 3048: else
3049: {
3050: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 3051: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 3052: {
3053: if (tsch)
3054: cssRule = CheckImportantRule (cssRule, context);
3055: /* install the new presentation */
3056: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
3057: }
1.65 cvs 3058: }
3059: return (cssRule);
3060: }
3061:
3062: /*----------------------------------------------------------------------
1.63 cvs 3063: ParseSVGFill: parse a SVG fill property
3064: ----------------------------------------------------------------------*/
1.79 cvs 3065: static char *ParseSVGFill (Element element, PSchema tsch,
3066: PresentationContext context, char *cssRule,
3067: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 3068: {
3069: PresentationValue best;
1.245 quint 3070: char *url;
1.63 cvs 3071:
1.184 vatton 3072: best.typed_data.unit = UNIT_INVALID;
1.63 cvs 3073: best.typed_data.real = FALSE;
1.82 cvs 3074: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 3075: {
1.184 vatton 3076: best.typed_data.value = PATTERN_NONE;
3077: best.typed_data.unit = UNIT_REL;
1.116 vatton 3078: if (DoApply)
1.117 vatton 3079: {
3080: if (tsch)
3081: cssRule = CheckImportantRule (cssRule, context);
3082: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
3083: }
1.65 cvs 3084: cssRule = SkipWord (cssRule);
1.63 cvs 3085: }
1.245 quint 3086: else if (!strncasecmp (cssRule, "currentColor", 12))
3087: {
3088: /* **** do something here to inherit color */;
3089: }
3090: else if (!strncasecmp (cssRule, "url", 3))
3091: {
3092: cssRule += 3;
3093: cssRule = ParseCSSUrl (cssRule, &url);
3094: /* **** do something with the url ***** */;
3095: TtaFreeMemory (url);
3096: /* **** caution: another color value may follow the uri (in case
3097: the uri could ne be dereferenced) *** */
3098: }
1.63 cvs 3099: else
3100: {
3101: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 3102: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.63 cvs 3103: {
1.117 vatton 3104: if (tsch)
3105: cssRule = CheckImportantRule (cssRule, context);
1.63 cvs 3106: /* install the new presentation. */
3107: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
3108: /* thot specificity: need to set fill pattern for background color */
1.184 vatton 3109: best.typed_data.value = PATTERN_BACKGROUND;
3110: best.typed_data.unit = UNIT_REL;
1.63 cvs 3111: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
3112: }
3113: }
3114: return (cssRule);
3115: }
1.161 quint 3116:
1.155 cheyroul 3117: /*----------------------------------------------------------------------
3118: ParseSVGOpacity: parse a SVG fill property
3119: ----------------------------------------------------------------------*/
3120: static char *ParseSVGOpacity (Element element, PSchema tsch,
3121: PresentationContext context, char *cssRule,
3122: CSSInfoPtr css, ThotBool isHTML)
3123: {
3124: PresentationValue best;
1.63 cvs 3125:
1.184 vatton 3126: best.typed_data.unit = UNIT_INVALID;
1.155 cheyroul 3127: best.typed_data.real = FALSE;
3128: cssRule = ParseClampedUnit (cssRule, &best);
3129: if (DoApply)
3130: {
3131: if (tsch)
3132: cssRule = CheckImportantRule (cssRule, context);
3133: /* install the new presentation. */
3134: TtaSetStylePresentation (PROpacity, element,
3135: tsch, context, best);
3136: }
3137: return (cssRule);
3138: }
1.170 cheyroul 3139: /*----------------------------------------------------------------------
3140: ParseSVGOpacity: parse a SVG fill property
3141: ----------------------------------------------------------------------*/
3142: static char *ParseSVGStrokeOpacity (Element element, PSchema tsch,
3143: PresentationContext context, char *cssRule,
3144: CSSInfoPtr css, ThotBool isHTML)
3145: {
3146: PresentationValue best;
1.161 quint 3147:
1.184 vatton 3148: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 3149: best.typed_data.real = FALSE;
3150: cssRule = ParseClampedUnit (cssRule, &best);
3151: if (DoApply)
3152: {
3153: if (tsch)
3154: cssRule = CheckImportantRule (cssRule, context);
3155: /* install the new presentation. */
3156: TtaSetStylePresentation (PRStrokeOpacity, element,
3157: tsch, context, best);
3158: }
3159: return (cssRule);
3160: }
3161: /*----------------------------------------------------------------------
3162: ParseSVGOpacity: parse a SVG fill property
3163: ----------------------------------------------------------------------*/
3164: static char *ParseSVGFillOpacity (Element element, PSchema tsch,
3165: PresentationContext context, char *cssRule,
3166: CSSInfoPtr css, ThotBool isHTML)
3167: {
3168: PresentationValue best;
3169:
1.184 vatton 3170: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 3171: best.typed_data.real = FALSE;
3172: cssRule = ParseClampedUnit (cssRule, &best);
3173: if (DoApply)
3174: {
3175: if (tsch)
3176: cssRule = CheckImportantRule (cssRule, context);
3177: /* install the new presentation. */
3178: TtaSetStylePresentation (PRFillOpacity, element,
3179: tsch, context, best);
3180: }
3181: return (cssRule);
3182: }
1.207 vatton 3183:
1.1 cvs 3184: /*----------------------------------------------------------------------
1.59 cvs 3185: ParseCSSBackgroundImageCallback: Callback called asynchronously by
3186: FetchImage when a background image has been fetched.
1.1 cvs 3187: ----------------------------------------------------------------------*/
1.82 cvs 3188: void ParseCSSBackgroundImageCallback (Document doc, Element element,
1.203 vatton 3189: char *file, void *extra,
3190: ThotBool isnew)
1.1 cvs 3191: {
1.233 vatton 3192: DisplayMode dispMode = DisplayImmediately;
1.82 cvs 3193: BackgroundImageCallbackPtr callblock;
3194: Element el;
3195: PSchema tsch;
1.185 vatton 3196: CSSInfoPtr css;
1.206 vatton 3197: PInfoPtr pInfo;
1.207 vatton 3198: PresentationContext ctxt;
1.82 cvs 3199: PresentationValue image;
3200: PresentationValue value;
1.206 vatton 3201: ThotBool enabled;
1.82 cvs 3202: callblock = (BackgroundImageCallbackPtr) extra;
1.34 cvs 3203: if (callblock == NULL)
3204: return;
1.1 cvs 3205:
1.188 cheyroul 3206: css = NULL;
1.34 cvs 3207: el = callblock->el;
3208: tsch = callblock->tsch;
1.207 vatton 3209: ctxt = callblock->ctxt;
1.203 vatton 3210: if (doc == 0 && !isnew)
3211: /* apply to the current document only */
1.207 vatton 3212: doc = ctxt->doc;
1.185 vatton 3213: if (doc)
3214: {
3215: /* avoid too many redisplay */
3216: dispMode = TtaGetDisplayMode (doc);
3217: if (dispMode == DisplayImmediately)
3218: TtaSetDisplayMode (doc, DeferredDisplay);
3219: }
3220: else
3221: {
3222: /* check if the CSS still exists */
3223: css = CSSList;
3224: while (css && css != callblock->css)
3225: css = css->NextCSS;
3226: if (css == NULL)
3227: tsch = NULL;
3228: }
1.34 cvs 3229:
1.185 vatton 3230: if (el || tsch)
3231: {
3232: /* Ok the image was fetched, finish the background-image handling */
1.193 vatton 3233: image.typed_data.unit = UNIT_REL;
3234: image.typed_data.real = FALSE;
1.185 vatton 3235: image.pointer = file;
1.207 vatton 3236: TtaSetStylePresentation (PRBackgroundPicture, el, tsch, ctxt, image);
1.185 vatton 3237:
3238: /* enforce the showbox */
3239: value.typed_data.value = 1;
3240: value.typed_data.unit = UNIT_REL;
3241: value.typed_data.real = FALSE;
1.207 vatton 3242: TtaSetStylePresentation (PRShowBox, el, tsch, ctxt, value);
3243: /* check if the context can be freed */
3244: ctxt->uses -= 1;
3245: if (ctxt->uses == 0)
3246: /* no other image loading */
3247: TtaFreeMemory (ctxt);
1.185 vatton 3248: }
1.34 cvs 3249:
3250: TtaFreeMemory (callblock);
3251: /* restore the display mode */
1.185 vatton 3252: if (doc)
3253: {
3254: if (dispMode == DisplayImmediately)
3255: TtaSetDisplayMode (doc, dispMode);
3256: }
3257: else if (css)
3258: {
3259: for (doc = 1; doc < DocumentTableLength; doc++)
1.206 vatton 3260: if (css->infos[doc] &&
1.185 vatton 3261: /* don't manage a document used by make book */
3262: (DocumentMeta[doc] == NULL ||
3263: DocumentMeta[doc]->method != CE_MAKEBOOK))
3264: {
1.206 vatton 3265: pInfo = css->infos[doc];
3266: enabled = FALSE;
3267: while (pInfo && !enabled)
3268: {
3269: enabled = pInfo->PiEnabled;
3270: pInfo = pInfo->PiNext;
3271: }
1.185 vatton 3272: /* Change the Display Mode to take into account the new presentation */
3273: dispMode = TtaGetDisplayMode (doc);
3274: if (dispMode == DisplayImmediately)
1.194 vatton 3275: {
3276: TtaSetDisplayMode (doc, NoComputedDisplay);
3277: /* Restore the display mode */
3278: TtaSetDisplayMode (doc, dispMode);
3279: }
1.185 vatton 3280: }
3281: }
1.1 cvs 3282: }
3283:
1.217 vatton 3284: /*----------------------------------------------------------------------
3285: GetCSSBackgroundURL searches a CSS BackgroundImage url within
3286: the cssRule.
3287: Returns NULL or a new allocated url string.
3288: ----------------------------------------------------------------------*/
3289: char *GetCSSBackgroundURL (char *cssRule)
3290: {
3291: char *b, *url;
3292:
3293: url = NULL;
3294: b = strstr (cssRule, "url");
3295: if (b)
3296: b = ParseCSSUrl (url, &url);
3297: return (url);
3298: }
3299:
3300: /*----------------------------------------------------------------------
3301: ParseCSSContent: parse a CSS content value
3302: ----------------------------------------------------------------------*/
3303: static char *ParseCSSContent (Element element, PSchema tsch,
3304: PresentationContext context, char *cssRule,
3305: CSSInfoPtr css, ThotBool isHTML)
3306: {
3307: char *p, quoteChar, *url;
3308:
3309: cssRule = SkipBlanksAndComments (cssRule);
3310: p = cssRule;
3311: if (!strncasecmp (cssRule, "url", 3))
3312: {
3313: cssRule += 3;
3314: cssRule = ParseCSSUrl (cssRule, &url);
3315: TtaFreeMemory (url);
3316: }
3317: else if (*cssRule == '"' || *cssRule == '\'')
3318: {
3319: quoteChar = *cssRule;
3320: cssRule++;
3321: cssRule = SkipQuotedString (cssRule, quoteChar);
3322: }
3323: else
3324: cssRule = SkipValue ("Invalid content value", p);
3325: return (cssRule);
3326: }
1.1 cvs 3327:
3328: /*----------------------------------------------------------------------
1.59 cvs 3329: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 3330: ----------------------------------------------------------------------*/
1.79 cvs 3331: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
1.207 vatton 3332: PresentationContext ctxt,
1.79 cvs 3333: char *cssRule, CSSInfoPtr css,
3334: ThotBool isHTML)
1.1 cvs 3335: {
1.49 cvs 3336: Element el;
1.1 cvs 3337: BackgroundImageCallbackPtr callblock;
1.49 cvs 3338: PresentationValue image, value;
1.79 cvs 3339: char *url;
1.82 cvs 3340: char *bg_image;
1.79 cvs 3341: char tempname[MAX_LENGTH];
3342: char imgname[MAX_LENGTH];
1.148 vatton 3343:
1.163 quint 3344: if (element)
1.148 vatton 3345: el = element;
1.163 quint 3346: else
3347: /* default element for FetchImage */
1.207 vatton 3348: el = TtaGetMainRoot (ctxt->doc);
1.163 quint 3349:
1.1 cvs 3350: url = NULL;
1.82 cvs 3351: cssRule = SkipBlanksAndComments (cssRule);
1.161 quint 3352: if (!strncasecmp (cssRule, "none", 4))
3353: {
1.247 quint 3354: if (DoApply)
3355: {
3356: /* no background image */
3357: image.pointer = NULL;
3358: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt, image);
3359: /* no background color */
3360: value.typed_data.unit = UNIT_INVALID;
3361: value.typed_data.real = FALSE;
3362: value.typed_data.value = PATTERN_NONE;
3363: value.typed_data.unit = UNIT_REL;
3364: if (tsch)
3365: cssRule = CheckImportantRule (cssRule, ctxt);
3366: TtaSetStylePresentation (PRFillPattern, element, tsch, ctxt, value);
3367: }
1.198 vatton 3368: cssRule += 4;
1.161 quint 3369: }
3370: else if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 3371: {
3372: cssRule += 3;
1.217 vatton 3373: cssRule = ParseCSSUrl (cssRule, &url);
1.207 vatton 3374: if (ctxt->destroy)
1.1 cvs 3375: {
3376: /* remove the background image PRule */
3377: image.pointer = NULL;
1.207 vatton 3378: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt, image);
3379: if (TtaGetStylePresentation (PRFillPattern, element, tsch, ctxt, &value) < 0)
1.1 cvs 3380: {
3381: /* there is no FillPattern rule -> remove ShowBox rule */
3382: value.typed_data.value = 1;
1.184 vatton 3383: value.typed_data.unit = UNIT_REL;
1.1 cvs 3384: value.typed_data.real = FALSE;
1.207 vatton 3385: TtaSetStylePresentation (PRShowBox, element, tsch, ctxt, value);
1.1 cvs 3386: }
3387: }
3388: else if (url)
3389: {
1.30 cvs 3390: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
1.82 cvs 3391: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
1.161 quint 3392: /* background images are enabled */
1.1 cvs 3393: {
1.185 vatton 3394: callblock = (BackgroundImageCallbackPtr) TtaGetMemory (sizeof (BackgroundImageCallbackBlock));
1.191 vatton 3395: if (callblock)
1.1 cvs 3396: {
3397: callblock->el = element;
3398: callblock->tsch = tsch;
1.185 vatton 3399: callblock->css = css;
1.207 vatton 3400: callblock->ctxt = ctxt;
3401: /* new use of the context */
3402: ctxt->uses += 1;
1.18 cvs 3403: /* check if the image url is related to an external CSS */
1.182 vatton 3404: if (css)
1.18 cvs 3405: {
1.189 vatton 3406: if (css->url)
3407: /* the image concerns a CSS file */
3408: NormalizeURL (url, 0, tempname, imgname, css->url);
3409: else
3410: /* the image concerns a style element */
1.207 vatton 3411: NormalizeURL (url, ctxt->doc, tempname, imgname, NULL);
1.18 cvs 3412: /* fetch and display background image of element */
1.181 vatton 3413: FetchImage (0, el, tempname, AMAYA_LOAD_IMAGE,
1.161 quint 3414: ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 3415: }
3416: else
1.207 vatton 3417: FetchImage (ctxt->doc, el, url, AMAYA_LOAD_IMAGE,
1.161 quint 3418: ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 3419: }
3420: }
3421: }
1.229 vatton 3422: if (url)
3423: TtaFreeMemory (url);
1.18 cvs 3424: }
3425: return (cssRule);
3426: }
3427:
3428: /*----------------------------------------------------------------------
1.59 cvs 3429: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 3430: ----------------------------------------------------------------------*/
1.79 cvs 3431: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.207 vatton 3432: PresentationContext ctxt,
1.97 vatton 3433: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3434: {
3435: PresentationValue repeat;
3436:
1.184 vatton 3437: repeat.typed_data.value = REALSIZE;
1.191 vatton 3438: repeat.typed_data.unit = UNIT_BOX;
1.18 cvs 3439: repeat.typed_data.real = FALSE;
1.82 cvs 3440: cssRule = SkipBlanksAndComments (cssRule);
3441: if (!strncasecmp (cssRule, "no-repeat", 9))
1.184 vatton 3442: repeat.typed_data.value = REALSIZE;
1.82 cvs 3443: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.184 vatton 3444: repeat.typed_data.value = VREPEAT;
1.82 cvs 3445: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.184 vatton 3446: repeat.typed_data.value = HREPEAT;
1.82 cvs 3447: else if (!strncasecmp (cssRule, "repeat", 6))
1.184 vatton 3448: repeat.typed_data.value = REPEAT;
1.18 cvs 3449: else
3450: return (cssRule);
3451:
3452: /* install the new presentation */
1.116 vatton 3453: if (DoApply)
1.117 vatton 3454: {
3455: /* check if it's an important rule */
3456: if (tsch)
1.207 vatton 3457: cssRule = CheckImportantRule (cssRule, ctxt);
3458: TtaSetStylePresentation (PRPictureMode, element, tsch, ctxt, repeat);
1.117 vatton 3459: }
1.18 cvs 3460: cssRule = SkipWord (cssRule);
1.163 quint 3461: return (cssRule);
1.18 cvs 3462: }
3463:
3464: /*----------------------------------------------------------------------
1.59 cvs 3465: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18 cvs 3466: attribute string.
3467: ----------------------------------------------------------------------*/
1.79 cvs 3468: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
1.207 vatton 3469: PresentationContext ctxt,
1.79 cvs 3470: char *cssRule, CSSInfoPtr css,
3471: ThotBool isHTML)
1.18 cvs 3472: {
1.200 vatton 3473: char *ptr;
3474:
1.163 quint 3475: cssRule = SkipBlanksAndComments (cssRule);
3476: if (!strncasecmp (cssRule, "scroll", 6))
1.199 vatton 3477: {
3478: /* force no-repeat for that background image */
1.200 vatton 3479: ptr = "no-repeat";
1.207 vatton 3480: ParseCSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.199 vatton 3481: cssRule = SkipWord (cssRule);
3482: }
1.163 quint 3483: else if (!strncasecmp (cssRule, "fixed", 5))
1.199 vatton 3484: {
3485: /* force no-repeat for that background image */
1.201 vatton 3486: ptr = "no-repeat";
1.207 vatton 3487: ParseCSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.199 vatton 3488: cssRule = SkipWord (cssRule);
3489: }
1.163 quint 3490: return (cssRule);
1.1 cvs 3491: }
3492:
3493: /*----------------------------------------------------------------------
1.59 cvs 3494: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
1.1 cvs 3495: attribute string.
3496: ----------------------------------------------------------------------*/
1.79 cvs 3497: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
1.207 vatton 3498: PresentationContext ctxt,
1.79 cvs 3499: char *cssRule, CSSInfoPtr css,
3500: ThotBool isHTML)
1.1 cvs 3501: {
1.18 cvs 3502: PresentationValue repeat;
1.200 vatton 3503: char *ptr;
1.18 cvs 3504: ThotBool ok;
1.1 cvs 3505:
1.163 quint 3506: cssRule = SkipBlanksAndComments (cssRule);
3507: ok = TRUE;
3508: if (!strncasecmp (cssRule, "left", 4))
3509: cssRule = SkipWord (cssRule);
3510: else if (!strncasecmp (cssRule, "right", 5))
3511: cssRule = SkipWord (cssRule);
3512: else if (!strncasecmp (cssRule, "center", 6))
3513: cssRule = SkipWord (cssRule);
3514: else if (!strncasecmp (cssRule, "top", 3))
3515: cssRule = SkipWord (cssRule);
3516: else if (!strncasecmp (cssRule, "bottom", 6))
3517: cssRule = SkipWord (cssRule);
3518: else if (isdigit (*cssRule) || *cssRule == '.')
1.191 vatton 3519: {
1.206 vatton 3520: while (*cssRule != EOS && *cssRule != SPACE &&
3521: *cssRule != ',' && *cssRule != ';')
3522: cssRule++;
1.191 vatton 3523: }
1.163 quint 3524: else
3525: ok = FALSE;
3526:
3527: if (ok && DoApply)
1.148 vatton 3528: {
1.199 vatton 3529: /* force no-repeat for that background image */
1.200 vatton 3530: ptr = "no-repeat";
1.207 vatton 3531: ParseCSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.163 quint 3532: /* force realsize for the background image */
1.184 vatton 3533: repeat.typed_data.value = REALSIZE;
3534: repeat.typed_data.unit = UNIT_REL;
1.163 quint 3535: repeat.typed_data.real = FALSE;
3536: /* check if it's an important rule */
3537: if (tsch)
1.207 vatton 3538: cssRule = CheckImportantRule (cssRule, ctxt);
3539: /*TtaSetStylePresentation (PRPictureMode, element, tsch, ctxt, repeat);*/
1.218 vatton 3540:
3541: /* check the second value */
3542: cssRule = SkipBlanksAndComments (cssRule);
3543: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
3544: cssRule = ParseCSSBackgroundPosition (element, tsch, ctxt,
3545: cssRule, css, isHTML);
1.148 vatton 3546: }
1.163 quint 3547: return (cssRule);
1.18 cvs 3548: }
3549:
3550: /*----------------------------------------------------------------------
1.59 cvs 3551: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 3552: ----------------------------------------------------------------------*/
1.79 cvs 3553: static char *ParseCSSBackground (Element element, PSchema tsch,
1.207 vatton 3554: PresentationContext ctxt, char *cssRule,
1.79 cvs 3555: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3556: {
1.79 cvs 3557: char *ptr;
1.93 vatton 3558: int skippedNL;
1.18 cvs 3559:
1.82 cvs 3560: cssRule = SkipBlanksAndComments (cssRule);
3561: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 3562: {
1.71 cvs 3563: /* perhaps a Background Image */
1.198 vatton 3564: if (!strncasecmp (cssRule, "url", 3) || !strncasecmp (cssRule, "none", 4))
1.207 vatton 3565: cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
1.63 cvs 3566: css, isHTML);
1.18 cvs 3567: /* perhaps a Background Attachment */
1.82 cvs 3568: else if (!strncasecmp (cssRule, "scroll", 6) ||
3569: !strncasecmp (cssRule, "fixed", 5))
1.207 vatton 3570: cssRule = ParseCSSBackgroundAttachment (element, tsch, ctxt,
1.63 cvs 3571: cssRule, css, isHTML);
1.18 cvs 3572: /* perhaps a Background Repeat */
1.82 cvs 3573: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
3574: !strncasecmp (cssRule, "repeat-y", 8) ||
3575: !strncasecmp (cssRule, "repeat-x", 8) ||
3576: !strncasecmp (cssRule, "repeat", 6))
1.207 vatton 3577: cssRule = ParseCSSBackgroundRepeat (element, tsch, ctxt,
1.82 cvs 3578: cssRule, css, isHTML);
1.18 cvs 3579: /* perhaps a Background Position */
1.82 cvs 3580: else if (!strncasecmp (cssRule, "left", 4) ||
3581: !strncasecmp (cssRule, "right", 5) ||
3582: !strncasecmp (cssRule, "center", 6) ||
3583: !strncasecmp (cssRule, "top", 3) ||
3584: !strncasecmp (cssRule, "bottom", 6) ||
1.110 vatton 3585: isdigit (*cssRule) || *cssRule == '.')
1.207 vatton 3586: cssRule = ParseCSSBackgroundPosition (element, tsch, ctxt,
1.63 cvs 3587: cssRule, css, isHTML);
1.18 cvs 3588: /* perhaps a Background Color */
3589: else
3590: {
1.93 vatton 3591: skippedNL = NewLineSkipped;
1.18 cvs 3592: /* check if the rule has been found */
3593: ptr = cssRule;
1.207 vatton 3594: cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
1.82 cvs 3595: cssRule, css, isHTML);
1.43 cvs 3596: if (ptr == cssRule)
1.93 vatton 3597: {
3598: NewLineSkipped = skippedNL;
3599: /* rule not found */
1.234 vatton 3600: cssRule = SkipProperty (cssRule, FALSE);
1.93 vatton 3601: }
1.18 cvs 3602: }
1.82 cvs 3603: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3604: }
3605: return (cssRule);
3606: }
3607:
1.59 cvs 3608: /*----------------------------------------------------------------------
1.60 cvs 3609: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 3610: ----------------------------------------------------------------------*/
1.79 cvs 3611: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.207 vatton 3612: PresentationContext ctxt, char *cssRule,
1.79 cvs 3613: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 3614: {
3615: PresentationValue page;
3616:
1.184 vatton 3617: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 3618: page.typed_data.real = FALSE;
1.82 cvs 3619: cssRule = SkipBlanksAndComments (cssRule);
3620: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 3621: page.typed_data.value = PageAuto;
1.82 cvs 3622: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3623: {
1.184 vatton 3624: page.typed_data.unit = UNIT_REL;
3625: page.typed_data.value = PageAlways;
1.59 cvs 3626: }
1.82 cvs 3627: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3628: {
1.184 vatton 3629: page.typed_data.unit = UNIT_REL;
3630: page.typed_data.value = PageAvoid;
1.59 cvs 3631: }
1.82 cvs 3632: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 3633: {
1.184 vatton 3634: page.typed_data.unit = UNIT_REL;
3635: page.typed_data.value = PageLeft;
1.59 cvs 3636: }
1.82 cvs 3637: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3638: {
1.184 vatton 3639: page.typed_data.unit = UNIT_REL;
3640: page.typed_data.value = PageRight;
1.59 cvs 3641: }
1.82 cvs 3642: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3643: {
1.184 vatton 3644: /*page.typed_data.unit = UNIT_REL;*/
3645: page.typed_data.value = PageInherit;
1.59 cvs 3646: }
3647: cssRule = SkipWord (cssRule);
3648: /* install the new presentation */
1.184 vatton 3649: if (page.typed_data.unit == UNIT_REL &&
3650: page.typed_data.value == PageAlways && DoApply)
1.117 vatton 3651: {
3652: /* check if it's an important rule */
3653: if (tsch)
1.207 vatton 3654: cssRule = CheckImportantRule (cssRule, ctxt);
3655: TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
1.117 vatton 3656: }
1.59 cvs 3657: return (cssRule);
3658: }
3659:
3660: /*----------------------------------------------------------------------
1.60 cvs 3661: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 3662: ----------------------------------------------------------------------*/
1.79 cvs 3663: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.207 vatton 3664: PresentationContext ctxt,
1.79 cvs 3665: char *cssRule, CSSInfoPtr css,
3666: ThotBool isHTML)
1.59 cvs 3667: {
3668: PresentationValue page;
3669:
1.184 vatton 3670: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 3671: page.typed_data.real = FALSE;
1.82 cvs 3672: cssRule = SkipBlanksAndComments (cssRule);
3673: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 3674: page.typed_data.value = PageAuto;
1.82 cvs 3675: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3676: {
1.184 vatton 3677: page.typed_data.unit = UNIT_REL;
3678: page.typed_data.value = PageAlways;
1.59 cvs 3679: }
1.82 cvs 3680: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3681: {
1.184 vatton 3682: page.typed_data.unit = UNIT_REL;
3683: page.typed_data.value = PageAvoid;
1.59 cvs 3684: }
1.82 cvs 3685: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 3686: {
1.184 vatton 3687: page.typed_data.unit = UNIT_REL;
3688: page.typed_data.value = PageLeft;
1.59 cvs 3689: }
1.82 cvs 3690: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3691: {
1.184 vatton 3692: page.typed_data.unit = UNIT_REL;
3693: page.typed_data.value = PageRight;
1.59 cvs 3694: }
1.82 cvs 3695: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3696: {
1.184 vatton 3697: /*page.typed_data.unit = UNIT_REL;*/
3698: page.typed_data.value = PageInherit;
1.59 cvs 3699: }
3700: cssRule = SkipWord (cssRule);
3701: /* install the new presentation */
1.184 vatton 3702: /*if (page.typed_data.unit == UNIT_REL && DoApply)
1.117 vatton 3703: {
3704: if (tsch)
1.207 vatton 3705: cssRule = CheckImportantRule (cssRule, ctxt);
3706: TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page);
1.117 vatton 3707: }*/
1.59 cvs 3708: return (cssRule);
3709: }
3710:
3711: /*----------------------------------------------------------------------
1.60 cvs 3712: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 3713: ----------------------------------------------------------------------*/
1.79 cvs 3714: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.207 vatton 3715: PresentationContext ctxt,
1.79 cvs 3716: char *cssRule, CSSInfoPtr css,
3717: ThotBool isHTML)
1.59 cvs 3718: {
3719: PresentationValue page;
3720:
1.184 vatton 3721: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 3722: page.typed_data.real = FALSE;
1.82 cvs 3723: cssRule = SkipBlanksAndComments (cssRule);
3724: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3725: {
1.184 vatton 3726: /*page.typed_data.unit = UNIT_REL;*/
3727: page.typed_data.value = PageAuto;
1.59 cvs 3728: }
1.82 cvs 3729: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3730: {
1.184 vatton 3731: page.typed_data.unit = UNIT_REL;
3732: page.typed_data.value = PageAvoid;
1.59 cvs 3733: }
1.82 cvs 3734: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3735: {
1.184 vatton 3736: /*page.typed_data.unit = UNIT_REL;*/
3737: page.typed_data.value = PageInherit;
1.59 cvs 3738: }
3739: cssRule = SkipWord (cssRule);
3740: /* install the new presentation */
1.184 vatton 3741: /*if (page.typed_data.unit == UNIT_REL &&
3742: page.typed_data.value == PageAvoid && DoApply)
1.117 vatton 3743: {
3744: if (tsch)
1.207 vatton 3745: cssRule = CheckImportantRule (cssRule, ctxt);
3746: TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);
1.117 vatton 3747: }*/
1.59 cvs 3748: return (cssRule);
3749: }
1.18 cvs 3750:
3751:
1.60 cvs 3752: /*----------------------------------------------------------------------
1.217 vatton 3753: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 3754: ----------------------------------------------------------------------*/
1.79 cvs 3755: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.207 vatton 3756: PresentationContext ctxt, char *cssRule,
1.79 cvs 3757: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 3758: {
3759: PresentationValue width;
3760:
1.82 cvs 3761: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 3762: width.typed_data.value = 0;
1.184 vatton 3763: width.typed_data.unit = UNIT_INVALID;
1.60 cvs 3764: width.typed_data.real = FALSE;
1.110 vatton 3765: if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 3766: {
1.60 cvs 3767: cssRule = ParseCSSUnit (cssRule, &width);
1.184 vatton 3768: if (width.typed_data.unit == UNIT_BOX)
3769: width.typed_data.unit = UNIT_PX;
1.166 vatton 3770: }
1.184 vatton 3771: if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 3772: {
3773: /* check if it's an important rule */
3774: if (tsch)
1.207 vatton 3775: cssRule = CheckImportantRule (cssRule, ctxt);
3776: TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117 vatton 3777: width.typed_data.value = 1;
1.184 vatton 3778: width.typed_data.unit = UNIT_REL;
1.117 vatton 3779: }
1.60 cvs 3780: return (cssRule);
3781: }
3782:
1.217 vatton 3783: /*----------------------------------------------------------------------
3784: ParseCSSPosition: parse a CSS Position attribute string.
3785: ----------------------------------------------------------------------*/
3786: static char *ParseCSSPosition (Element element, PSchema tsch,
3787: PresentationContext ctxt,
3788: char *cssRule, CSSInfoPtr css,
3789: ThotBool isHTML)
3790: {
3791: char *ptr;
3792:
3793: cssRule = SkipBlanksAndComments (cssRule);
3794: ptr = cssRule;
3795: if (!strncasecmp (cssRule, "static", 6))
3796: cssRule = SkipWord (cssRule);
3797: else if (!strncasecmp (cssRule, "relative", 7))
3798: cssRule = SkipWord (cssRule);
3799: else if (!strncasecmp (cssRule, "absolute", 8))
3800: cssRule = SkipWord (cssRule);
3801: else if (!strncasecmp (cssRule, "fixed", 5))
3802: cssRule = SkipWord (cssRule);
3803: else if (!strncasecmp (cssRule, "inherit", 7))
3804: cssRule = SkipWord (cssRule);
3805: else
3806: cssRule = SkipValue ("Invalid Position value", ptr);
3807: return (cssRule);
3808: }
3809:
3810: /*----------------------------------------------------------------------
3811: ParseCSSTop: parse a CSS Top attribute
3812: ----------------------------------------------------------------------*/
3813: static char *ParseCSSTop (Element element, PSchema tsch,
3814: PresentationContext context, char *cssRule,
3815: CSSInfoPtr css, ThotBool isHTML)
3816: {
3817: PresentationValue val;
3818: char *ptr;
3819:
3820: cssRule = SkipBlanksAndComments (cssRule);
3821: ptr = cssRule;
3822: /* first parse the attribute string */
3823: if (!strncasecmp (cssRule, "auto", 4) ||
3824: !strncasecmp (cssRule, "inherit", 7))
3825: {
3826: val.typed_data.unit = VALUE_AUTO;
3827: val.typed_data.value = 0;
3828: val.typed_data.real = FALSE;
3829: cssRule = SkipWord (cssRule);
3830: }
3831: else
3832: cssRule = ParseCSSUnit (cssRule, &val);
3833: if (val.typed_data.value != 0 &&
3834: (val.typed_data.unit == UNIT_INVALID ||
3835: val.typed_data.unit == UNIT_BOX))
3836: {
1.218 vatton 3837: cssRule = SkipValue ("top value", ptr);
1.217 vatton 3838: val.typed_data.unit = UNIT_PX;
3839: }
3840: /***
3841: if (DoApply)
3842: {
3843: if (tsch)
3844: cssRule = CheckImportantRule (cssRule, context);
3845: TtaSetStylePresentation (PR, element, tsch, context, val);
3846: }
3847: ***/
3848: return (cssRule);
3849: }
3850:
3851: /*----------------------------------------------------------------------
3852: ParseCSSRight: parse a CSS Right attribute
3853: ----------------------------------------------------------------------*/
3854: static char *ParseCSSRight (Element element, PSchema tsch,
3855: PresentationContext context, char *cssRule,
3856: CSSInfoPtr css, ThotBool isHTML)
3857: {
3858: PresentationValue val;
3859: char *ptr;
3860:
3861: cssRule = SkipBlanksAndComments (cssRule);
3862: ptr = cssRule;
3863: /* first parse the attribute string */
3864: if (!strncasecmp (cssRule, "auto", 4) ||
3865: !strncasecmp (cssRule, "inherit", 7))
3866: {
3867: val.typed_data.unit = VALUE_AUTO;
3868: val.typed_data.value = 0;
3869: val.typed_data.real = FALSE;
3870: cssRule = SkipWord (cssRule);
3871: }
3872: else
3873: cssRule = ParseCSSUnit (cssRule, &val);
3874: if (val.typed_data.value != 0 &&
3875: (val.typed_data.unit == UNIT_INVALID ||
3876: val.typed_data.unit == UNIT_BOX))
3877: {
1.218 vatton 3878: cssRule = SkipValue ("right value", ptr);
1.217 vatton 3879: val.typed_data.unit = UNIT_PX;
3880: }
3881: /***
3882: if (DoApply)
3883: {
3884: if (tsch)
3885: cssRule = CheckImportantRule (cssRule, context);
3886: TtaSetStylePresentation (PR, element, tsch, context, val);
3887: }
3888: ***/
3889: return (cssRule);
3890: }
3891:
3892: /*----------------------------------------------------------------------
3893: ParseCSSBottom: parse a CSS Bottom attribute
3894: ----------------------------------------------------------------------*/
3895: static char *ParseCSSBottom (Element element, PSchema tsch,
3896: PresentationContext context, char *cssRule,
3897: CSSInfoPtr css, ThotBool isHTML)
3898: {
3899: PresentationValue val;
3900: char *ptr;
3901:
3902: cssRule = SkipBlanksAndComments (cssRule);
3903: ptr = cssRule;
3904: /* first parse the attribute string */
3905: if (!strncasecmp (cssRule, "auto", 4) ||
3906: !strncasecmp (cssRule, "inherit", 7))
3907: {
3908: val.typed_data.unit = VALUE_AUTO;
3909: val.typed_data.value = 0;
3910: val.typed_data.real = FALSE;
3911: cssRule = SkipWord (cssRule);
3912: }
3913: else
3914: cssRule = ParseCSSUnit (cssRule, &val);
3915: if (val.typed_data.value != 0 &&
3916: (val.typed_data.unit == UNIT_INVALID ||
3917: val.typed_data.unit == UNIT_BOX))
3918: {
1.218 vatton 3919: cssRule = SkipValue ("bottom value", ptr);
1.217 vatton 3920: val.typed_data.unit = UNIT_PX;
3921: }
3922: /***
3923: if (DoApply)
3924: {
3925: if (tsch)
3926: cssRule = CheckImportantRule (cssRule, context);
3927: TtaSetStylePresentation (PR, element, tsch, context, val);
3928: }
3929: ***/
3930: return (cssRule);
3931: }
3932:
3933: /*----------------------------------------------------------------------
3934: ParseCSSLeft: parse a CSS Left attribute
3935: ----------------------------------------------------------------------*/
3936: static char *ParseCSSLeft (Element element, PSchema tsch,
3937: PresentationContext context, char *cssRule,
3938: CSSInfoPtr css, ThotBool isHTML)
3939: {
3940: PresentationValue val;
3941: char *ptr;
3942:
3943: cssRule = SkipBlanksAndComments (cssRule);
3944: ptr = cssRule;
3945: /* first parse the attribute string */
3946: if (!strncasecmp (cssRule, "auto", 4) ||
3947: !strncasecmp (cssRule, "inherit", 7))
3948: {
3949: val.typed_data.unit = VALUE_AUTO;
3950: val.typed_data.value = 0;
3951: val.typed_data.real = FALSE;
3952: cssRule = SkipWord (cssRule);
3953: }
3954: else
3955: cssRule = ParseCSSUnit (cssRule, &val);
3956: if (val.typed_data.value != 0 &&
3957: (val.typed_data.unit == UNIT_INVALID ||
3958: val.typed_data.unit == UNIT_BOX))
3959: {
1.218 vatton 3960: cssRule = SkipValue ("left value", ptr);
1.217 vatton 3961: val.typed_data.unit = UNIT_PX;
3962: }
3963: /***
3964: if (DoApply)
3965: {
3966: if (tsch)
3967: cssRule = CheckImportantRule (cssRule, context);
3968: TtaSetStylePresentation (PR, element, tsch, context, val);
3969: }
3970: ***/
3971: return (cssRule);
3972: }
3973:
3974: /*----------------------------------------------------------------------
3975: ParseCSSZIndex: parse a CSS z-index attribute
3976: ----------------------------------------------------------------------*/
3977: static char *ParseCSSZIndex (Element element, PSchema tsch,
3978: PresentationContext context, char *cssRule,
3979: CSSInfoPtr css, ThotBool isHTML)
3980: {
3981: PresentationValue val;
3982: char *ptr;
3983:
3984: cssRule = SkipBlanksAndComments (cssRule);
3985: ptr = cssRule;
3986: /* first parse the attribute string */
3987: if (!strncasecmp (cssRule, "auto", 4) ||
3988: !strncasecmp (cssRule, "inherit", 7))
3989: {
3990: val.typed_data.unit = VALUE_AUTO;
3991: val.typed_data.value = 0;
3992: val.typed_data.real = FALSE;
3993: cssRule = SkipWord (cssRule);
3994: }
3995: else
3996: {
3997: cssRule = ParseCSSUnit (cssRule, &val);
3998: if (val.typed_data.unit != UNIT_BOX)
3999: {
1.218 vatton 4000: cssRule = SkipValue ("z-index value", ptr);
1.217 vatton 4001: val.typed_data.unit = UNIT_BOX;
4002: }
4003: }
4004: /***
4005: if (DoApply)
4006: {
4007: if (tsch)
4008: cssRule = CheckImportantRule (cssRule, context);
4009: TtaSetStylePresentation (PR, element, tsch, context, val);
4010: }
4011: ***/
4012: return (cssRule);
4013: }
4014:
1.18 cvs 4015: /************************************************************************
4016: * *
4017: * FUNCTIONS STYLE DECLARATIONS *
4018: * *
4019: ************************************************************************/
4020: /*
1.59 cvs 4021: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 4022: * e.g. "FONT-SIZE" must be placed before "FONT"
4023: */
4024: static CSSProperty CSSProperties[] =
4025: {
1.82 cvs 4026: {"background-color", ParseCSSBackgroundColor},
4027: {"background-image", ParseCSSBackgroundImage},
4028: {"background-repeat", ParseCSSBackgroundRepeat},
4029: {"background-attachment", ParseCSSBackgroundAttachment},
4030: {"background-position", ParseCSSBackgroundPosition},
4031: {"background", ParseCSSBackground},
4032: {"border-top-width", ParseCSSBorderTopWidth},
4033: {"border-right-width", ParseCSSBorderRightWidth},
4034: {"border-bottom-width", ParseCSSBorderBottomWidth},
4035: {"border-left-width", ParseCSSBorderLeftWidth},
4036: {"border-width", ParseCSSBorderWidth},
4037: {"border-top-color", ParseCSSBorderColorTop},
4038: {"border-right-color", ParseCSSBorderColorRight},
4039: {"border-bottom-color", ParseCSSBorderColorBottom},
4040: {"border-left-color", ParseCSSBorderColorLeft},
4041: {"border-color", ParseCSSBorderColor},
4042: {"border-top-style", ParseCSSBorderStyleTop},
4043: {"border-right-style", ParseCSSBorderStyleRight},
4044: {"border-bottom-style", ParseCSSBorderStyleBottom},
4045: {"border-left-style", ParseCSSBorderStyleLeft},
4046: {"border-style", ParseCSSBorderStyle},
4047: {"border-top", ParseCSSBorderTop},
4048: {"border-right", ParseCSSBorderRight},
4049: {"border-bottom", ParseCSSBorderBottom},
4050: {"border-left", ParseCSSBorderLeft},
4051: {"border", ParseCSSBorder},
1.234 vatton 4052: {"bottom", ParseCSSBottom},
1.82 cvs 4053: {"clear", ParseCSSClear},
1.234 vatton 4054: {"color", ParseCSSForeground},
1.184 vatton 4055: {"content", ParseCSSContent},
1.234 vatton 4056: {"direction", ParseCSSDirection},
1.82 cvs 4057: {"display", ParseCSSDisplay},
1.234 vatton 4058: {"float", ParseCSSFloat},
4059: {"font-family", ParseCSSFontFamily},
4060: {"font-style", ParseCSSFontStyle},
4061: {"font-variant", ParseCSSFontVariant},
4062: {"font-weight", ParseCSSFontWeight},
4063: {"font-size-adjust", ParseCSSFontSizeAdjust},
4064: {"font-size", ParseCSSFontSize},
4065: {"font", ParseCSSFont},
4066: {"height", ParseCSSHeight},
1.217 vatton 4067: {"left", ParseCSSLeft},
1.234 vatton 4068: {"letter-spacing", ParseCSSLetterSpacing},
4069: {"line-height", ParseCSSLineHeight},
1.82 cvs 4070: {"list-style-type", ParseCSSListStyleType},
4071: {"list-style-image", ParseCSSListStyleImage},
4072: {"list-style-position", ParseCSSListStylePosition},
4073: {"list-style", ParseCSSListStyle},
1.234 vatton 4074: {"margin-bottom", ParseCSSMarginBottom},
4075: {"margin-top", ParseCSSMarginTop},
4076: {"margin-right", ParseCSSMarginRight},
4077: {"margin-left", ParseCSSMarginLeft},
4078: {"margin", ParseCSSMargin},
4079: {"padding-top", ParseCSSPaddingTop},
4080: {"padding-right", ParseCSSPaddingRight},
4081: {"padding-bottom", ParseCSSPaddingBottom},
4082: {"padding-left", ParseCSSPaddingLeft},
4083: {"padding", ParseCSSPadding},
1.82 cvs 4084: {"page-break-before", ParseCSSPageBreakBefore},
4085: {"page-break-after", ParseCSSPageBreakAfter},
4086: {"page-break-inside", ParseCSSPageBreakInside},
1.234 vatton 4087: {"position", ParseCSSPosition},
4088: {"right", ParseCSSRight},
4089: {"text-align", ParseCSSTextAlign},
1.243 quint 4090: {"text-anchor", ParseCSSTextAnchor},
1.234 vatton 4091: {"text-indent", ParseCSSTextIndent},
4092: {"text-decoration", ParseCSSTextDecoration},
4093: {"text-transform", ParseCSSTextTransform},
4094: {"top", ParseCSSTop},
4095: {"unicode-bidi", ParseCSSUnicodeBidi},
4096: {"vertical-align", ParseCSSVerticalAlign},
4097: {"white-space", ParseCSSWhiteSpace},
4098: {"width", ParseCSSWidth},
4099: {"word-spacing", ParseCSSWordSpacing},
4100: {"z-index", ParseCSSZIndex},
1.60 cvs 4101:
4102: /* SVG extensions */
1.234 vatton 4103: {"fill-opacity", ParseSVGFillOpacity},
4104: {"fill", ParseSVGFill},
4105: {"opacity", ParseSVGOpacity},
1.170 cheyroul 4106: {"stroke-opacity", ParseSVGStrokeOpacity},
1.82 cvs 4107: {"stroke-width", ParseSVGStrokeWidth},
1.234 vatton 4108: {"stroke", ParseSVGStroke}
1.18 cvs 4109: };
1.155 cheyroul 4110:
1.18 cvs 4111: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
4112:
4113: /*----------------------------------------------------------------------
1.59 cvs 4114: ParseCSSRule: parse a CSS Style string
1.18 cvs 4115: we expect the input string describing the style to be of the
1.59 cvs 4116: form: PRORPERTY: DESCRIPTION [ ; PROPERTY: DESCRIPTION ] *
1.18 cvs 4117: but tolerate incorrect or incomplete input
4118: ----------------------------------------------------------------------*/
1.79 cvs 4119: static void ParseCSSRule (Element element, PSchema tsch,
1.207 vatton 4120: PresentationContext ctxt, char *cssRule,
1.79 cvs 4121: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 4122: {
1.34 cvs 4123: DisplayMode dispMode;
1.250 vatton 4124: char *p = NULL, *next;
1.214 quint 4125: char *valueStart;
1.18 cvs 4126: int lg;
1.34 cvs 4127: unsigned int i;
1.76 cvs 4128: ThotBool found;
1.18 cvs 4129:
1.34 cvs 4130: /* avoid too many redisplay */
1.207 vatton 4131: dispMode = TtaGetDisplayMode (ctxt->doc);
1.34 cvs 4132: if (dispMode == DisplayImmediately)
1.207 vatton 4133: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
1.34 cvs 4134:
1.82 cvs 4135: while (*cssRule != EOS)
1.18 cvs 4136: {
1.82 cvs 4137: cssRule = SkipBlanksAndComments (cssRule);
1.153 vatton 4138: if (*cssRule < 0x41 || *cssRule > 0x7A ||
1.133 vatton 4139: (*cssRule > 0x5A && *cssRule < 0x60))
1.153 vatton 4140: cssRule++;
1.194 vatton 4141: else if (*cssRule != EOS)
1.89 cvs 4142: {
1.153 vatton 4143: found = FALSE;
4144: /* look for the type of property */
4145: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
1.18 cvs 4146: {
1.153 vatton 4147: lg = strlen (CSSProperties[i].name);
4148: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
4149: {
4150: p = cssRule + lg;
4151: found = TRUE;
4152: i--;
4153: }
1.18 cvs 4154: }
1.153 vatton 4155: if (i == NB_CSSSTYLEATTRIBUTE)
1.234 vatton 4156: cssRule = SkipProperty (cssRule, TRUE);
1.153 vatton 4157: else
1.18 cvs 4158: {
1.153 vatton 4159: /* update index and skip the ":" indicator if present */
1.86 cvs 4160: p = SkipBlanksAndComments (p);
1.153 vatton 4161: if (*p == ':')
1.61 cvs 4162: {
1.153 vatton 4163: p++;
4164: p = SkipBlanksAndComments (p);
4165: /* try to parse the value associated with this property */
4166: if (CSSProperties[i].parsing_function != NULL)
4167: {
1.214 quint 4168: valueStart = p;
4169: p = CSSProperties[i].parsing_function (element, tsch,
4170: ctxt, p, css, isHTML);
4171: if (!element && isHTML)
4172: {
4173: if (ctxt->type == HTML_EL_Input)
4174: /* it's a generic rule for the HTML element input.
4175: Generate a Thot Pres rule for each kind of
4176: input element */
4177: {
4178: ctxt->type = HTML_EL_Text_Input;
4179: p = CSSProperties[i].parsing_function (element,
4180: tsch, ctxt, valueStart, css, isHTML);
4181: ctxt->type = HTML_EL_Password_Input;
4182: p = CSSProperties[i].parsing_function (element,
4183: tsch, ctxt, valueStart, css, isHTML);
4184: ctxt->type = HTML_EL_File_Input;
4185: p = CSSProperties[i].parsing_function (element,
4186: tsch, ctxt, valueStart, css, isHTML);
4187: ctxt->type = HTML_EL_Checkbox_Input;
4188: p = CSSProperties[i].parsing_function (element,
4189: tsch, ctxt, valueStart, css, isHTML);
4190: ctxt->type = HTML_EL_Radio_Input;
4191: p = CSSProperties[i].parsing_function (element,
4192: tsch, ctxt, valueStart, css, isHTML);
4193: ctxt->type = HTML_EL_Submit_Input;
4194: p = CSSProperties[i].parsing_function (element,
4195: tsch, ctxt, valueStart, css, isHTML);
4196: ctxt->type = HTML_EL_Reset_Input;
4197: p = CSSProperties[i].parsing_function (element,
4198: tsch, ctxt, valueStart, css, isHTML);
4199: ctxt->type = HTML_EL_Button_Input;
4200: p = CSSProperties[i].parsing_function (element,
4201: tsch, ctxt, valueStart, css, isHTML);
4202: ctxt->type = HTML_EL_Input;
4203: }
4204: else if (ctxt->type == HTML_EL_ruby)
4205: /* it's a generic rule for the HTML element ruby.
4206: Generate a Thot Pres rule for each kind of
4207: ruby element. */
4208: {
4209: ctxt->type = HTML_EL_simple_ruby;
4210: p = CSSProperties[i].parsing_function (element,
4211: tsch, ctxt, valueStart, css, isHTML);
4212: ctxt->type = HTML_EL_complex_ruby;
4213: p = CSSProperties[i].parsing_function (element,
4214: tsch, ctxt, valueStart, css, isHTML);
4215: ctxt->type = HTML_EL_ruby;
4216: }
4217: }
1.153 vatton 4218: /* update index and skip the ";" separator if present */
1.250 vatton 4219: next = SkipBlanksAndComments (p);
4220: if (*next != EOS && *next != ';')
1.251 ! vatton 4221: CSSParseError ("Missing closing ';'", cssRule, p);
1.250 vatton 4222: cssRule = next;
1.153 vatton 4223: }
1.61 cvs 4224: }
1.153 vatton 4225: else
1.234 vatton 4226: cssRule = SkipProperty (cssRule, TRUE);
1.18 cvs 4227: }
4228: }
4229: /* next property */
1.82 cvs 4230: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 4231: if (*cssRule == '}')
4232: {
4233: cssRule++;
1.168 vatton 4234: CSSPrintError ("Invalid character", "}");
1.89 cvs 4235: cssRule = SkipBlanksAndComments (cssRule);
4236: }
1.155 cheyroul 4237: if (*cssRule == ',' ||
4238: *cssRule == ';')
1.18 cvs 4239: {
4240: cssRule++;
1.82 cvs 4241: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 4242: }
4243: }
1.34 cvs 4244:
4245: /* restore the display mode */
4246: if (dispMode == DisplayImmediately)
1.207 vatton 4247: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 4248: }
1.1 cvs 4249:
1.111 cvs 4250: /*----------------------------------------------------------------------
1.59 cvs 4251: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18 cvs 4252: This function must be called when a specific style is applied to an
4253: element.
1.114 quint 4254: The parameter specificity is the specificity of the style, 0 if it is
4255: not really a CSS rule.
1.1 cvs 4256: ----------------------------------------------------------------------*/
1.79 cvs 4257: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.114 quint 4258: int specificity, ThotBool destroy)
1.1 cvs 4259: {
1.207 vatton 4260: PresentationContext ctxt;
4261: ElementType elType;
4262: ThotBool isHTML;
1.1 cvs 4263:
1.207 vatton 4264: /* A rule applying to BODY is really meant to address HTML */
4265: elType = TtaGetElementType (el);
1.89 cvs 4266:
1.207 vatton 4267: /* store the current line for eventually reported errors */
4268: LineNumber = TtaGetElementLineNumber (el);
4269: if (destroy)
4270: /* no reported errors */
4271: ParsedDoc = 0;
4272: else if (ParsedDoc != doc)
4273: {
4274: /* update the context for reported errors */
4275: ParsedDoc = doc;
4276: DocURL = DocumentURLs[doc];
4277: }
4278: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
4279: /* create the context of the Specific presentation driver */
4280: ctxt = TtaGetSpecificStyleContext (doc);
4281: if (ctxt == NULL)
4282: return;
4283: ctxt->type = elType.ElTypeNum;
4284: ctxt->cssSpecificity = specificity;
1.236 quint 4285: ctxt->cssLine = LineNumber;
1.207 vatton 4286: ctxt->destroy = destroy;
4287: /* first use of the context */
4288: ctxt->uses = 1;
4289: /* Call the parser */
4290: ParseCSSRule (el, NULL, (PresentationContext) ctxt, cssRule, NULL, isHTML);
4291: /* check if the context can be freed */
4292: ctxt->uses -= 1;
4293: if (ctxt->uses == 0)
4294: /* no image loading */
4295: TtaFreeMemory(ctxt);
1.1 cvs 4296: }
4297:
1.68 cvs 4298:
1.1 cvs 4299: /*----------------------------------------------------------------------
1.207 vatton 4300: ParseGenericSelector: Create a generic context for a given selector
4301: string.
4302: If the selector is made of multiple comma, it parses them one at a time
4303: and return the end of the selector string to be handled or NULL.
1.231 vatton 4304: The parameter ctxt gives the current style context which will be passed
4305: to Thotlib.
4306: The parameter css points to the current CSS context.
4307: The parameter link points to the link element.
4308: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 4309: ----------------------------------------------------------------------*/
1.207 vatton 4310: static char *ParseGenericSelector (char *selector, char *cssRule,
1.79 cvs 4311: GenericContext ctxt, Document doc,
1.231 vatton 4312: CSSInfoPtr css, Element link, char *url)
1.79 cvs 4313: {
4314: ElementType elType;
4315: PSchema tsch;
1.119 vatton 4316: AttributeType attrType;
1.240 quint 4317: char *deb, *cur, *sel, *next, c;
1.118 vatton 4318: char *schemaName, *mappedName;
1.79 cvs 4319: char *names[MAX_ANCESTORS];
4320: char *ids[MAX_ANCESTORS];
4321: char *classes[MAX_ANCESTORS];
4322: char *pseudoclasses[MAX_ANCESTORS];
4323: char *attrs[MAX_ANCESTORS];
4324: char *attrvals[MAX_ANCESTORS];
1.133 vatton 4325: AttrMatch attrmatch[MAX_ANCESTORS];
1.250 vatton 4326: ThotBool rel[MAX_ANCESTORS];
1.91 cvs 4327: int i, j, k, max;
1.125 vatton 4328: int att, maxAttr, kind;
1.118 vatton 4329: int specificity, xmlType;
1.217 vatton 4330: int skippedNL;
1.79 cvs 4331: ThotBool isHTML;
1.183 vatton 4332: ThotBool level, quoted;
1.1 cvs 4333:
1.207 vatton 4334: sel = ctxt->sel;
1.82 cvs 4335: sel[0] = EOS;
1.117 vatton 4336: specificity = 0;
1.1 cvs 4337: for (i = 0; i < MAX_ANCESTORS; i++)
4338: {
1.25 cvs 4339: names[i] = NULL;
4340: ids[i] = NULL;
4341: classes[i] = NULL;
4342: pseudoclasses[i] = NULL;
4343: attrs[i] = NULL;
4344: attrvals[i] = NULL;
1.133 vatton 4345: attrmatch[i] = Txtmatch;
1.250 vatton 4346: rel[i] = 0;
1.25 cvs 4347: ctxt->name[i] = 0;
4348: ctxt->names_nb[i] = 0;
4349: ctxt->attrType[i] = 0;
1.129 vatton 4350: ctxt->attrLevel[i] = 0;
1.25 cvs 4351: ctxt->attrText[i] = NULL;
1.178 quint 4352: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 4353: }
1.25 cvs 4354: ctxt->box = 0;
4355: ctxt->type = 0;
1.114 quint 4356: /* the specificity of the rule depends on the selector */
4357: ctxt->cssSpecificity = 0;
1.231 vatton 4358: /* localisation of the CSS rule */
4359: ctxt->cssLine = LineNumber + NewLineSkipped;
4360: ctxt->cssURL = url;
1.240 quint 4361:
1.82 cvs 4362: selector = SkipBlanksAndComments (selector);
1.27 cvs 4363: cur = &sel[0];
1.25 cvs 4364: max = 0; /* number of loops */
1.1 cvs 4365: while (1)
4366: {
1.85 cvs 4367: /* point to the following word in sel[] */
1.27 cvs 4368: deb = cur;
1.25 cvs 4369: /* copy an item of the selector into sel[] */
1.1 cvs 4370: /* put one word in the sel buffer */
1.82 cvs 4371: while (*selector != EOS && *selector != ',' &&
4372: *selector != '.' && *selector != ':' &&
1.118 vatton 4373: *selector != '#' && *selector != '[' &&
1.250 vatton 4374: *selector != '>' && *selector != '+' &&
1.118 vatton 4375: !TtaIsBlank (selector))
1.50 cvs 4376: *cur++ = *selector++;
1.82 cvs 4377: *cur++ = EOS; /* close the first string in sel[] */
4378: if (deb[0] != EOS)
1.117 vatton 4379: {
1.240 quint 4380: if (deb[0] <= 64 && deb[0] != '*')
4381: {
4382: CSSPrintError ("Invalid element", deb);
4383: return NULL;
4384: }
1.149 vatton 4385: else
1.240 quint 4386: {
4387: names[0] = deb;
4388: if (!strcmp (names[0], "html"))
4389: /* give a greater priority to the backgoud color of html */
4390: specificity += 3;
4391: else
4392: /* selector "*" has specificity zero */
4393: if (strcmp (names[0], "*"))
4394: specificity += 1;
4395: }
1.117 vatton 4396: }
1.25 cvs 4397: else
1.27 cvs 4398: names[0] = NULL;
1.226 quint 4399:
1.27 cvs 4400: classes[0] = NULL;
4401: pseudoclasses[0] = NULL;
4402: ids[0] = NULL;
4403: attrs[0] = NULL;
4404: attrvals[0] = NULL;
1.25 cvs 4405:
1.27 cvs 4406: /* now names[0] points to the beginning of the parsed item
1.25 cvs 4407: and cur to the next chain to be parsed */
1.129 vatton 4408: while (*selector == '.' || *selector == ':' ||
1.234 vatton 4409: *selector == '#' || *selector == '[')
1.129 vatton 4410: {
1.85 cvs 4411: /* point to the following word in sel[] */
4412: deb = cur;
1.129 vatton 4413: if (*selector == '.')
4414: {
4415: selector++;
4416: while (*selector != EOS && *selector != ',' &&
4417: *selector != '.' && *selector != ':' &&
4418: !TtaIsBlank (selector))
1.240 quint 4419: {
4420: if (*selector == '\\')
4421: {
4422: selector++;
4423: if (*selector != EOS)
4424: *cur++ = *selector++;
4425: }
4426: else
4427: *cur++ = *selector++;
4428: }
1.129 vatton 4429: /* close the word */
4430: *cur++ = EOS;
4431: /* point to the class in sel[] if it's valid name */
4432: if (deb[0] <= 64)
4433: {
1.168 vatton 4434: CSSPrintError ("Invalid class", deb);
1.116 vatton 4435: DoApply = FALSE;
1.129 vatton 4436: }
4437: else
4438: {
4439: classes[0] = deb;
1.178 quint 4440: /* a "class" attribute on an element may contain several
4441: words, one for each class it matches */
4442: attrmatch[0] = Txtword;
1.117 vatton 4443: specificity += 10;
1.227 quint 4444: if (names[0] && !strcmp (names[0], "*"))
1.226 quint 4445: names[0] = NULL;
1.129 vatton 4446: }
4447: }
4448: else if (*selector == ':')
4449: {
4450: selector++;
4451: while (*selector != EOS && *selector != ',' &&
4452: *selector != '.' && *selector != ':' &&
4453: !TtaIsBlank (selector))
4454: *cur++ = *selector++;
4455: /* close the word */
4456: *cur++ = EOS;
4457: /* point to the pseudoclass in sel[] if it's valid name */
4458: if (deb[0] <= 64)
4459: {
1.168 vatton 4460: CSSPrintError ("Invalid pseudoclass", deb);
1.129 vatton 4461: DoApply = FALSE;
4462: }
4463: else
4464: {
4465: if (!strcmp (deb, "first-letter") ||
4466: !strcmp (deb, "first-line") ||
4467: !strcmp (deb, "before") ||
4468: !strcmp (deb, "after"))
4469: /* not supported */
1.116 vatton 4470: DoApply = FALSE;
1.129 vatton 4471: else
4472: specificity += 10;
1.238 quint 4473: if (!strncmp (deb, "lang", 4))
4474: /* it's the lang pseudo-class */
4475: {
4476: if (deb[4] != '(' || deb[strlen(deb)-1] != ')')
4477: /* at least one paranthesis is missing. Error */
4478: {
4479: CSSPrintError ("Invalid :lang pseudoclass", deb);
4480: DoApply = FALSE;
4481: }
4482: else
4483: /* simulate selector [lang|="xxx"] if there no
4484: attribute yet in the selector */
4485: if (!attrs[0])
4486: {
4487: deb[strlen(deb)-1] = EOS;
4488: deb[4] = EOS;
4489: attrmatch[0] = Txtsubstring;
4490: attrs[0] = deb;
4491: attrvals[0] = &deb[5];
4492: }
4493: }
4494: else
4495: pseudoclasses[0] = deb;
1.227 quint 4496: if (names[0] && !strcmp (names[0], "*"))
1.226 quint 4497: names[0] = NULL;
1.129 vatton 4498: }
4499: }
4500: else if (*selector == '#')
4501: {
4502: selector++;
4503: while (*selector != EOS && *selector != ',' &&
4504: *selector != '.' && *selector != ':' &&
1.237 quint 4505: *selector != '#' &&
1.129 vatton 4506: !TtaIsBlank (selector))
4507: *cur++ = *selector++;
4508: /* close the word */
4509: *cur++ = EOS;
4510: /* point to the attribute in sel[] if it's valid name */
4511: if (deb[0] <= 64)
4512: {
1.168 vatton 4513: CSSPrintError ("Invalid id", deb);
1.129 vatton 4514: DoApply = FALSE;
4515: }
4516: else
4517: {
1.237 quint 4518: if (ids[0] && strcmp(ids[0], deb))
4519: {
4520: CSSPrintError ("Too many ids", deb);
4521: DoApply = FALSE;
4522: }
4523: else
4524: {
4525: ids[0] = deb;
4526: specificity += 100;
4527: if (names[0] && !strcmp (names[0], "*"))
4528: names[0] = NULL;
4529: }
1.129 vatton 4530: }
4531: }
4532: else if (*selector == '[')
4533: {
1.118 vatton 4534: selector++;
1.129 vatton 4535: while (*selector != EOS && *selector != ']' &&
1.131 vatton 4536: *selector != '=' && *selector != '~' &&
1.133 vatton 4537: *selector != '|' && *selector != '^' &&
4538: *selector != '!')
1.129 vatton 4539: *cur++ = *selector++;
1.133 vatton 4540: /* check matching */
4541: if (*selector == '~')
4542: {
4543: attrmatch[0] = Txtword;
4544: selector++;
4545: }
4546: else if (*selector == '|')
4547: {
4548: attrmatch[0] = Txtsubstring;
4549: selector++;
4550: }
4551: else
4552: attrmatch[0] = Txtmatch;
1.129 vatton 4553: /* close the word */
4554: *cur++ = EOS;
4555: /* point to the attribute in sel[] if it's valid name */
4556: if (deb[0] <= 64)
4557: {
1.168 vatton 4558: CSSPrintError ("Invalid attribute", deb);
1.129 vatton 4559: DoApply = FALSE;
4560: }
4561: else
4562: {
4563: attrs[0] = deb;
4564: specificity += 10;
4565: }
4566: if (*selector == '=')
4567: {
4568: /* look for a value "xxxx" */
4569: selector++;
4570: if (*selector != '"')
1.183 vatton 4571: quoted = FALSE;
1.129 vatton 4572: else
4573: {
1.183 vatton 4574: quoted = TRUE;
1.129 vatton 4575: /* we are now parsing the attribute value */
4576: selector++;
1.183 vatton 4577: }
4578: deb = cur;
4579: while ((quoted &&
4580: (*selector != '"' ||
4581: (*selector == '"' && selector[-1] == '\\'))) ||
4582: (!quoted && *selector != ']'))
4583: {
4584: if (*selector == EOS)
1.129 vatton 4585: {
1.183 vatton 4586: CSSPrintError ("Invalid attribute value", deb);
4587: DoApply = FALSE;
1.129 vatton 4588: }
1.183 vatton 4589: else
1.129 vatton 4590: {
1.228 quint 4591: if (attrmatch[0] == Txtword && TtaIsBlank (selector))
4592: {
4593: CSSPrintError ("No space allowed here: ", selector);
4594: DoApply = FALSE;
4595: }
1.238 quint 4596: *cur++ = *selector;
1.129 vatton 4597: }
1.228 quint 4598: selector++;
1.129 vatton 4599: }
1.183 vatton 4600: /* there is a value */
1.204 quint 4601: if (quoted && *selector == '"')
1.183 vatton 4602: {
4603: selector++;
4604: quoted = FALSE;
4605: }
4606: if (*selector != ']')
4607: {
4608: CSSPrintError ("Invalid attribute value", deb);
4609: DoApply = FALSE;
4610: }
4611: else
4612: {
4613: *cur++ = EOS;
4614: attrvals[0] = deb;
4615: selector++;
4616: }
1.129 vatton 4617: }
4618: /* end of the attribute */
1.183 vatton 4619: else if (*selector != ']')
1.129 vatton 4620: {
1.133 vatton 4621: selector[1] = EOS;
1.183 vatton 4622: CSSPrintError ("Invalid attribute", selector);
1.133 vatton 4623: selector += 2;
1.129 vatton 4624: DoApply = FALSE;
4625: }
4626: else
1.226 quint 4627: {
1.129 vatton 4628: selector++;
1.227 quint 4629: if (names[0] && !strcmp (names[0], "*"))
1.226 quint 4630: names[0] = NULL;
4631: }
1.130 vatton 4632: }
4633: else
4634: {
4635: /* not supported selector */
4636: while (*selector != EOS && *selector != ',' &&
4637: *selector != '.' && *selector != ':' &&
4638: !TtaIsBlank (selector))
4639: *cur++ = *selector++;
4640: /* close the word */
4641: *cur++ = EOS;
1.205 quint 4642: CSSPrintError ("Selector not supported:", deb);
1.130 vatton 4643: DoApply = FALSE;
1.129 vatton 4644: }
4645: }
1.1 cvs 4646:
1.82 cvs 4647: selector = SkipBlanksAndComments (selector);
1.25 cvs 4648: /* is it a multi-level selector? */
1.82 cvs 4649: if (*selector == EOS)
1.1 cvs 4650: /* end of the selector */
4651: break;
1.82 cvs 4652: else if (*selector == ',')
1.1 cvs 4653: {
4654: /* end of the current selector */
4655: selector++;
1.240 quint 4656: next = SkipBlanksAndComments (selector);
4657: if (*next == EOS)
4658: /* nothing after the comma. Invalid selector */
4659: {
4660: CSSPrintError ("Syntax error:", selector);
4661: return NULL;
4662: }
1.1 cvs 4663: break;
4664: }
1.25 cvs 4665: else
4666: {
1.143 vatton 4667: if (*selector == '>')
4668: {
4669: /* handle immediat parent as a simple parent */
4670: selector++;
4671: selector = SkipBlanksAndComments (selector);
1.250 vatton 4672: rel[0] = 1;
4673: }
4674: else if (*selector == '+')
4675: {
4676: /* handle immediat parent as a simple parent */
4677: selector++;
4678: selector = SkipBlanksAndComments (selector);
4679: rel[0] = 2;
1.143 vatton 4680: }
1.25 cvs 4681: /* shifts the list to make room for the new name */
4682: max++; /* a new level in ancestor tables */
4683: if (max == MAX_ANCESTORS)
4684: /* abort the CSS parsing */
4685: return (selector);
4686: for (i = max; i > 0; i--)
4687: {
4688: names[i] = names[i - 1];
4689: ids[i] = ids[i - 1];
4690: classes[i] = classes[i - 1];
1.133 vatton 4691: pseudoclasses[i] = pseudoclasses[i - 1];
1.25 cvs 4692: attrs[i] = attrs[i - 1];
4693: attrvals[i] = attrvals[i - 1];
1.133 vatton 4694: attrmatch[i] = attrmatch[i - 1];
1.250 vatton 4695: rel[i] = rel[i - 1];
1.25 cvs 4696: }
4697: }
1.1 cvs 4698: }
4699:
4700: /* Now set up the context block */
1.25 cvs 4701: i = 0;
4702: k = 0;
4703: j = 0;
1.35 cvs 4704: maxAttr = 0;
1.91 cvs 4705: /* default schema name */
1.119 vatton 4706: ctxt->schema = NULL;
1.122 vatton 4707: elType.ElSSchema = NULL;
4708: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 4709: if (!strcmp (schemaName, "HTML"))
4710: xmlType = XHTML_TYPE;
4711: else if (!strcmp (schemaName, "MathML"))
4712: xmlType = MATH_TYPE;
4713: else if (!strcmp (schemaName, "SVG"))
4714: xmlType = SVG_TYPE;
4715: else if (!strcmp (schemaName, "XLink"))
4716: xmlType = XLINK_TYPE;
4717: else if (!strcmp (schemaName, "Annot"))
4718: xmlType = ANNOT_TYPE;
4719: else
4720: xmlType = XML_TYPE;
1.25 cvs 4721: while (i <= max)
4722: {
4723: if (names[i])
4724: {
1.118 vatton 4725: /* get the element type of this name in the current document */
1.220 quint 4726: if (xmlType == XML_TYPE)
1.223 quint 4727: /* it's a generic XML document. Check the main document schema */
1.220 quint 4728: {
4729: elType.ElSSchema = TtaGetDocumentSSchema (doc);
4730: TtaGetXmlElementType (names[i], &elType, &mappedName, doc);
4731: if (!elType.ElTypeNum)
1.226 quint 4732: {
4733: if (!strcmp (names[i], "*"))
4734: elType.ElTypeNum = HTML_EL_ANY_TYPE;
4735: else
4736: elType.ElSSchema = NULL;
4737: }
1.220 quint 4738: }
4739: else
1.226 quint 4740: {
4741: if (!strcmp (names[i], "*"))
4742: {
4743: elType.ElSSchema = TtaGetDocumentSSchema (doc);
4744: elType.ElTypeNum = HTML_EL_ANY_TYPE;
4745: }
4746: else
4747: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c,
4748: &level, doc);
4749: }
1.25 cvs 4750: if (i == 0)
4751: {
1.106 cvs 4752: if (elType.ElSSchema == NULL)
4753: {
1.119 vatton 4754: /* Search in the list of loaded schemas */
1.106 cvs 4755: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.119 vatton 4756: if (elType.ElSSchema)
4757: {
1.154 vatton 4758: /* the element type concerns an imported nature */
1.119 vatton 4759: schemaName = TtaGetSSchemaName(elType.ElSSchema);
4760: if (!strcmp (schemaName, "HTML"))
4761: xmlType = XHTML_TYPE;
4762: else if (!strcmp (schemaName, "MathML"))
4763: xmlType = MATH_TYPE;
4764: else if (!strcmp (schemaName, "SVG"))
4765: xmlType = SVG_TYPE;
4766: else if (!strcmp (schemaName, "XLink"))
4767: xmlType = XLINK_TYPE;
4768: else if (!strcmp (schemaName, "Annot"))
4769: xmlType = ANNOT_TYPE;
4770: else
4771: xmlType = XML_TYPE;
4772: }
1.118 vatton 4773: #ifdef XML_GENERIC
1.119 vatton 4774: else if (xmlType == XML_TYPE)
1.106 cvs 4775: {
4776: /* Creation of a new element type in the main schema */
4777: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.118 vatton 4778: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.106 cvs 4779: }
1.118 vatton 4780: #endif /* XML_GENERIC */
1.122 vatton 4781: else
4782: {
4783: if (xmlType != XHTML_TYPE)
4784: {
4785: MapXMLElementType (XHTML_TYPE, names[i], &elType,
4786: &mappedName, &c, &level, doc);
4787: if (elType.ElSSchema)
1.123 vatton 4788: elType.ElSSchema = GetXHTMLSSchema (doc);
1.122 vatton 4789: }
4790: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
4791: {
4792: MapXMLElementType (MATH_TYPE, names[i], &elType,
4793: &mappedName, &c, &level, doc);
4794: if (elType.ElSSchema)
1.123 vatton 4795: elType.ElSSchema = GetMathMLSSchema (doc);
1.122 vatton 4796: }
4797: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
4798: {
4799: MapXMLElementType (SVG_TYPE, names[i], &elType,
4800: &mappedName, &c, &level, doc);
4801: if (elType.ElSSchema)
1.123 vatton 4802: elType.ElSSchema = GetSVGSSchema (doc);
1.122 vatton 4803: }
4804: }
1.118 vatton 4805: }
1.119 vatton 4806:
1.118 vatton 4807: if (elType.ElSSchema == NULL)
4808: /* cannot apply these CSS rules */
4809: DoApply = FALSE;
4810: else
4811: {
4812: /* Store the element type */
4813: ctxt->type = elType.ElTypeNum;
4814: ctxt->name[0] = elType.ElTypeNum;
4815: ctxt->names_nb[0] = 0;
1.250 vatton 4816: ctxt->rel[0] = 0;
1.118 vatton 4817: ctxt->schema = elType.ElSSchema;
1.106 cvs 4818: }
1.25 cvs 4819: }
4820: else if (elType.ElTypeNum != 0)
4821: {
4822: /* look at the current context to see if the type is already
4823: stored */
1.121 vatton 4824: j = 1;
1.250 vatton 4825: while (j < k &&
4826: (ctxt->name[j] != elType.ElTypeNum || ctxt->rel[j] != 0))
1.25 cvs 4827: j++;
4828: if (j == k)
4829: {
4830: ctxt->name[j] = elType.ElTypeNum;
4831: if (j != 0)
1.121 vatton 4832: ctxt->names_nb[j] = 1;
1.25 cvs 4833: }
4834: else
4835: /* increment the number of ancestor levels */
4836: ctxt->names_nb[j]++;
4837: }
1.154 vatton 4838: #ifdef XML_GENERIC
4839: else if (xmlType == XML_TYPE)
4840: {
1.158 vatton 4841: TtaGetXmlElementType (names[i], &elType, NULL, doc);
4842: if (elType.ElTypeNum == 0)
4843: {
4844: /* Creation of a new element type in the main schema */
4845: elType.ElSSchema = TtaGetDocumentSSchema (doc);
4846: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
4847: }
1.154 vatton 4848: if (elType.ElTypeNum != 0)
4849: {
4850: /* look at the current context to see if the type is already
4851: stored */
4852: j = 1;
1.250 vatton 4853: while (j < k &&
4854: (ctxt->name[j] != elType.ElTypeNum || ctxt->rel[j] != 0))
1.154 vatton 4855: j++;
4856: if (j == k)
4857: {
4858: ctxt->name[j] = elType.ElTypeNum;
4859: if (j != 0)
1.250 vatton 4860: {
4861: ctxt->names_nb[j] = 1;
4862: ctxt->rel[j] = rel[i];
4863: }
4864: else
4865: ctxt->rel[j] = 0;
1.154 vatton 4866: }
4867: else
4868: /* increment the number of ancestor levels */
4869: ctxt->names_nb[j]++;
4870: }
4871: }
4872: #endif /* XML_GENERIC */
1.25 cvs 4873: else
1.117 vatton 4874: j = k;
1.25 cvs 4875: }
1.117 vatton 4876: else
4877: j = k;
1.1 cvs 4878:
1.25 cvs 4879: /* store attributes information */
4880: if (classes[i])
4881: {
4882: ctxt->attrText[j] = classes[i];
1.119 vatton 4883: if (xmlType == SVG_TYPE)
1.100 vatton 4884: ctxt->attrType[j] = SVG_ATTR_class;
1.119 vatton 4885: else if (xmlType == MATH_TYPE)
1.91 cvs 4886: ctxt->attrType[j] = MathML_ATTR_class;
1.119 vatton 4887: else if (xmlType == XHTML_TYPE)
1.107 cvs 4888: ctxt->attrType[j] = HTML_ATTR_Class;
4889: else
1.119 vatton 4890: #ifdef XML_GENERIC
1.107 cvs 4891: ctxt->attrType[j] = XML_ATTR_class;
4892: #else /* XML_GENERIC */
1.91 cvs 4893: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 4894: #endif /* XML_GENERIC */
1.157 vatton 4895: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4896: /* add a new entry */
1.80 cvs 4897: maxAttr = i + 1;
1.129 vatton 4898: /* update attrLevel */
4899: ctxt->attrLevel[j] = i;
4900: j++;
1.25 cvs 4901: }
1.79 cvs 4902: if (pseudoclasses[i])
1.25 cvs 4903: {
4904: ctxt->attrText[j] = pseudoclasses[i];
1.119 vatton 4905: if (xmlType == SVG_TYPE)
1.100 vatton 4906: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
1.119 vatton 4907: else if (xmlType == MATH_TYPE)
1.91 cvs 4908: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
1.119 vatton 4909: else if (xmlType == XHTML_TYPE)
1.107 cvs 4910: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
4911: else
1.119 vatton 4912: #ifdef XML_GENERIC
1.107 cvs 4913: ctxt->attrType[j] = XML_ATTR_PseudoClass;
4914: #else /* XML_GENERIC */
1.91 cvs 4915: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 4916: #endif /* XML_GENERIC */
1.157 vatton 4917: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4918: /* add a new entry */
1.80 cvs 4919: maxAttr = i + 1;
1.129 vatton 4920: /* update attrLevel */
4921: ctxt->attrLevel[j] = i;
4922: j++;
1.25 cvs 4923: }
1.79 cvs 4924: if (ids[i])
1.25 cvs 4925: {
4926: ctxt->attrText[j] = ids[i];
1.119 vatton 4927: if (xmlType == SVG_TYPE)
1.100 vatton 4928: ctxt->attrType[j] = SVG_ATTR_id;
1.119 vatton 4929: else if (xmlType == MATH_TYPE)
1.91 cvs 4930: ctxt->attrType[j] = MathML_ATTR_id;
1.119 vatton 4931: else if (xmlType == XHTML_TYPE)
1.107 cvs 4932: ctxt->attrType[j] = HTML_ATTR_ID;
4933: else
1.119 vatton 4934: #ifdef XML_GENERIC
1.107 cvs 4935: ctxt->attrType[j] = XML_ATTR_id;
4936: #else /* XML_GENERIC */
1.91 cvs 4937: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 4938: #endif /* XML_GENERIC */
1.157 vatton 4939: ctxt->attrMatch[j] = attrmatch[i];
1.80 cvs 4940: /* add a new entry */
4941: maxAttr = i + 1;
1.129 vatton 4942: /* update attrLevel */
4943: ctxt->attrLevel[j] = i;
4944: j++;
1.25 cvs 4945: }
1.79 cvs 4946: if (attrs[i])
1.25 cvs 4947: {
1.125 vatton 4948: /* it's an attribute */
1.220 quint 4949: if (xmlType == XML_TYPE)
4950: {
4951: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
4952: TtaGetXmlAttributeType (attrs[i], &attrType, doc);
4953: att = attrType.AttrTypeNum;
4954: }
4955: else
1.221 vatton 4956: {
4957: MapXMLAttribute (xmlType, attrs[i], names[i], &level, doc, &att);
4958: if (ctxt->schema == NULL && att != 0)
4959: ctxt->schema = TtaGetDocumentSSchema (doc);
4960: }
1.127 quint 4961: if (att == DummyAttribute && !strcmp (schemaName, "HTML"))
4962: /* it's the "type" attribute for an "input" element. In the tree
4963: it's represented by the element type, not by an attribute */
4964: att = 0;
1.119 vatton 4965: ctxt->attrType[j] = att;
1.133 vatton 4966: ctxt->attrMatch[j] = attrmatch[i];
1.125 vatton 4967: attrType.AttrSSchema = ctxt->schema;
4968: attrType.AttrTypeNum = att;
1.119 vatton 4969: if (i == 0 && att == 0 && ctxt->schema == NULL)
4970: {
1.125 vatton 4971: /* Not found -> search in the list of loaded schemas */
1.119 vatton 4972: attrType.AttrSSchema = NULL;
4973: TtaGetXmlAttributeType (attrs[i], &attrType, doc);
4974: ctxt->attrType[j] = attrType.AttrTypeNum;
4975: if (attrType.AttrSSchema)
1.125 vatton 4976: /* the element type concerns an imported nature */
4977: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
1.119 vatton 4978: #ifdef XML_GENERIC
4979: else if (xmlType == XML_TYPE)
4980: {
4981: /* The attribute is not yet present in the tree */
4982: /* Create a new global attribute */
4983: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
4984: TtaAppendXmlAttribute (attrs[i], &attrType, doc);
4985: }
4986: #endif /* XML_GENERIC */
4987:
4988: if (attrType.AttrSSchema == NULL)
4989: /* cannot apply these CSS rules */
4990: DoApply = FALSE;
1.136 quint 4991: else if (elType.ElSSchema)
4992: ctxt->schema = elType.ElSSchema;
1.119 vatton 4993: else
1.136 quint 4994: ctxt->schema = attrType.AttrSSchema;
1.119 vatton 4995: }
1.125 vatton 4996: /* check the attribute type */
4997: if (!strcmp (schemaName, "HTML"))
4998: xmlType = XHTML_TYPE;
4999: else if (!strcmp (schemaName, "MathML"))
5000: xmlType = MATH_TYPE;
5001: else if (!strcmp (schemaName, "SVG"))
5002: xmlType = SVG_TYPE;
5003: else if (!strcmp (schemaName, "XLink"))
5004: xmlType = XLINK_TYPE;
5005: else if (!strcmp (schemaName, "Annot"))
5006: xmlType = ANNOT_TYPE;
5007: else
5008: xmlType = XML_TYPE;
5009: kind = TtaGetAttributeKind (attrType);
1.220 quint 5010: if (kind == 0 && attrvals[i])
1.125 vatton 5011: {
5012: /* enumerated value */
1.248 gully 5013: MapXMLAttributeValue (xmlType, attrvals[i], &attrType, &kind);
1.125 vatton 5014: /* store the attribute value */
5015: ctxt->attrText[j] = (char *) kind;
5016: }
5017: else
5018: ctxt->attrText[j] = attrvals[i];
1.80 cvs 5019: maxAttr = i + 1;
1.129 vatton 5020: /* update attrLevel */
5021: ctxt->attrLevel[j] = i;
5022: j++;
1.25 cvs 5023: }
5024: i++;
1.117 vatton 5025: /* add a new entry */
5026: k++;
1.129 vatton 5027: if (k < j)
5028: k = j;
1.119 vatton 5029: if (i == 1 && ctxt->schema == NULL)
5030: /* use the document schema */
5031: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 5032: }
1.117 vatton 5033: /* set the selector specificity */
5034: ctxt->cssSpecificity = specificity;
1.25 cvs 5035: /* Get the schema name of the main element */
1.119 vatton 5036: schemaName = TtaGetSSchemaName (ctxt->schema);
5037: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 5038: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.217 vatton 5039: skippedNL = NewLineSkipped;
1.119 vatton 5040: if (tsch && cssRule)
5041: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.116 vatton 5042: /* future CSS rules should apply */
5043: DoApply = TRUE;
1.217 vatton 5044: if (selector)
5045: NewLineSkipped = skippedNL;
1.1 cvs 5046: return (selector);
5047: }
5048:
5049: /*----------------------------------------------------------------------
1.206 vatton 5050: ParseStyleDeclaration: parse a style declaration stored in the style
5051: element of a document
5052: We expect the style string to be of the form:
5053: .pinky, .awful { color: pink; font-family: helvetica }
1.231 vatton 5054: The parameter css points to the current CSS context.
5055: The parameter link points to the link element.
5056: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 5057: ----------------------------------------------------------------------*/
1.206 vatton 5058: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
1.231 vatton 5059: CSSInfoPtr css, Element link, char *url,
5060: ThotBool destroy)
1.1 cvs 5061: {
1.79 cvs 5062: GenericContext ctxt;
5063: char *decl_end;
5064: char *sel_end;
5065: char *selector;
1.1 cvs 5066:
5067: /* separate the selectors string */
1.82 cvs 5068: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 5069: decl_end = cssRule;
1.82 cvs 5070: while (*decl_end != EOS && *decl_end != '{')
1.1 cvs 5071: decl_end++;
1.82 cvs 5072: if (*decl_end == EOS)
1.86 cvs 5073: {
1.168 vatton 5074: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 5075: return;
5076: }
1.1 cvs 5077: /* verify and clean the selector string */
5078: sel_end = decl_end - 1;
1.82 cvs 5079: while (*sel_end == SPACE || *sel_end == BSPACE ||
5080: *sel_end == EOL || *sel_end == CR)
1.1 cvs 5081: sel_end--;
5082: sel_end++;
1.82 cvs 5083: *sel_end = EOS;
1.1 cvs 5084: selector = cssRule;
5085:
5086: /* now, deal with the content ... */
5087: decl_end++;
5088: cssRule = decl_end;
1.137 vatton 5089: decl_end = &cssRule[strlen (cssRule) - 1];
5090: if (*decl_end != '{')
5091: *decl_end = EOS;
1.1 cvs 5092: /*
5093: * parse the style attribute string and install the corresponding
5094: * presentation attributes on the new element
5095: */
5096: ctxt = TtaGetGenericStyleContext (doc);
5097: if (ctxt == NULL)
5098: return;
5099: ctxt->destroy = destroy;
1.207 vatton 5100: /* first use of the context */
5101: ctxt->uses = 1;
1.197 vatton 5102: while (selector && *selector != EOS)
1.231 vatton 5103: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css,
5104: link, url);
1.207 vatton 5105: /* check if the context can be freed */
5106: ctxt->uses -= 1;
5107: if (ctxt->uses == 0)
5108: /* no image loading */
5109: TtaFreeMemory (ctxt);
1.1 cvs 5110: }
5111:
5112: /************************************************************************
5113: * *
5114: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
5115: * *
5116: ************************************************************************/
5117:
5118: /*----------------------------------------------------------------------
1.59 cvs 5119: IsImplicitClassName: return wether the Class name is an
1.1 cvs 5120: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
5121: or an HTML context name.
5122: ----------------------------------------------------------------------*/
1.248 gully 5123: int IsImplicitClassName (char *class_, Document doc)
1.1 cvs 5124: {
1.79 cvs 5125: char name[200];
5126: char *cur = name;
5127: char *first;
5128: char save;
5129: SSchema schema;
1.1 cvs 5130:
5131: /* make a local copy */
1.248 gully 5132: strncpy (name, class_, 199);
1.1 cvs 5133: name[199] = 0;
5134:
5135: /* loop looking if each word is a GI */
5136: while (*cur != 0)
5137: {
5138: first = cur;
5139: cur = SkipWord (cur);
5140: save = *cur;
5141: *cur = 0;
5142: schema = NULL;
5143: if (MapGI (first, &schema, doc) == -1)
5144: {
5145: return (0);
5146: }
5147: *cur = save;
1.82 cvs 5148: cur = SkipBlanksAndComments (cur);
1.1 cvs 5149: }
5150: return (1);
5151: }
5152:
5153: /************************************************************************
5154: * *
1.114 quint 5155: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 5156: * *
5157: ************************************************************************/
5158:
5159: /*----------------------------------------------------------------------
1.59 cvs 5160: HTMLSetBackgroundColor:
1.1 cvs 5161: ----------------------------------------------------------------------*/
1.79 cvs 5162: void HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1 cvs 5163: {
1.79 cvs 5164: char css_command[100];
1.1 cvs 5165:
1.82 cvs 5166: sprintf (css_command, "background-color: %s", color);
1.114 quint 5167: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 5168: }
5169:
5170: /*----------------------------------------------------------------------
1.59 cvs 5171: HTMLSetForegroundColor:
1.1 cvs 5172: ----------------------------------------------------------------------*/
1.97 vatton 5173: void HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1 cvs 5174: {
1.79 cvs 5175: char css_command[100];
1.1 cvs 5176:
1.82 cvs 5177: sprintf (css_command, "color: %s", color);
1.114 quint 5178: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 5179: }
5180:
5181: /*----------------------------------------------------------------------
1.59 cvs 5182: HTMLResetBackgroundColor:
1.1 cvs 5183: ----------------------------------------------------------------------*/
1.97 vatton 5184: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 5185: {
1.79 cvs 5186: char css_command[100];
1.1 cvs 5187:
1.82 cvs 5188: sprintf (css_command, "background: red");
1.114 quint 5189: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5190: }
5191:
5192: /*----------------------------------------------------------------------
1.59 cvs 5193: HTMLResetBackgroundImage:
1.1 cvs 5194: ----------------------------------------------------------------------*/
1.97 vatton 5195: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 5196: {
1.79 cvs 5197: char css_command[1000];
1.1 cvs 5198:
1.82 cvs 5199: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.114 quint 5200: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5201: }
5202:
5203: /*----------------------------------------------------------------------
1.59 cvs 5204: HTMLResetForegroundColor:
1.1 cvs 5205: ----------------------------------------------------------------------*/
1.97 vatton 5206: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 5207: {
1.79 cvs 5208: char css_command[100];
1.1 cvs 5209:
1.36 cvs 5210: /* it's not necessary to well know the current color but it must be valid */
1.82 cvs 5211: sprintf (css_command, "color: red");
1.114 quint 5212: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5213: }
5214:
5215: /*----------------------------------------------------------------------
1.59 cvs 5216: HTMLSetAlinkColor:
1.1 cvs 5217: ----------------------------------------------------------------------*/
1.208 vatton 5218: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 5219: {
1.79 cvs 5220: char css_command[100];
1.1 cvs 5221:
1.215 quint 5222: sprintf (css_command, ":link { color: %s }", color);
1.208 vatton 5223: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5224: }
5225:
5226: /*----------------------------------------------------------------------
1.59 cvs 5227: HTMLSetAactiveColor:
1.1 cvs 5228: ----------------------------------------------------------------------*/
1.208 vatton 5229: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 5230: {
1.79 cvs 5231: char css_command[100];
1.1 cvs 5232:
1.215 quint 5233: sprintf (css_command, ":active { color: %s }", color);
1.208 vatton 5234: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5235: }
5236:
5237: /*----------------------------------------------------------------------
1.59 cvs 5238: HTMLSetAvisitedColor:
1.1 cvs 5239: ----------------------------------------------------------------------*/
1.208 vatton 5240: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 5241: {
1.79 cvs 5242: char css_command[100];
1.1 cvs 5243:
1.215 quint 5244: sprintf (css_command, ":visited { color: %s }", color);
1.208 vatton 5245: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5246: }
5247:
5248: /*----------------------------------------------------------------------
1.59 cvs 5249: HTMLResetAlinkColor:
1.1 cvs 5250: ----------------------------------------------------------------------*/
1.208 vatton 5251: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 5252: {
1.79 cvs 5253: char css_command[100];
1.1 cvs 5254:
1.215 quint 5255: sprintf (css_command, ":link { color: red }");
1.208 vatton 5256: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5257: }
5258:
5259: /*----------------------------------------------------------------------
1.59 cvs 5260: HTMLResetAactiveColor:
1.1 cvs 5261: ----------------------------------------------------------------------*/
1.208 vatton 5262: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 5263: {
1.79 cvs 5264: char css_command[100];
1.1 cvs 5265:
1.215 quint 5266: sprintf (css_command, ":active { color: red }");
1.208 vatton 5267: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5268: }
5269:
5270: /*----------------------------------------------------------------------
1.59 cvs 5271: HTMLResetAvisitedColor:
1.1 cvs 5272: ----------------------------------------------------------------------*/
1.208 vatton 5273: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 5274: {
1.79 cvs 5275: char css_command[100];
1.1 cvs 5276:
1.215 quint 5277: sprintf (css_command, ":visited { color: red }");
1.208 vatton 5278: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5279: }
5280:
5281: /*----------------------------------------------------------------------
1.206 vatton 5282: ApplyCSSRules: parse a CSS Style description stored in the header of
5283: a HTML document.
1.1 cvs 5284: ----------------------------------------------------------------------*/
1.79 cvs 5285: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 5286: {
1.206 vatton 5287: CSSInfoPtr css;
5288: PInfoPtr pInfo;
1.207 vatton 5289: ThotBool loadcss;
5290:
5291: /* check if we have to load CSS */
5292: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
5293: if (!loadcss)
5294: return;
1.1 cvs 5295:
1.206 vatton 5296: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 5297: if (css == NULL)
1.209 vatton 5298: {
5299: /* create the document css context */
5300: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
5301: pInfo = css->infos[doc];
5302: }
1.206 vatton 5303: else if (pInfo == NULL)
5304: /* create the entry into the css context */
5305: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 5306: if (pInfo->PiEnabled)
1.231 vatton 5307: ParseStyleDeclaration (el, cssRule, doc, css, el, NULL, destroy);
1.1 cvs 5308: }
5309:
5310: /*----------------------------------------------------------------------
1.145 quint 5311: ReadCSSRules: is the front-end function called by the document parser
5312: when detecting a <style type="text/css"> indicating it's the
1.1 cvs 5313: beginning of a CSS fragment or when reading a file .css.
5314:
5315: The CSS parser has to handle <!-- ... --> constructs used to
5316: prevent prehistoric browser from displaying the CSS as a text
5317: content. It will stop on any sequence "<x" where x is different
5318: from ! and will return x as to the caller. Theorically x should
1.145 quint 5319: be equal to / for the </style> end of style.
1.1 cvs 5320: The parameter doc gives the document tree that contains CSS information.
5321: The parameter docRef gives the document to which CSS are to be applied.
5322: This function uses the current css context or creates it. It's able
1.23 cvs 5323: to work on the given buffer or call GetNextChar to read the parsed
1.1 cvs 5324: file.
1.231 vatton 5325: The parameter url gives the URL of the parsed style sheet.
5326: The parameter numberOfLinesRead gives the number of lines already
1.86 cvs 5327: read in the file.
1.231 vatton 5328: The parameter withUndo indicates whether the changes made in the document
1.145 quint 5329: structure and content have to be registered in the Undo queue or not.
1.1 cvs 5330: ----------------------------------------------------------------------*/
1.133 vatton 5331: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.144 quint 5332: int numberOfLinesRead, ThotBool withUndo,
1.206 vatton 5333: Element link)
1.1 cvs 5334: {
1.6 cvs 5335: DisplayMode dispMode;
1.206 vatton 5336: CSSInfoPtr refcss = NULL;
5337: PInfoPtr pInfo;
1.82 cvs 5338: char c;
1.138 vatton 5339: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 5340: int index;
1.1 cvs 5341: int CSSindex;
5342: int CSScomment;
5343: int import;
5344: int openRule;
1.93 vatton 5345: int newlines;
1.14 cvs 5346: ThotBool HTMLcomment;
1.102 vatton 5347: ThotBool toParse, eof, quoted;
1.234 vatton 5348: ThotBool ignore, media, page;
5349: ThotBool noRule, ignoreImport, fontface;
1.1 cvs 5350:
5351: CSScomment = MAX_CSS_LENGTH;
5352: HTMLcomment = FALSE;
5353: CSSindex = 0;
5354: toParse = FALSE;
5355: noRule = FALSE;
1.234 vatton 5356: media = FALSE;
1.88 cvs 5357: ignoreImport = FALSE;
1.234 vatton 5358: ignore = FALSE;
5359: page = FALSE;
5360: quoted = FALSE;
5361: fontface = FALSE;
1.1 cvs 5362: eof = FALSE;
5363: openRule = 0;
1.234 vatton 5364: import = MAX_CSS_LENGTH;
1.82 cvs 5365: c = SPACE;
1.1 cvs 5366: index = 0;
1.134 vatton 5367: base = NULL;
1.93 vatton 5368: /* number of new lines parsed */
5369: newlines = 0;
1.6 cvs 5370: /* avoid too many redisplay */
5371: dispMode = TtaGetDisplayMode (docRef);
5372: if (dispMode == DisplayImmediately)
5373: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 5374:
5375: /* look for the CSS context */
5376: if (css == NULL)
1.206 vatton 5377: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 5378: else
5379: pInfo = css->infos[docRef];
1.18 cvs 5380: if (css == NULL)
1.206 vatton 5381: {
5382: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
5383: pInfo = css->infos[docRef];
5384: }
5385: else if (pInfo == NULL)
5386: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 5387: /* look for the CSS descriptor that points to the extension schema */
5388: refcss = css;
1.224 vatton 5389: if (pInfo && pInfo->PiCategory == CSS_IMPORT)
1.173 cvs 5390: {
1.206 vatton 5391: while (refcss &&
5392: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
1.174 vatton 5393: refcss = refcss->NextCSS;
1.206 vatton 5394: if (refcss)
5395: pInfo = refcss->infos[docRef];
1.173 cvs 5396: }
5397:
1.144 quint 5398: /* register parsed CSS file and the document to which CSS are to be applied*/
1.86 cvs 5399: ParsedDoc = docRef;
1.133 vatton 5400: if (url)
5401: DocURL = url;
1.86 cvs 5402: else
5403: /* the CSS source in within the document itself */
5404: DocURL = DocumentURLs[docRef];
5405: LineNumber = numberOfLinesRead + 1;
1.93 vatton 5406: NewLineSkipped = 0;
1.217 vatton 5407: newlines = 0;
1.82 cvs 5408: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
5409: {
5410: c = buffer[index++];
5411: eof = (c == EOS);
5412: CSSbuffer[CSSindex] = c;
1.234 vatton 5413: if (CSScomment == MAX_CSS_LENGTH ||
1.246 vatton 5414: c == '*' || c == '/' || c == '<' || c == EOL)
1.82 cvs 5415: {
5416: /* we're not within a comment or we're parsing * or / */
5417: switch (c)
5418: {
5419: case '@': /* perhaps an import primitive */
1.234 vatton 5420: if (!fontface && !page && !quoted)
1.135 vatton 5421: import = CSSindex;
1.82 cvs 5422: break;
5423: case ';':
1.135 vatton 5424: if (!quoted && !media && import != MAX_CSS_LENGTH)
1.82 cvs 5425: {
5426: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
5427: /* it's not an import */
5428: import = MAX_CSS_LENGTH;
5429: /* save the text */
5430: noRule = TRUE;
5431: }
5432: break;
5433: case '*':
1.135 vatton 5434: if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5435: CSSbuffer[CSSindex - 1] == '/')
5436: /* start a comment */
5437: CSScomment = CSSindex - 1;
5438: break;
5439: case '/':
1.135 vatton 5440: if (!quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.82 cvs 5441: CSSbuffer[CSSindex - 1] == '*')
5442: {
1.234 vatton 5443: /* close a comment and ignore its contents */
1.82 cvs 5444: CSSindex = CSScomment - 1; /* will be incremented later */
5445: CSScomment = MAX_CSS_LENGTH;
1.93 vatton 5446: /* clean up the buffer */
1.103 vatton 5447: if (newlines && CSSindex > 0)
5448: while (CSSindex > 0 &&
5449: (CSSbuffer[CSSindex] == SPACE ||
5450: CSSbuffer[CSSindex] == BSPACE ||
5451: CSSbuffer[CSSindex] == EOL ||
5452: CSSbuffer[CSSindex] == TAB ||
5453: CSSbuffer[CSSindex] == __CR__))
1.93 vatton 5454: {
5455: if ( CSSbuffer[CSSindex] == EOL)
5456: {
5457: LineNumber ++;
1.217 vatton 5458: newlines --;
1.93 vatton 5459: }
5460: CSSindex--;
5461: }
1.82 cvs 5462: }
1.234 vatton 5463: else if (!fontface && !page && !quoted &&
5464: CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5465: CSSbuffer[CSSindex - 1] == '<')
5466: {
5467: /* this is the closing tag ! */
5468: CSSindex -= 2; /* remove </ from the CSS string */
5469: noRule = TRUE;
5470: }
5471: break;
5472: case '<':
1.234 vatton 5473: if (!fontface && !page && !quoted &&
5474: CSScomment == MAX_CSS_LENGTH)
1.82 cvs 5475: {
5476: /* only if we're not parsing a comment */
5477: c = buffer[index++];
5478: eof = (c == EOS);
5479: if (c == '!')
5480: {
5481: /* CSS within an HTML comment */
5482: HTMLcomment = TRUE;
5483: CSSindex++;
5484: CSSbuffer[CSSindex] = c;
5485: }
5486: else if (c == EOS)
5487: CSSindex++;
5488: }
5489: break;
5490: case '-':
1.234 vatton 5491: if (!fontface && !page && !quoted &&
5492: CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
1.82 cvs 5493: HTMLcomment)
5494: /* CSS within an HTML comment */
5495: noRule = TRUE;
5496: break;
5497: case '>':
1.234 vatton 5498: if (!fontface && !page && !quoted && HTMLcomment)
1.82 cvs 5499: noRule = TRUE;
5500: break;
5501: case ' ':
1.135 vatton 5502: if (!quoted && import != MAX_CSS_LENGTH && openRule == 0)
1.234 vatton 5503: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
1.82 cvs 5504: break;
5505: case '{':
1.135 vatton 5506: if (!quoted)
1.82 cvs 5507: {
1.135 vatton 5508: openRule++;
1.234 vatton 5509: if (import != MAX_CSS_LENGTH)
1.135 vatton 5510: {
1.234 vatton 5511: if (openRule == 1 && media)
5512: {
5513: /* is it the screen concerned? */
5514: CSSbuffer[CSSindex+1] = EOS;
5515: if (TtaIsPrinting ())
5516: base = strstr (&CSSbuffer[import], "print");
5517: else
5518: base = strstr (&CSSbuffer[import], "screen");
5519: if (base == NULL)
5520: base = strstr (&CSSbuffer[import], "all");
5521: if (base == NULL)
5522: ignore = TRUE;
1.235 vatton 5523: noRule = TRUE;
1.234 vatton 5524: }
5525: else if (!strncasecmp (&CSSbuffer[import+1], "page", 4))
1.235 vatton 5526: {
5527: page = TRUE;
5528: noRule = TRUE;
5529: }
1.234 vatton 5530: else if (!strncasecmp (&CSSbuffer[import+1], "font-face", 9))
1.235 vatton 5531: {
5532: fontface = TRUE;
5533: noRule = TRUE;
5534: }
1.135 vatton 5535: }
5536: }
5537: break;
5538: case '}':
5539: if (!quoted)
5540: {
5541: openRule--;
1.234 vatton 5542: if (page)
5543: {
5544: noRule = TRUE;
5545: page = FALSE; /* close the page section */
5546: }
5547: else if (fontface)
5548: {
5549: noRule = TRUE;
5550: fontface = FALSE; /* close the fontface section */
5551: }
5552: else if (openRule == 0 && import != MAX_CSS_LENGTH)
1.135 vatton 5553: {
5554: import = MAX_CSS_LENGTH;
5555: noRule = TRUE;
1.234 vatton 5556: ignore = FALSE;
1.135 vatton 5557: media = FALSE;
5558: }
1.82 cvs 5559: else
1.135 vatton 5560: toParse = TRUE;
1.82 cvs 5561: }
5562: break;
1.135 vatton 5563: case '"':
5564: if (quoted)
1.82 cvs 5565: {
1.135 vatton 5566: if (CSSbuffer[CSSindex - 1] != '\\')
5567: quoted = FALSE;
1.82 cvs 5568: }
5569: else
1.135 vatton 5570: quoted = TRUE;
1.82 cvs 5571: break;
5572: default:
1.86 cvs 5573: if (c == EOL)
1.93 vatton 5574: newlines++;
1.82 cvs 5575: break;
5576: }
5577: }
1.93 vatton 5578: else if (c == EOL)
1.217 vatton 5579: {
5580: LineNumber++;
5581: c = CR;
5582: }
1.234 vatton 5583:
1.82 cvs 5584: if (c != CR)
5585: CSSindex++;
5586:
5587: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
5588: /* we're still parsing a comment: remove the text comment */
5589: CSSindex = CSScomment;
5590:
5591: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
5592: {
5593: CSSbuffer[CSSindex] = EOS;
5594: /* parse a not empty string */
5595: if (CSSindex > 0)
5596: {
1.50 cvs 5597: /* apply CSS rule if it's not just a saving of text */
1.234 vatton 5598: if (!noRule && !ignore)
1.88 cvs 5599: {
5600: /* future import rules must be ignored */
5601: ignoreImport = TRUE;
1.217 vatton 5602: NewLineSkipped = 0;
1.210 vatton 5603: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
1.231 vatton 5604: pInfo->PiLink, url, FALSE);
1.93 vatton 5605: LineNumber += newlines;
5606: newlines = 0;
1.88 cvs 5607: }
1.82 cvs 5608: else if (import != MAX_CSS_LENGTH &&
5609: !strncasecmp (&CSSbuffer[import+1], "import", 6))
5610: {
5611: /* import section */
5612: cssRule = &CSSbuffer[import+7];
5613: cssRule = TtaSkipBlanks (cssRule);
1.93 vatton 5614: /* save the current line number */
5615: newlines += LineNumber;
1.82 cvs 5616: if (!strncasecmp (cssRule, "url", 3))
5617: {
1.50 cvs 5618: cssRule = &cssRule[3];
1.82 cvs 5619: cssRule = TtaSkipBlanks (cssRule);
5620: if (*cssRule == '(')
5621: {
5622: cssRule++;
5623: cssRule = TtaSkipBlanks (cssRule);
1.102 vatton 5624: quoted = (*cssRule == '"' || *cssRule == '\'');
5625: if (quoted)
5626: cssRule++;
1.82 cvs 5627: base = cssRule;
5628: while (*cssRule != EOS && *cssRule != ')')
5629: cssRule++;
1.102 vatton 5630: if (quoted)
1.167 vatton 5631: {
5632: /* isolate the file name */
5633: cssRule[-1] = EOS;
5634: quoted = FALSE;
5635: }
1.216 vatton 5636: else
5637: {
5638: /* remove extra spaces */
5639: if (cssRule[-1] == SPACE)
5640: {
5641: *cssRule = SPACE;
5642: cssRule--;
5643: while (cssRule[-1] == SPACE)
5644: cssRule--;
5645: }
5646: }
1.160 vatton 5647: *cssRule = EOS;
1.82 cvs 5648: }
5649: }
1.87 cvs 5650: else if (*cssRule == '"')
5651: {
1.88 cvs 5652: /*
5653: Do we have to accept single quotes?
5654: Double quotes are acceted here.
5655: Escaped quotes are not handled. See function SkipQuotedString
5656: */
1.87 cvs 5657: cssRule++;
5658: cssRule = TtaSkipBlanks (cssRule);
5659: base = cssRule;
1.179 vatton 5660: while (*cssRule != EOS &&
5661: (*cssRule != '"' ||
1.180 vatton 5662: (*cssRule == '"' && cssRule[-1] == '\\')))
1.87 cvs 5663: cssRule++;
1.160 vatton 5664: /* isolate the file name */
5665: *cssRule = EOS;
1.133 vatton 5666: }
5667: /* check if a media is defined */
5668: cssRule++;
5669: cssRule = TtaSkipBlanks (cssRule);
5670: if (*cssRule != ';')
5671: {
5672: if (TtaIsPrinting ())
5673: ignoreImport = (strncasecmp (cssRule, "print", 5) &&
5674: strncasecmp (cssRule, "all", 3));
5675: else
5676: ignoreImport = (strncasecmp (cssRule, "screen", 6) &&
5677: strncasecmp (cssRule, "all", 3));
5678: }
5679: if (!ignoreImport)
5680: {
5681: /* save the displayed URL when an error is reported */
5682: saveDocURL = DocURL;
1.138 vatton 5683: ptr = TtaStrdup (base);
5684: /* get the CSS URI in UTF-8 */
5685: ptr = ReallocUTF8String (ptr, docRef);
1.206 vatton 5686: LoadStyleSheet (base, docRef, (Element) css, css,
5687: pInfo->PiMedia,
5688: pInfo->PiCategory == CSS_USER_STYLE);
1.133 vatton 5689: /* restore the displayed URL when an error is reported */
5690: DocURL = saveDocURL;
1.138 vatton 5691: TtaFreeMemory (ptr);
1.82 cvs 5692: }
1.93 vatton 5693: /* restore the number of lines */
5694: LineNumber = newlines;
5695: newlines = 0;
1.217 vatton 5696: NewLineSkipped = 0;
1.82 cvs 5697: import = MAX_CSS_LENGTH;
5698: }
1.234 vatton 5699: else
5700: {
5701: LineNumber += newlines;
5702: newlines = 0;
5703: }
1.82 cvs 5704: }
5705: toParse = FALSE;
5706: noRule = FALSE;
5707: CSSindex = 0;
1.50 cvs 5708: }
1.82 cvs 5709: }
1.6 cvs 5710: /* restore the display mode */
5711: if (dispMode == DisplayImmediately)
1.82 cvs 5712: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 5713:
5714: /* Prepare the context for style attributes */
5715: DocURL = DocumentURLs[docRef];
5716: LineNumber = -1;
1.1 cvs 5717: return (c);
5718: }
1.89 cvs 5719:
Webmaster