Annotation of Amaya/amaya/styleparser.c, revision 1.162
1.1 cvs 1: /*
2: *
1.113 quint 3: * (c) COPYRIGHT MIT and INRIA, 1996-2002
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: {
1.149 vatton 2568: GenericContext ctxt = (GenericContext) context;
1.1 cvs 2569: PresentationValue best;
1.148 vatton 2570: unsigned int savedtype = 0;
2571: ThotBool moved;
2572:
1.149 vatton 2573: /* Horrible hack requested by CSS: move the rule to the root element */
1.155 cheyroul 2574: moved = (isHTML &&
2575: (element != NULL || ctxt->attrType[0] == 0) &&
1.152 vatton 2576: (ctxt->type == HTML_EL_HTML || ctxt->type == HTML_EL_BODY));
1.148 vatton 2577: if (moved)
2578: {
2579: if (element)
2580: element = TtaGetMainRoot (context->doc);
2581: else
2582: {
2583: savedtype = context->type;
2584: context->type = HTML_EL_Document;
2585: }
2586: }
1.1 cvs 2587:
2588: best.typed_data.unit = STYLE_UNIT_INVALID;
2589: best.typed_data.real = FALSE;
1.82 cvs 2590: if (!strncasecmp (cssRule, "transparent", strlen ("transparent")))
1.1 cvs 2591: {
2592: best.typed_data.value = STYLE_PATTERN_NONE;
2593: best.typed_data.unit = STYLE_UNIT_REL;
1.116 vatton 2594: if (DoApply)
1.117 vatton 2595: {
2596: if (tsch)
2597: cssRule = CheckImportantRule (cssRule, context);
2598: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2599: }
1.65 cvs 2600: cssRule = SkipWord (cssRule);
1.1 cvs 2601: }
2602: else
2603: {
2604: cssRule = ParseCSSColor (cssRule, &best);
1.116 vatton 2605: if (best.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.1 cvs 2606: {
1.117 vatton 2607: if (tsch)
2608: cssRule = CheckImportantRule (cssRule, context);
1.1 cvs 2609: /* install the new presentation. */
2610: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59 cvs 2611: /* thot specificity: need to set fill pattern for background color */
1.1 cvs 2612: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2613: best.typed_data.unit = STYLE_UNIT_REL;
2614: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2615: best.typed_data.value = 1;
2616: best.typed_data.unit = STYLE_UNIT_REL;
2617: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
2618: }
2619: }
2620:
2621: /* restore the refered element */
1.148 vatton 2622: if (moved && !element)
2623: context->type = savedtype;
1.1 cvs 2624: return (cssRule);
2625: }
2626:
1.63 cvs 2627:
2628: /*----------------------------------------------------------------------
1.65 cvs 2629: ParseSVGStroke: parse a SVG stroke property
2630: ----------------------------------------------------------------------*/
1.79 cvs 2631: static char *ParseSVGStroke (Element element, PSchema tsch,
2632: PresentationContext context, char *cssRule,
2633: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 2634: {
2635: PresentationValue best;
2636:
2637: best.typed_data.unit = STYLE_UNIT_INVALID;
2638: best.typed_data.real = FALSE;
1.82 cvs 2639: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 2640: {
2641: best.typed_data.value = -2; /* -2 means transparent */
2642: best.typed_data.unit = STYLE_UNIT_REL;
1.116 vatton 2643: if (DoApply)
1.117 vatton 2644: {
2645: if (tsch)
2646: cssRule = CheckImportantRule (cssRule, context);
2647: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2648: }
1.65 cvs 2649: cssRule = SkipWord (cssRule);
2650: }
2651: else
2652: {
2653: cssRule = ParseCSSColor (cssRule, &best);
1.116 vatton 2654: if (best.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2655: {
2656: if (tsch)
2657: cssRule = CheckImportantRule (cssRule, context);
2658: /* install the new presentation */
2659: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2660: }
1.65 cvs 2661: }
2662: return (cssRule);
2663: }
2664:
2665: /*----------------------------------------------------------------------
1.63 cvs 2666: ParseSVGFill: parse a SVG fill property
2667: ----------------------------------------------------------------------*/
1.79 cvs 2668: static char *ParseSVGFill (Element element, PSchema tsch,
2669: PresentationContext context, char *cssRule,
2670: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 2671: {
2672: PresentationValue best;
2673:
2674: best.typed_data.unit = STYLE_UNIT_INVALID;
2675: best.typed_data.real = FALSE;
1.82 cvs 2676: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 2677: {
2678: best.typed_data.value = STYLE_PATTERN_NONE;
2679: best.typed_data.unit = STYLE_UNIT_REL;
1.116 vatton 2680: if (DoApply)
1.117 vatton 2681: {
2682: if (tsch)
2683: cssRule = CheckImportantRule (cssRule, context);
2684: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2685: }
1.65 cvs 2686: cssRule = SkipWord (cssRule);
1.63 cvs 2687: }
2688: else
2689: {
2690: cssRule = ParseCSSColor (cssRule, &best);
1.162 ! quint 2691: if (best.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.63 cvs 2692: {
1.117 vatton 2693: if (tsch)
2694: cssRule = CheckImportantRule (cssRule, context);
1.63 cvs 2695: /* install the new presentation. */
2696: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
2697: /* thot specificity: need to set fill pattern for background color */
2698: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2699: best.typed_data.unit = STYLE_UNIT_REL;
2700: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2701: }
2702: }
2703: return (cssRule);
2704: }
1.161 quint 2705:
1.155 cheyroul 2706: /*----------------------------------------------------------------------
2707: ParseSVGOpacity: parse a SVG fill property
2708: ----------------------------------------------------------------------*/
2709: static char *ParseSVGOpacity (Element element, PSchema tsch,
2710: PresentationContext context, char *cssRule,
2711: CSSInfoPtr css, ThotBool isHTML)
2712: {
2713: PresentationValue best;
1.63 cvs 2714:
1.155 cheyroul 2715: best.typed_data.unit = STYLE_UNIT_INVALID;
2716: best.typed_data.real = FALSE;
2717: cssRule = ParseClampedUnit (cssRule, &best);
2718: if (DoApply)
2719: {
2720: if (tsch)
2721: cssRule = CheckImportantRule (cssRule, context);
2722: /* install the new presentation. */
2723: TtaSetStylePresentation (PROpacity, element,
2724: tsch, context, best);
2725: }
2726: return (cssRule);
2727: }
1.161 quint 2728:
1.1 cvs 2729: /*----------------------------------------------------------------------
1.59 cvs 2730: ParseCSSBackgroundImageCallback: Callback called asynchronously by
2731: FetchImage when a background image has been fetched.
1.1 cvs 2732: ----------------------------------------------------------------------*/
1.82 cvs 2733: void ParseCSSBackgroundImageCallback (Document doc, Element element,
2734: char *file, void *extra)
1.1 cvs 2735: {
1.82 cvs 2736: DisplayMode dispMode;
2737: BackgroundImageCallbackPtr callblock;
2738: Element el;
2739: PSchema tsch;
2740: PresentationContext context;
2741: PresentationValue image;
2742: PresentationValue value;
1.1 cvs 2743:
1.82 cvs 2744: callblock = (BackgroundImageCallbackPtr) extra;
1.34 cvs 2745: if (callblock == NULL)
2746: return;
1.1 cvs 2747:
1.34 cvs 2748: /* avoid too many redisplay */
2749: dispMode = TtaGetDisplayMode (doc);
2750: if (dispMode == DisplayImmediately)
2751: TtaSetDisplayMode (doc, DeferredDisplay);
2752:
2753: el = callblock->el;
2754: tsch = callblock->tsch;
2755: context = &callblock->context.specific;
2756:
2757: /* Ok the image was fetched, finish the background-image handling */
2758: image.pointer = file;
2759: TtaSetStylePresentation (PRBackgroundPicture, el, tsch, context, image);
1.1 cvs 2760:
1.70 cvs 2761: /* enforce the showbox */
1.34 cvs 2762: value.typed_data.value = 1;
2763: value.typed_data.unit = STYLE_UNIT_REL;
2764: value.typed_data.real = FALSE;
2765: TtaSetStylePresentation (PRShowBox, el, tsch, context, value);
2766:
2767: TtaFreeMemory (callblock);
2768: /* restore the display mode */
2769: if (dispMode == DisplayImmediately)
2770: TtaSetDisplayMode (doc, dispMode);
1.1 cvs 2771: }
2772:
2773: /*----------------------------------------------------------------------
2774: GetCSSBackgroundURL searches a CSS BackgroundImage url within
2775: the styleString.
2776: Returns NULL or a new allocated url string.
2777: ----------------------------------------------------------------------*/
1.79 cvs 2778: char *GetCSSBackgroundURL (char *styleString)
1.1 cvs 2779: {
1.79 cvs 2780: char *b, *e, *ptr;
2781: int len;
1.1 cvs 2782:
2783: ptr = NULL;
1.82 cvs 2784: b = strstr (styleString, "url");
1.1 cvs 2785: if (b != NULL)
2786: {
2787: b += 3;
1.82 cvs 2788: b = SkipBlanksAndComments (b);
2789: if (*b == '(')
1.1 cvs 2790: {
2791: b++;
1.82 cvs 2792: b = SkipBlanksAndComments (b);
1.161 quint 2793: /*** Escaped quotes are not handled. See function SkipQuotedString */
1.82 cvs 2794: if (*b == '"')
1.1 cvs 2795: {
2796: b++;
2797: /* search the url end */
2798: e = b;
1.82 cvs 2799: while (*e != EOS && *e != '"')
1.1 cvs 2800: e++;
2801: }
1.161 quint 2802: else if (*b == '\'')
2803: {
2804: b++;
2805: /* search the url end */
2806: e = b;
2807: while (*e != EOS && *e != '\'')
2808: e++;
2809: }
1.1 cvs 2810: else
2811: {
2812: /* search the url end */
2813: e = b;
1.82 cvs 2814: while (*e != EOS && *e != ')')
1.1 cvs 2815: e++;
2816: }
1.82 cvs 2817: if (*e != EOS)
1.1 cvs 2818: {
2819: len = (int)(e - b);
1.82 cvs 2820: ptr = (char*) TtaGetMemory (len+1);
2821: strncpy (ptr, b, len);
2822: ptr[len] = EOS;
1.1 cvs 2823: }
2824: }
2825: }
2826: return (ptr);
2827: }
2828:
2829:
2830: /*----------------------------------------------------------------------
1.59 cvs 2831: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 2832: ----------------------------------------------------------------------*/
1.79 cvs 2833: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
2834: PresentationContext context,
2835: char *cssRule, CSSInfoPtr css,
2836: ThotBool isHTML)
1.1 cvs 2837: {
1.149 vatton 2838: GenericContext ctxt = (GenericContext) context;
1.49 cvs 2839: Element el;
1.1 cvs 2840: BackgroundImageCallbackPtr callblock;
1.49 cvs 2841: PresentationValue image, value;
1.79 cvs 2842: char *url;
1.82 cvs 2843: char *bg_image;
1.79 cvs 2844: char saved;
2845: char *base;
2846: char tempname[MAX_LENGTH];
2847: char imgname[MAX_LENGTH];
1.148 vatton 2848: unsigned int savedtype = 0;
2849: ThotBool moved;
2850:
2851: /* default element for FetchImage */
2852: el = TtaGetMainRoot (context->doc);
1.149 vatton 2853: /* Horrible hack requested by CSS: move the rule to the root element */
1.152 vatton 2854: moved = (isHTML && (element != NULL || ctxt->attrType[0] == 0) &&
2855: (ctxt->type == HTML_EL_HTML || ctxt->type == HTML_EL_BODY));
1.148 vatton 2856: if (moved)
2857: {
2858: if (element)
2859: element = el;
2860: else
2861: {
2862: savedtype = context->type;
2863: context->type = HTML_EL_Document;
2864: }
2865: }
2866: else if (element)
2867: el = element;
1.1 cvs 2868:
2869: url = NULL;
1.82 cvs 2870: cssRule = SkipBlanksAndComments (cssRule);
1.161 quint 2871: if (!strncasecmp (cssRule, "none", 4))
2872: {
2873: image.pointer = NULL;
2874: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, context,
2875: image);
2876: }
2877: else if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 2878: {
2879: cssRule += 3;
1.82 cvs 2880: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2881: if (*cssRule == '(')
2882: {
2883: cssRule++;
1.82 cvs 2884: cssRule = SkipBlanksAndComments (cssRule);
1.161 quint 2885: /*** Escaped quotes are not handled. See function SkipQuotedString */
1.1 cvs 2886: if (*cssRule == '"')
2887: {
2888: cssRule++;
2889: base = cssRule;
1.82 cvs 2890: while (*cssRule != EOS && *cssRule != '"')
1.1 cvs 2891: cssRule++;
2892: }
1.161 quint 2893: else if (*cssRule == '\'')
2894: {
2895: cssRule++;
2896: base = cssRule;
2897: while (*cssRule != EOS && *cssRule != '\'')
2898: cssRule++;
2899: }
1.1 cvs 2900: else
2901: {
2902: base = cssRule;
2903: while (*cssRule != EOS && *cssRule != ')')
2904: cssRule++;
2905: }
2906: saved = *cssRule;
1.82 cvs 2907: *cssRule = EOS;
2908: url = TtaStrdup (base);
1.1 cvs 2909: *cssRule = saved;
1.161 quint 2910: if (saved == '"' || saved == '\'')
2911: /* we need to skip the quote character and possinble spaces */
2912: {
2913: cssRule++;
2914: cssRule = SkipBlanksAndComments (cssRule);
2915: }
1.1 cvs 2916: }
2917: cssRule++;
2918:
2919: if (context->destroy)
2920: {
2921: /* remove the background image PRule */
2922: image.pointer = NULL;
2923: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, context, image);
2924: if (TtaGetStylePresentation (PRFillPattern, element, tsch, context, &value) < 0)
2925: {
2926: /* there is no FillPattern rule -> remove ShowBox rule */
2927: value.typed_data.value = 1;
2928: value.typed_data.unit = STYLE_UNIT_REL;
2929: value.typed_data.real = FALSE;
2930: TtaSetStylePresentation (PRShowBox, element, tsch, context, value);
2931: }
2932: }
2933: else if (url)
2934: {
1.30 cvs 2935: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
1.82 cvs 2936: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
1.161 quint 2937: /* background images are enabled */
1.1 cvs 2938: {
2939: callblock = (BackgroundImageCallbackPtr) TtaGetMemory(sizeof(BackgroundImageCallbackBlock));
2940: if (callblock != NULL)
2941: {
2942: callblock->el = element;
2943: callblock->tsch = tsch;
2944: if (element == NULL)
1.149 vatton 2945: memcpy (&callblock->context.generic, ctxt,
2946: sizeof (GenericContextBlock));
1.18 cvs 2947: else
1.149 vatton 2948: memcpy (&callblock->context.specific, context,
2949: sizeof(PresentationContextBlock));
1.18 cvs 2950:
2951: /* check if the image url is related to an external CSS */
2952: if (css != NULL && css->category == CSS_EXTERNAL_STYLE)
2953: {
2954: NormalizeURL (url, 0, tempname, imgname, css->url);
2955: /* fetch and display background image of element */
1.161 quint 2956: FetchImage (context->doc, el, tempname, AMAYA_LOAD_IMAGE,
2957: ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2958: }
2959: else
1.161 quint 2960: FetchImage (context->doc, el, url, AMAYA_LOAD_IMAGE,
2961: ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2962: }
2963: }
2964:
2965: if (url)
2966: TtaFreeMemory (url);
2967: }
2968: }
1.148 vatton 2969:
2970: /* restore the refered element */
2971: if (moved && !element)
2972: context->type = savedtype;
1.18 cvs 2973: return (cssRule);
2974: }
2975:
2976: /*----------------------------------------------------------------------
1.59 cvs 2977: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 2978: ----------------------------------------------------------------------*/
1.79 cvs 2979: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.97 vatton 2980: PresentationContext context,
2981: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2982: {
1.149 vatton 2983: GenericContext ctxt = (GenericContext) context;
1.18 cvs 2984: PresentationValue repeat;
1.148 vatton 2985: unsigned int savedtype = 0;
2986: ThotBool moved;
2987:
1.149 vatton 2988: /* Horrible hack requested by CSS: move the rule to the root element */
1.152 vatton 2989: moved = (isHTML && (element != NULL || ctxt->attrType[0] == 0) &&
2990: (ctxt->type == HTML_EL_HTML || ctxt->type == HTML_EL_BODY));
1.148 vatton 2991: if (moved)
2992: {
2993: if (element)
2994: element = TtaGetMainRoot (context->doc);
2995: else
2996: {
2997: savedtype = context->type;
2998: context->type = HTML_EL_Document;
2999: }
3000: }
1.18 cvs 3001:
3002: repeat.typed_data.value = STYLE_REALSIZE;
3003: repeat.typed_data.unit = STYLE_UNIT_REL;
3004: repeat.typed_data.real = FALSE;
1.82 cvs 3005: cssRule = SkipBlanksAndComments (cssRule);
3006: if (!strncasecmp (cssRule, "no-repeat", 9))
1.18 cvs 3007: repeat.typed_data.value = STYLE_REALSIZE;
1.82 cvs 3008: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.18 cvs 3009: repeat.typed_data.value = STYLE_VREPEAT;
1.82 cvs 3010: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.18 cvs 3011: repeat.typed_data.value = STYLE_HREPEAT;
1.82 cvs 3012: else if (!strncasecmp (cssRule, "repeat", 6))
1.18 cvs 3013: repeat.typed_data.value = STYLE_REPEAT;
3014: else
3015: return (cssRule);
3016:
3017: /* install the new presentation */
1.116 vatton 3018: if (DoApply)
1.117 vatton 3019: {
3020: /* check if it's an important rule */
3021: if (tsch)
3022: cssRule = CheckImportantRule (cssRule, context);
3023: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
3024: }
1.18 cvs 3025: cssRule = SkipWord (cssRule);
1.148 vatton 3026:
3027: /* restore the refered element */
3028: if (moved && !element)
3029: context->type = savedtype;
3030: return (cssRule);
1.18 cvs 3031: }
3032:
3033: /*----------------------------------------------------------------------
1.59 cvs 3034: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18 cvs 3035: attribute string.
3036: ----------------------------------------------------------------------*/
1.79 cvs 3037: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
3038: PresentationContext context,
3039: char *cssRule, CSSInfoPtr css,
3040: ThotBool isHTML)
1.18 cvs 3041: {
1.149 vatton 3042: GenericContext ctxt = (GenericContext) context;
1.148 vatton 3043: unsigned int savedtype = 0;
3044: ThotBool moved;
3045:
1.149 vatton 3046: /* Horrible hack requested by CSS: move the rule to the root element */
1.152 vatton 3047: moved = (isHTML && (element != NULL || ctxt->attrType[0] == 0) &&
3048: (ctxt->type == HTML_EL_HTML || ctxt->type == HTML_EL_BODY));
1.148 vatton 3049: if (moved)
3050: {
3051: if (element)
3052: element = TtaGetMainRoot (context->doc);
3053: else
3054: {
3055: savedtype = context->type;
3056: context->type = HTML_EL_Document;
3057: }
3058: }
3059:
1.82 cvs 3060: cssRule = SkipBlanksAndComments (cssRule);
3061: if (!strncasecmp (cssRule, "scroll", 6))
1.18 cvs 3062: cssRule = SkipWord (cssRule);
1.82 cvs 3063: else if (!strncasecmp (cssRule, "fixed", 5))
1.18 cvs 3064: cssRule = SkipWord (cssRule);
1.148 vatton 3065:
3066: /* restore the refered element */
3067: if (moved && !element)
3068: context->type = savedtype;
1.18 cvs 3069: return (cssRule);
1.1 cvs 3070: }
3071:
3072: /*----------------------------------------------------------------------
1.59 cvs 3073: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
1.1 cvs 3074: attribute string.
3075: ----------------------------------------------------------------------*/
1.79 cvs 3076: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
3077: PresentationContext context,
3078: char *cssRule, CSSInfoPtr css,
3079: ThotBool isHTML)
1.1 cvs 3080: {
1.149 vatton 3081: GenericContext ctxt = (GenericContext) context;
1.18 cvs 3082: PresentationValue repeat;
1.148 vatton 3083: unsigned int savedtype = 0;
3084: ThotBool moved;
1.18 cvs 3085: ThotBool ok;
1.1 cvs 3086:
1.149 vatton 3087: /* Horrible hack requested by CSS: move the rule to the root element */
1.152 vatton 3088: moved = (isHTML && (element != NULL || ctxt->attrType[0] == 0) &&
3089: (ctxt->type == HTML_EL_HTML || ctxt->type == HTML_EL_BODY));
1.148 vatton 3090: if (moved)
3091: {
3092: if (element)
3093: element = TtaGetMainRoot (context->doc);
3094: else
3095: {
3096: savedtype = context->type;
3097: context->type = HTML_EL_Document;
3098: }
3099: }
3100:
1.82 cvs 3101: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3102: ok = TRUE;
1.82 cvs 3103: if (!strncasecmp (cssRule, "left", 4))
1.18 cvs 3104: cssRule = SkipWord (cssRule);
1.82 cvs 3105: else if (!strncasecmp (cssRule, "right", 5))
1.18 cvs 3106: cssRule = SkipWord (cssRule);
1.82 cvs 3107: else if (!strncasecmp (cssRule, "center", 6))
1.18 cvs 3108: cssRule = SkipWord (cssRule);
1.82 cvs 3109: else if (!strncasecmp (cssRule, "top", 3))
1.18 cvs 3110: cssRule = SkipWord (cssRule);
1.82 cvs 3111: else if (!strncasecmp (cssRule, "bottom", 6))
1.18 cvs 3112: cssRule = SkipWord (cssRule);
1.110 vatton 3113: else if (isdigit (*cssRule) || *cssRule == '.')
1.18 cvs 3114: cssRule = SkipWord (cssRule);
3115: else
3116: ok = FALSE;
3117:
1.116 vatton 3118: if (ok && DoApply)
1.18 cvs 3119: {
3120: /* force realsize for the background image */
3121: repeat.typed_data.value = STYLE_REALSIZE;
3122: repeat.typed_data.unit = STYLE_UNIT_REL;
3123: repeat.typed_data.real = FALSE;
1.117 vatton 3124: /* check if it's an important rule */
3125: if (tsch)
3126: cssRule = CheckImportantRule (cssRule, context);
1.18 cvs 3127: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
3128: }
1.148 vatton 3129:
3130: /* restore the refered element */
3131: if (moved && !element)
3132: context->type = savedtype;
1.18 cvs 3133: return (cssRule);
3134: }
3135:
3136: /*----------------------------------------------------------------------
1.59 cvs 3137: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 3138: ----------------------------------------------------------------------*/
1.79 cvs 3139: static char *ParseCSSBackground (Element element, PSchema tsch,
3140: PresentationContext context, char *cssRule,
3141: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3142: {
1.79 cvs 3143: char *ptr;
1.93 vatton 3144: int skippedNL;
1.18 cvs 3145:
1.82 cvs 3146: cssRule = SkipBlanksAndComments (cssRule);
3147: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 3148: {
1.71 cvs 3149: /* perhaps a Background Image */
1.82 cvs 3150: if (!strncasecmp (cssRule, "url", 3))
1.63 cvs 3151: cssRule = ParseCSSBackgroundImage (element, tsch, context, cssRule,
3152: css, isHTML);
1.18 cvs 3153: /* perhaps a Background Attachment */
1.82 cvs 3154: else if (!strncasecmp (cssRule, "scroll", 6) ||
3155: !strncasecmp (cssRule, "fixed", 5))
1.63 cvs 3156: cssRule = ParseCSSBackgroundAttachment (element, tsch, context,
3157: cssRule, css, isHTML);
1.18 cvs 3158: /* perhaps a Background Repeat */
1.82 cvs 3159: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
3160: !strncasecmp (cssRule, "repeat-y", 8) ||
3161: !strncasecmp (cssRule, "repeat-x", 8) ||
3162: !strncasecmp (cssRule, "repeat", 6))
3163: cssRule = ParseCSSBackgroundRepeat (element, tsch, context,
3164: cssRule, css, isHTML);
1.18 cvs 3165: /* perhaps a Background Position */
1.82 cvs 3166: else if (!strncasecmp (cssRule, "left", 4) ||
3167: !strncasecmp (cssRule, "right", 5) ||
3168: !strncasecmp (cssRule, "center", 6) ||
3169: !strncasecmp (cssRule, "top", 3) ||
3170: !strncasecmp (cssRule, "bottom", 6) ||
1.110 vatton 3171: isdigit (*cssRule) || *cssRule == '.')
1.63 cvs 3172: cssRule = ParseCSSBackgroundPosition (element, tsch, context,
3173: cssRule, css, isHTML);
1.18 cvs 3174: /* perhaps a Background Color */
3175: else
3176: {
1.93 vatton 3177: skippedNL = NewLineSkipped;
1.18 cvs 3178: /* check if the rule has been found */
3179: ptr = cssRule;
1.82 cvs 3180: cssRule = ParseCSSBackgroundColor (element, tsch, context,
3181: cssRule, css, isHTML);
1.43 cvs 3182: if (ptr == cssRule)
1.93 vatton 3183: {
3184: NewLineSkipped = skippedNL;
3185: /* rule not found */
3186: cssRule = SkipProperty (cssRule);
3187: }
1.18 cvs 3188: }
1.82 cvs 3189: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3190: }
3191: return (cssRule);
3192: }
3193:
1.59 cvs 3194: /*----------------------------------------------------------------------
1.60 cvs 3195: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 3196: ----------------------------------------------------------------------*/
1.79 cvs 3197: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
3198: PresentationContext context, char *cssRule,
3199: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 3200: {
3201: PresentationValue page;
3202:
3203: page.typed_data.unit = STYLE_UNIT_INVALID;
3204: page.typed_data.real = FALSE;
1.82 cvs 3205: cssRule = SkipBlanksAndComments (cssRule);
3206: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3207: {
3208: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3209: page.typed_data.value = STYLE_AUTO;
3210: }
1.82 cvs 3211: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3212: {
3213: page.typed_data.unit = STYLE_UNIT_REL;
3214: page.typed_data.value = STYLE_ALWAYS;
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, "left", 4))
1.59 cvs 3222: {
3223: page.typed_data.unit = STYLE_UNIT_REL;
3224: page.typed_data.value = STYLE_PAGELEFT;
3225: }
1.82 cvs 3226: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3227: {
3228: page.typed_data.unit = STYLE_UNIT_REL;
3229: page.typed_data.value = STYLE_PAGERIGHT;
3230: }
1.82 cvs 3231: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3232: {
3233: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3234: page.typed_data.value = STYLE_INHERIT;
3235: }
3236: cssRule = SkipWord (cssRule);
3237: /* install the new presentation */
3238: if (page.typed_data.unit == STYLE_UNIT_REL &&
1.116 vatton 3239: page.typed_data.value == STYLE_ALWAYS && DoApply)
1.117 vatton 3240: {
3241: /* check if it's an important rule */
3242: if (tsch)
3243: cssRule = CheckImportantRule (cssRule, context);
3244: TtaSetStylePresentation (PRPageBefore, element, tsch, context, page);
3245: }
1.59 cvs 3246: return (cssRule);
3247: }
3248:
3249: /*----------------------------------------------------------------------
1.60 cvs 3250: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 3251: ----------------------------------------------------------------------*/
1.79 cvs 3252: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
3253: PresentationContext context,
3254: char *cssRule, CSSInfoPtr css,
3255: ThotBool isHTML)
1.59 cvs 3256: {
3257: PresentationValue page;
3258:
3259: page.typed_data.unit = STYLE_UNIT_INVALID;
3260: page.typed_data.real = FALSE;
1.82 cvs 3261: cssRule = SkipBlanksAndComments (cssRule);
3262: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3263: {
3264: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3265: page.typed_data.value = STYLE_AUTO;
3266: }
1.82 cvs 3267: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3268: {
3269: page.typed_data.unit = STYLE_UNIT_REL;
3270: page.typed_data.value = STYLE_ALWAYS;
3271: }
1.82 cvs 3272: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3273: {
3274: page.typed_data.unit = STYLE_UNIT_REL;
3275: page.typed_data.value = STYLE_AVOID;
3276: }
1.82 cvs 3277: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 3278: {
3279: page.typed_data.unit = STYLE_UNIT_REL;
3280: page.typed_data.value = STYLE_PAGELEFT;
3281: }
1.82 cvs 3282: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3283: {
3284: page.typed_data.unit = STYLE_UNIT_REL;
3285: page.typed_data.value = STYLE_PAGERIGHT;
3286: }
1.82 cvs 3287: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3288: {
3289: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3290: page.typed_data.value = STYLE_INHERIT;
3291: }
3292: cssRule = SkipWord (cssRule);
3293: /* install the new presentation */
1.116 vatton 3294: /*if (page.typed_data.unit == STYLE_UNIT_REL && DoApply)
1.117 vatton 3295: {
3296: if (tsch)
3297: cssRule = CheckImportantRule (cssRule, context);
3298: TtaSetStylePresentation (PRPageAfter, element, tsch, context, page);
3299: }*/
1.59 cvs 3300: return (cssRule);
3301: }
3302:
3303: /*----------------------------------------------------------------------
1.60 cvs 3304: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 3305: ----------------------------------------------------------------------*/
1.79 cvs 3306: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
3307: PresentationContext context,
3308: char *cssRule, CSSInfoPtr css,
3309: ThotBool isHTML)
1.59 cvs 3310: {
3311: PresentationValue page;
3312:
3313: page.typed_data.unit = STYLE_UNIT_INVALID;
3314: page.typed_data.real = FALSE;
1.82 cvs 3315: cssRule = SkipBlanksAndComments (cssRule);
3316: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3317: {
3318: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3319: page.typed_data.value = STYLE_AUTO;
3320: }
1.82 cvs 3321: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3322: {
3323: page.typed_data.unit = STYLE_UNIT_REL;
3324: page.typed_data.value = STYLE_AVOID;
3325: }
1.82 cvs 3326: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3327: {
3328: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3329: page.typed_data.value = STYLE_INHERIT;
3330: }
3331: cssRule = SkipWord (cssRule);
3332: /* install the new presentation */
1.96 vatton 3333: /*if (page.typed_data.unit == STYLE_UNIT_REL &&
1.117 vatton 3334: page.typed_data.value == STYLE_AVOID && DoApply)
3335: {
3336: if (tsch)
3337: cssRule = CheckImportantRule (cssRule, context);
3338: TtaSetStylePresentation (PRPageInside, element, tsch, context, page);
3339: }*/
1.59 cvs 3340: return (cssRule);
3341: }
1.18 cvs 3342:
3343:
1.60 cvs 3344: /*----------------------------------------------------------------------
1.117 vatton 3345: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 3346: ----------------------------------------------------------------------*/
1.79 cvs 3347: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
3348: PresentationContext context, char *cssRule,
3349: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 3350: {
3351: PresentationValue width;
3352:
1.82 cvs 3353: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 3354: width.typed_data.value = 0;
3355: width.typed_data.unit = STYLE_UNIT_INVALID;
3356: width.typed_data.real = FALSE;
1.110 vatton 3357: if (isdigit (*cssRule) || *cssRule == '.')
1.60 cvs 3358: cssRule = ParseCSSUnit (cssRule, &width);
1.116 vatton 3359: if (width.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 3360: {
3361: /* check if it's an important rule */
3362: if (tsch)
3363: cssRule = CheckImportantRule (cssRule, context);
3364: TtaSetStylePresentation (PRLineWeight, element, tsch, context, width);
3365: width.typed_data.value = 1;
3366: width.typed_data.unit = STYLE_UNIT_REL;
3367: }
1.60 cvs 3368: return (cssRule);
3369: }
3370:
1.18 cvs 3371: /************************************************************************
3372: * *
3373: * FUNCTIONS STYLE DECLARATIONS *
3374: * *
3375: ************************************************************************/
3376: /*
1.59 cvs 3377: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 3378: * e.g. "FONT-SIZE" must be placed before "FONT"
3379: */
3380: static CSSProperty CSSProperties[] =
3381: {
1.82 cvs 3382: {"font-family", ParseCSSFontFamily},
3383: {"font-style", ParseCSSFontStyle},
3384: {"font-variant", ParseCSSFontVariant},
3385: {"font-weight", ParseCSSFontWeight},
3386: {"font-size", ParseCSSFontSize},
3387: {"font", ParseCSSFont},
3388:
3389: {"color", ParseCSSForeground},
3390: {"background-color", ParseCSSBackgroundColor},
3391: {"background-image", ParseCSSBackgroundImage},
3392: {"background-repeat", ParseCSSBackgroundRepeat},
3393: {"background-attachment", ParseCSSBackgroundAttachment},
3394: {"background-position", ParseCSSBackgroundPosition},
3395: {"background", ParseCSSBackground},
3396:
3397: {"word-spacing", ParseCSSWordSpacing},
3398: {"letter-spacing", ParseCSSLetterSpacing},
3399: {"text-decoration", ParseCSSTextDecoration},
3400: {"vertical-align", ParseCSSVerticalAlign},
3401: {"text-transform", ParseCSSTextTransform},
3402: {"text-align", ParseCSSTextAlign},
3403: {"text-indent", ParseCSSTextIndent},
1.162 ! quint 3404: {"line-height", ParseCSSLineHeight},
1.82 cvs 3405:
1.112 quint 3406: {"direction", ParseCSSDirection},
1.113 quint 3407: {"unicode-bidi", ParseCSSUnicodeBidi},
1.112 quint 3408:
1.82 cvs 3409: {"margin-top", ParseCSSMarginTop},
3410: {"margin-right", ParseCSSMarginRight},
3411: {"margin-bottom", ParseCSSMarginBottom},
3412: {"margin-left", ParseCSSMarginLeft},
3413: {"margin", ParseCSSMargin},
3414:
3415: {"padding-top", ParseCSSPaddingTop},
3416: {"padding-right", ParseCSSPaddingRight},
3417: {"padding-bottom", ParseCSSPaddingBottom},
3418: {"padding-left", ParseCSSPaddingLeft},
3419: {"padding", ParseCSSPadding},
3420:
3421: {"border-top-width", ParseCSSBorderTopWidth},
3422: {"border-right-width", ParseCSSBorderRightWidth},
3423: {"border-bottom-width", ParseCSSBorderBottomWidth},
3424: {"border-left-width", ParseCSSBorderLeftWidth},
3425: {"border-width", ParseCSSBorderWidth},
3426: {"border-top-color", ParseCSSBorderColorTop},
3427: {"border-right-color", ParseCSSBorderColorRight},
3428: {"border-bottom-color", ParseCSSBorderColorBottom},
3429: {"border-left-color", ParseCSSBorderColorLeft},
3430: {"border-color", ParseCSSBorderColor},
3431: {"border-top-style", ParseCSSBorderStyleTop},
3432: {"border-right-style", ParseCSSBorderStyleRight},
3433: {"border-bottom-style", ParseCSSBorderStyleBottom},
3434: {"border-left-style", ParseCSSBorderStyleLeft},
3435: {"border-style", ParseCSSBorderStyle},
3436: {"border-top", ParseCSSBorderTop},
3437: {"border-right", ParseCSSBorderRight},
3438: {"border-bottom", ParseCSSBorderBottom},
3439: {"border-left", ParseCSSBorderLeft},
3440: {"border", ParseCSSBorder},
3441:
3442: {"width", ParseCSSWidth},
3443: {"height", ParseCSSHeight},
3444: {"float", ParseCSSFloat},
3445: {"clear", ParseCSSClear},
3446:
3447: {"display", ParseCSSDisplay},
3448: {"white-space", ParseCSSWhiteSpace},
3449:
3450: {"list-style-type", ParseCSSListStyleType},
3451: {"list-style-image", ParseCSSListStyleImage},
3452: {"list-style-position", ParseCSSListStylePosition},
3453: {"list-style", ParseCSSListStyle},
3454:
3455: {"page-break-before", ParseCSSPageBreakBefore},
3456: {"page-break-after", ParseCSSPageBreakAfter},
3457: {"page-break-inside", ParseCSSPageBreakInside},
1.60 cvs 3458:
3459: /* SVG extensions */
1.82 cvs 3460: {"stroke-width", ParseSVGStrokeWidth},
3461: {"stroke", ParseSVGStroke},
1.155 cheyroul 3462: {"fill", ParseSVGFill},
3463: {"opacity", ParseSVGOpacity}
1.18 cvs 3464: };
1.155 cheyroul 3465:
1.18 cvs 3466: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
3467:
3468: /*----------------------------------------------------------------------
1.59 cvs 3469: ParseCSSRule: parse a CSS Style string
1.18 cvs 3470: we expect the input string describing the style to be of the
1.59 cvs 3471: form: PRORPERTY: DESCRIPTION [ ; PROPERTY: DESCRIPTION ] *
1.18 cvs 3472: but tolerate incorrect or incomplete input
3473: ----------------------------------------------------------------------*/
1.79 cvs 3474: static void ParseCSSRule (Element element, PSchema tsch,
3475: PresentationContext context, char *cssRule,
3476: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3477: {
1.34 cvs 3478: DisplayMode dispMode;
1.79 cvs 3479: char *p = NULL;
1.18 cvs 3480: int lg;
1.34 cvs 3481: unsigned int i;
1.76 cvs 3482: ThotBool found;
1.18 cvs 3483:
1.34 cvs 3484: /* avoid too many redisplay */
3485: dispMode = TtaGetDisplayMode (context->doc);
3486: if (dispMode == DisplayImmediately)
3487: TtaSetDisplayMode (context->doc, DeferredDisplay);
3488:
1.82 cvs 3489: while (*cssRule != EOS)
1.18 cvs 3490: {
1.82 cvs 3491: cssRule = SkipBlanksAndComments (cssRule);
1.153 vatton 3492: if (*cssRule < 0x41 || *cssRule > 0x7A ||
1.133 vatton 3493: (*cssRule > 0x5A && *cssRule < 0x60))
1.153 vatton 3494: cssRule++;
3495: else
1.89 cvs 3496: {
1.153 vatton 3497: found = FALSE;
3498: /* look for the type of property */
3499: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
1.18 cvs 3500: {
1.153 vatton 3501: lg = strlen (CSSProperties[i].name);
3502: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
3503: {
3504: p = cssRule + lg;
3505: found = TRUE;
3506: i--;
3507: }
1.18 cvs 3508: }
1.153 vatton 3509: if (i == NB_CSSSTYLEATTRIBUTE)
3510: cssRule = SkipProperty (cssRule);
3511: else
1.18 cvs 3512: {
1.153 vatton 3513: /* update index and skip the ":" indicator if present */
1.86 cvs 3514: p = SkipBlanksAndComments (p);
1.153 vatton 3515: if (*p == ':')
1.61 cvs 3516: {
1.153 vatton 3517: p++;
3518: p = SkipBlanksAndComments (p);
3519: /* try to parse the value associated with this property */
3520: if (CSSProperties[i].parsing_function != NULL)
3521: {
3522: p = CSSProperties[i].parsing_function (element, tsch, context,
3523: p, css, isHTML);
3524: /* update index and skip the ";" separator if present */
3525: cssRule = p;
3526: }
1.61 cvs 3527: }
1.153 vatton 3528: else
3529: cssRule = SkipProperty (cssRule);
1.18 cvs 3530: }
3531: }
3532: /* next property */
1.82 cvs 3533: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 3534: if (*cssRule == '}')
3535: {
3536: cssRule++;
3537: CSSParseError ("Invalid character", "}");
3538: cssRule = SkipBlanksAndComments (cssRule);
3539: }
1.155 cheyroul 3540: if (*cssRule == ',' ||
3541: *cssRule == ';')
1.18 cvs 3542: {
3543: cssRule++;
1.82 cvs 3544: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3545: }
3546: }
1.34 cvs 3547:
3548: /* restore the display mode */
3549: if (dispMode == DisplayImmediately)
3550: TtaSetDisplayMode (context->doc, dispMode);
1.18 cvs 3551: }
1.1 cvs 3552:
1.111 cvs 3553: /*----------------------------------------------------------------------
3554: AddBorderStyleValue
3555: -----------------------------------------------------------------------*/
3556: static void AddBorderStyleValue (char *buffer, int value)
3557: {
3558: switch (value)
3559: {
3560: case STYLE_BORDERNONE:
3561: strcat (buffer, "none");
3562: break;
3563: case STYLE_BORDERHIDDEN:
3564: strcat (buffer, "hidden");
3565: break;
3566: case STYLE_BORDERDOTTED:
3567: strcat (buffer, "dotted");
3568: break;
3569: case STYLE_BORDERDASHED:
3570: strcat (buffer, "dashed");
3571: break;
3572: case STYLE_BORDERSOLID:
3573: strcat (buffer, "solid");
3574: break;
3575: case STYLE_BORDERDOUBLE:
3576: strcat (buffer, "double");
3577: break;
3578: case STYLE_BORDERGROOVE:
3579: strcat (buffer, "groove");
3580: break;
3581: case STYLE_BORDERRIDGE:
3582: strcat (buffer, "ridge");
3583: break;
3584: case STYLE_BORDERINSET:
3585: strcat (buffer, "inset");
3586: break;
3587: case STYLE_BORDEROUTSET:
3588: strcat (buffer, "outset");
3589: break;
3590: }
3591: }
1.1 cvs 3592:
3593: /*----------------------------------------------------------------------
1.59 cvs 3594: PToCss: translate a PresentationSetting to the
1.18 cvs 3595: equivalent CSS string, and add it to the buffer given as the
1.67 cvs 3596: argument. It is used when extracting the CSS string from actual
3597: presentation.
3598: el is the element for which the style rule is generated
1.18 cvs 3599:
3600: All the possible values returned by the presentation drivers are
3601: described in thotlib/include/presentation.h
3602: -----------------------------------------------------------------------*/
1.79 cvs 3603: void PToCss (PresentationSetting settings, char *buffer, int len, Element el)
1.1 cvs 3604: {
1.76 cvs 3605: ElementType elType;
1.18 cvs 3606: float fval = 0;
3607: unsigned short red, green, blue;
3608: int add_unit = 0;
3609: unsigned int unit, i;
3610: ThotBool real = FALSE;
3611:
1.82 cvs 3612: buffer[0] = EOS;
1.18 cvs 3613: if (len < 40)
3614: return;
3615:
3616: unit = settings->value.typed_data.unit;
3617: if (settings->value.typed_data.real)
3618: {
3619: real = TRUE;
3620: fval = (float) settings->value.typed_data.value;
3621: fval /= 1000;
3622: }
1.1 cvs 3623:
1.18 cvs 3624: switch (settings->type)
1.1 cvs 3625: {
1.18 cvs 3626: case PRVisibility:
3627: break;
1.111 cvs 3628: case PRHeight:
3629: if (real)
3630: sprintf (buffer, "height: %g", fval);
3631: else
3632: sprintf (buffer, "height: %d", settings->value.typed_data.value);
3633: add_unit = 1;
3634: break;
3635: case PRWidth:
3636: if (real)
3637: sprintf (buffer, "width: %g", fval);
3638: else
3639: sprintf (buffer, "width: %d", settings->value.typed_data.value);
3640: add_unit = 1;
3641: break;
3642: case PRMarginTop:
3643: if (real)
3644: sprintf (buffer, "margin-top: %g", fval);
3645: else
3646: sprintf (buffer, "margin-top: %d",settings->value.typed_data.value);
3647: add_unit = 1;
3648: break;
3649: case PRMarginBottom:
3650: if (real)
3651: sprintf (buffer, "margin-bottom: %g", fval);
3652: else
3653: sprintf (buffer, "margin-bottom: %d",
3654: settings->value.typed_data.value);
3655: add_unit = 1;
3656: break;
3657: case PRMarginLeft:
3658: if (real)
3659: sprintf (buffer, "margin-left: %g", fval);
3660: else
3661: sprintf (buffer, "margin-left: %d",
3662: settings->value.typed_data.value);
3663: add_unit = 1;
3664: break;
3665: case PRMarginRight:
3666: if (real)
3667: sprintf (buffer, "margin-right: %g", fval);
3668: else
3669: sprintf (buffer, "margin-right: %d",
3670: settings->value.typed_data.value);
3671: add_unit = 1;
3672: break;
3673: case PRPaddingTop:
3674: if (real)
3675: sprintf (buffer, "padding-top: %g", fval);
3676: else
3677: sprintf (buffer, "padding-top: %d",settings->value.typed_data.value);
3678: add_unit = 1;
3679: break;
3680: case PRPaddingBottom:
3681: if (real)
3682: sprintf (buffer, "padding-bottom: %g", fval);
3683: else
3684: sprintf (buffer, "padding-bottom: %d",
3685: settings->value.typed_data.value);
3686: add_unit = 1;
3687: break;
3688: case PRPaddingLeft:
3689: if (real)
3690: sprintf (buffer, "padding-left: %g", fval);
3691: else
3692: sprintf (buffer, "padding-left: %d",
3693: settings->value.typed_data.value);
3694: add_unit = 1;
3695: break;
3696: case PRPaddingRight:
3697: if (real)
3698: sprintf (buffer, "padding-right: %g", fval);
3699: else
3700: sprintf (buffer, "padding-right: %d",
3701: settings->value.typed_data.value);
3702: add_unit = 1;
3703: break;
3704: case PRBorderTopWidth:
3705: if (real)
3706: sprintf (buffer, "border-top-width: %g", fval);
3707: else
3708: sprintf (buffer, "border-top-width: %d",
3709: settings->value.typed_data.value);
3710: add_unit = 1;
3711: break;
3712: case PRBorderBottomWidth:
3713: if (real)
3714: sprintf (buffer, "border-bottom-width: %g", fval);
3715: else
3716: sprintf (buffer, "border-bottom-width: %d",
3717: settings->value.typed_data.value);
3718: add_unit = 1;
3719: break;
3720: case PRBorderLeftWidth:
3721: if (real)
3722: sprintf (buffer, "border-left-width: %g", fval);
3723: else
3724: sprintf (buffer, "border-left-width: %d",
3725: settings->value.typed_data.value);
3726: add_unit = 1;
3727: break;
3728: case PRBorderRightWidth:
3729: if (real)
3730: sprintf (buffer, "border-right-width: %g", fval);
3731: else
3732: sprintf (buffer, "border-right-width: %d",
3733: settings->value.typed_data.value);
3734: add_unit = 1;
3735: break;
3736: case PRBorderTopColor:
3737: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3738: elType = TtaGetElementType(el);
3739: sprintf (buffer, "border-top-color: #%02X%02X%02X", red, green, blue);
3740: break;
3741: case PRBorderRightColor:
3742: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3743: elType = TtaGetElementType(el);
3744: sprintf (buffer, "border-right-color: #%02X%02X%02X", red, green, blue);
3745: break;
3746: case PRBorderBottomColor:
3747: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3748: elType = TtaGetElementType(el);
3749: sprintf (buffer, "border-bottom-color: #%02X%02X%02X", red, green, blue);
1.18 cvs 3750: break;
1.111 cvs 3751: case PRBorderLeftColor:
3752: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3753: elType = TtaGetElementType(el);
3754: sprintf (buffer, "border-left-color: #%02X%02X%02X", red, green, blue);
1.20 cvs 3755: break;
1.111 cvs 3756: case PRBorderTopStyle:
3757: strcpy (buffer, "border-top-style: ");
3758: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3759: break;
3760: case PRBorderRightStyle:
3761: strcpy (buffer, "border-right-style: ");
3762: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3763: break;
3764: case PRBorderBottomStyle:
3765: strcpy (buffer, "border-bottom-style: ");
3766: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3767: break;
3768: case PRBorderLeftStyle:
3769: strcpy (buffer, "border-left-style: ");
3770: AddBorderStyleValue (buffer, settings->value.typed_data.value);
1.18 cvs 3771: break;
3772: case PRSize:
3773: if (unit == STYLE_UNIT_REL)
3774: {
3775: if (real)
3776: {
1.82 cvs 3777: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 3778: add_unit = 1;
3779: }
3780: else
3781: switch (settings->value.typed_data.value)
3782: {
3783: case 1:
1.82 cvs 3784: strcpy (buffer, "font-size: xx-small");
1.18 cvs 3785: break;
3786: case 2:
1.82 cvs 3787: strcpy (buffer, "font-size: x-small");
1.18 cvs 3788: break;
3789: case 3:
1.82 cvs 3790: strcpy (buffer, "font-size: small");
1.18 cvs 3791: break;
3792: case 4:
1.82 cvs 3793: strcpy (buffer, "font-size: medium");
1.18 cvs 3794: break;
3795: case 5:
1.82 cvs 3796: strcpy (buffer, "font-size: large");
1.18 cvs 3797: break;
3798: case 6:
1.82 cvs 3799: strcpy (buffer, "font-size: x-large");
1.18 cvs 3800: break;
3801: case 7:
3802: case 8:
3803: case 9:
3804: case 10:
3805: case 11:
3806: case 12:
1.82 cvs 3807: strcpy (buffer, "font-size: xx-large");
1.18 cvs 3808: break;
3809: }
3810: }
3811: else
3812: {
3813: if (real)
1.82 cvs 3814: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 3815: else
1.82 cvs 3816: sprintf (buffer, "font-size: %d",
1.67 cvs 3817: settings->value.typed_data.value);
1.18 cvs 3818: add_unit = 1;
3819: }
3820: break;
1.111 cvs 3821: case PRStyle:
3822: switch (settings->value.typed_data.value)
3823: {
3824: case STYLE_FONT_ROMAN:
3825: strcpy (buffer, "font-style: normal");
3826: break;
3827: case STYLE_FONT_ITALICS:
3828: strcpy (buffer, "font-style: italic");
3829: break;
3830: case STYLE_FONT_OBLIQUE:
3831: strcpy (buffer, "font-style: oblique");
3832: break;
3833: }
3834: break;
3835: case PRWeight:
3836: switch (settings->value.typed_data.value)
3837: {
3838: case STYLE_WEIGHT_BOLD:
3839: strcpy (buffer, "font-weight: bold");
3840: break;
3841: case STYLE_WEIGHT_NORMAL:
3842: strcpy (buffer, "font-weight: normal");
3843: break;
3844: }
3845: break;
3846: case PRFont:
3847: switch (settings->value.typed_data.value)
3848: {
3849: case STYLE_FONT_HELVETICA:
3850: strcpy (buffer, "font-family: helvetica");
3851: break;
3852: case STYLE_FONT_TIMES:
3853: strcpy (buffer, "font-family: times");
3854: break;
3855: case STYLE_FONT_COURIER:
3856: strcpy (buffer, "font-family: courier");
3857: break;
3858: }
3859: break;
1.18 cvs 3860: case PRUnderline:
3861: switch (settings->value.typed_data.value)
3862: {
3863: case STYLE_UNDERLINE:
1.82 cvs 3864: strcpy (buffer, "text-decoration: underline");
1.18 cvs 3865: break;
3866: case STYLE_OVERLINE:
1.82 cvs 3867: strcpy (buffer, "text-decoration: overline");
1.18 cvs 3868: break;
3869: case STYLE_CROSSOUT:
1.82 cvs 3870: strcpy (buffer, "text-decoration: line-through");
1.18 cvs 3871: break;
3872: }
3873: break;
1.111 cvs 3874: case PRThickness:
3875: break;
1.18 cvs 3876: case PRIndent:
3877: if (real)
1.82 cvs 3878: sprintf (buffer, "text-indent: %g", fval);
1.18 cvs 3879: else
1.82 cvs 3880: sprintf (buffer, "text-indent: %d",
1.67 cvs 3881: settings->value.typed_data.value);
1.18 cvs 3882: add_unit = 1;
3883: break;
3884: case PRLineSpacing:
3885: if (real)
1.82 cvs 3886: sprintf (buffer, "line-height: %g", fval);
1.1 cvs 3887: else
1.82 cvs 3888: sprintf (buffer, "line-height: %d",
1.67 cvs 3889: settings->value.typed_data.value);
1.18 cvs 3890: add_unit = 1;
3891: break;
1.111 cvs 3892: case PRDepth:
3893: break;
1.18 cvs 3894: case PRAdjust:
3895: switch (settings->value.typed_data.value)
1.1 cvs 3896: {
1.18 cvs 3897: case STYLE_ADJUSTLEFT:
1.82 cvs 3898: strcpy (buffer, "text-align: left");
1.18 cvs 3899: break;
3900: case STYLE_ADJUSTRIGHT:
1.82 cvs 3901: strcpy (buffer, "text-align: right");
1.18 cvs 3902: break;
3903: case STYLE_ADJUSTCENTERED:
1.82 cvs 3904: strcpy (buffer, "text-align: center");
1.18 cvs 3905: break;
3906: case STYLE_ADJUSTLEFTWITHDOTS:
1.82 cvs 3907: strcpy (buffer, "text-align: left");
1.81 cvs 3908: break;
3909: case STYLE_ADJUSTJUSTIFY:
1.82 cvs 3910: strcpy (buffer, "text-align: justify");
1.112 quint 3911: break;
3912: }
3913: break;
3914: case PRDirection:
3915: switch (settings->value.typed_data.value)
3916: {
3917: case STYLE_LEFTTORIGHT:
3918: strcpy (buffer, "direction: ltr");
3919: break;
3920: case STYLE_RIGHTTOLEFT:
3921: strcpy (buffer, "direction: rtl");
1.113 quint 3922: break;
3923: }
3924: break;
3925: case PRUnicodeBidi:
3926: switch (settings->value.typed_data.value)
3927: {
3928: case STYLE_BIDINORMAL:
3929: strcpy (buffer, "unicode-bidi: normal");
3930: break;
3931: case STYLE_BIDIEMBED:
3932: strcpy (buffer, "unicode-bidi: embed");
3933: break;
3934: case STYLE_BIDIOVERRIDE:
3935: strcpy (buffer, "unicode-bidi: bidi-override");
1.18 cvs 3936: break;
1.1 cvs 3937: }
1.18 cvs 3938: break;
1.111 cvs 3939: case PRLineStyle:
3940: break;
1.126 vatton 3941: case PRDisplay:
3942: switch (settings->value.typed_data.value)
3943: {
3944: case STYLE_DISPLAYINLINE:
3945: strcpy (buffer, "display: inline");
3946: break;
3947: case STYLE_DISPLAYBLOCK:
3948: strcpy (buffer, "display: block");
3949: break;
3950: case STYLE_DISPLAYLISTITEM:
3951: strcpy (buffer, "display: list-item");
3952: break;
3953: case STYLE_DISPLAYRUNIN:
3954: strcpy (buffer, "display: runin");
3955: break;
3956: case STYLE_DISPLAYCOMPACT:
3957: strcpy (buffer, "display: compact");
3958: break;
3959: case STYLE_DISPLAYMARKER:
3960: strcpy (buffer, "display: marker");
3961: break;
3962: default:
3963: break;
3964: }
3965: break;
1.111 cvs 3966: case PRLineWeight:
3967: elType = TtaGetElementType(el);
3968: #ifdef _SVG
3969: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
3970: #endif /* _SVG */
3971: {
3972: if (real)
3973: sprintf (buffer, "stroke-width: %g", fval);
3974: else
3975: sprintf (buffer, "stroke-width: %d",
3976: settings->value.typed_data.value);
3977: }
3978: add_unit = 1;
1.18 cvs 3979: break;
3980: case PRFillPattern:
3981: break;
3982: case PRBackground:
3983: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3984: elType = TtaGetElementType(el);
1.100 vatton 3985: #ifdef _SVG
3986: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 3987: sprintf (buffer, "fill: #%02X%02X%02X", red, green, blue);
1.67 cvs 3988: else
1.100 vatton 3989: #endif /* _SVG */
1.82 cvs 3990: sprintf (buffer, "background-color: #%02X%02X%02X", red, green,
1.67 cvs 3991: blue);
1.18 cvs 3992: break;
3993: case PRForeground:
3994: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3995: elType = TtaGetElementType(el);
1.100 vatton 3996: #ifdef _SVG
3997: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 3998: sprintf (buffer, "stroke: #%02X%02X%02X", red, green, blue);
1.67 cvs 3999: else
1.100 vatton 4000: #endif /* _SVG */
1.82 cvs 4001: sprintf (buffer, "color: #%02X%02X%02X", red, green, blue);
1.67 cvs 4002: break;
1.111 cvs 4003: case PRHyphenate:
1.18 cvs 4004: break;
1.111 cvs 4005: case PRVertOverflow:
1.18 cvs 4006: break;
1.111 cvs 4007: case PRHorizOverflow:
1.18 cvs 4008: break;
4009: case PRBackgroundPicture:
4010: if (settings->value.pointer != NULL)
1.82 cvs 4011: sprintf (buffer, "background-image: url(%s)",
1.67 cvs 4012: (char*)(settings->value.pointer));
1.1 cvs 4013: else
1.82 cvs 4014: sprintf (buffer, "background-image: none");
1.18 cvs 4015: break;
4016: case PRPictureMode:
4017: switch (settings->value.typed_data.value)
1.1 cvs 4018: {
1.18 cvs 4019: case STYLE_REALSIZE:
1.82 cvs 4020: sprintf (buffer, "background-repeat: no-repeat");
1.18 cvs 4021: break;
4022: case STYLE_REPEAT:
1.82 cvs 4023: sprintf (buffer, "background-repeat: repeat");
1.18 cvs 4024: break;
4025: case STYLE_VREPEAT:
1.82 cvs 4026: sprintf (buffer, "background-repeat: repeat-y");
1.18 cvs 4027: break;
4028: case STYLE_HREPEAT:
1.82 cvs 4029: sprintf (buffer, "background-repeat: repeat-x");
1.18 cvs 4030: break;
1.1 cvs 4031: }
1.18 cvs 4032: break;
4033: default:
4034: break;
1.1 cvs 4035: }
4036:
1.18 cvs 4037: if (add_unit)
1.1 cvs 4038: {
1.18 cvs 4039: /* add the unit string to the CSS string */
4040: for (i = 0; i < NB_UNITS; i++)
1.1 cvs 4041: {
1.18 cvs 4042: if (CSSUnitNames[i].unit == unit)
1.1 cvs 4043: {
1.82 cvs 4044: strcat (buffer, CSSUnitNames[i].sign);
1.18 cvs 4045: break;
1.1 cvs 4046: }
4047: }
4048: }
4049: }
4050:
4051: /*----------------------------------------------------------------------
1.59 cvs 4052: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18 cvs 4053: This function must be called when a specific style is applied to an
4054: element.
1.114 quint 4055: The parameter specificity is the specificity of the style, 0 if it is
4056: not really a CSS rule.
1.1 cvs 4057: ----------------------------------------------------------------------*/
1.79 cvs 4058: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.114 quint 4059: int specificity, ThotBool destroy)
1.1 cvs 4060: {
4061: PresentationContext context;
4062: ElementType elType;
1.14 cvs 4063: ThotBool isHTML;
1.1 cvs 4064:
4065: /* A rule applying to BODY is really meant to address HTML */
4066: elType = TtaGetElementType (el);
1.89 cvs 4067:
1.86 cvs 4068: /* store the current line for eventually reported errors */
4069: LineNumber = TtaGetElementLineNumber (el);
1.89 cvs 4070: if (destroy)
4071: /* no reported errors */
4072: ParsedDoc = 0;
4073: else if (ParsedDoc != doc)
4074: {
4075: /* update the context for reported errors */
4076: ParsedDoc = doc;
4077: DocURL = DocumentURLs[doc];
4078: }
1.82 cvs 4079: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
1.1 cvs 4080: /* create the context of the Specific presentation driver */
4081: context = TtaGetSpecificStyleContext (doc);
4082: if (context == NULL)
4083: return;
4084: context->type = elType.ElTypeNum;
1.114 quint 4085: context->cssSpecificity = specificity;
1.1 cvs 4086: context->destroy = destroy;
4087: /* Call the parser */
1.155 cheyroul 4088: ParseCSSRule (el, NULL,
4089: (PresentationContext) context,
4090: cssRule, NULL, isHTML);
1.1 cvs 4091: /* free the context */
4092: TtaFreeMemory(context);
4093: }
4094:
1.68 cvs 4095:
1.1 cvs 4096: /*----------------------------------------------------------------------
1.59 cvs 4097: ParseGenericSelector: Create a generic context for a given
1.1 cvs 4098: selector string. If the selector is made of multiple comma-
4099: separated selector items, it parses them one at a time and
4100: return the end of the selector string to be handled or NULL
4101: ----------------------------------------------------------------------*/
1.79 cvs 4102: static char *ParseGenericSelector (char *selector, char *cssRule,
4103: GenericContext ctxt, Document doc,
4104: CSSInfoPtr css)
4105: {
4106: ElementType elType;
4107: PSchema tsch;
1.119 vatton 4108: AttributeType attrType;
1.79 cvs 4109: char sel[MAX_ANCESTORS * 50];
1.118 vatton 4110: char *deb, *cur, c;
4111: char *schemaName, *mappedName;
1.79 cvs 4112: char *names[MAX_ANCESTORS];
4113: char *ids[MAX_ANCESTORS];
4114: char *classes[MAX_ANCESTORS];
4115: char *pseudoclasses[MAX_ANCESTORS];
4116: char *attrs[MAX_ANCESTORS];
4117: char *attrvals[MAX_ANCESTORS];
1.133 vatton 4118: AttrMatch attrmatch[MAX_ANCESTORS];
1.91 cvs 4119: int i, j, k, max;
1.125 vatton 4120: int att, maxAttr, kind;
1.118 vatton 4121: int specificity, xmlType;
1.79 cvs 4122: ThotBool isHTML;
4123: ThotBool level;
1.1 cvs 4124:
1.82 cvs 4125: sel[0] = EOS;
1.117 vatton 4126: specificity = 0;
1.1 cvs 4127: for (i = 0; i < MAX_ANCESTORS; i++)
4128: {
1.25 cvs 4129: names[i] = NULL;
4130: ids[i] = NULL;
4131: classes[i] = NULL;
4132: pseudoclasses[i] = NULL;
4133: attrs[i] = NULL;
4134: attrvals[i] = NULL;
1.133 vatton 4135: attrmatch[i] = Txtmatch;
1.25 cvs 4136: ctxt->name[i] = 0;
4137: ctxt->names_nb[i] = 0;
4138: ctxt->attrType[i] = 0;
1.129 vatton 4139: ctxt->attrLevel[i] = 0;
1.25 cvs 4140: ctxt->attrText[i] = NULL;
1.133 vatton 4141: ctxt->attrMatch[1] = Txtmatch;
1.1 cvs 4142: }
1.25 cvs 4143: ctxt->box = 0;
4144: ctxt->type = 0;
1.114 quint 4145: /* the specificity of the rule depends on the selector */
4146: ctxt->cssSpecificity = 0;
1.25 cvs 4147:
1.82 cvs 4148: selector = SkipBlanksAndComments (selector);
1.27 cvs 4149: cur = &sel[0];
1.25 cvs 4150: max = 0; /* number of loops */
1.1 cvs 4151: while (1)
4152: {
1.85 cvs 4153: /* point to the following word in sel[] */
1.27 cvs 4154: deb = cur;
1.25 cvs 4155: /* copy an item of the selector into sel[] */
1.1 cvs 4156: /* put one word in the sel buffer */
1.82 cvs 4157: while (*selector != EOS && *selector != ',' &&
4158: *selector != '.' && *selector != ':' &&
1.118 vatton 4159: *selector != '#' && *selector != '[' &&
1.130 vatton 4160: *selector != '*' && *selector != '>' &&
1.118 vatton 4161: !TtaIsBlank (selector))
1.50 cvs 4162: *cur++ = *selector++;
1.82 cvs 4163: *cur++ = EOS; /* close the first string in sel[] */
4164: if (deb[0] != EOS)
1.117 vatton 4165: {
4166: names[0] = deb;
1.150 vatton 4167: if (!strcmp (names[0], "html"))
1.149 vatton 4168: /* give a greater priority to the backgoud color of html */
4169: specificity += 3;
4170: else
4171: specificity += 1;
1.117 vatton 4172: }
1.25 cvs 4173: else
1.27 cvs 4174: names[0] = NULL;
4175: classes[0] = NULL;
4176: pseudoclasses[0] = NULL;
4177: ids[0] = NULL;
4178: attrs[0] = NULL;
4179: attrvals[0] = NULL;
1.25 cvs 4180:
1.27 cvs 4181: /* now names[0] points to the beginning of the parsed item
1.25 cvs 4182: and cur to the next chain to be parsed */
1.129 vatton 4183: while (*selector == '.' || *selector == ':' ||
1.130 vatton 4184: *selector == '#' || *selector == '[' ||
4185: *selector == '*' || *selector == '>')
1.129 vatton 4186: {
1.85 cvs 4187: /* point to the following word in sel[] */
4188: deb = cur;
1.129 vatton 4189: if (*selector == '.')
4190: {
4191: selector++;
4192: while (*selector != EOS && *selector != ',' &&
4193: *selector != '.' && *selector != ':' &&
4194: !TtaIsBlank (selector))
4195: *cur++ = *selector++;
4196: /* close the word */
4197: *cur++ = EOS;
4198: /* point to the class in sel[] if it's valid name */
4199: if (deb[0] <= 64)
4200: {
4201: CSSParseError ("Invalid class", deb);
1.116 vatton 4202: DoApply = FALSE;
1.129 vatton 4203: }
4204: else
4205: {
4206: classes[0] = deb;
1.117 vatton 4207: specificity += 10;
1.129 vatton 4208: }
4209: }
4210: else if (*selector == ':')
4211: {
4212: selector++;
4213: while (*selector != EOS && *selector != ',' &&
4214: *selector != '.' && *selector != ':' &&
4215: !TtaIsBlank (selector))
4216: *cur++ = *selector++;
4217: /* close the word */
4218: *cur++ = EOS;
4219: /* point to the pseudoclass in sel[] if it's valid name */
4220: if (deb[0] <= 64)
4221: {
4222: CSSParseError ("Invalid pseudoclass", deb);
4223: DoApply = FALSE;
4224: }
4225: else
4226: {
4227: if (!strcmp (deb, "first-letter") ||
4228: !strcmp (deb, "first-line") ||
4229: !strcmp (deb, "before") ||
4230: !strcmp (deb, "after"))
4231: /* not supported */
1.116 vatton 4232: DoApply = FALSE;
1.129 vatton 4233: else
4234: specificity += 10;
4235: pseudoclasses[0]= deb;
4236: }
4237: }
4238: else if (*selector == '#')
4239: {
4240: selector++;
4241: while (*selector != EOS && *selector != ',' &&
4242: *selector != '.' && *selector != ':' &&
4243: !TtaIsBlank (selector))
4244: *cur++ = *selector++;
4245: /* close the word */
4246: *cur++ = EOS;
4247: /* point to the attribute in sel[] if it's valid name */
4248: if (deb[0] <= 64)
4249: {
4250: CSSParseError ("Invalid id", deb);
4251: DoApply = FALSE;
4252: }
4253: else
4254: {
4255: ids[0] = deb;
4256: specificity += 100;
4257: }
4258: }
4259: else if (*selector == '[')
4260: {
1.118 vatton 4261: selector++;
1.129 vatton 4262: while (*selector != EOS && *selector != ']' &&
1.131 vatton 4263: *selector != '=' && *selector != '~' &&
1.133 vatton 4264: *selector != '|' && *selector != '^' &&
4265: *selector != '!')
1.129 vatton 4266: *cur++ = *selector++;
1.133 vatton 4267: /* check matching */
4268: if (*selector == '~')
4269: {
4270: attrmatch[0] = Txtword;
4271: selector++;
4272: }
4273: else if (*selector == '|')
4274: {
4275: attrmatch[0] = Txtsubstring;
4276: selector++;
4277: }
4278: else
4279: attrmatch[0] = Txtmatch;
1.129 vatton 4280: /* close the word */
4281: *cur++ = EOS;
4282: /* point to the attribute in sel[] if it's valid name */
4283: if (deb[0] <= 64)
4284: {
4285: CSSParseError ("Invalid attribute", deb);
4286: DoApply = FALSE;
4287: }
4288: else
4289: {
4290: attrs[0] = deb;
4291: specificity += 10;
4292: }
4293: if (*selector == '=')
4294: {
4295: /* look for a value "xxxx" */
4296: selector++;
4297: if (*selector != '"')
4298: {
4299: CSSParseError ("Invalid attribute value", deb);
4300: DoApply = FALSE;
4301: }
4302: else
4303: {
4304: /* we are now parsing the attribute value */
4305: selector++;
4306: deb = cur;
4307: while (*selector != '"')
4308: {
4309: if (*selector == EOS)
4310: {
4311: CSSParseError ("Invalid attribute value", deb);
4312: DoApply = FALSE;
4313: }
4314: else
1.133 vatton 4315: {
4316: *cur++ = tolower (*selector);
4317: selector++;
4318: }
1.129 vatton 4319: }
4320: /* there is a value */
4321: if (*selector == '"')
4322: {
4323: selector++;
4324: *cur++ = EOS;
4325: attrvals[0] = deb;
4326: }
4327: }
4328: }
4329: /* end of the attribute */
4330: if (*selector != ']')
4331: {
1.133 vatton 4332: selector[1] = EOS;
4333: CSSParseError ("Not supported selector", selector);
4334: selector += 2;
1.129 vatton 4335: DoApply = FALSE;
4336: }
4337: else
4338: selector++;
1.130 vatton 4339: }
4340: else
4341: {
4342: /* not supported selector */
4343: while (*selector != EOS && *selector != ',' &&
4344: *selector != '.' && *selector != ':' &&
4345: !TtaIsBlank (selector))
4346: *cur++ = *selector++;
4347: /* close the word */
4348: *cur++ = EOS;
4349: CSSParseError ("Not supported selector", deb);
4350: DoApply = FALSE;
1.129 vatton 4351: }
4352: }
1.1 cvs 4353:
1.82 cvs 4354: selector = SkipBlanksAndComments (selector);
1.25 cvs 4355: /* is it a multi-level selector? */
1.82 cvs 4356: if (*selector == EOS)
1.1 cvs 4357: /* end of the selector */
4358: break;
1.82 cvs 4359: else if (*selector == ',')
1.1 cvs 4360: {
4361: /* end of the current selector */
4362: selector++;
4363: break;
4364: }
1.25 cvs 4365: else
4366: {
1.143 vatton 4367: if (*selector == '>')
4368: {
4369: /* handle immediat parent as a simple parent */
4370: selector++;
4371: selector = SkipBlanksAndComments (selector);
4372: }
1.25 cvs 4373: /* shifts the list to make room for the new name */
4374: max++; /* a new level in ancestor tables */
4375: if (max == MAX_ANCESTORS)
4376: /* abort the CSS parsing */
4377: return (selector);
4378: for (i = max; i > 0; i--)
4379: {
4380: names[i] = names[i - 1];
4381: ids[i] = ids[i - 1];
4382: classes[i] = classes[i - 1];
1.133 vatton 4383: pseudoclasses[i] = pseudoclasses[i - 1];
1.25 cvs 4384: attrs[i] = attrs[i - 1];
4385: attrvals[i] = attrvals[i - 1];
1.133 vatton 4386: attrmatch[i] = attrmatch[i - 1];
1.25 cvs 4387: }
4388: }
1.1 cvs 4389: }
4390:
4391: /* Now set up the context block */
1.25 cvs 4392: i = 0;
4393: k = 0;
4394: j = 0;
1.35 cvs 4395: maxAttr = 0;
1.91 cvs 4396: /* default schema name */
1.119 vatton 4397: ctxt->schema = NULL;
1.122 vatton 4398: elType.ElSSchema = NULL;
4399: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 4400: if (!strcmp (schemaName, "HTML"))
4401: xmlType = XHTML_TYPE;
4402: else if (!strcmp (schemaName, "MathML"))
4403: xmlType = MATH_TYPE;
4404: else if (!strcmp (schemaName, "SVG"))
4405: xmlType = SVG_TYPE;
4406: else if (!strcmp (schemaName, "XLink"))
4407: xmlType = XLINK_TYPE;
4408: else if (!strcmp (schemaName, "Annot"))
4409: xmlType = ANNOT_TYPE;
4410: else
4411: xmlType = XML_TYPE;
1.25 cvs 4412: while (i <= max)
4413: {
4414: if (names[i])
4415: {
1.118 vatton 4416: /* get the element type of this name in the current document */
4417: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c, &level, doc);
1.25 cvs 4418: if (i == 0)
4419: {
1.106 cvs 4420: if (elType.ElSSchema == NULL)
4421: {
1.119 vatton 4422: /* Search in the list of loaded schemas */
1.106 cvs 4423: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.119 vatton 4424: if (elType.ElSSchema)
4425: {
1.154 vatton 4426: /* the element type concerns an imported nature */
1.119 vatton 4427: schemaName = TtaGetSSchemaName(elType.ElSSchema);
4428: if (!strcmp (schemaName, "HTML"))
4429: xmlType = XHTML_TYPE;
4430: else if (!strcmp (schemaName, "MathML"))
4431: xmlType = MATH_TYPE;
4432: else if (!strcmp (schemaName, "SVG"))
4433: xmlType = SVG_TYPE;
4434: else if (!strcmp (schemaName, "XLink"))
4435: xmlType = XLINK_TYPE;
4436: else if (!strcmp (schemaName, "Annot"))
4437: xmlType = ANNOT_TYPE;
4438: else
4439: xmlType = XML_TYPE;
4440: }
1.118 vatton 4441: #ifdef XML_GENERIC
1.119 vatton 4442: else if (xmlType == XML_TYPE)
1.106 cvs 4443: {
4444: /* Creation of a new element type in the main schema */
4445: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.118 vatton 4446: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.106 cvs 4447: }
1.118 vatton 4448: #endif /* XML_GENERIC */
1.122 vatton 4449: else
4450: {
4451: if (xmlType != XHTML_TYPE)
4452: {
4453: MapXMLElementType (XHTML_TYPE, names[i], &elType,
4454: &mappedName, &c, &level, doc);
4455: if (elType.ElSSchema)
1.123 vatton 4456: elType.ElSSchema = GetXHTMLSSchema (doc);
1.122 vatton 4457: }
4458: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
4459: {
4460: MapXMLElementType (MATH_TYPE, names[i], &elType,
4461: &mappedName, &c, &level, doc);
4462: if (elType.ElSSchema)
1.123 vatton 4463: elType.ElSSchema = GetMathMLSSchema (doc);
1.122 vatton 4464: }
4465: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
4466: {
4467: MapXMLElementType (SVG_TYPE, names[i], &elType,
4468: &mappedName, &c, &level, doc);
4469: if (elType.ElSSchema)
1.123 vatton 4470: elType.ElSSchema = GetSVGSSchema (doc);
1.122 vatton 4471: }
4472: }
1.118 vatton 4473: }
1.119 vatton 4474:
1.118 vatton 4475: if (elType.ElSSchema == NULL)
4476: /* cannot apply these CSS rules */
4477: DoApply = FALSE;
4478: else
4479: {
4480: /* Store the element type */
4481: ctxt->type = elType.ElTypeNum;
4482: ctxt->name[0] = elType.ElTypeNum;
4483: ctxt->names_nb[0] = 0;
4484: ctxt->schema = elType.ElSSchema;
1.106 cvs 4485: }
1.25 cvs 4486: }
4487: else if (elType.ElTypeNum != 0)
4488: {
4489: /* look at the current context to see if the type is already
4490: stored */
1.121 vatton 4491: j = 1;
1.32 cvs 4492: while (j < k && ctxt->name[j] != elType.ElTypeNum)
1.25 cvs 4493: j++;
4494: if (j == k)
4495: {
4496: ctxt->name[j] = elType.ElTypeNum;
4497: if (j != 0)
1.121 vatton 4498: ctxt->names_nb[j] = 1;
1.25 cvs 4499: }
4500: else
4501: /* increment the number of ancestor levels */
4502: ctxt->names_nb[j]++;
4503: }
1.154 vatton 4504: #ifdef XML_GENERIC
4505: else if (xmlType == XML_TYPE)
4506: {
1.158 vatton 4507: TtaGetXmlElementType (names[i], &elType, NULL, doc);
4508: if (elType.ElTypeNum == 0)
4509: {
4510: /* Creation of a new element type in the main schema */
4511: elType.ElSSchema = TtaGetDocumentSSchema (doc);
4512: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
4513: }
1.154 vatton 4514: if (elType.ElTypeNum != 0)
4515: {
4516: /* look at the current context to see if the type is already
4517: stored */
4518: j = 1;
4519: while (j < k && ctxt->name[j] != elType.ElTypeNum)
4520: j++;
4521: if (j == k)
4522: {
4523: ctxt->name[j] = elType.ElTypeNum;
4524: if (j != 0)
4525: ctxt->names_nb[j] = 1;
4526: }
4527: else
4528: /* increment the number of ancestor levels */
4529: ctxt->names_nb[j]++;
4530: }
4531: }
4532: #endif /* XML_GENERIC */
1.25 cvs 4533: else
1.117 vatton 4534: j = k;
1.25 cvs 4535: }
1.117 vatton 4536: else
4537: j = k;
1.1 cvs 4538:
1.25 cvs 4539: /* store attributes information */
4540: if (classes[i])
4541: {
4542: ctxt->attrText[j] = classes[i];
1.119 vatton 4543: if (xmlType == SVG_TYPE)
1.100 vatton 4544: ctxt->attrType[j] = SVG_ATTR_class;
1.119 vatton 4545: else if (xmlType == MATH_TYPE)
1.91 cvs 4546: ctxt->attrType[j] = MathML_ATTR_class;
1.119 vatton 4547: else if (xmlType == XHTML_TYPE)
1.107 cvs 4548: ctxt->attrType[j] = HTML_ATTR_Class;
4549: else
1.119 vatton 4550: #ifdef XML_GENERIC
1.107 cvs 4551: ctxt->attrType[j] = XML_ATTR_class;
4552: #else /* XML_GENERIC */
1.91 cvs 4553: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 4554: #endif /* XML_GENERIC */
1.157 vatton 4555: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4556: /* add a new entry */
1.80 cvs 4557: maxAttr = i + 1;
1.129 vatton 4558: /* update attrLevel */
4559: ctxt->attrLevel[j] = i;
4560: j++;
1.25 cvs 4561: }
1.79 cvs 4562: if (pseudoclasses[i])
1.25 cvs 4563: {
4564: ctxt->attrText[j] = pseudoclasses[i];
1.119 vatton 4565: if (xmlType == SVG_TYPE)
1.100 vatton 4566: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
1.119 vatton 4567: else if (xmlType == MATH_TYPE)
1.91 cvs 4568: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
1.119 vatton 4569: else if (xmlType == XHTML_TYPE)
1.107 cvs 4570: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
4571: else
1.119 vatton 4572: #ifdef XML_GENERIC
1.107 cvs 4573: ctxt->attrType[j] = XML_ATTR_PseudoClass;
4574: #else /* XML_GENERIC */
1.91 cvs 4575: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 4576: #endif /* XML_GENERIC */
1.157 vatton 4577: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4578: /* add a new entry */
1.80 cvs 4579: maxAttr = i + 1;
1.129 vatton 4580: /* update attrLevel */
4581: ctxt->attrLevel[j] = i;
4582: j++;
1.25 cvs 4583: }
1.79 cvs 4584: if (ids[i])
1.25 cvs 4585: {
4586: ctxt->attrText[j] = ids[i];
1.119 vatton 4587: if (xmlType == SVG_TYPE)
1.100 vatton 4588: ctxt->attrType[j] = SVG_ATTR_id;
1.119 vatton 4589: else if (xmlType == MATH_TYPE)
1.91 cvs 4590: ctxt->attrType[j] = MathML_ATTR_id;
1.119 vatton 4591: else if (xmlType == XHTML_TYPE)
1.107 cvs 4592: ctxt->attrType[j] = HTML_ATTR_ID;
4593: else
1.119 vatton 4594: #ifdef XML_GENERIC
1.107 cvs 4595: ctxt->attrType[j] = XML_ATTR_id;
4596: #else /* XML_GENERIC */
1.91 cvs 4597: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 4598: #endif /* XML_GENERIC */
1.157 vatton 4599: ctxt->attrMatch[j] = attrmatch[i];
1.80 cvs 4600: /* add a new entry */
4601: maxAttr = i + 1;
1.129 vatton 4602: /* update attrLevel */
4603: ctxt->attrLevel[j] = i;
4604: j++;
1.25 cvs 4605: }
1.79 cvs 4606: if (attrs[i])
1.25 cvs 4607: {
1.125 vatton 4608: /* it's an attribute */
1.119 vatton 4609: MapXMLAttribute (xmlType, attrs[i], names[i], &level, doc, &att);
1.127 quint 4610: if (att == DummyAttribute && !strcmp (schemaName, "HTML"))
4611: /* it's the "type" attribute for an "input" element. In the tree
4612: it's represented by the element type, not by an attribute */
4613: att = 0;
1.119 vatton 4614: ctxt->attrType[j] = att;
1.133 vatton 4615: ctxt->attrMatch[j] = attrmatch[i];
1.125 vatton 4616: attrType.AttrSSchema = ctxt->schema;
4617: attrType.AttrTypeNum = att;
1.119 vatton 4618: if (i == 0 && att == 0 && ctxt->schema == NULL)
4619: {
1.125 vatton 4620: /* Not found -> search in the list of loaded schemas */
1.119 vatton 4621: attrType.AttrSSchema = NULL;
4622: TtaGetXmlAttributeType (attrs[i], &attrType, doc);
4623: ctxt->attrType[j] = attrType.AttrTypeNum;
4624: if (attrType.AttrSSchema)
1.125 vatton 4625: /* the element type concerns an imported nature */
4626: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
1.119 vatton 4627: #ifdef XML_GENERIC
4628: else if (xmlType == XML_TYPE)
4629: {
4630: /* The attribute is not yet present in the tree */
4631: /* Create a new global attribute */
4632: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
4633: TtaAppendXmlAttribute (attrs[i], &attrType, doc);
4634: }
4635: #endif /* XML_GENERIC */
4636:
4637: if (attrType.AttrSSchema == NULL)
4638: /* cannot apply these CSS rules */
4639: DoApply = FALSE;
1.136 quint 4640: else if (elType.ElSSchema)
4641: ctxt->schema = elType.ElSSchema;
1.119 vatton 4642: else
1.136 quint 4643: ctxt->schema = attrType.AttrSSchema;
1.119 vatton 4644: }
1.125 vatton 4645: /* check the attribute type */
4646: if (!strcmp (schemaName, "HTML"))
4647: xmlType = XHTML_TYPE;
4648: else if (!strcmp (schemaName, "MathML"))
4649: xmlType = MATH_TYPE;
4650: else if (!strcmp (schemaName, "SVG"))
4651: xmlType = SVG_TYPE;
4652: else if (!strcmp (schemaName, "XLink"))
4653: xmlType = XLINK_TYPE;
4654: else if (!strcmp (schemaName, "Annot"))
4655: xmlType = ANNOT_TYPE;
4656: else
4657: xmlType = XML_TYPE;
4658: kind = TtaGetAttributeKind (attrType);
4659: if (kind == 0 && attrvals[i])
4660: {
4661: /* enumerated value */
4662: MapXMLAttributeValue (xmlType, attrvals[i], attrType, &kind);
4663: /* store the attribute value */
4664: ctxt->attrText[j] = (char *) kind;
4665: }
4666: else
4667: ctxt->attrText[j] = attrvals[i];
1.80 cvs 4668: maxAttr = i + 1;
1.129 vatton 4669: /* update attrLevel */
4670: ctxt->attrLevel[j] = i;
4671: j++;
1.25 cvs 4672: }
4673: i++;
1.117 vatton 4674: /* add a new entry */
4675: k++;
1.129 vatton 4676: if (k < j)
4677: k = j;
1.119 vatton 4678: if (i == 1 && ctxt->schema == NULL)
4679: /* use the document schema */
4680: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 4681: }
1.117 vatton 4682: /* set the selector specificity */
4683: ctxt->cssSpecificity = specificity;
1.25 cvs 4684: /* sort the list of ancestors by name order */
4685: max = k;
4686: i = 1;
4687: while (i < max)
1.28 cvs 4688: {
4689: for (k = i + 1; k < max; k++)
4690: if (ctxt->name[i] > ctxt->name[k])
4691: {
4692: j = ctxt->name[i];
4693: ctxt->name[i] = ctxt->name[k];
4694: ctxt->name[k] = j;
4695: j = ctxt->names_nb[i];
4696: ctxt->names_nb[i] = ctxt->names_nb[k];
4697: ctxt->names_nb[k] = j;
4698: j = ctxt->attrType[i];
4699: ctxt->attrType[i] = ctxt->attrType[k];
4700: ctxt->attrType[k] = j;
4701: cur = ctxt->attrText[i];
4702: ctxt->attrText[i] = ctxt->attrText[k];
4703: ctxt->attrText[k] = cur;
4704: }
4705: i++;
4706: }
1.84 cvs 4707:
1.25 cvs 4708: /* Get the schema name of the main element */
1.119 vatton 4709: schemaName = TtaGetSSchemaName (ctxt->schema);
4710: isHTML = (strcmp (schemaName, "HTML") == 0);
4711: tsch = GetPExtension (doc, ctxt->schema, css);
4712: if (tsch && cssRule)
4713: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.116 vatton 4714: /* future CSS rules should apply */
4715: DoApply = TRUE;
1.1 cvs 4716: return (selector);
4717: }
4718:
4719: /*----------------------------------------------------------------------
1.73 cvs 4720: ParseStyleDeclaration: parse a style declaration
4721: stored in the style element of a document
1.59 cvs 4722: We expect the style string to be of the form:
1.1 cvs 4723: [
4724: e.g: pinky, awful { color: pink, font-family: helvetica }
4725: ----------------------------------------------------------------------*/
1.79 cvs 4726: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
4727: CSSInfoPtr css, ThotBool destroy)
1.1 cvs 4728: {
1.79 cvs 4729: GenericContext ctxt;
4730: char *decl_end;
4731: char *sel_end;
4732: char *selector;
1.1 cvs 4733:
4734: /* separate the selectors string */
1.82 cvs 4735: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 4736: decl_end = cssRule;
1.82 cvs 4737: while (*decl_end != EOS && *decl_end != '{')
1.1 cvs 4738: decl_end++;
1.82 cvs 4739: if (*decl_end == EOS)
1.86 cvs 4740: {
4741: CSSParseError ("Invalid selector", cssRule);
4742: return;
4743: }
1.1 cvs 4744: /* verify and clean the selector string */
4745: sel_end = decl_end - 1;
1.82 cvs 4746: while (*sel_end == SPACE || *sel_end == BSPACE ||
4747: *sel_end == EOL || *sel_end == CR)
1.1 cvs 4748: sel_end--;
4749: sel_end++;
1.82 cvs 4750: *sel_end = EOS;
1.1 cvs 4751: selector = cssRule;
4752:
4753: /* now, deal with the content ... */
4754: decl_end++;
4755: cssRule = decl_end;
1.137 vatton 4756: decl_end = &cssRule[strlen (cssRule) - 1];
4757: if (*decl_end != '{')
4758: *decl_end = EOS;
1.1 cvs 4759: /*
4760: * parse the style attribute string and install the corresponding
4761: * presentation attributes on the new element
4762: */
4763: ctxt = TtaGetGenericStyleContext (doc);
4764: if (ctxt == NULL)
4765: return;
4766: ctxt->destroy = destroy;
4767:
1.82 cvs 4768: while ((selector != NULL) && (*selector != EOS))
1.25 cvs 4769: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css);
1.1 cvs 4770: TtaFreeMemory (ctxt);
4771: }
4772:
4773: /************************************************************************
4774: * *
4775: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
4776: * *
4777: ************************************************************************/
4778:
4779: /*----------------------------------------------------------------------
1.59 cvs 4780: IsImplicitClassName: return wether the Class name is an
1.1 cvs 4781: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
4782: or an HTML context name.
4783: ----------------------------------------------------------------------*/
1.79 cvs 4784: int IsImplicitClassName (char *class, Document doc)
1.1 cvs 4785: {
1.79 cvs 4786: char name[200];
4787: char *cur = name;
4788: char *first;
4789: char save;
4790: SSchema schema;
1.1 cvs 4791:
4792: /* make a local copy */
1.82 cvs 4793: strncpy (name, class, 199);
1.1 cvs 4794: name[199] = 0;
4795:
4796: /* loop looking if each word is a GI */
4797: while (*cur != 0)
4798: {
4799: first = cur;
4800: cur = SkipWord (cur);
4801: save = *cur;
4802: *cur = 0;
4803: schema = NULL;
4804: if (MapGI (first, &schema, doc) == -1)
4805: {
4806: return (0);
4807: }
4808: *cur = save;
1.82 cvs 4809: cur = SkipBlanksAndComments (cur);
1.1 cvs 4810: }
4811: return (1);
4812: }
4813:
4814: /************************************************************************
4815: * *
1.114 quint 4816: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 4817: * *
4818: ************************************************************************/
4819:
4820: /*----------------------------------------------------------------------
1.59 cvs 4821: HTMLSetBackgroundColor:
1.1 cvs 4822: ----------------------------------------------------------------------*/
1.79 cvs 4823: void HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1 cvs 4824: {
1.79 cvs 4825: char css_command[100];
1.1 cvs 4826:
1.82 cvs 4827: sprintf (css_command, "background-color: %s", color);
1.114 quint 4828: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4829: }
4830:
4831: /*----------------------------------------------------------------------
1.59 cvs 4832: HTMLSetForegroundColor:
1.1 cvs 4833: ----------------------------------------------------------------------*/
1.97 vatton 4834: void HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1 cvs 4835: {
1.79 cvs 4836: char css_command[100];
1.1 cvs 4837:
1.82 cvs 4838: sprintf (css_command, "color: %s", color);
1.114 quint 4839: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4840: }
4841:
4842: /*----------------------------------------------------------------------
1.59 cvs 4843: HTMLResetBackgroundColor:
1.1 cvs 4844: ----------------------------------------------------------------------*/
1.97 vatton 4845: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 4846: {
1.79 cvs 4847: char css_command[100];
1.1 cvs 4848:
1.82 cvs 4849: sprintf (css_command, "background: red");
1.114 quint 4850: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4851: }
4852:
4853: /*----------------------------------------------------------------------
1.59 cvs 4854: HTMLResetBackgroundImage:
1.1 cvs 4855: ----------------------------------------------------------------------*/
1.97 vatton 4856: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 4857: {
1.79 cvs 4858: char css_command[1000];
1.1 cvs 4859:
1.82 cvs 4860: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.114 quint 4861: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4862: }
4863:
4864: /*----------------------------------------------------------------------
1.59 cvs 4865: HTMLResetForegroundColor:
1.1 cvs 4866: ----------------------------------------------------------------------*/
1.97 vatton 4867: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 4868: {
1.79 cvs 4869: char css_command[100];
1.1 cvs 4870:
1.36 cvs 4871: /* it's not necessary to well know the current color but it must be valid */
1.82 cvs 4872: sprintf (css_command, "color: red");
1.114 quint 4873: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4874: }
4875:
4876: /*----------------------------------------------------------------------
1.59 cvs 4877: HTMLSetAlinkColor:
1.1 cvs 4878: ----------------------------------------------------------------------*/
1.97 vatton 4879: void HTMLSetAlinkColor (Document doc, char *color)
1.1 cvs 4880: {
1.79 cvs 4881: char css_command[100];
1.1 cvs 4882:
1.82 cvs 4883: sprintf (css_command, "a:link { color: %s }", color);
1.1 cvs 4884: ApplyCSSRules (NULL, css_command, doc, FALSE);
4885: }
4886:
4887: /*----------------------------------------------------------------------
1.59 cvs 4888: HTMLSetAactiveColor:
1.1 cvs 4889: ----------------------------------------------------------------------*/
1.97 vatton 4890: void HTMLSetAactiveColor (Document doc, char *color)
1.1 cvs 4891: {
1.79 cvs 4892: char css_command[100];
1.1 cvs 4893:
1.82 cvs 4894: sprintf (css_command, "a:active { color: %s }", color);
1.1 cvs 4895: ApplyCSSRules (NULL, css_command, doc, FALSE);
4896: }
4897:
4898: /*----------------------------------------------------------------------
1.59 cvs 4899: HTMLSetAvisitedColor:
1.1 cvs 4900: ----------------------------------------------------------------------*/
1.79 cvs 4901: void HTMLSetAvisitedColor (Document doc, char *color)
1.1 cvs 4902: {
1.79 cvs 4903: char css_command[100];
1.1 cvs 4904:
1.82 cvs 4905: sprintf (css_command, "a:visited { color: %s }", color);
1.1 cvs 4906: ApplyCSSRules (NULL, css_command, doc, FALSE);
4907: }
4908:
4909: /*----------------------------------------------------------------------
1.59 cvs 4910: HTMLResetAlinkColor:
1.1 cvs 4911: ----------------------------------------------------------------------*/
4912: void HTMLResetAlinkColor (Document doc)
4913: {
1.79 cvs 4914: char css_command[100];
1.1 cvs 4915:
1.82 cvs 4916: sprintf (css_command, "a:link { color: red }");
1.1 cvs 4917: ApplyCSSRules (NULL, css_command, doc, TRUE);
4918: }
4919:
4920: /*----------------------------------------------------------------------
1.59 cvs 4921: HTMLResetAactiveColor:
1.1 cvs 4922: ----------------------------------------------------------------------*/
4923: void HTMLResetAactiveColor (Document doc)
4924: {
1.79 cvs 4925: char css_command[100];
1.1 cvs 4926:
1.82 cvs 4927: sprintf (css_command, "a:active { color: red }");
1.1 cvs 4928: ApplyCSSRules (NULL, css_command, doc, TRUE);
4929: }
4930:
4931: /*----------------------------------------------------------------------
1.59 cvs 4932: HTMLResetAvisitedColor:
1.1 cvs 4933: ----------------------------------------------------------------------*/
4934: void HTMLResetAvisitedColor (Document doc)
4935: {
1.79 cvs 4936: char css_command[100];
1.1 cvs 4937:
1.82 cvs 4938: sprintf (css_command, "a:visited { color: red }");
1.1 cvs 4939: ApplyCSSRules (NULL, css_command, doc, TRUE);
4940: }
4941:
4942: /*----------------------------------------------------------------------
1.73 cvs 4943: ApplyCSSRules: parse a CSS Style description stored in the
1.1 cvs 4944: header of a HTML document.
4945: ----------------------------------------------------------------------*/
1.79 cvs 4946: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 4947: {
4948: CSSInfoPtr css;
4949:
1.144 quint 4950: css = SearchCSS (doc, NULL, el);
1.1 cvs 4951: if (css == NULL)
4952: /* create the document css */
1.144 quint 4953: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, NULL, NULL, el);
1.1 cvs 4954: ParseStyleDeclaration (el, cssRule, doc, css, destroy);
4955: }
4956:
4957: /*----------------------------------------------------------------------
1.145 quint 4958: ReadCSSRules: is the front-end function called by the document parser
4959: when detecting a <style type="text/css"> indicating it's the
1.1 cvs 4960: beginning of a CSS fragment or when reading a file .css.
4961:
4962: The CSS parser has to handle <!-- ... --> constructs used to
4963: prevent prehistoric browser from displaying the CSS as a text
4964: content. It will stop on any sequence "<x" where x is different
4965: from ! and will return x as to the caller. Theorically x should
1.145 quint 4966: be equal to / for the </style> end of style.
1.1 cvs 4967: The parameter doc gives the document tree that contains CSS information.
4968: The parameter docRef gives the document to which CSS are to be applied.
4969: This function uses the current css context or creates it. It's able
1.23 cvs 4970: to work on the given buffer or call GetNextChar to read the parsed
1.1 cvs 4971: file.
1.133 vatton 4972: The parameter url gives the URL of the style shheet parsed.
1.86 cvs 4973: Parameter numberOfLinesRead indicates the number of lines already
4974: read in the file.
1.1 cvs 4975: Parameter withUndo indicates whether the changes made in the document
1.145 quint 4976: structure and content have to be registered in the Undo queue or not.
4977: refElement is the element (image or use, for instance) that references
4978: the document containing the style element to be parsed.
1.1 cvs 4979: ----------------------------------------------------------------------*/
1.133 vatton 4980: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.144 quint 4981: int numberOfLinesRead, ThotBool withUndo,
1.145 quint 4982: Element styleElement, Element refElement)
1.1 cvs 4983: {
1.6 cvs 4984: DisplayMode dispMode;
1.82 cvs 4985: char c;
1.138 vatton 4986: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 4987: int index;
1.1 cvs 4988: int CSSindex;
4989: int CSScomment;
4990: int import;
4991: int openRule;
1.93 vatton 4992: int newlines;
1.14 cvs 4993: ThotBool HTMLcomment;
1.102 vatton 4994: ThotBool toParse, eof, quoted;
1.36 cvs 4995: ThotBool ignoreMedia, media;
1.88 cvs 4996: ThotBool noRule, ignoreImport;
1.1 cvs 4997:
4998: CSScomment = MAX_CSS_LENGTH;
4999: HTMLcomment = FALSE;
5000: CSSindex = 0;
5001: toParse = FALSE;
5002: noRule = FALSE;
1.36 cvs 5003: media = FALSE;
1.88 cvs 5004: ignoreImport = FALSE;
1.1 cvs 5005: ignoreMedia = FALSE;
5006: import = MAX_CSS_LENGTH;
5007: eof = FALSE;
5008: openRule = 0;
1.82 cvs 5009: c = SPACE;
1.1 cvs 5010: index = 0;
1.134 vatton 5011: base = NULL;
1.135 vatton 5012: quoted = FALSE;
1.93 vatton 5013: /* number of new lines parsed */
5014: newlines = 0;
1.6 cvs 5015: /* avoid too many redisplay */
5016: dispMode = TtaGetDisplayMode (docRef);
5017: if (dispMode == DisplayImmediately)
5018: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 5019:
5020: /* look for the CSS context */
5021: if (css == NULL)
1.144 quint 5022: css = SearchCSS (docRef, NULL, styleElement);
1.18 cvs 5023: if (css == NULL)
1.144 quint 5024: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, NULL, NULL,
5025: styleElement);
1.145 quint 5026: if (css)
5027: css->refEl = refElement;
1.1 cvs 5028:
1.144 quint 5029: /* register parsed CSS file and the document to which CSS are to be applied*/
1.86 cvs 5030: ParsedDoc = docRef;
1.133 vatton 5031: if (url)
5032: DocURL = url;
1.86 cvs 5033: else
5034: /* the CSS source in within the document itself */
5035: DocURL = DocumentURLs[docRef];
5036: LineNumber = numberOfLinesRead + 1;
1.93 vatton 5037: NewLineSkipped = 0;
1.82 cvs 5038: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
5039: {
5040: c = buffer[index++];
5041: eof = (c == EOS);
5042: CSSbuffer[CSSindex] = c;
5043: if (CSScomment == MAX_CSS_LENGTH ||
5044: c == '*' || c == '/' || c == '<')
5045: {
5046: /* we're not within a comment or we're parsing * or / */
5047: switch (c)
5048: {
5049: case '@': /* perhaps an import primitive */
1.135 vatton 5050: if (!quoted)
5051: import = CSSindex;
1.82 cvs 5052: break;
5053: case ';':
1.135 vatton 5054: if (!quoted && !media && import != MAX_CSS_LENGTH)
1.82 cvs 5055: {
5056: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
5057: /* it's not an import */
5058: import = MAX_CSS_LENGTH;
5059: /* save the text */
5060: noRule = TRUE;
5061: }
5062: break;
5063: case '*':
1.135 vatton 5064: if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5065: CSSbuffer[CSSindex - 1] == '/')
5066: /* start a comment */
5067: CSScomment = CSSindex - 1;
5068: break;
5069: case '/':
1.135 vatton 5070: if (!quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.82 cvs 5071: CSSbuffer[CSSindex - 1] == '*')
5072: {
5073: /* close a comment:and ignore its contents */
5074: CSSindex = CSScomment - 1; /* will be incremented later */
5075: CSScomment = MAX_CSS_LENGTH;
1.93 vatton 5076: /* clean up the buffer */
1.103 vatton 5077: if (newlines && CSSindex > 0)
5078: while (CSSindex > 0 &&
5079: (CSSbuffer[CSSindex] == SPACE ||
5080: CSSbuffer[CSSindex] == BSPACE ||
5081: CSSbuffer[CSSindex] == EOL ||
5082: CSSbuffer[CSSindex] == TAB ||
5083: CSSbuffer[CSSindex] == __CR__))
1.93 vatton 5084: {
5085: if ( CSSbuffer[CSSindex] == EOL)
5086: {
5087: LineNumber ++;
5088: newlines --;
5089: }
5090: CSSindex--;
5091: }
1.82 cvs 5092: }
1.135 vatton 5093: else if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5094: CSSbuffer[CSSindex - 1] == '<')
5095: {
5096: /* this is the closing tag ! */
5097: CSSindex -= 2; /* remove </ from the CSS string */
5098: noRule = TRUE;
5099: }
5100: break;
5101: case '<':
1.135 vatton 5102: if (!quoted && CSScomment == MAX_CSS_LENGTH)
1.82 cvs 5103: {
5104: /* only if we're not parsing a comment */
5105: c = buffer[index++];
5106: eof = (c == EOS);
5107: if (c == '!')
5108: {
5109: /* CSS within an HTML comment */
5110: HTMLcomment = TRUE;
5111: CSSindex++;
5112: CSSbuffer[CSSindex] = c;
5113: }
5114: else if (c == EOS)
5115: CSSindex++;
5116: }
5117: break;
5118: case '-':
1.135 vatton 5119: if (!quoted && CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
1.82 cvs 5120: HTMLcomment)
5121: /* CSS within an HTML comment */
5122: noRule = TRUE;
5123: break;
5124: case '>':
1.135 vatton 5125: if (!quoted && HTMLcomment)
1.82 cvs 5126: noRule = TRUE;
5127: break;
5128: case ' ':
1.135 vatton 5129: if (!quoted && import != MAX_CSS_LENGTH && openRule == 0)
1.162 ! quint 5130: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
1.82 cvs 5131: break;
5132: case '{':
1.135 vatton 5133: if (!quoted)
1.82 cvs 5134: {
1.135 vatton 5135: openRule++;
5136: if (import != MAX_CSS_LENGTH && openRule == 1 && media)
5137: {
5138: /* is it the screen concerned? */
5139: CSSbuffer[CSSindex+1] = EOS;
5140: if (TtaIsPrinting ())
5141: base = strstr (&CSSbuffer[import], "print");
5142: else
5143: base = strstr (&CSSbuffer[import], "screen");
5144: if (base == NULL)
5145: base = strstr (&CSSbuffer[import], "all");
5146: if (base == NULL)
5147: ignoreMedia = TRUE;
5148: noRule = TRUE;
5149: }
5150: }
5151: break;
5152: case '}':
5153: if (!quoted)
5154: {
5155: openRule--;
5156: if (import != MAX_CSS_LENGTH && openRule == 0)
5157: {
5158: import = MAX_CSS_LENGTH;
5159: noRule = TRUE;
5160: ignoreMedia = FALSE;
5161: media = FALSE;
5162: }
1.82 cvs 5163: else
1.135 vatton 5164: toParse = TRUE;
1.82 cvs 5165: }
5166: break;
1.135 vatton 5167: case '"':
5168: if (quoted)
1.82 cvs 5169: {
1.135 vatton 5170: if (CSSbuffer[CSSindex - 1] != '\\')
5171: quoted = FALSE;
1.82 cvs 5172: }
5173: else
1.135 vatton 5174: quoted = TRUE;
1.82 cvs 5175: break;
5176: default:
1.86 cvs 5177: if (c == EOL)
1.93 vatton 5178: newlines++;
1.82 cvs 5179: break;
5180: }
5181: }
1.93 vatton 5182: else if (c == EOL)
5183: LineNumber++;
1.82 cvs 5184: if (c != CR)
5185: CSSindex++;
5186:
5187: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
5188: /* we're still parsing a comment: remove the text comment */
5189: CSSindex = CSScomment;
5190:
5191: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
5192: {
5193: CSSbuffer[CSSindex] = EOS;
5194: /* parse a not empty string */
5195: if (CSSindex > 0)
5196: {
1.50 cvs 5197: /* apply CSS rule if it's not just a saving of text */
5198: if (!noRule && !ignoreMedia)
1.88 cvs 5199: {
5200: /* future import rules must be ignored */
5201: ignoreImport = TRUE;
5202: ParseStyleDeclaration (NULL, CSSbuffer, docRef, css, FALSE);
1.93 vatton 5203: LineNumber += newlines;
5204: newlines = 0;
5205: NewLineSkipped = 0;
1.88 cvs 5206: }
1.82 cvs 5207: else if (import != MAX_CSS_LENGTH &&
5208: !strncasecmp (&CSSbuffer[import+1], "import", 6))
5209: {
5210: /* import section */
5211: cssRule = &CSSbuffer[import+7];
5212: cssRule = TtaSkipBlanks (cssRule);
1.93 vatton 5213: /* save the current line number */
5214: newlines += LineNumber;
1.82 cvs 5215: if (!strncasecmp (cssRule, "url", 3))
5216: {
1.50 cvs 5217: cssRule = &cssRule[3];
1.82 cvs 5218: cssRule = TtaSkipBlanks (cssRule);
5219: if (*cssRule == '(')
5220: {
5221: cssRule++;
5222: cssRule = TtaSkipBlanks (cssRule);
1.102 vatton 5223: quoted = (*cssRule == '"' || *cssRule == '\'');
5224: if (quoted)
5225: cssRule++;
1.82 cvs 5226: base = cssRule;
5227: while (*cssRule != EOS && *cssRule != ')')
5228: cssRule++;
1.102 vatton 5229: if (quoted)
1.160 vatton 5230: /* isolate the file name */
5231: cssRule[-1] = EOS;
5232: *cssRule = EOS;
1.82 cvs 5233: }
5234: }
1.87 cvs 5235: else if (*cssRule == '"')
5236: {
1.88 cvs 5237: /*
5238: Do we have to accept single quotes?
5239: Double quotes are acceted here.
5240: Escaped quotes are not handled. See function SkipQuotedString
5241: */
1.87 cvs 5242: cssRule++;
5243: cssRule = TtaSkipBlanks (cssRule);
5244: base = cssRule;
5245: while (*cssRule != EOS && *cssRule != '"')
5246: cssRule++;
1.160 vatton 5247: /* isolate the file name */
5248: *cssRule = EOS;
1.133 vatton 5249: }
5250: /* check if a media is defined */
5251: cssRule++;
5252: cssRule = TtaSkipBlanks (cssRule);
5253: if (*cssRule != ';')
5254: {
5255: if (TtaIsPrinting ())
5256: ignoreImport = (strncasecmp (cssRule, "print", 5) &&
5257: strncasecmp (cssRule, "all", 3));
5258: else
5259: ignoreImport = (strncasecmp (cssRule, "screen", 6) &&
5260: strncasecmp (cssRule, "all", 3));
5261: }
5262: if (!ignoreImport)
5263: {
5264: /* save the displayed URL when an error is reported */
5265: saveDocURL = DocURL;
1.138 vatton 5266: ptr = TtaStrdup (base);
5267: /* get the CSS URI in UTF-8 */
5268: ptr = ReallocUTF8String (ptr, docRef);
1.133 vatton 5269: LoadStyleSheet (base, docRef, NULL, css,
5270: css->media[docRef],
5271: css->category == CSS_USER_STYLE);
5272: /* restore the displayed URL when an error is reported */
5273: DocURL = saveDocURL;
1.138 vatton 5274: TtaFreeMemory (ptr);
1.82 cvs 5275: }
1.93 vatton 5276: /* restore the number of lines */
5277: LineNumber = newlines;
5278: newlines = 0;
1.82 cvs 5279: import = MAX_CSS_LENGTH;
5280: }
1.93 vatton 5281:
1.82 cvs 5282: }
5283: toParse = FALSE;
5284: noRule = FALSE;
5285: CSSindex = 0;
1.50 cvs 5286: }
1.82 cvs 5287: }
1.6 cvs 5288: /* restore the display mode */
5289: if (dispMode == DisplayImmediately)
1.82 cvs 5290: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 5291:
5292: /* Prepare the context for style attributes */
5293: DocURL = DocumentURLs[docRef];
5294: LineNumber = -1;
1.1 cvs 5295: return (c);
5296: }
1.89 cvs 5297:
Webmaster