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