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