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