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