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