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