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