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