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