Annotation of Amaya/amaya/styleparser.c, revision 1.215
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.214 quint 3734: char *valueStart;
1.18 cvs 3735: int lg;
1.34 cvs 3736: unsigned int i;
1.76 cvs 3737: ThotBool found;
1.18 cvs 3738:
1.34 cvs 3739: /* avoid too many redisplay */
1.207 vatton 3740: dispMode = TtaGetDisplayMode (ctxt->doc);
1.34 cvs 3741: if (dispMode == DisplayImmediately)
1.207 vatton 3742: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
1.34 cvs 3743:
1.82 cvs 3744: while (*cssRule != EOS)
1.18 cvs 3745: {
1.82 cvs 3746: cssRule = SkipBlanksAndComments (cssRule);
1.153 vatton 3747: if (*cssRule < 0x41 || *cssRule > 0x7A ||
1.133 vatton 3748: (*cssRule > 0x5A && *cssRule < 0x60))
1.153 vatton 3749: cssRule++;
1.194 vatton 3750: else if (*cssRule != EOS)
1.89 cvs 3751: {
1.153 vatton 3752: found = FALSE;
3753: /* look for the type of property */
3754: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
1.18 cvs 3755: {
1.153 vatton 3756: lg = strlen (CSSProperties[i].name);
3757: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
3758: {
3759: p = cssRule + lg;
3760: found = TRUE;
3761: i--;
3762: }
1.18 cvs 3763: }
1.153 vatton 3764: if (i == NB_CSSSTYLEATTRIBUTE)
3765: cssRule = SkipProperty (cssRule);
3766: else
1.18 cvs 3767: {
1.153 vatton 3768: /* update index and skip the ":" indicator if present */
1.86 cvs 3769: p = SkipBlanksAndComments (p);
1.153 vatton 3770: if (*p == ':')
1.61 cvs 3771: {
1.153 vatton 3772: p++;
3773: p = SkipBlanksAndComments (p);
3774: /* try to parse the value associated with this property */
3775: if (CSSProperties[i].parsing_function != NULL)
3776: {
1.214 quint 3777: valueStart = p;
3778: p = CSSProperties[i].parsing_function (element, tsch,
3779: ctxt, p, css, isHTML);
3780: if (!element && isHTML)
3781: {
3782: if (ctxt->type == HTML_EL_Input)
3783: /* it's a generic rule for the HTML element input.
3784: Generate a Thot Pres rule for each kind of
3785: input element */
3786: {
3787: ctxt->type = HTML_EL_Text_Input;
3788: p = CSSProperties[i].parsing_function (element,
3789: tsch, ctxt, valueStart, css, isHTML);
3790: ctxt->type = HTML_EL_Password_Input;
3791: p = CSSProperties[i].parsing_function (element,
3792: tsch, ctxt, valueStart, css, isHTML);
3793: ctxt->type = HTML_EL_File_Input;
3794: p = CSSProperties[i].parsing_function (element,
3795: tsch, ctxt, valueStart, css, isHTML);
3796: ctxt->type = HTML_EL_Checkbox_Input;
3797: p = CSSProperties[i].parsing_function (element,
3798: tsch, ctxt, valueStart, css, isHTML);
3799: ctxt->type = HTML_EL_Radio_Input;
3800: p = CSSProperties[i].parsing_function (element,
3801: tsch, ctxt, valueStart, css, isHTML);
3802: ctxt->type = HTML_EL_Submit_Input;
3803: p = CSSProperties[i].parsing_function (element,
3804: tsch, ctxt, valueStart, css, isHTML);
3805: ctxt->type = HTML_EL_Reset_Input;
3806: p = CSSProperties[i].parsing_function (element,
3807: tsch, ctxt, valueStart, css, isHTML);
3808: ctxt->type = HTML_EL_Button_Input;
3809: p = CSSProperties[i].parsing_function (element,
3810: tsch, ctxt, valueStart, css, isHTML);
3811: ctxt->type = HTML_EL_Input;
3812: }
3813: else if (ctxt->type == HTML_EL_ruby)
3814: /* it's a generic rule for the HTML element ruby.
3815: Generate a Thot Pres rule for each kind of
3816: ruby element. */
3817: {
3818: ctxt->type = HTML_EL_simple_ruby;
3819: p = CSSProperties[i].parsing_function (element,
3820: tsch, ctxt, valueStart, css, isHTML);
3821: ctxt->type = HTML_EL_complex_ruby;
3822: p = CSSProperties[i].parsing_function (element,
3823: tsch, ctxt, valueStart, css, isHTML);
3824: ctxt->type = HTML_EL_ruby;
3825: }
3826: }
1.153 vatton 3827: /* update index and skip the ";" separator if present */
3828: cssRule = p;
3829: }
1.61 cvs 3830: }
1.153 vatton 3831: else
3832: cssRule = SkipProperty (cssRule);
1.18 cvs 3833: }
3834: }
3835: /* next property */
1.82 cvs 3836: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 3837: if (*cssRule == '}')
3838: {
3839: cssRule++;
1.168 vatton 3840: CSSPrintError ("Invalid character", "}");
1.89 cvs 3841: cssRule = SkipBlanksAndComments (cssRule);
3842: }
1.155 cheyroul 3843: if (*cssRule == ',' ||
3844: *cssRule == ';')
1.18 cvs 3845: {
3846: cssRule++;
1.82 cvs 3847: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3848: }
3849: }
1.34 cvs 3850:
3851: /* restore the display mode */
3852: if (dispMode == DisplayImmediately)
1.207 vatton 3853: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 3854: }
1.1 cvs 3855:
1.111 cvs 3856: /*----------------------------------------------------------------------
3857: AddBorderStyleValue
3858: -----------------------------------------------------------------------*/
3859: static void AddBorderStyleValue (char *buffer, int value)
3860: {
3861: switch (value)
3862: {
1.184 vatton 3863: case BorderStyleNone:
1.111 cvs 3864: strcat (buffer, "none");
3865: break;
1.184 vatton 3866: case BorderStyleHidden:
1.111 cvs 3867: strcat (buffer, "hidden");
3868: break;
1.184 vatton 3869: case BorderStyleDotted:
1.111 cvs 3870: strcat (buffer, "dotted");
3871: break;
1.184 vatton 3872: case BorderStyleDashed:
1.111 cvs 3873: strcat (buffer, "dashed");
3874: break;
1.184 vatton 3875: case BorderStyleSolid:
1.111 cvs 3876: strcat (buffer, "solid");
3877: break;
1.184 vatton 3878: case BorderStyleDouble:
1.111 cvs 3879: strcat (buffer, "double");
3880: break;
1.184 vatton 3881: case BorderStyleGroove:
1.111 cvs 3882: strcat (buffer, "groove");
3883: break;
1.184 vatton 3884: case BorderStyleRidge:
1.111 cvs 3885: strcat (buffer, "ridge");
3886: break;
1.184 vatton 3887: case BorderStyleInset:
1.111 cvs 3888: strcat (buffer, "inset");
3889: break;
1.184 vatton 3890: case BorderStyleOutset:
1.111 cvs 3891: strcat (buffer, "outset");
3892: break;
3893: }
3894: }
1.1 cvs 3895:
3896: /*----------------------------------------------------------------------
1.59 cvs 3897: PToCss: translate a PresentationSetting to the
1.18 cvs 3898: equivalent CSS string, and add it to the buffer given as the
1.67 cvs 3899: argument. It is used when extracting the CSS string from actual
3900: presentation.
3901: el is the element for which the style rule is generated
1.18 cvs 3902:
3903: All the possible values returned by the presentation drivers are
3904: described in thotlib/include/presentation.h
3905: -----------------------------------------------------------------------*/
1.79 cvs 3906: void PToCss (PresentationSetting settings, char *buffer, int len, Element el)
1.1 cvs 3907: {
1.76 cvs 3908: ElementType elType;
1.18 cvs 3909: float fval = 0;
3910: unsigned short red, green, blue;
3911: int add_unit = 0;
3912: unsigned int unit, i;
3913: ThotBool real = FALSE;
3914:
1.82 cvs 3915: buffer[0] = EOS;
1.18 cvs 3916: if (len < 40)
3917: return;
3918:
3919: unit = settings->value.typed_data.unit;
3920: if (settings->value.typed_data.real)
3921: {
3922: real = TRUE;
3923: fval = (float) settings->value.typed_data.value;
1.195 vatton 3924: fval /= 1000.;
1.18 cvs 3925: }
1.1 cvs 3926:
1.18 cvs 3927: switch (settings->type)
1.1 cvs 3928: {
1.18 cvs 3929: case PRVisibility:
3930: break;
1.111 cvs 3931: case PRHeight:
3932: if (real)
3933: sprintf (buffer, "height: %g", fval);
3934: else
3935: sprintf (buffer, "height: %d", settings->value.typed_data.value);
3936: add_unit = 1;
3937: break;
3938: case PRWidth:
3939: if (real)
3940: sprintf (buffer, "width: %g", fval);
3941: else
3942: sprintf (buffer, "width: %d", settings->value.typed_data.value);
3943: add_unit = 1;
3944: break;
3945: case PRMarginTop:
3946: if (real)
3947: sprintf (buffer, "margin-top: %g", fval);
3948: else
3949: sprintf (buffer, "margin-top: %d",settings->value.typed_data.value);
3950: add_unit = 1;
3951: break;
3952: case PRMarginBottom:
3953: if (real)
3954: sprintf (buffer, "margin-bottom: %g", fval);
3955: else
3956: sprintf (buffer, "margin-bottom: %d",
3957: settings->value.typed_data.value);
3958: add_unit = 1;
3959: break;
3960: case PRMarginLeft:
3961: if (real)
3962: sprintf (buffer, "margin-left: %g", fval);
3963: else
1.164 quint 3964: sprintf (buffer, "margin-left: %d", settings->value.typed_data.value);
1.111 cvs 3965: add_unit = 1;
3966: break;
3967: case PRMarginRight:
3968: if (real)
3969: sprintf (buffer, "margin-right: %g", fval);
3970: else
1.164 quint 3971: sprintf (buffer, "margin-right: %d", settings->value.typed_data.value);
1.111 cvs 3972: add_unit = 1;
3973: break;
3974: case PRPaddingTop:
3975: if (real)
3976: sprintf (buffer, "padding-top: %g", fval);
3977: else
1.164 quint 3978: sprintf (buffer, "padding-top: %d", settings->value.typed_data.value);
1.111 cvs 3979: add_unit = 1;
3980: break;
3981: case PRPaddingBottom:
3982: if (real)
3983: sprintf (buffer, "padding-bottom: %g", fval);
3984: else
3985: sprintf (buffer, "padding-bottom: %d",
3986: settings->value.typed_data.value);
3987: add_unit = 1;
3988: break;
3989: case PRPaddingLeft:
3990: if (real)
3991: sprintf (buffer, "padding-left: %g", fval);
3992: else
1.164 quint 3993: sprintf (buffer, "padding-left: %d", settings->value.typed_data.value);
1.111 cvs 3994: add_unit = 1;
3995: break;
3996: case PRPaddingRight:
3997: if (real)
3998: sprintf (buffer, "padding-right: %g", fval);
3999: else
4000: sprintf (buffer, "padding-right: %d",
4001: settings->value.typed_data.value);
4002: add_unit = 1;
4003: break;
4004: case PRBorderTopWidth:
4005: if (real)
4006: sprintf (buffer, "border-top-width: %g", fval);
4007: else
4008: sprintf (buffer, "border-top-width: %d",
4009: settings->value.typed_data.value);
4010: add_unit = 1;
4011: break;
4012: case PRBorderBottomWidth:
4013: if (real)
4014: sprintf (buffer, "border-bottom-width: %g", fval);
4015: else
4016: sprintf (buffer, "border-bottom-width: %d",
4017: settings->value.typed_data.value);
4018: add_unit = 1;
4019: break;
4020: case PRBorderLeftWidth:
4021: if (real)
4022: sprintf (buffer, "border-left-width: %g", fval);
4023: else
4024: sprintf (buffer, "border-left-width: %d",
4025: settings->value.typed_data.value);
4026: add_unit = 1;
4027: break;
4028: case PRBorderRightWidth:
4029: if (real)
4030: sprintf (buffer, "border-right-width: %g", fval);
4031: else
4032: sprintf (buffer, "border-right-width: %d",
4033: settings->value.typed_data.value);
4034: add_unit = 1;
4035: break;
4036: case PRBorderTopColor:
4037: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4038: elType = TtaGetElementType(el);
4039: sprintf (buffer, "border-top-color: #%02X%02X%02X", red, green, blue);
4040: break;
4041: case PRBorderRightColor:
4042: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4043: elType = TtaGetElementType(el);
4044: sprintf (buffer, "border-right-color: #%02X%02X%02X", red, green, blue);
4045: break;
4046: case PRBorderBottomColor:
4047: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4048: elType = TtaGetElementType(el);
4049: sprintf (buffer, "border-bottom-color: #%02X%02X%02X", red, green, blue);
1.18 cvs 4050: break;
1.111 cvs 4051: case PRBorderLeftColor:
4052: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4053: elType = TtaGetElementType(el);
4054: sprintf (buffer, "border-left-color: #%02X%02X%02X", red, green, blue);
1.20 cvs 4055: break;
1.111 cvs 4056: case PRBorderTopStyle:
4057: strcpy (buffer, "border-top-style: ");
4058: AddBorderStyleValue (buffer, settings->value.typed_data.value);
4059: break;
4060: case PRBorderRightStyle:
4061: strcpy (buffer, "border-right-style: ");
4062: AddBorderStyleValue (buffer, settings->value.typed_data.value);
4063: break;
4064: case PRBorderBottomStyle:
4065: strcpy (buffer, "border-bottom-style: ");
4066: AddBorderStyleValue (buffer, settings->value.typed_data.value);
4067: break;
4068: case PRBorderLeftStyle:
4069: strcpy (buffer, "border-left-style: ");
4070: AddBorderStyleValue (buffer, settings->value.typed_data.value);
1.18 cvs 4071: break;
4072: case PRSize:
1.184 vatton 4073: if (unit == UNIT_REL)
1.18 cvs 4074: {
4075: if (real)
4076: {
1.82 cvs 4077: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 4078: add_unit = 1;
4079: }
4080: else
4081: switch (settings->value.typed_data.value)
4082: {
4083: case 1:
1.82 cvs 4084: strcpy (buffer, "font-size: xx-small");
1.18 cvs 4085: break;
4086: case 2:
1.82 cvs 4087: strcpy (buffer, "font-size: x-small");
1.18 cvs 4088: break;
4089: case 3:
1.82 cvs 4090: strcpy (buffer, "font-size: small");
1.18 cvs 4091: break;
4092: case 4:
1.82 cvs 4093: strcpy (buffer, "font-size: medium");
1.18 cvs 4094: break;
4095: case 5:
1.82 cvs 4096: strcpy (buffer, "font-size: large");
1.18 cvs 4097: break;
4098: case 6:
1.82 cvs 4099: strcpy (buffer, "font-size: x-large");
1.18 cvs 4100: break;
4101: case 7:
4102: case 8:
4103: case 9:
4104: case 10:
4105: case 11:
4106: case 12:
1.82 cvs 4107: strcpy (buffer, "font-size: xx-large");
1.18 cvs 4108: break;
4109: }
4110: }
4111: else
4112: {
4113: if (real)
1.82 cvs 4114: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 4115: else
1.82 cvs 4116: sprintf (buffer, "font-size: %d",
1.67 cvs 4117: settings->value.typed_data.value);
1.18 cvs 4118: add_unit = 1;
4119: }
4120: break;
1.111 cvs 4121: case PRStyle:
4122: switch (settings->value.typed_data.value)
4123: {
1.184 vatton 4124: case StyleRoman:
1.111 cvs 4125: strcpy (buffer, "font-style: normal");
4126: break;
1.184 vatton 4127: case StyleItalics:
1.111 cvs 4128: strcpy (buffer, "font-style: italic");
4129: break;
1.184 vatton 4130: case StyleOblique:
1.111 cvs 4131: strcpy (buffer, "font-style: oblique");
4132: break;
4133: }
4134: break;
4135: case PRWeight:
4136: switch (settings->value.typed_data.value)
4137: {
1.184 vatton 4138: case WeightBold:
1.111 cvs 4139: strcpy (buffer, "font-weight: bold");
4140: break;
1.184 vatton 4141: case WeightNormal:
1.111 cvs 4142: strcpy (buffer, "font-weight: normal");
4143: break;
4144: }
4145: break;
4146: case PRFont:
4147: switch (settings->value.typed_data.value)
4148: {
1.184 vatton 4149: case FontHelvetica:
1.111 cvs 4150: strcpy (buffer, "font-family: helvetica");
4151: break;
1.184 vatton 4152: case FontTimes:
1.111 cvs 4153: strcpy (buffer, "font-family: times");
4154: break;
1.184 vatton 4155: case FontCourier:
1.111 cvs 4156: strcpy (buffer, "font-family: courier");
4157: break;
4158: }
4159: break;
1.18 cvs 4160: case PRUnderline:
4161: switch (settings->value.typed_data.value)
4162: {
1.184 vatton 4163: case Underline:
1.82 cvs 4164: strcpy (buffer, "text-decoration: underline");
1.18 cvs 4165: break;
1.184 vatton 4166: case Overline:
1.82 cvs 4167: strcpy (buffer, "text-decoration: overline");
1.18 cvs 4168: break;
1.184 vatton 4169: case CrossOut:
1.82 cvs 4170: strcpy (buffer, "text-decoration: line-through");
1.18 cvs 4171: break;
4172: }
4173: break;
1.111 cvs 4174: case PRThickness:
4175: break;
1.18 cvs 4176: case PRIndent:
4177: if (real)
1.82 cvs 4178: sprintf (buffer, "text-indent: %g", fval);
1.18 cvs 4179: else
1.82 cvs 4180: sprintf (buffer, "text-indent: %d",
1.67 cvs 4181: settings->value.typed_data.value);
1.18 cvs 4182: add_unit = 1;
4183: break;
4184: case PRLineSpacing:
4185: if (real)
1.82 cvs 4186: sprintf (buffer, "line-height: %g", fval);
1.1 cvs 4187: else
1.82 cvs 4188: sprintf (buffer, "line-height: %d",
1.67 cvs 4189: settings->value.typed_data.value);
1.18 cvs 4190: add_unit = 1;
4191: break;
1.111 cvs 4192: case PRDepth:
4193: break;
1.18 cvs 4194: case PRAdjust:
4195: switch (settings->value.typed_data.value)
1.1 cvs 4196: {
1.184 vatton 4197: case AdjustLeft:
1.82 cvs 4198: strcpy (buffer, "text-align: left");
1.18 cvs 4199: break;
1.184 vatton 4200: case AdjustRight:
1.82 cvs 4201: strcpy (buffer, "text-align: right");
1.18 cvs 4202: break;
1.184 vatton 4203: case Centered:
1.82 cvs 4204: strcpy (buffer, "text-align: center");
1.18 cvs 4205: break;
1.184 vatton 4206: case LeftWithDots:
1.82 cvs 4207: strcpy (buffer, "text-align: left");
1.81 cvs 4208: break;
1.184 vatton 4209: case Justify:
1.82 cvs 4210: strcpy (buffer, "text-align: justify");
1.112 quint 4211: break;
4212: }
4213: break;
4214: case PRDirection:
4215: switch (settings->value.typed_data.value)
4216: {
1.184 vatton 4217: case LeftToRight:
1.112 quint 4218: strcpy (buffer, "direction: ltr");
4219: break;
1.184 vatton 4220: case RightToLeft:
1.112 quint 4221: strcpy (buffer, "direction: rtl");
1.113 quint 4222: break;
4223: }
4224: break;
4225: case PRUnicodeBidi:
4226: switch (settings->value.typed_data.value)
4227: {
1.184 vatton 4228: case Normal:
1.113 quint 4229: strcpy (buffer, "unicode-bidi: normal");
4230: break;
1.184 vatton 4231: case Embed:
1.113 quint 4232: strcpy (buffer, "unicode-bidi: embed");
4233: break;
1.184 vatton 4234: case Override:
1.113 quint 4235: strcpy (buffer, "unicode-bidi: bidi-override");
1.18 cvs 4236: break;
1.1 cvs 4237: }
1.18 cvs 4238: break;
1.111 cvs 4239: case PRLineStyle:
4240: break;
1.126 vatton 4241: case PRDisplay:
4242: switch (settings->value.typed_data.value)
4243: {
1.184 vatton 4244: case Inline:
1.126 vatton 4245: strcpy (buffer, "display: inline");
4246: break;
1.184 vatton 4247: case Block:
1.126 vatton 4248: strcpy (buffer, "display: block");
4249: break;
1.184 vatton 4250: case ListItem:
1.126 vatton 4251: strcpy (buffer, "display: list-item");
4252: break;
1.184 vatton 4253: case RunIn:
1.126 vatton 4254: strcpy (buffer, "display: runin");
4255: break;
1.184 vatton 4256: case Compact:
1.126 vatton 4257: strcpy (buffer, "display: compact");
4258: break;
1.184 vatton 4259: case Marker:
1.126 vatton 4260: strcpy (buffer, "display: marker");
1.196 vatton 4261: break;
4262: default:
4263: break;
4264: }
4265: break;
4266: case PRFloat:
4267: switch (settings->value.typed_data.value)
4268: {
4269: case FloatNone:
4270: strcpy (buffer, "float: none");
4271: break;
4272: case FloatLeft:
4273: strcpy (buffer, "float: left");
4274: break;
4275: case FloatRight:
4276: strcpy (buffer, "float: right");
4277: break;
4278: default:
4279: break;
4280: }
4281: break;
4282: case PRClear:
4283: switch (settings->value.typed_data.value)
4284: {
4285: case ClearNone:
4286: strcpy (buffer, "clear: none");
4287: break;
4288: case ClearLeft:
4289: strcpy (buffer, "clear: left");
4290: break;
4291: case ClearRight:
4292: strcpy (buffer, "clear: right");
4293: break;
4294: case ClearBoth:
4295: strcpy (buffer, "clear: both");
1.126 vatton 4296: break;
4297: default:
4298: break;
4299: }
4300: break;
1.111 cvs 4301: case PRLineWeight:
4302: elType = TtaGetElementType(el);
4303: #ifdef _SVG
4304: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
4305: #endif /* _SVG */
4306: {
4307: if (real)
4308: sprintf (buffer, "stroke-width: %g", fval);
4309: else
4310: sprintf (buffer, "stroke-width: %d",
4311: settings->value.typed_data.value);
4312: }
4313: add_unit = 1;
1.18 cvs 4314: break;
4315: case PRFillPattern:
4316: break;
4317: case PRBackground:
4318: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 4319: elType = TtaGetElementType(el);
1.100 vatton 4320: #ifdef _SVG
4321: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 4322: sprintf (buffer, "fill: #%02X%02X%02X", red, green, blue);
1.67 cvs 4323: else
1.100 vatton 4324: #endif /* _SVG */
1.82 cvs 4325: sprintf (buffer, "background-color: #%02X%02X%02X", red, green,
1.67 cvs 4326: blue);
1.18 cvs 4327: break;
4328: case PRForeground:
4329: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 4330: elType = TtaGetElementType(el);
1.100 vatton 4331: #ifdef _SVG
4332: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 4333: sprintf (buffer, "stroke: #%02X%02X%02X", red, green, blue);
1.67 cvs 4334: else
1.100 vatton 4335: #endif /* _SVG */
1.82 cvs 4336: sprintf (buffer, "color: #%02X%02X%02X", red, green, blue);
1.67 cvs 4337: break;
1.111 cvs 4338: case PRHyphenate:
1.195 vatton 4339: case PRVertOverflow:
4340: case PRHorizOverflow:
4341: break;
4342: case PROpacity:
4343: sprintf (buffer, "opacity: %g", fval);
1.18 cvs 4344: break;
1.195 vatton 4345: case PRStrokeOpacity:
4346: sprintf (buffer, "stroke-opacity: %g", fval);
1.18 cvs 4347: break;
1.195 vatton 4348: case PRFillOpacity:
4349: sprintf (buffer, "fill-opacity: %g", fval);
1.18 cvs 4350: break;
4351: case PRBackgroundPicture:
4352: if (settings->value.pointer != NULL)
1.82 cvs 4353: sprintf (buffer, "background-image: url(%s)",
1.67 cvs 4354: (char*)(settings->value.pointer));
1.1 cvs 4355: else
1.82 cvs 4356: sprintf (buffer, "background-image: none");
1.18 cvs 4357: break;
4358: case PRPictureMode:
4359: switch (settings->value.typed_data.value)
1.1 cvs 4360: {
1.184 vatton 4361: case REALSIZE:
1.82 cvs 4362: sprintf (buffer, "background-repeat: no-repeat");
1.18 cvs 4363: break;
1.184 vatton 4364: case REPEAT:
1.82 cvs 4365: sprintf (buffer, "background-repeat: repeat");
1.18 cvs 4366: break;
1.184 vatton 4367: case VREPEAT:
1.82 cvs 4368: sprintf (buffer, "background-repeat: repeat-y");
1.18 cvs 4369: break;
1.184 vatton 4370: case HREPEAT:
1.82 cvs 4371: sprintf (buffer, "background-repeat: repeat-x");
1.18 cvs 4372: break;
1.1 cvs 4373: }
1.18 cvs 4374: break;
4375: default:
4376: break;
1.1 cvs 4377: }
4378:
1.18 cvs 4379: if (add_unit)
1.1 cvs 4380: {
1.18 cvs 4381: /* add the unit string to the CSS string */
4382: for (i = 0; i < NB_UNITS; i++)
1.1 cvs 4383: {
1.18 cvs 4384: if (CSSUnitNames[i].unit == unit)
1.1 cvs 4385: {
1.82 cvs 4386: strcat (buffer, CSSUnitNames[i].sign);
1.18 cvs 4387: break;
1.1 cvs 4388: }
4389: }
4390: }
4391: }
4392:
4393: /*----------------------------------------------------------------------
1.59 cvs 4394: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18 cvs 4395: This function must be called when a specific style is applied to an
4396: element.
1.114 quint 4397: The parameter specificity is the specificity of the style, 0 if it is
4398: not really a CSS rule.
1.1 cvs 4399: ----------------------------------------------------------------------*/
1.79 cvs 4400: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.114 quint 4401: int specificity, ThotBool destroy)
1.1 cvs 4402: {
1.207 vatton 4403: PresentationContext ctxt;
4404: ElementType elType;
4405: ThotBool isHTML;
1.1 cvs 4406:
1.207 vatton 4407: /* A rule applying to BODY is really meant to address HTML */
4408: elType = TtaGetElementType (el);
1.89 cvs 4409:
1.207 vatton 4410: /* store the current line for eventually reported errors */
4411: LineNumber = TtaGetElementLineNumber (el);
4412: if (destroy)
4413: /* no reported errors */
4414: ParsedDoc = 0;
4415: else if (ParsedDoc != doc)
4416: {
4417: /* update the context for reported errors */
4418: ParsedDoc = doc;
4419: DocURL = DocumentURLs[doc];
4420: }
4421: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
4422: /* create the context of the Specific presentation driver */
4423: ctxt = TtaGetSpecificStyleContext (doc);
4424: if (ctxt == NULL)
4425: return;
4426: ctxt->type = elType.ElTypeNum;
4427: ctxt->cssSpecificity = specificity;
4428: ctxt->destroy = destroy;
4429: /* first use of the context */
4430: ctxt->uses = 1;
4431: /* Call the parser */
4432: ParseCSSRule (el, NULL, (PresentationContext) ctxt, cssRule, NULL, isHTML);
4433: /* check if the context can be freed */
4434: ctxt->uses -= 1;
4435: if (ctxt->uses == 0)
4436: /* no image loading */
4437: TtaFreeMemory(ctxt);
1.1 cvs 4438: }
4439:
1.68 cvs 4440:
1.1 cvs 4441: /*----------------------------------------------------------------------
1.207 vatton 4442: ParseGenericSelector: Create a generic context for a given selector
4443: string.
4444: If the selector is made of multiple comma, it parses them one at a time
4445: and return the end of the selector string to be handled or NULL.
1.1 cvs 4446: ----------------------------------------------------------------------*/
1.207 vatton 4447: static char *ParseGenericSelector (char *selector, char *cssRule,
1.79 cvs 4448: GenericContext ctxt, Document doc,
1.206 vatton 4449: CSSInfoPtr css, Element link)
1.79 cvs 4450: {
4451: ElementType elType;
4452: PSchema tsch;
1.119 vatton 4453: AttributeType attrType;
1.207 vatton 4454: char *deb, *cur, *sel, c;
1.118 vatton 4455: char *schemaName, *mappedName;
1.79 cvs 4456: char *names[MAX_ANCESTORS];
4457: char *ids[MAX_ANCESTORS];
4458: char *classes[MAX_ANCESTORS];
4459: char *pseudoclasses[MAX_ANCESTORS];
4460: char *attrs[MAX_ANCESTORS];
4461: char *attrvals[MAX_ANCESTORS];
1.133 vatton 4462: AttrMatch attrmatch[MAX_ANCESTORS];
1.91 cvs 4463: int i, j, k, max;
1.125 vatton 4464: int att, maxAttr, kind;
1.118 vatton 4465: int specificity, xmlType;
1.79 cvs 4466: ThotBool isHTML;
1.183 vatton 4467: ThotBool level, quoted;
1.1 cvs 4468:
1.207 vatton 4469: sel = ctxt->sel;
1.82 cvs 4470: sel[0] = EOS;
1.117 vatton 4471: specificity = 0;
1.1 cvs 4472: for (i = 0; i < MAX_ANCESTORS; i++)
4473: {
1.25 cvs 4474: names[i] = NULL;
4475: ids[i] = NULL;
4476: classes[i] = NULL;
4477: pseudoclasses[i] = NULL;
4478: attrs[i] = NULL;
4479: attrvals[i] = NULL;
1.133 vatton 4480: attrmatch[i] = Txtmatch;
1.25 cvs 4481: ctxt->name[i] = 0;
4482: ctxt->names_nb[i] = 0;
4483: ctxt->attrType[i] = 0;
1.129 vatton 4484: ctxt->attrLevel[i] = 0;
1.25 cvs 4485: ctxt->attrText[i] = NULL;
1.178 quint 4486: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 4487: }
1.25 cvs 4488: ctxt->box = 0;
4489: ctxt->type = 0;
1.114 quint 4490: /* the specificity of the rule depends on the selector */
4491: ctxt->cssSpecificity = 0;
1.25 cvs 4492:
1.82 cvs 4493: selector = SkipBlanksAndComments (selector);
1.27 cvs 4494: cur = &sel[0];
1.25 cvs 4495: max = 0; /* number of loops */
1.1 cvs 4496: while (1)
4497: {
1.85 cvs 4498: /* point to the following word in sel[] */
1.27 cvs 4499: deb = cur;
1.25 cvs 4500: /* copy an item of the selector into sel[] */
1.1 cvs 4501: /* put one word in the sel buffer */
1.82 cvs 4502: while (*selector != EOS && *selector != ',' &&
4503: *selector != '.' && *selector != ':' &&
1.118 vatton 4504: *selector != '#' && *selector != '[' &&
1.130 vatton 4505: *selector != '*' && *selector != '>' &&
1.118 vatton 4506: !TtaIsBlank (selector))
1.50 cvs 4507: *cur++ = *selector++;
1.82 cvs 4508: *cur++ = EOS; /* close the first string in sel[] */
4509: if (deb[0] != EOS)
1.117 vatton 4510: {
4511: names[0] = deb;
1.150 vatton 4512: if (!strcmp (names[0], "html"))
1.149 vatton 4513: /* give a greater priority to the backgoud color of html */
4514: specificity += 3;
4515: else
4516: specificity += 1;
1.117 vatton 4517: }
1.25 cvs 4518: else
1.27 cvs 4519: names[0] = NULL;
4520: classes[0] = NULL;
4521: pseudoclasses[0] = NULL;
4522: ids[0] = NULL;
4523: attrs[0] = NULL;
4524: attrvals[0] = NULL;
1.25 cvs 4525:
1.27 cvs 4526: /* now names[0] points to the beginning of the parsed item
1.25 cvs 4527: and cur to the next chain to be parsed */
1.129 vatton 4528: while (*selector == '.' || *selector == ':' ||
1.130 vatton 4529: *selector == '#' || *selector == '[' ||
1.183 vatton 4530: *selector == '*')
1.129 vatton 4531: {
1.85 cvs 4532: /* point to the following word in sel[] */
4533: deb = cur;
1.202 vatton 4534: if (*selector == '*' &&
4535: (selector[1] == '.' || selector[1] == ':' ||
4536: selector[1] == '#' || selector[1] == '['))
4537: selector++;
1.129 vatton 4538: if (*selector == '.')
4539: {
4540: selector++;
4541: while (*selector != EOS && *selector != ',' &&
4542: *selector != '.' && *selector != ':' &&
4543: !TtaIsBlank (selector))
4544: *cur++ = *selector++;
4545: /* close the word */
4546: *cur++ = EOS;
4547: /* point to the class in sel[] if it's valid name */
4548: if (deb[0] <= 64)
4549: {
1.168 vatton 4550: CSSPrintError ("Invalid class", deb);
1.116 vatton 4551: DoApply = FALSE;
1.129 vatton 4552: }
4553: else
4554: {
4555: classes[0] = deb;
1.178 quint 4556: /* a "class" attribute on an element may contain several
4557: words, one for each class it matches */
4558: attrmatch[0] = Txtword;
1.117 vatton 4559: specificity += 10;
1.129 vatton 4560: }
4561: }
4562: else if (*selector == ':')
4563: {
4564: selector++;
4565: while (*selector != EOS && *selector != ',' &&
4566: *selector != '.' && *selector != ':' &&
4567: !TtaIsBlank (selector))
4568: *cur++ = *selector++;
4569: /* close the word */
4570: *cur++ = EOS;
4571: /* point to the pseudoclass in sel[] if it's valid name */
4572: if (deb[0] <= 64)
4573: {
1.168 vatton 4574: CSSPrintError ("Invalid pseudoclass", deb);
1.129 vatton 4575: DoApply = FALSE;
4576: }
4577: else
4578: {
4579: if (!strcmp (deb, "first-letter") ||
4580: !strcmp (deb, "first-line") ||
4581: !strcmp (deb, "before") ||
4582: !strcmp (deb, "after"))
4583: /* not supported */
1.116 vatton 4584: DoApply = FALSE;
1.129 vatton 4585: else
4586: specificity += 10;
4587: pseudoclasses[0]= deb;
4588: }
4589: }
4590: else if (*selector == '#')
4591: {
4592: selector++;
4593: while (*selector != EOS && *selector != ',' &&
4594: *selector != '.' && *selector != ':' &&
4595: !TtaIsBlank (selector))
4596: *cur++ = *selector++;
4597: /* close the word */
4598: *cur++ = EOS;
4599: /* point to the attribute in sel[] if it's valid name */
4600: if (deb[0] <= 64)
4601: {
1.168 vatton 4602: CSSPrintError ("Invalid id", deb);
1.129 vatton 4603: DoApply = FALSE;
4604: }
4605: else
4606: {
4607: ids[0] = deb;
4608: specificity += 100;
4609: }
4610: }
4611: else if (*selector == '[')
4612: {
1.118 vatton 4613: selector++;
1.129 vatton 4614: while (*selector != EOS && *selector != ']' &&
1.131 vatton 4615: *selector != '=' && *selector != '~' &&
1.133 vatton 4616: *selector != '|' && *selector != '^' &&
4617: *selector != '!')
1.129 vatton 4618: *cur++ = *selector++;
1.133 vatton 4619: /* check matching */
4620: if (*selector == '~')
4621: {
4622: attrmatch[0] = Txtword;
4623: selector++;
4624: }
4625: else if (*selector == '|')
4626: {
4627: attrmatch[0] = Txtsubstring;
4628: selector++;
4629: }
4630: else
4631: attrmatch[0] = Txtmatch;
1.129 vatton 4632: /* close the word */
4633: *cur++ = EOS;
4634: /* point to the attribute in sel[] if it's valid name */
4635: if (deb[0] <= 64)
4636: {
1.168 vatton 4637: CSSPrintError ("Invalid attribute", deb);
1.129 vatton 4638: DoApply = FALSE;
4639: }
4640: else
4641: {
4642: attrs[0] = deb;
4643: specificity += 10;
4644: }
4645: if (*selector == '=')
4646: {
4647: /* look for a value "xxxx" */
4648: selector++;
4649: if (*selector != '"')
1.183 vatton 4650: quoted = FALSE;
1.129 vatton 4651: else
4652: {
1.183 vatton 4653: quoted = TRUE;
1.129 vatton 4654: /* we are now parsing the attribute value */
4655: selector++;
1.183 vatton 4656: }
4657: deb = cur;
4658: while ((quoted &&
4659: (*selector != '"' ||
4660: (*selector == '"' && selector[-1] == '\\'))) ||
4661: (!quoted && *selector != ']'))
4662: {
4663: if (*selector == EOS)
1.129 vatton 4664: {
1.183 vatton 4665: CSSPrintError ("Invalid attribute value", deb);
4666: DoApply = FALSE;
1.129 vatton 4667: }
1.183 vatton 4668: else
1.129 vatton 4669: {
1.183 vatton 4670: *cur++ = tolower (*selector);
1.129 vatton 4671: selector++;
4672: }
4673: }
1.183 vatton 4674: /* there is a value */
1.204 quint 4675: if (quoted && *selector == '"')
1.183 vatton 4676: {
4677: selector++;
4678: quoted = FALSE;
4679: }
4680: if (*selector != ']')
4681: {
4682: CSSPrintError ("Invalid attribute value", deb);
4683: DoApply = FALSE;
4684: }
4685: else
4686: {
4687: *cur++ = EOS;
4688: attrvals[0] = deb;
4689: selector++;
4690: }
1.129 vatton 4691: }
4692: /* end of the attribute */
1.183 vatton 4693: else if (*selector != ']')
1.129 vatton 4694: {
1.133 vatton 4695: selector[1] = EOS;
1.183 vatton 4696: CSSPrintError ("Invalid attribute", selector);
1.133 vatton 4697: selector += 2;
1.129 vatton 4698: DoApply = FALSE;
4699: }
4700: else
4701: selector++;
1.130 vatton 4702: }
4703: else
4704: {
4705: /* not supported selector */
4706: while (*selector != EOS && *selector != ',' &&
4707: *selector != '.' && *selector != ':' &&
4708: !TtaIsBlank (selector))
4709: *cur++ = *selector++;
4710: /* close the word */
4711: *cur++ = EOS;
1.205 quint 4712: CSSPrintError ("Selector not supported:", deb);
1.130 vatton 4713: DoApply = FALSE;
1.129 vatton 4714: }
4715: }
1.1 cvs 4716:
1.82 cvs 4717: selector = SkipBlanksAndComments (selector);
1.25 cvs 4718: /* is it a multi-level selector? */
1.82 cvs 4719: if (*selector == EOS)
1.1 cvs 4720: /* end of the selector */
4721: break;
1.82 cvs 4722: else if (*selector == ',')
1.1 cvs 4723: {
4724: /* end of the current selector */
4725: selector++;
4726: break;
4727: }
1.25 cvs 4728: else
4729: {
1.143 vatton 4730: if (*selector == '>')
4731: {
4732: /* handle immediat parent as a simple parent */
4733: selector++;
4734: selector = SkipBlanksAndComments (selector);
4735: }
1.25 cvs 4736: /* shifts the list to make room for the new name */
4737: max++; /* a new level in ancestor tables */
4738: if (max == MAX_ANCESTORS)
4739: /* abort the CSS parsing */
4740: return (selector);
4741: for (i = max; i > 0; i--)
4742: {
4743: names[i] = names[i - 1];
4744: ids[i] = ids[i - 1];
4745: classes[i] = classes[i - 1];
1.133 vatton 4746: pseudoclasses[i] = pseudoclasses[i - 1];
1.25 cvs 4747: attrs[i] = attrs[i - 1];
4748: attrvals[i] = attrvals[i - 1];
1.133 vatton 4749: attrmatch[i] = attrmatch[i - 1];
1.25 cvs 4750: }
4751: }
1.1 cvs 4752: }
4753:
4754: /* Now set up the context block */
1.25 cvs 4755: i = 0;
4756: k = 0;
4757: j = 0;
1.35 cvs 4758: maxAttr = 0;
1.91 cvs 4759: /* default schema name */
1.119 vatton 4760: ctxt->schema = NULL;
1.122 vatton 4761: elType.ElSSchema = NULL;
4762: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 4763: if (!strcmp (schemaName, "HTML"))
4764: xmlType = XHTML_TYPE;
4765: else if (!strcmp (schemaName, "MathML"))
4766: xmlType = MATH_TYPE;
4767: else if (!strcmp (schemaName, "SVG"))
4768: xmlType = SVG_TYPE;
4769: else if (!strcmp (schemaName, "XLink"))
4770: xmlType = XLINK_TYPE;
4771: else if (!strcmp (schemaName, "Annot"))
4772: xmlType = ANNOT_TYPE;
4773: else
4774: xmlType = XML_TYPE;
1.25 cvs 4775: while (i <= max)
4776: {
4777: if (names[i])
4778: {
1.118 vatton 4779: /* get the element type of this name in the current document */
4780: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c, &level, doc);
1.25 cvs 4781: if (i == 0)
4782: {
1.106 cvs 4783: if (elType.ElSSchema == NULL)
4784: {
1.119 vatton 4785: /* Search in the list of loaded schemas */
1.106 cvs 4786: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.119 vatton 4787: if (elType.ElSSchema)
4788: {
1.154 vatton 4789: /* the element type concerns an imported nature */
1.119 vatton 4790: schemaName = TtaGetSSchemaName(elType.ElSSchema);
4791: if (!strcmp (schemaName, "HTML"))
4792: xmlType = XHTML_TYPE;
4793: else if (!strcmp (schemaName, "MathML"))
4794: xmlType = MATH_TYPE;
4795: else if (!strcmp (schemaName, "SVG"))
4796: xmlType = SVG_TYPE;
4797: else if (!strcmp (schemaName, "XLink"))
4798: xmlType = XLINK_TYPE;
4799: else if (!strcmp (schemaName, "Annot"))
4800: xmlType = ANNOT_TYPE;
4801: else
4802: xmlType = XML_TYPE;
4803: }
1.118 vatton 4804: #ifdef XML_GENERIC
1.119 vatton 4805: else if (xmlType == XML_TYPE)
1.106 cvs 4806: {
4807: /* Creation of a new element type in the main schema */
4808: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.118 vatton 4809: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.106 cvs 4810: }
1.118 vatton 4811: #endif /* XML_GENERIC */
1.122 vatton 4812: else
4813: {
4814: if (xmlType != XHTML_TYPE)
4815: {
4816: MapXMLElementType (XHTML_TYPE, names[i], &elType,
4817: &mappedName, &c, &level, doc);
4818: if (elType.ElSSchema)
1.123 vatton 4819: elType.ElSSchema = GetXHTMLSSchema (doc);
1.122 vatton 4820: }
4821: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
4822: {
4823: MapXMLElementType (MATH_TYPE, names[i], &elType,
4824: &mappedName, &c, &level, doc);
4825: if (elType.ElSSchema)
1.123 vatton 4826: elType.ElSSchema = GetMathMLSSchema (doc);
1.122 vatton 4827: }
4828: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
4829: {
4830: MapXMLElementType (SVG_TYPE, names[i], &elType,
4831: &mappedName, &c, &level, doc);
4832: if (elType.ElSSchema)
1.123 vatton 4833: elType.ElSSchema = GetSVGSSchema (doc);
1.122 vatton 4834: }
4835: }
1.118 vatton 4836: }
1.119 vatton 4837:
1.118 vatton 4838: if (elType.ElSSchema == NULL)
4839: /* cannot apply these CSS rules */
4840: DoApply = FALSE;
4841: else
4842: {
4843: /* Store the element type */
4844: ctxt->type = elType.ElTypeNum;
4845: ctxt->name[0] = elType.ElTypeNum;
4846: ctxt->names_nb[0] = 0;
4847: ctxt->schema = elType.ElSSchema;
1.106 cvs 4848: }
1.25 cvs 4849: }
4850: else if (elType.ElTypeNum != 0)
4851: {
4852: /* look at the current context to see if the type is already
4853: stored */
1.121 vatton 4854: j = 1;
1.32 cvs 4855: while (j < k && ctxt->name[j] != elType.ElTypeNum)
1.25 cvs 4856: j++;
4857: if (j == k)
4858: {
4859: ctxt->name[j] = elType.ElTypeNum;
4860: if (j != 0)
1.121 vatton 4861: ctxt->names_nb[j] = 1;
1.25 cvs 4862: }
4863: else
4864: /* increment the number of ancestor levels */
4865: ctxt->names_nb[j]++;
4866: }
1.154 vatton 4867: #ifdef XML_GENERIC
4868: else if (xmlType == XML_TYPE)
4869: {
1.158 vatton 4870: TtaGetXmlElementType (names[i], &elType, NULL, doc);
4871: if (elType.ElTypeNum == 0)
4872: {
4873: /* Creation of a new element type in the main schema */
4874: elType.ElSSchema = TtaGetDocumentSSchema (doc);
4875: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
4876: }
1.154 vatton 4877: if (elType.ElTypeNum != 0)
4878: {
4879: /* look at the current context to see if the type is already
4880: stored */
4881: j = 1;
4882: while (j < k && ctxt->name[j] != elType.ElTypeNum)
4883: j++;
4884: if (j == k)
4885: {
4886: ctxt->name[j] = elType.ElTypeNum;
4887: if (j != 0)
4888: ctxt->names_nb[j] = 1;
4889: }
4890: else
4891: /* increment the number of ancestor levels */
4892: ctxt->names_nb[j]++;
4893: }
4894: }
4895: #endif /* XML_GENERIC */
1.25 cvs 4896: else
1.117 vatton 4897: j = k;
1.25 cvs 4898: }
1.117 vatton 4899: else
4900: j = k;
1.1 cvs 4901:
1.25 cvs 4902: /* store attributes information */
4903: if (classes[i])
4904: {
4905: ctxt->attrText[j] = classes[i];
1.119 vatton 4906: if (xmlType == SVG_TYPE)
1.100 vatton 4907: ctxt->attrType[j] = SVG_ATTR_class;
1.119 vatton 4908: else if (xmlType == MATH_TYPE)
1.91 cvs 4909: ctxt->attrType[j] = MathML_ATTR_class;
1.119 vatton 4910: else if (xmlType == XHTML_TYPE)
1.107 cvs 4911: ctxt->attrType[j] = HTML_ATTR_Class;
4912: else
1.119 vatton 4913: #ifdef XML_GENERIC
1.107 cvs 4914: ctxt->attrType[j] = XML_ATTR_class;
4915: #else /* XML_GENERIC */
1.91 cvs 4916: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 4917: #endif /* XML_GENERIC */
1.157 vatton 4918: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4919: /* add a new entry */
1.80 cvs 4920: maxAttr = i + 1;
1.129 vatton 4921: /* update attrLevel */
4922: ctxt->attrLevel[j] = i;
4923: j++;
1.25 cvs 4924: }
1.79 cvs 4925: if (pseudoclasses[i])
1.25 cvs 4926: {
4927: ctxt->attrText[j] = pseudoclasses[i];
1.119 vatton 4928: if (xmlType == SVG_TYPE)
1.100 vatton 4929: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
1.119 vatton 4930: else if (xmlType == MATH_TYPE)
1.91 cvs 4931: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
1.119 vatton 4932: else if (xmlType == XHTML_TYPE)
1.107 cvs 4933: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
4934: else
1.119 vatton 4935: #ifdef XML_GENERIC
1.107 cvs 4936: ctxt->attrType[j] = XML_ATTR_PseudoClass;
4937: #else /* XML_GENERIC */
1.91 cvs 4938: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 4939: #endif /* XML_GENERIC */
1.157 vatton 4940: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4941: /* add a new entry */
1.80 cvs 4942: maxAttr = i + 1;
1.129 vatton 4943: /* update attrLevel */
4944: ctxt->attrLevel[j] = i;
4945: j++;
1.25 cvs 4946: }
1.79 cvs 4947: if (ids[i])
1.25 cvs 4948: {
4949: ctxt->attrText[j] = ids[i];
1.119 vatton 4950: if (xmlType == SVG_TYPE)
1.100 vatton 4951: ctxt->attrType[j] = SVG_ATTR_id;
1.119 vatton 4952: else if (xmlType == MATH_TYPE)
1.91 cvs 4953: ctxt->attrType[j] = MathML_ATTR_id;
1.119 vatton 4954: else if (xmlType == XHTML_TYPE)
1.107 cvs 4955: ctxt->attrType[j] = HTML_ATTR_ID;
4956: else
1.119 vatton 4957: #ifdef XML_GENERIC
1.107 cvs 4958: ctxt->attrType[j] = XML_ATTR_id;
4959: #else /* XML_GENERIC */
1.91 cvs 4960: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 4961: #endif /* XML_GENERIC */
1.157 vatton 4962: ctxt->attrMatch[j] = attrmatch[i];
1.80 cvs 4963: /* add a new entry */
4964: maxAttr = i + 1;
1.129 vatton 4965: /* update attrLevel */
4966: ctxt->attrLevel[j] = i;
4967: j++;
1.25 cvs 4968: }
1.79 cvs 4969: if (attrs[i])
1.25 cvs 4970: {
1.125 vatton 4971: /* it's an attribute */
1.119 vatton 4972: MapXMLAttribute (xmlType, attrs[i], names[i], &level, doc, &att);
1.127 quint 4973: if (att == DummyAttribute && !strcmp (schemaName, "HTML"))
4974: /* it's the "type" attribute for an "input" element. In the tree
4975: it's represented by the element type, not by an attribute */
4976: att = 0;
1.119 vatton 4977: ctxt->attrType[j] = att;
1.133 vatton 4978: ctxt->attrMatch[j] = attrmatch[i];
1.125 vatton 4979: attrType.AttrSSchema = ctxt->schema;
4980: attrType.AttrTypeNum = att;
1.119 vatton 4981: if (i == 0 && att == 0 && ctxt->schema == NULL)
4982: {
1.125 vatton 4983: /* Not found -> search in the list of loaded schemas */
1.119 vatton 4984: attrType.AttrSSchema = NULL;
4985: TtaGetXmlAttributeType (attrs[i], &attrType, doc);
4986: ctxt->attrType[j] = attrType.AttrTypeNum;
4987: if (attrType.AttrSSchema)
1.125 vatton 4988: /* the element type concerns an imported nature */
4989: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
1.119 vatton 4990: #ifdef XML_GENERIC
4991: else if (xmlType == XML_TYPE)
4992: {
4993: /* The attribute is not yet present in the tree */
4994: /* Create a new global attribute */
4995: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
4996: TtaAppendXmlAttribute (attrs[i], &attrType, doc);
4997: }
4998: #endif /* XML_GENERIC */
4999:
5000: if (attrType.AttrSSchema == NULL)
5001: /* cannot apply these CSS rules */
5002: DoApply = FALSE;
1.136 quint 5003: else if (elType.ElSSchema)
5004: ctxt->schema = elType.ElSSchema;
1.119 vatton 5005: else
1.136 quint 5006: ctxt->schema = attrType.AttrSSchema;
1.119 vatton 5007: }
1.125 vatton 5008: /* check the attribute type */
5009: if (!strcmp (schemaName, "HTML"))
5010: xmlType = XHTML_TYPE;
5011: else if (!strcmp (schemaName, "MathML"))
5012: xmlType = MATH_TYPE;
5013: else if (!strcmp (schemaName, "SVG"))
5014: xmlType = SVG_TYPE;
5015: else if (!strcmp (schemaName, "XLink"))
5016: xmlType = XLINK_TYPE;
5017: else if (!strcmp (schemaName, "Annot"))
5018: xmlType = ANNOT_TYPE;
5019: else
5020: xmlType = XML_TYPE;
5021: kind = TtaGetAttributeKind (attrType);
1.213 vatton 5022: if (kind != 1 && attrvals[i])
1.125 vatton 5023: {
5024: /* enumerated value */
5025: MapXMLAttributeValue (xmlType, attrvals[i], attrType, &kind);
5026: /* store the attribute value */
5027: ctxt->attrText[j] = (char *) kind;
5028: }
5029: else
5030: ctxt->attrText[j] = attrvals[i];
1.80 cvs 5031: maxAttr = i + 1;
1.129 vatton 5032: /* update attrLevel */
5033: ctxt->attrLevel[j] = i;
5034: j++;
1.25 cvs 5035: }
5036: i++;
1.117 vatton 5037: /* add a new entry */
5038: k++;
1.129 vatton 5039: if (k < j)
5040: k = j;
1.119 vatton 5041: if (i == 1 && ctxt->schema == NULL)
5042: /* use the document schema */
5043: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 5044: }
1.117 vatton 5045: /* set the selector specificity */
5046: ctxt->cssSpecificity = specificity;
1.25 cvs 5047: /* sort the list of ancestors by name order */
5048: max = k;
5049: i = 1;
5050: while (i < max)
1.28 cvs 5051: {
5052: for (k = i + 1; k < max; k++)
5053: if (ctxt->name[i] > ctxt->name[k])
5054: {
5055: j = ctxt->name[i];
5056: ctxt->name[i] = ctxt->name[k];
5057: ctxt->name[k] = j;
5058: j = ctxt->names_nb[i];
5059: ctxt->names_nb[i] = ctxt->names_nb[k];
5060: ctxt->names_nb[k] = j;
5061: j = ctxt->attrType[i];
5062: ctxt->attrType[i] = ctxt->attrType[k];
5063: ctxt->attrType[k] = j;
5064: cur = ctxt->attrText[i];
5065: ctxt->attrText[i] = ctxt->attrText[k];
5066: ctxt->attrText[k] = cur;
5067: }
5068: i++;
5069: }
1.84 cvs 5070:
1.25 cvs 5071: /* Get the schema name of the main element */
1.119 vatton 5072: schemaName = TtaGetSSchemaName (ctxt->schema);
5073: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 5074: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.119 vatton 5075: if (tsch && cssRule)
5076: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.116 vatton 5077: /* future CSS rules should apply */
5078: DoApply = TRUE;
1.1 cvs 5079: return (selector);
5080: }
5081:
5082: /*----------------------------------------------------------------------
1.206 vatton 5083: ParseStyleDeclaration: parse a style declaration stored in the style
5084: element of a document
5085: We expect the style string to be of the form:
5086: .pinky, .awful { color: pink; font-family: helvetica }
1.1 cvs 5087: ----------------------------------------------------------------------*/
1.206 vatton 5088: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
5089: CSSInfoPtr css, Element link, ThotBool destroy)
1.1 cvs 5090: {
1.79 cvs 5091: GenericContext ctxt;
5092: char *decl_end;
5093: char *sel_end;
5094: char *selector;
1.1 cvs 5095:
5096: /* separate the selectors string */
1.82 cvs 5097: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 5098: decl_end = cssRule;
1.82 cvs 5099: while (*decl_end != EOS && *decl_end != '{')
1.1 cvs 5100: decl_end++;
1.82 cvs 5101: if (*decl_end == EOS)
1.86 cvs 5102: {
1.168 vatton 5103: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 5104: return;
5105: }
1.1 cvs 5106: /* verify and clean the selector string */
5107: sel_end = decl_end - 1;
1.82 cvs 5108: while (*sel_end == SPACE || *sel_end == BSPACE ||
5109: *sel_end == EOL || *sel_end == CR)
1.1 cvs 5110: sel_end--;
5111: sel_end++;
1.82 cvs 5112: *sel_end = EOS;
1.1 cvs 5113: selector = cssRule;
5114:
5115: /* now, deal with the content ... */
5116: decl_end++;
5117: cssRule = decl_end;
1.137 vatton 5118: decl_end = &cssRule[strlen (cssRule) - 1];
5119: if (*decl_end != '{')
5120: *decl_end = EOS;
1.1 cvs 5121: /*
5122: * parse the style attribute string and install the corresponding
5123: * presentation attributes on the new element
5124: */
5125: ctxt = TtaGetGenericStyleContext (doc);
5126: if (ctxt == NULL)
5127: return;
5128: ctxt->destroy = destroy;
1.207 vatton 5129: /* first use of the context */
5130: ctxt->uses = 1;
1.197 vatton 5131: while (selector && *selector != EOS)
1.207 vatton 5132: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css, link);
5133: /* check if the context can be freed */
5134: ctxt->uses -= 1;
5135: if (ctxt->uses == 0)
5136: /* no image loading */
5137: TtaFreeMemory (ctxt);
1.1 cvs 5138: }
5139:
5140: /************************************************************************
5141: * *
5142: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
5143: * *
5144: ************************************************************************/
5145:
5146: /*----------------------------------------------------------------------
1.59 cvs 5147: IsImplicitClassName: return wether the Class name is an
1.1 cvs 5148: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
5149: or an HTML context name.
5150: ----------------------------------------------------------------------*/
1.206 vatton 5151: int IsImplicitClassName (char *class, Document doc)
1.1 cvs 5152: {
1.79 cvs 5153: char name[200];
5154: char *cur = name;
5155: char *first;
5156: char save;
5157: SSchema schema;
1.1 cvs 5158:
5159: /* make a local copy */
1.82 cvs 5160: strncpy (name, class, 199);
1.1 cvs 5161: name[199] = 0;
5162:
5163: /* loop looking if each word is a GI */
5164: while (*cur != 0)
5165: {
5166: first = cur;
5167: cur = SkipWord (cur);
5168: save = *cur;
5169: *cur = 0;
5170: schema = NULL;
5171: if (MapGI (first, &schema, doc) == -1)
5172: {
5173: return (0);
5174: }
5175: *cur = save;
1.82 cvs 5176: cur = SkipBlanksAndComments (cur);
1.1 cvs 5177: }
5178: return (1);
5179: }
5180:
5181: /************************************************************************
5182: * *
1.114 quint 5183: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 5184: * *
5185: ************************************************************************/
5186:
5187: /*----------------------------------------------------------------------
1.59 cvs 5188: HTMLSetBackgroundColor:
1.1 cvs 5189: ----------------------------------------------------------------------*/
1.79 cvs 5190: void HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1 cvs 5191: {
1.79 cvs 5192: char css_command[100];
1.1 cvs 5193:
1.82 cvs 5194: sprintf (css_command, "background-color: %s", color);
1.114 quint 5195: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 5196: }
5197:
5198: /*----------------------------------------------------------------------
1.59 cvs 5199: HTMLSetForegroundColor:
1.1 cvs 5200: ----------------------------------------------------------------------*/
1.97 vatton 5201: void HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1 cvs 5202: {
1.79 cvs 5203: char css_command[100];
1.1 cvs 5204:
1.82 cvs 5205: sprintf (css_command, "color: %s", color);
1.114 quint 5206: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 5207: }
5208:
5209: /*----------------------------------------------------------------------
1.59 cvs 5210: HTMLResetBackgroundColor:
1.1 cvs 5211: ----------------------------------------------------------------------*/
1.97 vatton 5212: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 5213: {
1.79 cvs 5214: char css_command[100];
1.1 cvs 5215:
1.82 cvs 5216: sprintf (css_command, "background: red");
1.114 quint 5217: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5218: }
5219:
5220: /*----------------------------------------------------------------------
1.59 cvs 5221: HTMLResetBackgroundImage:
1.1 cvs 5222: ----------------------------------------------------------------------*/
1.97 vatton 5223: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 5224: {
1.79 cvs 5225: char css_command[1000];
1.1 cvs 5226:
1.82 cvs 5227: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.114 quint 5228: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5229: }
5230:
5231: /*----------------------------------------------------------------------
1.59 cvs 5232: HTMLResetForegroundColor:
1.1 cvs 5233: ----------------------------------------------------------------------*/
1.97 vatton 5234: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 5235: {
1.79 cvs 5236: char css_command[100];
1.1 cvs 5237:
1.36 cvs 5238: /* it's not necessary to well know the current color but it must be valid */
1.82 cvs 5239: sprintf (css_command, "color: red");
1.114 quint 5240: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5241: }
5242:
5243: /*----------------------------------------------------------------------
1.59 cvs 5244: HTMLSetAlinkColor:
1.1 cvs 5245: ----------------------------------------------------------------------*/
1.208 vatton 5246: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 5247: {
1.79 cvs 5248: char css_command[100];
1.1 cvs 5249:
1.215 ! quint 5250: sprintf (css_command, ":link { color: %s }", color);
1.208 vatton 5251: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5252: }
5253:
5254: /*----------------------------------------------------------------------
1.59 cvs 5255: HTMLSetAactiveColor:
1.1 cvs 5256: ----------------------------------------------------------------------*/
1.208 vatton 5257: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 5258: {
1.79 cvs 5259: char css_command[100];
1.1 cvs 5260:
1.215 ! quint 5261: sprintf (css_command, ":active { color: %s }", color);
1.208 vatton 5262: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5263: }
5264:
5265: /*----------------------------------------------------------------------
1.59 cvs 5266: HTMLSetAvisitedColor:
1.1 cvs 5267: ----------------------------------------------------------------------*/
1.208 vatton 5268: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 5269: {
1.79 cvs 5270: char css_command[100];
1.1 cvs 5271:
1.215 ! quint 5272: sprintf (css_command, ":visited { color: %s }", color);
1.208 vatton 5273: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5274: }
5275:
5276: /*----------------------------------------------------------------------
1.59 cvs 5277: HTMLResetAlinkColor:
1.1 cvs 5278: ----------------------------------------------------------------------*/
1.208 vatton 5279: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 5280: {
1.79 cvs 5281: char css_command[100];
1.1 cvs 5282:
1.215 ! quint 5283: sprintf (css_command, ":link { color: red }");
1.208 vatton 5284: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5285: }
5286:
5287: /*----------------------------------------------------------------------
1.59 cvs 5288: HTMLResetAactiveColor:
1.1 cvs 5289: ----------------------------------------------------------------------*/
1.208 vatton 5290: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 5291: {
1.79 cvs 5292: char css_command[100];
1.1 cvs 5293:
1.215 ! quint 5294: sprintf (css_command, ":active { color: red }");
1.208 vatton 5295: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5296: }
5297:
5298: /*----------------------------------------------------------------------
1.59 cvs 5299: HTMLResetAvisitedColor:
1.1 cvs 5300: ----------------------------------------------------------------------*/
1.208 vatton 5301: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 5302: {
1.79 cvs 5303: char css_command[100];
1.1 cvs 5304:
1.215 ! quint 5305: sprintf (css_command, ":visited { color: red }");
1.208 vatton 5306: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5307: }
5308:
5309: /*----------------------------------------------------------------------
1.206 vatton 5310: ApplyCSSRules: parse a CSS Style description stored in the header of
5311: a HTML document.
1.1 cvs 5312: ----------------------------------------------------------------------*/
1.79 cvs 5313: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 5314: {
1.206 vatton 5315: CSSInfoPtr css;
5316: PInfoPtr pInfo;
1.207 vatton 5317: ThotBool loadcss;
5318:
5319: /* check if we have to load CSS */
5320: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
5321: if (!loadcss)
5322: return;
1.1 cvs 5323:
1.206 vatton 5324: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 5325: if (css == NULL)
1.209 vatton 5326: {
5327: /* create the document css context */
5328: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
5329: pInfo = css->infos[doc];
5330: }
1.206 vatton 5331: else if (pInfo == NULL)
5332: /* create the entry into the css context */
5333: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 5334: if (pInfo->PiEnabled)
5335: ParseStyleDeclaration (el, cssRule, doc, css, el, destroy);
1.1 cvs 5336: }
5337:
5338: /*----------------------------------------------------------------------
1.145 quint 5339: ReadCSSRules: is the front-end function called by the document parser
5340: when detecting a <style type="text/css"> indicating it's the
1.1 cvs 5341: beginning of a CSS fragment or when reading a file .css.
5342:
5343: The CSS parser has to handle <!-- ... --> constructs used to
5344: prevent prehistoric browser from displaying the CSS as a text
5345: content. It will stop on any sequence "<x" where x is different
5346: from ! and will return x as to the caller. Theorically x should
1.145 quint 5347: be equal to / for the </style> end of style.
1.1 cvs 5348: The parameter doc gives the document tree that contains CSS information.
5349: The parameter docRef gives the document to which CSS are to be applied.
5350: This function uses the current css context or creates it. It's able
1.23 cvs 5351: to work on the given buffer or call GetNextChar to read the parsed
1.1 cvs 5352: file.
1.133 vatton 5353: The parameter url gives the URL of the style shheet parsed.
1.86 cvs 5354: Parameter numberOfLinesRead indicates the number of lines already
5355: read in the file.
1.1 cvs 5356: Parameter withUndo indicates whether the changes made in the document
1.145 quint 5357: structure and content have to be registered in the Undo queue or not.
1.1 cvs 5358: ----------------------------------------------------------------------*/
1.133 vatton 5359: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.144 quint 5360: int numberOfLinesRead, ThotBool withUndo,
1.206 vatton 5361: Element link)
1.1 cvs 5362: {
1.6 cvs 5363: DisplayMode dispMode;
1.206 vatton 5364: CSSInfoPtr refcss = NULL;
5365: PInfoPtr pInfo;
1.82 cvs 5366: char c;
1.138 vatton 5367: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 5368: int index;
1.1 cvs 5369: int CSSindex;
5370: int CSScomment;
5371: int import;
5372: int openRule;
1.93 vatton 5373: int newlines;
1.14 cvs 5374: ThotBool HTMLcomment;
1.102 vatton 5375: ThotBool toParse, eof, quoted;
1.36 cvs 5376: ThotBool ignoreMedia, media;
1.186 vatton 5377: ThotBool noRule, ignoreImport, skip;
1.1 cvs 5378:
5379: CSScomment = MAX_CSS_LENGTH;
5380: HTMLcomment = FALSE;
5381: CSSindex = 0;
5382: toParse = FALSE;
5383: noRule = FALSE;
1.36 cvs 5384: media = FALSE;
1.88 cvs 5385: ignoreImport = FALSE;
1.1 cvs 5386: ignoreMedia = FALSE;
5387: import = MAX_CSS_LENGTH;
5388: eof = FALSE;
5389: openRule = 0;
1.82 cvs 5390: c = SPACE;
1.1 cvs 5391: index = 0;
1.134 vatton 5392: base = NULL;
1.135 vatton 5393: quoted = FALSE;
1.186 vatton 5394: skip = FALSE;
1.93 vatton 5395: /* number of new lines parsed */
5396: newlines = 0;
1.6 cvs 5397: /* avoid too many redisplay */
5398: dispMode = TtaGetDisplayMode (docRef);
5399: if (dispMode == DisplayImmediately)
5400: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 5401:
5402: /* look for the CSS context */
5403: if (css == NULL)
1.206 vatton 5404: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 5405: else
5406: pInfo = css->infos[docRef];
1.18 cvs 5407: if (css == NULL)
1.206 vatton 5408: {
5409: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
5410: pInfo = css->infos[docRef];
5411: }
5412: else if (pInfo == NULL)
5413: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 5414: /* look for the CSS descriptor that points to the extension schema */
5415: refcss = css;
5416: if (import)
1.173 cvs 5417: {
1.206 vatton 5418: while (refcss &&
5419: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
1.174 vatton 5420: refcss = refcss->NextCSS;
1.206 vatton 5421: if (refcss)
5422: pInfo = refcss->infos[docRef];
1.173 cvs 5423: }
5424:
1.144 quint 5425: /* register parsed CSS file and the document to which CSS are to be applied*/
1.86 cvs 5426: ParsedDoc = docRef;
1.133 vatton 5427: if (url)
5428: DocURL = url;
1.86 cvs 5429: else
5430: /* the CSS source in within the document itself */
5431: DocURL = DocumentURLs[docRef];
5432: LineNumber = numberOfLinesRead + 1;
1.93 vatton 5433: NewLineSkipped = 0;
1.82 cvs 5434: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
5435: {
5436: c = buffer[index++];
5437: eof = (c == EOS);
5438: CSSbuffer[CSSindex] = c;
1.186 vatton 5439: if (skip)
5440: {
5441: if (c == '}')
5442: {
5443: /* end of the @font-face */
5444: skip = FALSE;
5445: import = MAX_CSS_LENGTH;
5446: noRule = TRUE;
5447: CSSindex = 0;
5448: }
5449: if (c == EOL)
5450: LineNumber++;
5451: c = CR;
5452: }
5453: else if (CSScomment == MAX_CSS_LENGTH ||
1.82 cvs 5454: c == '*' || c == '/' || c == '<')
5455: {
5456: /* we're not within a comment or we're parsing * or / */
5457: switch (c)
5458: {
5459: case '@': /* perhaps an import primitive */
1.135 vatton 5460: if (!quoted)
5461: import = CSSindex;
1.82 cvs 5462: break;
5463: case ';':
1.135 vatton 5464: if (!quoted && !media && import != MAX_CSS_LENGTH)
1.82 cvs 5465: {
5466: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
5467: /* it's not an import */
5468: import = MAX_CSS_LENGTH;
5469: /* save the text */
5470: noRule = TRUE;
5471: }
5472: break;
5473: case '*':
1.135 vatton 5474: if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5475: CSSbuffer[CSSindex - 1] == '/')
5476: /* start a comment */
5477: CSScomment = CSSindex - 1;
5478: break;
5479: case '/':
1.135 vatton 5480: if (!quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.82 cvs 5481: CSSbuffer[CSSindex - 1] == '*')
5482: {
5483: /* close a comment:and ignore its contents */
5484: CSSindex = CSScomment - 1; /* will be incremented later */
5485: CSScomment = MAX_CSS_LENGTH;
1.93 vatton 5486: /* clean up the buffer */
1.103 vatton 5487: if (newlines && CSSindex > 0)
5488: while (CSSindex > 0 &&
5489: (CSSbuffer[CSSindex] == SPACE ||
5490: CSSbuffer[CSSindex] == BSPACE ||
5491: CSSbuffer[CSSindex] == EOL ||
5492: CSSbuffer[CSSindex] == TAB ||
5493: CSSbuffer[CSSindex] == __CR__))
1.93 vatton 5494: {
5495: if ( CSSbuffer[CSSindex] == EOL)
5496: {
5497: LineNumber ++;
5498: newlines --;
5499: }
5500: CSSindex--;
5501: }
1.82 cvs 5502: }
1.135 vatton 5503: else if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5504: CSSbuffer[CSSindex - 1] == '<')
5505: {
5506: /* this is the closing tag ! */
5507: CSSindex -= 2; /* remove </ from the CSS string */
5508: noRule = TRUE;
5509: }
5510: break;
5511: case '<':
1.135 vatton 5512: if (!quoted && CSScomment == MAX_CSS_LENGTH)
1.82 cvs 5513: {
5514: /* only if we're not parsing a comment */
5515: c = buffer[index++];
5516: eof = (c == EOS);
5517: if (c == '!')
5518: {
5519: /* CSS within an HTML comment */
5520: HTMLcomment = TRUE;
5521: CSSindex++;
5522: CSSbuffer[CSSindex] = c;
5523: }
5524: else if (c == EOS)
5525: CSSindex++;
5526: }
5527: break;
5528: case '-':
1.135 vatton 5529: if (!quoted && CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
1.82 cvs 5530: HTMLcomment)
5531: /* CSS within an HTML comment */
5532: noRule = TRUE;
5533: break;
5534: case '>':
1.135 vatton 5535: if (!quoted && HTMLcomment)
1.82 cvs 5536: noRule = TRUE;
5537: break;
5538: case ' ':
1.135 vatton 5539: if (!quoted && import != MAX_CSS_LENGTH && openRule == 0)
1.162 quint 5540: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
1.82 cvs 5541: break;
5542: case '{':
1.135 vatton 5543: if (!quoted)
1.82 cvs 5544: {
1.135 vatton 5545: openRule++;
5546: if (import != MAX_CSS_LENGTH && openRule == 1 && media)
5547: {
5548: /* is it the screen concerned? */
5549: CSSbuffer[CSSindex+1] = EOS;
5550: if (TtaIsPrinting ())
5551: base = strstr (&CSSbuffer[import], "print");
5552: else
5553: base = strstr (&CSSbuffer[import], "screen");
5554: if (base == NULL)
5555: base = strstr (&CSSbuffer[import], "all");
5556: if (base == NULL)
5557: ignoreMedia = TRUE;
5558: noRule = TRUE;
5559: }
1.186 vatton 5560: else if (import != MAX_CSS_LENGTH &&
5561: !strncasecmp (&CSSbuffer[import], "@font-face", 10))
5562: skip = TRUE;
1.135 vatton 5563: }
5564: break;
5565: case '}':
5566: if (!quoted)
5567: {
5568: openRule--;
5569: if (import != MAX_CSS_LENGTH && openRule == 0)
5570: {
5571: import = MAX_CSS_LENGTH;
5572: noRule = TRUE;
5573: ignoreMedia = FALSE;
5574: media = FALSE;
5575: }
1.82 cvs 5576: else
1.135 vatton 5577: toParse = TRUE;
1.82 cvs 5578: }
5579: break;
1.135 vatton 5580: case '"':
5581: if (quoted)
1.82 cvs 5582: {
1.135 vatton 5583: if (CSSbuffer[CSSindex - 1] != '\\')
5584: quoted = FALSE;
1.82 cvs 5585: }
5586: else
1.135 vatton 5587: quoted = TRUE;
1.82 cvs 5588: break;
5589: default:
1.86 cvs 5590: if (c == EOL)
1.93 vatton 5591: newlines++;
1.82 cvs 5592: break;
5593: }
5594: }
1.93 vatton 5595: else if (c == EOL)
5596: LineNumber++;
1.82 cvs 5597: if (c != CR)
5598: CSSindex++;
5599:
5600: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
5601: /* we're still parsing a comment: remove the text comment */
5602: CSSindex = CSScomment;
5603:
5604: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
5605: {
5606: CSSbuffer[CSSindex] = EOS;
5607: /* parse a not empty string */
5608: if (CSSindex > 0)
5609: {
1.50 cvs 5610: /* apply CSS rule if it's not just a saving of text */
5611: if (!noRule && !ignoreMedia)
1.88 cvs 5612: {
5613: /* future import rules must be ignored */
5614: ignoreImport = TRUE;
1.210 vatton 5615: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
5616: pInfo->PiLink, FALSE);
1.93 vatton 5617: LineNumber += newlines;
5618: newlines = 0;
5619: NewLineSkipped = 0;
1.88 cvs 5620: }
1.82 cvs 5621: else if (import != MAX_CSS_LENGTH &&
5622: !strncasecmp (&CSSbuffer[import+1], "import", 6))
5623: {
5624: /* import section */
5625: cssRule = &CSSbuffer[import+7];
5626: cssRule = TtaSkipBlanks (cssRule);
1.93 vatton 5627: /* save the current line number */
5628: newlines += LineNumber;
1.82 cvs 5629: if (!strncasecmp (cssRule, "url", 3))
5630: {
1.50 cvs 5631: cssRule = &cssRule[3];
1.82 cvs 5632: cssRule = TtaSkipBlanks (cssRule);
5633: if (*cssRule == '(')
5634: {
5635: cssRule++;
5636: cssRule = TtaSkipBlanks (cssRule);
1.102 vatton 5637: quoted = (*cssRule == '"' || *cssRule == '\'');
5638: if (quoted)
5639: cssRule++;
1.82 cvs 5640: base = cssRule;
5641: while (*cssRule != EOS && *cssRule != ')')
5642: cssRule++;
1.102 vatton 5643: if (quoted)
1.167 vatton 5644: {
5645: /* isolate the file name */
5646: cssRule[-1] = EOS;
5647: quoted = FALSE;
5648: }
1.160 vatton 5649: *cssRule = EOS;
1.82 cvs 5650: }
5651: }
1.87 cvs 5652: else if (*cssRule == '"')
5653: {
1.88 cvs 5654: /*
5655: Do we have to accept single quotes?
5656: Double quotes are acceted here.
5657: Escaped quotes are not handled. See function SkipQuotedString
5658: */
1.87 cvs 5659: cssRule++;
5660: cssRule = TtaSkipBlanks (cssRule);
5661: base = cssRule;
1.179 vatton 5662: while (*cssRule != EOS &&
5663: (*cssRule != '"' ||
1.180 vatton 5664: (*cssRule == '"' && cssRule[-1] == '\\')))
1.87 cvs 5665: cssRule++;
1.160 vatton 5666: /* isolate the file name */
5667: *cssRule = EOS;
1.133 vatton 5668: }
5669: /* check if a media is defined */
5670: cssRule++;
5671: cssRule = TtaSkipBlanks (cssRule);
5672: if (*cssRule != ';')
5673: {
5674: if (TtaIsPrinting ())
5675: ignoreImport = (strncasecmp (cssRule, "print", 5) &&
5676: strncasecmp (cssRule, "all", 3));
5677: else
5678: ignoreImport = (strncasecmp (cssRule, "screen", 6) &&
5679: strncasecmp (cssRule, "all", 3));
5680: }
5681: if (!ignoreImport)
5682: {
5683: /* save the displayed URL when an error is reported */
5684: saveDocURL = DocURL;
1.138 vatton 5685: ptr = TtaStrdup (base);
5686: /* get the CSS URI in UTF-8 */
5687: ptr = ReallocUTF8String (ptr, docRef);
1.206 vatton 5688: LoadStyleSheet (base, docRef, (Element) css, css,
5689: pInfo->PiMedia,
5690: pInfo->PiCategory == CSS_USER_STYLE);
1.133 vatton 5691: /* restore the displayed URL when an error is reported */
5692: DocURL = saveDocURL;
1.138 vatton 5693: TtaFreeMemory (ptr);
1.82 cvs 5694: }
1.93 vatton 5695: /* restore the number of lines */
5696: LineNumber = newlines;
5697: newlines = 0;
1.82 cvs 5698: import = MAX_CSS_LENGTH;
5699: }
1.93 vatton 5700:
1.82 cvs 5701: }
5702: toParse = FALSE;
5703: noRule = FALSE;
5704: CSSindex = 0;
1.50 cvs 5705: }
1.82 cvs 5706: }
1.6 cvs 5707: /* restore the display mode */
5708: if (dispMode == DisplayImmediately)
1.82 cvs 5709: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 5710:
5711: /* Prepare the context for style attributes */
5712: DocURL = DocumentURLs[docRef];
5713: LineNumber = -1;
1.1 cvs 5714: return (c);
5715: }
1.89 cvs 5716:
Webmaster