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