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