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