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