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