Annotation of Amaya/amaya/styleparser.c, revision 1.391
1.1 cvs 1: /*
2: *
1.373 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2007
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:
1.302 quint 25: typedef struct _CSSImageCallbackBlock
1.1 cvs 26: {
1.207 vatton 27: Element el;
28: PSchema tsch;
29: CSSInfoPtr css;
30: PresentationContext ctxt;
1.302 quint 31: unsigned int ruleType;
1.1 cvs 32: }
1.302 quint 33: CSSImageCallbackBlock, *CSSImageCallbackPtr;
1.1 cvs 34:
35: #include "AHTURLTools_f.h"
36: #include "HTMLpresentation_f.h"
37: #include "HTMLimage_f.h"
38: #include "UIcss_f.h"
39: #include "css_f.h"
1.24 cvs 40: #include "fetchHTMLname_f.h"
1.91 cvs 41: #include "fetchXMLname_f.h"
1.1 cvs 42: #include "html2thot_f.h"
1.91 cvs 43: #include "init_f.h"
1.1 cvs 44: #include "styleparser_f.h"
1.366 vatton 45: #include "wxdialogapi_f.h"
1.1 cvs 46:
47: #define MAX_BUFFER_LENGTH 200
48: /*
49: * A PropertyParser is a function used to parse the
50: * description substring associated to a given style attribute
1.59 cvs 51: * e.g.: "red" for a color attribute or "12pt bold helvetica"
1.1 cvs 52: * for a font attribute.
53: */
1.79 cvs 54: typedef char *(*PropertyParser) (Element element,
1.327 vatton 55: PSchema tsch,
56: PresentationContext context,
57: char *cssRule,
58: CSSInfoPtr css,
59: ThotBool isHTML);
1.1 cvs 60:
61: /* Description of the set of CSS properties supported */
62: typedef struct CSSProperty
1.327 vatton 63: {
64: char *name;
65: PropertyParser parsing_function;
66: }
1.1 cvs 67: CSSProperty;
68:
1.86 cvs 69: static int LineNumber = -1; /* The line where the error occurs */
1.93 vatton 70: static int NewLineSkipped = 0;
1.311 vatton 71: static int RedisplayImages = 0; /* number of BG images loading */
72: static int RedisplayDoc = 0; /* document to be redisplayed */
73: static int Style_parsing = 0; /* > 0 when parsing a set of CSS rules */
1.360 vatton 74: static char *ImportantPos = NULL;
1.310 vatton 75: static ThotBool RedisplayBGImage = FALSE; /* TRUE when a BG image is inserted */
1.116 vatton 76: static ThotBool DoApply = TRUE;
1.366 vatton 77: static ThotBool All_sides = FALSE; // TRUE when "boder valus must be displayed
78:
1.1 cvs 79:
80: /*----------------------------------------------------------------------
1.327 vatton 81: SkipWord:
1.1 cvs 82: ----------------------------------------------------------------------*/
1.79 cvs 83: static char *SkipWord (char *ptr)
1.1 cvs 84: {
1.168 vatton 85: while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '#' || *ptr == '%')
86: ptr++;
1.1 cvs 87: return (ptr);
88: }
89:
90: /*----------------------------------------------------------------------
1.327 vatton 91: SkipBlanksAndComments:
1.13 cvs 92: ----------------------------------------------------------------------*/
1.82 cvs 93: char *SkipBlanksAndComments (char *ptr)
1.13 cvs 94: {
1.93 vatton 95: /* skip spaces */
1.155 cheyroul 96: while (*ptr == SPACE ||
1.327 vatton 97: *ptr == BSPACE ||
98: *ptr == EOL ||
99: *ptr == TAB ||
100: *ptr == __CR__)
1.93 vatton 101: {
102: if (*ptr == EOL)
1.327 vatton 103: /* increment the number of newline skipped */
104: NewLineSkipped++;
1.93 vatton 105: ptr++;
106: }
1.155 cheyroul 107: while (ptr[0] == '/' &&
1.327 vatton 108: ptr[1] == '*')
1.13 cvs 109: {
110: /* look for the end of the comment */
111: ptr = &ptr[2];
112: while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
1.327 vatton 113: ptr++;
1.13 cvs 114: if (ptr[0] != EOS)
1.327 vatton 115: ptr = &ptr[2];
1.93 vatton 116: /* skip spaces */
117: while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
1.327 vatton 118: *ptr == TAB || *ptr == __CR__)
119: {
120: if (*ptr == EOL)
121: /* increment the number of newline skipped */
122: NewLineSkipped++;
123: ptr++;
124: }
1.13 cvs 125: }
126: return (ptr);
127: }
128:
1.366 vatton 129:
130: /*----------------------------------------------------------------------
131: Number of values
132: ----------------------------------------------------------------------*/
133: static int NumberOfValues (char *ptr)
134: {
135: int n = 0;
136: while (*ptr != EOS && *ptr != ';' && *ptr != '}')
137: {
138: ptr = SkipBlanksAndComments (ptr);
139: n++;
140: ptr = SkipWord (ptr);
141: }
142: return n;
143: }
144:
1.49 cvs 145: /*----------------------------------------------------------------------
1.327 vatton 146: SkipQuotedString
1.1 cvs 147: ----------------------------------------------------------------------*/
1.79 cvs 148: static char *SkipQuotedString (char *ptr, char quote)
1.1 cvs 149: {
1.14 cvs 150: ThotBool stop;
1.1 cvs 151:
152: stop = FALSE;
153: while (!stop)
154: {
1.327 vatton 155: if (*ptr == quote)
156: {
157: ptr++;
158: stop = TRUE;
159: }
160: else if (*ptr == EOS)
161: stop = TRUE;
162: else if (*ptr == '\\')
163: /* escape character */
164: {
165: ptr++;
1.82 cvs 166: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
1.327 vatton 167: (*ptr >= 'a' && *ptr <= 'f'))
168: {
169: ptr++;
170: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
171: (*ptr >= 'a' && *ptr <= 'f'))
172: ptr++;
173: }
174: else
175: ptr++;
176: }
177: else
178: ptr++;
1.1 cvs 179: }
180: return (ptr);
181: }
182:
183: /*----------------------------------------------------------------------
1.327 vatton 184: CSSPrintError
185: print the error message msg on stderr.
186: When the line is 0 ask to expat the current line number
1.86 cvs 187: ----------------------------------------------------------------------*/
1.389 vatton 188: static void CSSPrintError (const char *msg, const char *value)
1.86 cvs 189: {
1.366 vatton 190: if (!DoDialog && !TtaIsPrinting () && ParsedDoc > 0)
1.86 cvs 191: {
192: if (!ErrFile)
1.327 vatton 193: {
194: if (OpenParsingErrors (ParsedDoc) == FALSE)
195: return;
196: }
1.86 cvs 197:
1.308 vatton 198: /* check if a CSS error file shoulb be updated too */
199: if (ParsedCSS > 0 && !CSSErrFile)
1.327 vatton 200: OpenParsingErrors (ParsedCSS);
1.308 vatton 201:
1.348 vatton 202: if (Error_DocURL)
1.327 vatton 203: {
1.348 vatton 204: fprintf (ErrFile, "\n*** Errors/warnings in %s\n", Error_DocURL);
1.327 vatton 205: /* set to NULL as long as the CSS file doesn't change */
1.348 vatton 206: Error_DocURL = NULL;
1.327 vatton 207: }
1.89 cvs 208: CSSErrorsFound = TRUE;
1.86 cvs 209: if (LineNumber < 0)
1.347 quint 210: {
211: if (value)
212: fprintf (ErrFile, " In style attribute, %s \"%s\"\n", msg, value);
213: else
214: fprintf (ErrFile, " In style attribute, %s\n", msg);
215: }
1.86 cvs 216: else
1.327 vatton 217: {
1.347 quint 218: if (value)
219: fprintf (ErrFile, "@ line %d: %s \"%s\"\n",
220: LineNumber+NewLineSkipped, msg, value);
221: else
222: fprintf (ErrFile, "@ line %d: %s\n", LineNumber+NewLineSkipped,
223: msg);
1.327 vatton 224: if (CSSErrFile)
1.347 quint 225: {
226: if (value)
227: fprintf (CSSErrFile, "@ line %d: %s \"%s\"\n",
228: LineNumber+NewLineSkipped, msg, value);
229: else
230: fprintf (CSSErrFile, "@ line %d: %s\n",
231: LineNumber+NewLineSkipped, msg);
232: }
1.327 vatton 233: }
1.86 cvs 234: }
235: }
236:
1.168 vatton 237: /*----------------------------------------------------------------------
1.327 vatton 238: CSSParseError
239: print the error message msg on stderr.
1.168 vatton 240: ----------------------------------------------------------------------*/
1.389 vatton 241: static void CSSParseError (const char *msg, const char *value, char *endvalue)
1.168 vatton 242: {
1.230 quint 243: char c = EOS;
1.168 vatton 244:
245: if (endvalue)
246: {
247: /* close the string here */
248: c = *endvalue;
249: *endvalue = EOS;
250: }
251: CSSPrintError (msg, value);
252: if (endvalue)
253: *endvalue = c;
254: }
255:
1.288 vatton 256: /*----------------------------------------------------------------------
1.342 vatton 257: SkipString move to the end of the string
258: ----------------------------------------------------------------------*/
259: static char *SkipString (char *ptr)
260: {
261: char c = *ptr;
262:
263: ptr++;
264: while (*ptr != EOS &&
265: (*ptr != c || (*ptr == c && ptr[-1] == '\\')))
266: ptr++;
267: return ptr;
268: }
269:
270: /*----------------------------------------------------------------------
1.327 vatton 271: CSSCheckEndValue
272: print an error message if another character is found
1.288 vatton 273: ----------------------------------------------------------------------*/
274: static char *CSSCheckEndValue (char *cssRule, char *endvalue, char *msg)
275: {
276: char c = EOS;
277: if (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.316 quint 278: *endvalue != ';' && *endvalue != '}' && *endvalue != EOL &&
279: *endvalue != TAB && *endvalue != __CR__)
1.288 vatton 280: {
281: while (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.327 vatton 282: *endvalue != ';' && *endvalue != '}' && *endvalue != EOL &&
283: *endvalue != TAB && *endvalue != __CR__)
1.342 vatton 284: {
285: if (*endvalue == '"' || *endvalue == '\'')
286: endvalue = SkipString (endvalue);
287: if (*endvalue != EOS)
288: endvalue++;
289: }
1.288 vatton 290: /* close the string here */
291: c = *endvalue;
292: *endvalue = EOS;
293: CSSPrintError (msg, cssRule);
294: *endvalue = c;
295: }
296: return endvalue;
297: }
298:
1.89 cvs 299:
1.86 cvs 300: /*----------------------------------------------------------------------
1.327 vatton 301: SkipProperty skips a property and display and error message
1.86 cvs 302: ----------------------------------------------------------------------*/
1.234 vatton 303: static char *SkipProperty (char *ptr, ThotBool reportError)
1.86 cvs 304: {
305: char *deb;
306: char c;
307:
308: deb = ptr;
1.301 vatton 309: while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '}')
1.133 vatton 310: {
1.342 vatton 311: if (*ptr == '"' || *ptr == '\'')
312: ptr = SkipString (ptr);
313: if (*ptr != EOS)
314: ptr++;
1.133 vatton 315: }
1.95 cvs 316: /* print the skipped property */
1.86 cvs 317: c = *ptr;
1.386 vatton 318: if (*ptr != EOS)
319: *ptr = EOS;
1.366 vatton 320: if (DoDialog)
321: DisplayStyleValue ("", deb, ptr);
322: else if (reportError && *deb != EOS &&
323: strncasecmp (deb, "azimuth", 7) &&
324: strncasecmp (deb, "border-collapse", 15) &&
325: strncasecmp (deb, "border-spacing", 14) &&
326: strncasecmp (deb, "caption-side", 12) &&
327: strncasecmp (deb, "clip", 4) &&
328: strncasecmp (deb, "counter-increment", 16) &&
329: strncasecmp (deb, "counter-reset", 13) &&
330: strncasecmp (deb, "cue-after", 9) &&
331: strncasecmp (deb, "cue-before", 10) &&
332: strncasecmp (deb, "cue", 3) &&
333: strncasecmp (deb, "cursor", 6) &&
334: strncasecmp (deb, "elevation", 9) &&
335: strncasecmp (deb, "empty-cells", 11) &&
336: strncasecmp (deb, "font-strech", 11) &&
337: strncasecmp (deb, "letter-spacing", 14) &&
338: strncasecmp (deb, "marker-offset", 12) &&
339: strncasecmp (deb, "orphans", 7) &&
340: strncasecmp (deb, "outline-color", 13) &&
341: strncasecmp (deb, "outline-style", 13) &&
342: strncasecmp (deb, "outline-width", 13) &&
343: strncasecmp (deb, "outline", 7) &&
344: strncasecmp (deb, "overflow", 8) &&
345: strncasecmp (deb, "pause-after", 11) &&
346: strncasecmp (deb, "pause-before", 12) &&
347: strncasecmp (deb, "pause", 5) &&
348: strncasecmp (deb, "quotes", 6) &&
349: strncasecmp (deb, "richness", 8) &&
350: strncasecmp (deb, "speech-rate", 11) &&
351: strncasecmp (deb, "speak-header", 12) &&
352: strncasecmp (deb, "speak-punctuation", 17) &&
353: strncasecmp (deb, "speak-numeral", 13) &&
354: strncasecmp (deb, "speak", 5) &&
355: strncasecmp (deb, "pitch-range", 11) &&
356: strncasecmp (deb, "pitch", 5) &&
357: strncasecmp (deb, "stress", 6) &&
358: strncasecmp (deb, "table-layout", 12) &&
359: strncasecmp (deb, "text-shadow", 11) &&
360: strncasecmp (deb, "voice-family", 12) &&
361: strncasecmp (deb, "volume", 6) &&
362: strncasecmp (deb, "widows", 6))
1.205 quint 363: CSSPrintError ("CSS property ignored:", deb);
1.386 vatton 364: if (c != EOS)
365: *ptr = c;
1.86 cvs 366: return (ptr);
367: }
368:
369: /*----------------------------------------------------------------------
1.327 vatton 370: SkipValue
371: skips the value and display an error message if msg is not NULL
1.1 cvs 372: ----------------------------------------------------------------------*/
1.168 vatton 373: static char *SkipValue (char *msg, char *ptr)
1.1 cvs 374: {
1.86 cvs 375: char *deb;
376: char c;
377:
378: deb = ptr;
1.387 quint 379: while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '\n')
1.133 vatton 380: {
1.342 vatton 381: if (*ptr == '"' || *ptr == '\'')
382: ptr = SkipString (ptr);
383: if (*ptr != EOS)
384: ptr++;
1.133 vatton 385: }
1.95 cvs 386: /* print the skipped property */
1.86 cvs 387: c = *ptr;
388: *ptr = EOS;
1.168 vatton 389: if (msg && *deb != EOS && *deb != ',')
390: CSSPrintError (msg, deb);
1.86 cvs 391: *ptr = c;
1.1 cvs 392: return (ptr);
393: }
394:
395: /*----------------------------------------------------------------------
1.327 vatton 396: ParseNumber:
397: parse a number and returns the corresponding value.
1.1 cvs 398: ----------------------------------------------------------------------*/
1.79 cvs 399: char *ParseNumber (char *cssRule, PresentationValue *pval)
1.1 cvs 400: {
401: int val = 0;
402: int minus = 0;
403: int valid = 0;
404: int f = 0;
1.14 cvs 405: ThotBool real = FALSE;
1.1 cvs 406:
1.184 vatton 407: pval->typed_data.unit = UNIT_REL;
1.1 cvs 408: pval->typed_data.real = FALSE;
1.82 cvs 409: cssRule = SkipBlanksAndComments (cssRule);
410: if (*cssRule == '-')
1.1 cvs 411: {
412: minus = 1;
413: cssRule++;
1.82 cvs 414: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 415: }
1.387 quint 416: else if (*cssRule == '+')
1.1 cvs 417: {
418: cssRule++;
1.82 cvs 419: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 420: }
421:
1.82 cvs 422: while ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 423: {
424: val *= 10;
1.82 cvs 425: val += *cssRule - '0';
1.1 cvs 426: cssRule++;
427: valid = 1;
428: }
429:
1.82 cvs 430: if (*cssRule == '.')
1.1 cvs 431: {
432: real = TRUE;
433: f = val;
434: val = 0;
435: cssRule++;
436: /* keep only 3 digits */
1.82 cvs 437: if (*cssRule >= '0' && *cssRule <= '9')
1.327 vatton 438: {
439: val = (*cssRule - '0') * 100;
440: cssRule++;
441: if (*cssRule >= '0' && *cssRule <= '9')
442: {
443: val += (*cssRule - '0') * 10;
444: cssRule++;
445: if ((*cssRule >= '0') && (*cssRule <= '9'))
446: {
447: val += *cssRule - '0';
448: cssRule++;
449: }
450: }
451:
452: while (*cssRule >= '0' && *cssRule <= '9')
453: cssRule++;
454: valid = 1;
455: }
1.1 cvs 456: }
457:
458: if (!valid)
459: {
1.184 vatton 460: pval->typed_data.unit = UNIT_INVALID;
1.1 cvs 461: pval->typed_data.value = 0;
462: }
463: else
464: {
465: pval->typed_data.real = real;
466: if (real)
1.327 vatton 467: {
468: if (minus)
469: pval->typed_data.value = -(f * 1000 + val);
470: else
471: pval->typed_data.value = f * 1000 + val;
472: }
1.1 cvs 473: else
1.327 vatton 474: {
475: if (minus)
476: pval->typed_data.value = -val;
477: else
478: pval->typed_data.value = val;
479: }
1.64 cvs 480: }
481: return (cssRule);
482: }
1.195 vatton 483:
1.155 cheyroul 484: /*----------------------------------------------------------------------
1.327 vatton 485: ParseCSSUnit:
1.369 quint 486: parse a number followed by a CSS Unit and returns the corresponding
1.327 vatton 487: value and its unit.
1.64 cvs 488: ----------------------------------------------------------------------*/
1.82 cvs 489: char *ParseCSSUnit (char *cssRule, PresentationValue *pval)
1.64 cvs 490: {
1.368 vatton 491: char *p;
1.64 cvs 492: unsigned int uni;
493:
1.184 vatton 494: pval->typed_data.unit = UNIT_REL;
1.64 cvs 495: cssRule = ParseNumber (cssRule, pval);
1.184 vatton 496: if (pval->typed_data.unit == UNIT_INVALID)
1.387 quint 497: /* it does not start with a valid number */
1.327 vatton 498: cssRule = SkipWord (cssRule);
1.64 cvs 499: else
500: {
1.369 quint 501: /* is there a space after the number? */
1.368 vatton 502: p = cssRule;
1.82 cvs 503: cssRule = SkipBlanksAndComments (cssRule);
1.368 vatton 504: if (p == cssRule)
1.369 quint 505: /* no space */
1.368 vatton 506: p = NULL;
1.369 quint 507: else
508: /* a space is here. restore the pointer */
509: cssRule = p;
1.231 vatton 510: uni = 0;
511: while (CSSUnitNames[uni].sign)
1.327 vatton 512: {
513: if (!strncasecmp (CSSUnitNames[uni].sign, cssRule,
514: strlen (CSSUnitNames[uni].sign)))
1.369 quint 515: /* this is a correct unit */
1.327 vatton 516: {
517: pval->typed_data.unit = CSSUnitNames[uni].unit;
1.368 vatton 518: if (p)
1.369 quint 519: /* there was a space before the unit. Syntax error */
1.368 vatton 520: pval->typed_data.unit = UNIT_INVALID;
1.327 vatton 521: return (cssRule + strlen (CSSUnitNames[uni].sign));
522: }
523: else
524: uni++;
525: }
1.369 quint 526: /* not in the list of accepted units */
1.184 vatton 527: pval->typed_data.unit = UNIT_BOX;
1.1 cvs 528: }
529: return (cssRule);
530: }
531:
1.43 cvs 532: /*----------------------------------------------------------------------
1.327 vatton 533: ParseClampedUnit:
534: parse a CSS Unit substring and returns the corresponding value and unit.
535: [0,1]
1.239 vatton 536: ----------------------------------------------------------------------*/
537: char *ParseClampedUnit (char *cssRule, PresentationValue *pval)
538: {
1.251 vatton 539: char *p;
540:
541: p = cssRule;
1.239 vatton 542: cssRule = ParseNumber (cssRule, pval);
1.301 vatton 543: if (*cssRule != EOS && *cssRule != SPACE && *cssRule != ';' && *cssRule != '}')
1.239 vatton 544: {
1.251 vatton 545: cssRule++;
1.239 vatton 546: pval->typed_data.unit = UNIT_REL;
547: if (pval->typed_data.value > 100)
1.327 vatton 548: pval->typed_data.value = 1000;
1.239 vatton 549: else
1.327 vatton 550: pval->typed_data.value *= 10;
1.251 vatton 551: CSSParseError ("Invalid value", p, cssRule);
1.239 vatton 552: }
553: else
554: {
555: pval->typed_data.unit = UNIT_REL;
556: if (pval->typed_data.real)
1.327 vatton 557: pval->typed_data.real = FALSE;
1.239 vatton 558: else if (pval->typed_data.value > 1)
1.327 vatton 559: {
560: pval->typed_data.value = 1000;
561: CSSParseError ("Invalid value", p, cssRule);
562: }
1.251 vatton 563: else if (pval->typed_data.value < 0)
1.327 vatton 564: {
565: pval->typed_data.value = 0;
566: CSSParseError ("Invalid value", p, cssRule);
567: }
1.239 vatton 568: else
1.327 vatton 569: pval->typed_data.value *= 1000;
1.239 vatton 570: }
571: pval->data = pval->typed_data.value;
572: return (cssRule);
573: }
574:
575:
576: /*----------------------------------------------------------------------
1.327 vatton 577: ParseABorderValue
1.43 cvs 578: ----------------------------------------------------------------------*/
1.288 vatton 579: static char *ParseABorderValue (char *cssRule, PresentationValue *border)
1.43 cvs 580: {
1.288 vatton 581: char *ptr = cssRule;
1.168 vatton 582:
1.43 cvs 583: /* first parse the attribute string */
1.319 quint 584: border->typed_data.value = 0;
585: border->typed_data.unit = UNIT_INVALID;
586: border->typed_data.real = FALSE;
587: if (!strncasecmp (cssRule, "thin", 4))
588: {
589: border->typed_data.unit = UNIT_PX;
590: border->typed_data.value = 1;
591: cssRule += 4;
592: }
593: else if (!strncasecmp (cssRule, "medium", 6))
594: {
595: border->typed_data.unit = UNIT_PX;
596: border->typed_data.value = 3;
597: cssRule += 6;
598: }
599: else if (!strncasecmp (cssRule, "thick", 5))
600: {
601: border->typed_data.unit = UNIT_PX;
602: border->typed_data.value = 5;
603: cssRule += 5;
604: }
605: else if (!strncasecmp (cssRule, "inherit", 7))
606: {
607: border->typed_data.unit = VALUE_INHERIT;
608: cssRule += 7;
609: }
610: else if (isdigit (*cssRule) || *cssRule == '.')
611: {
612: cssRule = ParseCSSUnit (cssRule, border);
1.387 quint 613: if (border->typed_data.value == 0 &&
614: border->typed_data.unit != UNIT_INVALID)
1.327 vatton 615: border->typed_data.unit = UNIT_PX;
1.319 quint 616: else if (border->typed_data.unit == UNIT_INVALID ||
1.327 vatton 617: border->typed_data.unit == UNIT_BOX ||
618: border->typed_data.unit == UNIT_PERCENT)
619: {
620: border->typed_data.unit = UNIT_INVALID;
621: border->typed_data.value = 0;
622: CSSParseError ("Invalid border-width value", ptr, cssRule);
623: }
1.319 quint 624: }
625: return (cssRule);
1.43 cvs 626: }
627:
1.288 vatton 628:
629: /*----------------------------------------------------------------------
1.327 vatton 630: ParseBorderStyle
1.43 cvs 631: ----------------------------------------------------------------------*/
1.79 cvs 632: static char *ParseBorderStyle (char *cssRule, PresentationValue *border)
1.43 cvs 633: {
634: /* first parse the attribute string */
1.327 vatton 635: border->typed_data.value = 0;
636: border->typed_data.unit = UNIT_PX;
637: border->typed_data.real = FALSE;
638: if (!strncasecmp (cssRule, "none", 4))
639: {
640: border->typed_data.value = BorderStyleNone;
641: cssRule += 4;
642: }
643: else if (!strncasecmp (cssRule, "hidden", 6))
644: {
645: border->typed_data.value = BorderStyleHidden;
646: cssRule += 6;
647: }
648: else if (!strncasecmp (cssRule, "dotted", 6))
649: {
1.288 vatton 650: cssRule += 6;
1.327 vatton 651: border->typed_data.value = BorderStyleDotted;
1.288 vatton 652: }
1.327 vatton 653: else if (!strncasecmp (cssRule, "dashed", 6))
654: {
655: border->typed_data.value = BorderStyleDashed;
656: cssRule += 6;
657: }
658: else if (!strncasecmp (cssRule, "solid", 5))
659: {
660: border->typed_data.value = BorderStyleSolid;
661: cssRule += 5;
662: }
663: else if (!strncasecmp (cssRule, "double", 6))
664: {
665: border->typed_data.value = BorderStyleDouble;
666: cssRule += 6;
667: }
668: else if (!strncasecmp (cssRule, "groove", 6))
669: {
670: border->typed_data.value = BorderStyleGroove;
671: cssRule += 6;
672: }
673: else if (!strncasecmp (cssRule, "ridge", 5))
674: {
675: border->typed_data.value = BorderStyleRidge;
676: cssRule += 5;
677: }
678: else if (!strncasecmp (cssRule, "inset", 5))
679: {
680: border->typed_data.value = BorderStyleInset;
681: cssRule += 5;
682: }
683: else if (!strncasecmp (cssRule, "outset", 6))
684: {
685: border->typed_data.value = BorderStyleOutset;
686: cssRule += 6;
687: }
688: else
689: {
690: /* invalid style */
691: border->typed_data.unit = UNIT_INVALID;
692: return (cssRule);
693: }
694: return (cssRule);
1.43 cvs 695: }
696:
697: /*----------------------------------------------------------------------
1.327 vatton 698: ParseCSSColor: parse a CSS color attribute string
699: we expect the input string describing the attribute to be
700: either a color name, a 3 tuple or an hexadecimal encoding.
701: The color used will be approximed from the current color
702: table
1.43 cvs 703: ----------------------------------------------------------------------*/
1.79 cvs 704: static char *ParseCSSColor (char *cssRule, PresentationValue * val)
1.43 cvs 705: {
1.79 cvs 706: char *ptr;
1.43 cvs 707: unsigned short redval = (unsigned short) -1;
708: unsigned short greenval = 0; /* composant of each RGB */
709: unsigned short blueval = 0; /* default to red if unknown ! */
710: int best = 0; /* best color in list found */
711:
1.82 cvs 712: cssRule = SkipBlanksAndComments (cssRule);
1.184 vatton 713: val->typed_data.unit = UNIT_INVALID;
1.43 cvs 714: val->typed_data.real = FALSE;
715: val->typed_data.value = 0;
1.57 cvs 716: ptr = TtaGiveRGB (cssRule, &redval, &greenval, &blueval);
1.292 vatton 717: if (!strncasecmp (cssRule, "InactiveCaptionText", 19))
718: {
1.364 vatton 719: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 720: cssRule += 19;
721: }
722: else if (!strncasecmp (cssRule, "ThreeDLightShadow", 17))
723: {
1.364 vatton 724: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 725: cssRule += 17;
726: }
727: else if (!strncasecmp (cssRule, "ThreeDDarkShadow", 16))
728: {
1.364 vatton 729: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 730: cssRule += 16;
731: }
732: else if (!strncasecmp (cssRule, "ButtonHighlight", 15) ||
1.327 vatton 733: !strncasecmp (cssRule, "InactiveCaption", 15) ||
734: !strncasecmp (cssRule, "ThreeDHighlight", 15))
1.292 vatton 735: {
1.364 vatton 736: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 737: cssRule += 15;
738: }
739: else if (!strncasecmp (cssRule, "InactiveBorder", 14) ||
1.327 vatton 740: !strncasecmp (cssRule, "InfoBackground", 14))
1.292 vatton 741: {
1.364 vatton 742: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 743: cssRule += 14;
744: }
745: else if (!strncasecmp (cssRule, "ActiveCaption", 13) ||
1.327 vatton 746: !strncasecmp (cssRule, "HighlightText", 13))
1.292 vatton 747: {
1.364 vatton 748: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 749: cssRule += 13;
750: }
751: else if (!strncasecmp (cssRule, "ActiveBorder", 12) ||
1.327 vatton 752: !strncasecmp (cssRule, "AppWorkspace", 12) ||
753: !strncasecmp (cssRule, "ButtonShadow", 12) ||
754: !strncasecmp (cssRule, "ThreeDShadow", 12))
1.292 vatton 755: {
1.364 vatton 756: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 757: cssRule += 12;
758: }
759: else if (!strncasecmp (cssRule, "CaptionText", 11) ||
1.327 vatton 760: !strncasecmp (cssRule, "WindowFrame", 11))
1.292 vatton 761: {
1.364 vatton 762: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 763: cssRule += 11;
764: }
765: else if (!strncasecmp (cssRule, "Background", 10) ||
1.327 vatton 766: !strncasecmp (cssRule, "ButtonFace", 10) ||
767: !strncasecmp (cssRule, "ButtonText", 10) ||
768: !strncasecmp (cssRule, "ThreeDFace", 10) ||
769: !strncasecmp (cssRule, "WindowText", 10))
1.292 vatton 770: {
1.364 vatton 771: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 772: cssRule += 10;
773: }
774: else if (!strncasecmp (cssRule, "Highlight", 9) ||
1.327 vatton 775: !strncasecmp (cssRule, "Scrollbar", 9))
1.292 vatton 776: {
1.364 vatton 777: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 778: cssRule += 9;
779: }
780: else if (!strncasecmp (cssRule, "GrayText", 8) ||
1.327 vatton 781: !strncasecmp (cssRule, "InfoText", 8) ||
782: !strncasecmp (cssRule, "MenuText", 8))
1.292 vatton 783: {
1.364 vatton 784: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 785: cssRule += 8;
786: }
787: else if (!strncasecmp (cssRule, "Window", 6))
788: {
1.364 vatton 789: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 790: cssRule += 6;
791: }
792: else if (!strncasecmp (cssRule, "Menu", 5))
793: {
1.364 vatton 794: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 795: cssRule += 5;
796: }
1.293 quint 797: else if (!strncasecmp (cssRule, "inherit", 7))
798: {
799: val->typed_data.unit = VALUE_INHERIT;
800: cssRule += 7;
801: }
1.292 vatton 802:
1.57 cvs 803: if (ptr == cssRule)
1.43 cvs 804: {
1.168 vatton 805: cssRule = SkipWord (cssRule);
806: CSSParseError ("Invalid color value", ptr, cssRule);
1.43 cvs 807: val->typed_data.value = 0;
1.184 vatton 808: val->typed_data.unit = UNIT_INVALID;
1.43 cvs 809: }
1.293 quint 810: else if (val->typed_data.unit != VALUE_INHERIT)
1.43 cvs 811: {
812: best = TtaGetThotColor (redval, greenval, blueval);
813: val->typed_data.value = best;
1.184 vatton 814: val->typed_data.unit = UNIT_REL;
1.57 cvs 815: cssRule = ptr;
1.43 cvs 816: }
817: val->typed_data.real = FALSE;
1.262 vatton 818: cssRule = SkipBlanksAndComments (cssRule);
1.65 cvs 819: return (cssRule);
1.43 cvs 820: }
1.1 cvs 821:
822: /*----------------------------------------------------------------------
1.231 vatton 823: CheckImportantRule updates the field important of the context and
824: the line number.
1.117 vatton 825: ----------------------------------------------------------------------*/
1.360 vatton 826: static void CheckImportantRule (char *cssRule, PresentationContext context)
1.117 vatton 827: {
1.276 vatton 828: PresentationContextBlock dummyctxt;
829:
830: if (context == NULL)
831: /* no context provided */
832: context = &dummyctxt;
833:
1.117 vatton 834: cssRule = SkipBlanksAndComments (cssRule);
1.360 vatton 835: while (*cssRule != EOS && *cssRule != '!' && *cssRule != ';')
836: cssRule++;
1.120 vatton 837: if (*cssRule != '!')
838: context->important = FALSE;
839: else
1.117 vatton 840: {
1.120 vatton 841: cssRule++;
1.360 vatton 842: ImportantPos = cssRule;
1.120 vatton 843: cssRule = SkipBlanksAndComments (cssRule);
844: if (!strncasecmp (cssRule, "important", 9))
1.327 vatton 845: {
1.360 vatton 846: ImportantPos[-1] = EOS;
1.327 vatton 847: context->important = TRUE;
848: }
1.120 vatton 849: else
1.360 vatton 850: {
851: ImportantPos = NULL;
852: context->important = FALSE;
853: }
854: }
855: }
856:
857: /*----------------------------------------------------------------------
858: SkipImportantRule skips important markup
859: ----------------------------------------------------------------------*/
860: static char *SkipImportantRule (char *cssRule)
861: {
862: if (ImportantPos)
863: {
864: ImportantPos[-1] = '!';
1.361 vatton 865: cssRule = ImportantPos;
866: cssRule = SkipBlanksAndComments (cssRule);
867: cssRule += 9;
1.360 vatton 868: ImportantPos = NULL;
1.117 vatton 869: }
1.360 vatton 870: cssRule = SkipBlanksAndComments (cssRule);
1.117 vatton 871: return (cssRule);
872: }
873:
874: /*----------------------------------------------------------------------
1.327 vatton 875: ParseCSSBorderTopWidth: parse a CSS BorderTopWidth
876: attribute string.
1.1 cvs 877: ----------------------------------------------------------------------*/
1.79 cvs 878: static char *ParseCSSBorderTopWidth (Element element, PSchema tsch,
1.327 vatton 879: PresentationContext context,
880: char *cssRule, CSSInfoPtr css,
881: ThotBool isHTML)
1.1 cvs 882: {
1.41 cvs 883: PresentationValue border;
1.366 vatton 884: char *start_value = cssRule;
1.41 cvs 885:
1.82 cvs 886: cssRule = SkipBlanksAndComments (cssRule);
1.288 vatton 887: cssRule = ParseABorderValue (cssRule, &border);
1.366 vatton 888: if (border.typed_data.unit != UNIT_INVALID)
889: {
890: if (DoDialog)
891: {
892: if (All_sides)
893: DisplayStyleValue ("border-width", start_value, cssRule);
894: else
895: DisplayStyleValue ("border-top-width", start_value, cssRule);
896: }
897: else if (DoApply)
898: TtaSetStylePresentation (PRBorderTopWidth, element, tsch, context, border);
899: }
1.1 cvs 900: return (cssRule);
901: }
902:
903: /*----------------------------------------------------------------------
1.327 vatton 904: ParseCSSBorderBottomWidth: parse a CSS BorderBottomWidth
905: attribute string.
1.1 cvs 906: ----------------------------------------------------------------------*/
1.79 cvs 907: static char *ParseCSSBorderBottomWidth (Element element, PSchema tsch,
1.327 vatton 908: PresentationContext context,
909: char *cssRule, CSSInfoPtr css,
910: ThotBool isHTML)
1.1 cvs 911: {
1.41 cvs 912: PresentationValue border;
1.366 vatton 913: char *start_value = cssRule;
1.41 cvs 914:
1.82 cvs 915: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 916: /* first parse the attribute string */
1.288 vatton 917: cssRule = ParseABorderValue (cssRule, &border);
1.366 vatton 918: if (border.typed_data.unit != UNIT_INVALID)
919: {
920: if (DoDialog)
921: DisplayStyleValue ("border-bottom-width", start_value, cssRule);
922: else if (DoApply)
923: TtaSetStylePresentation (PRBorderBottomWidth, element, tsch, context, border);
924: }
1.1 cvs 925: return (cssRule);
926: }
927:
928: /*----------------------------------------------------------------------
1.327 vatton 929: ParseCSSBorderLeftWidth: parse a CSS BorderLeftWidth
930: attribute string.
1.1 cvs 931: ----------------------------------------------------------------------*/
1.79 cvs 932: static char *ParseCSSBorderLeftWidth (Element element, PSchema tsch,
1.327 vatton 933: PresentationContext context,
934: char *cssRule, CSSInfoPtr css,
935: ThotBool isHTML)
1.1 cvs 936: {
1.41 cvs 937: PresentationValue border;
1.366 vatton 938: char *start_value = cssRule;
1.41 cvs 939:
1.82 cvs 940: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 941: /* first parse the attribute string */
1.288 vatton 942: cssRule = ParseABorderValue (cssRule, &border);
1.366 vatton 943: if (border.typed_data.unit != UNIT_INVALID)
944: {
945: if (DoDialog)
946: DisplayStyleValue ("border-left-width", start_value, cssRule);
947: else if (DoApply)
948: TtaSetStylePresentation (PRBorderLeftWidth, element, tsch, context, border);
949: }
1.1 cvs 950: return (cssRule);
951: }
952:
953: /*----------------------------------------------------------------------
1.327 vatton 954: ParseCSSBorderRightWidth: parse a CSS BorderRightWidth
955: attribute string.
1.1 cvs 956: ----------------------------------------------------------------------*/
1.79 cvs 957: static char *ParseCSSBorderRightWidth (Element element, PSchema tsch,
1.327 vatton 958: PresentationContext context,
959: char *cssRule, CSSInfoPtr css,
960: ThotBool isHTML)
1.1 cvs 961: {
1.41 cvs 962: PresentationValue border;
1.366 vatton 963: char *start_value = cssRule;
1.41 cvs 964:
1.82 cvs 965: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 966: /* first parse the attribute string */
1.288 vatton 967: cssRule = ParseABorderValue (cssRule, &border);
1.184 vatton 968: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 969: {
970: if (DoDialog)
971: DisplayStyleValue ("border-right-width", start_value, cssRule);
972: else if (DoApply)
973: TtaSetStylePresentation (PRBorderRightWidth, element, tsch, context, border);
974: }
1.1 cvs 975: return (cssRule);
976: }
977:
978: /*----------------------------------------------------------------------
1.327 vatton 979: ParseCSSBorderWidth: parse a CSS BorderWidth
980: attribute string.
1.1 cvs 981: ----------------------------------------------------------------------*/
1.79 cvs 982: static char *ParseCSSBorderWidth (Element element, PSchema tsch,
1.327 vatton 983: PresentationContext context,
984: char *cssRule, CSSInfoPtr css,
985: ThotBool isHTML)
1.1 cvs 986: {
1.79 cvs 987: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 988: int skippedNL, n;
1.41 cvs 989:
1.82 cvs 990: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 991: if (DoDialog)
992: n = NumberOfValues (ptrT);
993: if (DoDialog && n < 2)
1.42 cvs 994: {
1.366 vatton 995: // check if the border dialog must be updated
996: All_sides = TRUE;
997: ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
998: All_sides = FALSE;
1.42 cvs 999: }
1000: else
1001: {
1.366 vatton 1002: /* First parse Border-Top */
1003: ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1004: ptrR = SkipBlanksAndComments (ptrR);
1005: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 1006: {
1007: skippedNL = NewLineSkipped;
1.366 vatton 1008: cssRule = ptrR;
1009: /* apply the Border-Top to all */
1010: ptrR = ParseCSSBorderRightWidth (element, tsch, context, ptrT, css, isHTML);
1011: NewLineSkipped = skippedNL;
1012: ptrR = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1013: NewLineSkipped = skippedNL;
1.366 vatton 1014: ptrR = ParseCSSBorderLeftWidth (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1015: }
1.42 cvs 1016: else
1.327 vatton 1017: {
1.366 vatton 1018: /* parse Border-Right */
1019: ptrB = ParseCSSBorderRightWidth (element, tsch, context, ptrR, css, isHTML);
1020: ptrB = SkipBlanksAndComments (ptrB);
1021: if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 1022: {
1.366 vatton 1023: skippedNL = NewLineSkipped;
1024: cssRule = ptrB;
1025: /* apply the Border-Top to Border-Bottom */
1026: ptrB = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1027: NewLineSkipped = skippedNL;
1.327 vatton 1028: /* apply the Border-Right to Border-Left */
1.366 vatton 1029: ptrB = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 1030: }
1031: else
1.366 vatton 1032: {
1033: /* parse Border-Bottom */
1034: ptrL = ParseCSSBorderBottomWidth (element, tsch, context, ptrB, css, isHTML);
1035: ptrL = SkipBlanksAndComments (ptrL);
1036: if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
1037: {
1038: cssRule = ptrL;
1039: /* apply the Border-Right to Border-Left */
1040: ptrL = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
1041: }
1042: else
1043: /* parse Border-Left */
1044: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, ptrL, css, isHTML);
1045: cssRule = SkipBlanksAndComments (cssRule);
1046: }
1.327 vatton 1047: }
1.42 cvs 1048: }
1.1 cvs 1049: return (cssRule);
1050: }
1051:
1052: /*----------------------------------------------------------------------
1.327 vatton 1053: ParseCSSBorderColorTop: parse a CSS BorderColorTop
1054: attribute string.
1.1 cvs 1055: ----------------------------------------------------------------------*/
1.79 cvs 1056: static char *ParseCSSBorderColorTop (Element element, PSchema tsch,
1.327 vatton 1057: PresentationContext context,
1058: char *cssRule, CSSInfoPtr css,
1059: ThotBool isHTML)
1.1 cvs 1060: {
1.117 vatton 1061: PresentationValue best;
1.366 vatton 1062: char *start_value = cssRule;
1.43 cvs 1063:
1.234 vatton 1064: if (!strncasecmp (cssRule, "transparent", 11))
1065: {
1066: best.typed_data.value = -2; /* -2 means transparent */
1067: best.typed_data.unit = UNIT_REL;
1068: cssRule = SkipWord (cssRule);
1069: }
1070: else
1071: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 1072: if (best.typed_data.unit != UNIT_INVALID)
1073: {
1074: if (DoDialog)
1075: {
1076: if (All_sides)
1077: DisplayStyleValue ("border-color", start_value, cssRule);
1078: else
1079: DisplayStyleValue ("border-top-color", start_value, cssRule);
1080: }
1081: else if (DoApply)
1082: /* install the new presentation */
1083: TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
1084: }
1.117 vatton 1085: return (cssRule);
1.1 cvs 1086: }
1087:
1088: /*----------------------------------------------------------------------
1.327 vatton 1089: ParseCSSBorderColorLeft: parse a CSS BorderColorLeft
1090: attribute string.
1.42 cvs 1091: ----------------------------------------------------------------------*/
1.79 cvs 1092: static char *ParseCSSBorderColorLeft (Element element, PSchema tsch,
1.327 vatton 1093: PresentationContext context,
1094: char *cssRule, CSSInfoPtr css,
1095: ThotBool isHTML)
1.42 cvs 1096: {
1.117 vatton 1097: PresentationValue best;
1.366 vatton 1098: char *start_value = cssRule;
1.117 vatton 1099:
1.234 vatton 1100: if (!strncasecmp (cssRule, "transparent", 11))
1101: {
1102: best.typed_data.value = -2; /* -2 means transparent */
1103: best.typed_data.unit = UNIT_REL;
1104: cssRule = SkipWord (cssRule);
1105: }
1106: else
1107: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 1108: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1109: {
1110: if (DoDialog)
1111: DisplayStyleValue ("border-left-color", start_value, cssRule);
1112: else if (DoApply)
1113: /* install the new presentation */
1114: TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
1115: }
1.117 vatton 1116: return (cssRule);
1.42 cvs 1117: }
1118:
1119: /*----------------------------------------------------------------------
1.327 vatton 1120: ParseCSSBorderColorBottom: parse a CSS BorderColorBottom
1121: attribute string.
1.42 cvs 1122: ----------------------------------------------------------------------*/
1.79 cvs 1123: static char *ParseCSSBorderColorBottom (Element element, PSchema tsch,
1.327 vatton 1124: PresentationContext context,
1125: char *cssRule, CSSInfoPtr css,
1126: ThotBool isHTML)
1.42 cvs 1127: {
1.117 vatton 1128: PresentationValue best;
1.366 vatton 1129: char *start_value = cssRule;
1.43 cvs 1130:
1.234 vatton 1131: if (!strncasecmp (cssRule, "transparent", 11))
1132: {
1133: best.typed_data.value = -2; /* -2 means transparent */
1134: best.typed_data.unit = UNIT_REL;
1135: cssRule = SkipWord (cssRule);
1136: }
1137: else
1138: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 1139: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1140: {
1141: if (DoDialog)
1142: DisplayStyleValue ("border-bottom-color", start_value, cssRule);
1143: else if (DoApply)
1144: /* install the new presentation */
1145: TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
1146: }
1.327 vatton 1147: return (cssRule);
1.42 cvs 1148: }
1149:
1150: /*----------------------------------------------------------------------
1.327 vatton 1151: ParseCSSBorderColorRight: parse a CSS BorderColorRight
1152: attribute string.
1.1 cvs 1153: ----------------------------------------------------------------------*/
1.79 cvs 1154: static char *ParseCSSBorderColorRight (Element element, PSchema tsch,
1.327 vatton 1155: PresentationContext context,
1156: char *cssRule, CSSInfoPtr css,
1157: ThotBool isHTML)
1.1 cvs 1158: {
1.117 vatton 1159: PresentationValue best;
1.366 vatton 1160: char *start_value = cssRule;
1.43 cvs 1161:
1.234 vatton 1162: if (!strncasecmp (cssRule, "transparent", 11))
1163: {
1164: best.typed_data.value = -2; /* -2 means transparent */
1165: best.typed_data.unit = UNIT_REL;
1166: cssRule = SkipWord (cssRule);
1167: }
1168: else
1169: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 1170: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1171: {
1172: if (DoDialog)
1173: DisplayStyleValue ("border-right-color", start_value, cssRule);
1174: else if (DoApply)
1175: TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
1176: }
1.117 vatton 1177: return (cssRule);
1.1 cvs 1178: }
1179:
1180: /*----------------------------------------------------------------------
1.327 vatton 1181: ParseCSSBorderColor: parse a CSS border-color
1182: attribute string.
1.42 cvs 1183: ----------------------------------------------------------------------*/
1.79 cvs 1184: static char *ParseCSSBorderColor (Element element, PSchema tsch,
1.327 vatton 1185: PresentationContext context,
1186: char *cssRule, CSSInfoPtr css,
1187: ThotBool isHTML)
1.42 cvs 1188: {
1.79 cvs 1189: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 1190: int skippedNL, n;
1.42 cvs 1191:
1.82 cvs 1192: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 1193: if (DoDialog)
1194: n = NumberOfValues (ptrT);
1195: if (DoDialog && n < 2)
1.42 cvs 1196: {
1.366 vatton 1197: // check if the border dialog must be updated
1198: All_sides = TRUE;
1199: ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1200: All_sides = FALSE;
1.42 cvs 1201: }
1202: else
1203: {
1.366 vatton 1204: /* First parse Border-Top */
1205: ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1206: ptrR = SkipBlanksAndComments (ptrR);
1207: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 1208: {
1209: skippedNL = NewLineSkipped;
1.366 vatton 1210: cssRule = ptrR;
1211: /* apply the Border-Top to all */
1212: ptrR = ParseCSSBorderColorRight (element, tsch, context, ptrT, css, isHTML);
1213: NewLineSkipped = skippedNL;
1214: ptrR = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1215: NewLineSkipped = skippedNL;
1.366 vatton 1216: ptrR = ParseCSSBorderColorLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1217: }
1.42 cvs 1218: else
1.327 vatton 1219: {
1.366 vatton 1220: /* parse Border-Right */
1221: ptrB = ParseCSSBorderColorRight (element, tsch, context, ptrR, css, isHTML);
1222: ptrB = SkipBlanksAndComments (ptrB);
1223: if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 1224: {
1.366 vatton 1225: skippedNL = NewLineSkipped;
1226: cssRule = ptrB;
1227: /* apply the Border-Top to Border-Bottom */
1228: ptrB = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1229: NewLineSkipped = skippedNL;
1.327 vatton 1230: /* apply the Border-Right to Border-Left */
1.366 vatton 1231: ptrB = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 1232: }
1233: else
1.366 vatton 1234: {
1235: skippedNL = NewLineSkipped;
1236: /* parse Border-Bottom */
1237: ptrL = ParseCSSBorderColorBottom (element, tsch, context, ptrB, css, isHTML);
1238: NewLineSkipped = skippedNL;
1239: ptrL = SkipBlanksAndComments (ptrL);
1240: if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
1241: {
1242: cssRule = ptrL;
1243: /* apply the Border-Right to Border-Left */
1244: ptrL = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1245: }
1246: else
1247: /* parse Border-Left */
1248: cssRule = ParseCSSBorderColorLeft (element, tsch, context, ptrL, css, isHTML);
1249: cssRule = SkipBlanksAndComments (cssRule);
1250: }
1.327 vatton 1251: }
1.42 cvs 1252: }
1253: return (cssRule);
1254: }
1255:
1256: /*----------------------------------------------------------------------
1.327 vatton 1257: ParseCSSBorderStyleTop: parse a CSS BorderStyleTop
1258: attribute string.
1.42 cvs 1259: ----------------------------------------------------------------------*/
1.79 cvs 1260: static char *ParseCSSBorderStyleTop (Element element, PSchema tsch,
1.327 vatton 1261: PresentationContext context,
1262: char *cssRule, CSSInfoPtr css,
1263: ThotBool isHTML)
1.42 cvs 1264: {
1.43 cvs 1265: PresentationValue border;
1.366 vatton 1266: char *start_value;
1.43 cvs 1267:
1.82 cvs 1268: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1269: start_value = cssRule;
1.43 cvs 1270: cssRule = ParseBorderStyle (cssRule, &border);
1.366 vatton 1271: if (border.typed_data.unit != UNIT_INVALID)
1272: {
1273: if (DoDialog)
1274: {
1275: if (All_sides)
1276: DisplayStyleValue ("border-style", start_value, cssRule);
1277: else
1278: DisplayStyleValue ("border-top-style", start_value, cssRule);
1279: }
1280: else if (DoApply)
1281: TtaSetStylePresentation (PRBorderTopStyle, element, tsch, context, border);
1282: }
1.42 cvs 1283: return (cssRule);
1284: }
1285:
1286: /*----------------------------------------------------------------------
1.327 vatton 1287: ParseCSSBorderStyleLeft: parse a CSS BorderStyleLeft
1288: attribute string.
1.42 cvs 1289: ----------------------------------------------------------------------*/
1.79 cvs 1290: static char *ParseCSSBorderStyleLeft (Element element, PSchema tsch,
1.327 vatton 1291: PresentationContext context,
1292: char *cssRule, CSSInfoPtr css,
1293: ThotBool isHTML)
1.42 cvs 1294: {
1.43 cvs 1295: PresentationValue border;
1.366 vatton 1296: char *start_value;
1.43 cvs 1297:
1.82 cvs 1298: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1299: start_value = cssRule;
1.43 cvs 1300: cssRule = ParseBorderStyle (cssRule, &border);
1.366 vatton 1301: if (border.typed_data.unit != UNIT_INVALID)
1302: {
1303: if (DoDialog)
1304: DisplayStyleValue ("border-left-style", start_value, cssRule);
1305: else if (DoApply)
1306: TtaSetStylePresentation (PRBorderLeftStyle, element, tsch, context, border);
1307: }
1.42 cvs 1308: return (cssRule);
1309: }
1310:
1311: /*----------------------------------------------------------------------
1.327 vatton 1312: ParseCSSBorderStyleBottom: parse a CSS BorderStyleBottom
1313: attribute string.
1.1 cvs 1314: ----------------------------------------------------------------------*/
1.79 cvs 1315: static char *ParseCSSBorderStyleBottom (Element element, PSchema tsch,
1.327 vatton 1316: PresentationContext context,
1317: char *cssRule, CSSInfoPtr css,
1318: ThotBool isHTML)
1.1 cvs 1319: {
1.43 cvs 1320: PresentationValue border;
1.366 vatton 1321: char *start_value;
1.43 cvs 1322:
1.82 cvs 1323: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1324: start_value = cssRule;
1.43 cvs 1325: cssRule = ParseBorderStyle (cssRule, &border);
1.366 vatton 1326: if (border.typed_data.unit != UNIT_INVALID)
1327: {
1328: if (DoDialog)
1329: DisplayStyleValue ("border-bottom-style", start_value, cssRule);
1330: else if (DoApply)
1331: TtaSetStylePresentation (PRBorderBottomStyle, element, tsch, context, border);
1332: }
1.1 cvs 1333: return (cssRule);
1334: }
1335:
1336: /*----------------------------------------------------------------------
1.327 vatton 1337: ParseCSSBorderStyleRight: parse a CSS BorderStyleRight
1338: attribute string.
1.1 cvs 1339: ----------------------------------------------------------------------*/
1.79 cvs 1340: static char *ParseCSSBorderStyleRight (Element element, PSchema tsch,
1.327 vatton 1341: PresentationContext context,
1342: char *cssRule, CSSInfoPtr css,
1343: ThotBool isHTML)
1.1 cvs 1344: {
1.43 cvs 1345: PresentationValue border;
1.366 vatton 1346: char *start_value;
1.43 cvs 1347:
1.82 cvs 1348: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1349: start_value = cssRule;
1.43 cvs 1350: cssRule = ParseBorderStyle (cssRule, &border);
1.184 vatton 1351: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1352: {
1353: if (DoDialog)
1354: DisplayStyleValue ("border-right-style", start_value, cssRule);
1355: else if (DoApply)
1356: TtaSetStylePresentation (PRBorderRightStyle, element, tsch, context, border);
1357: }
1.1 cvs 1358: return (cssRule);
1359: }
1360:
1361: /*----------------------------------------------------------------------
1.349 quint 1362: ParseCSSBorderStyle: parse a CSS border-style attribute string.
1.1 cvs 1363: ----------------------------------------------------------------------*/
1.79 cvs 1364: static char *ParseCSSBorderStyle (Element element, PSchema tsch,
1.327 vatton 1365: PresentationContext context,
1366: char *cssRule, CSSInfoPtr css,
1367: ThotBool isHTML)
1.1 cvs 1368: {
1.79 cvs 1369: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 1370: int skippedNL, n;
1.42 cvs 1371:
1.82 cvs 1372: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 1373: if (DoDialog)
1374: n = NumberOfValues (ptrT);
1375: if (DoDialog && n < 2)
1.42 cvs 1376: {
1.366 vatton 1377: // check if the border dialog must be updated
1378: All_sides = TRUE;
1379: ptrR = ParseCSSBorderStyleTop(element, tsch, context, ptrT, css, isHTML);
1380: All_sides = FALSE;
1.42 cvs 1381: }
1382: else
1383: {
1.366 vatton 1384: /* First parse Border-Top */
1385: ptrR = ParseCSSBorderStyleTop (element, tsch, context, ptrT, css, isHTML);
1386: ptrR = SkipBlanksAndComments (ptrR);
1387: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 1388: {
1389: skippedNL = NewLineSkipped;
1.366 vatton 1390: cssRule = ptrR;
1391: /* apply the Border-Top to all */
1392: ptrR = ParseCSSBorderStyleRight (element, tsch, context, ptrT, css, isHTML);
1393: NewLineSkipped = skippedNL;
1394: ptrR = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1395: NewLineSkipped = skippedNL;
1.366 vatton 1396: ptrR = ParseCSSBorderStyleLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1397: }
1.42 cvs 1398: else
1.327 vatton 1399: {
1.366 vatton 1400: /* parse Border-Right */
1401: ptrB = ParseCSSBorderStyleRight (element, tsch, context, ptrR, css, isHTML);
1402: ptrB = SkipBlanksAndComments (ptrB);
1403: if (*ptrB == ';' || *ptrR == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 1404: {
1.366 vatton 1405: skippedNL = NewLineSkipped;
1406: cssRule = ptrB;
1407: /* apply the Border-Top to Border-Bottom */
1408: ptrB = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1409: NewLineSkipped = skippedNL;
1.327 vatton 1410: /* apply the Border-Right to Border-Left */
1.366 vatton 1411: ptrB = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 1412: }
1413: else
1.366 vatton 1414: {
1415: /* parse Border-Bottom */
1416: ptrL = ParseCSSBorderStyleBottom (element, tsch, context, ptrB, css, isHTML);
1417: ptrL = SkipBlanksAndComments (ptrL);
1418: if (*ptrL == ';' || *ptrR == '}' || *ptrL == EOS || *ptrL == ',')
1419: {
1420: cssRule = ptrL;
1421: /* apply the Border-Right to Border-Left */
1422: ptrL = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1423: }
1424: else
1425: /* parse Border-Left */
1426: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, ptrL, css, isHTML);
1427: cssRule = SkipBlanksAndComments (cssRule);
1428: }
1.327 vatton 1429: }
1.42 cvs 1430: }
1431: return (cssRule);
1432: }
1433:
1434: /*----------------------------------------------------------------------
1.327 vatton 1435: ParseCSSBorderTop: parse a CSS BorderTop
1436: attribute string.
1.42 cvs 1437: ----------------------------------------------------------------------*/
1.79 cvs 1438: static char *ParseCSSBorderTop (Element element, PSchema tsch,
1.327 vatton 1439: PresentationContext context, char *cssRule,
1440: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1441: {
1.370 vatton 1442: PresentationValue best;
1443: char *ptr;
1444: ThotBool style, width, color;
1.43 cvs 1445:
1.82 cvs 1446: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1447: /* register given values */
1.337 vatton 1448: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1449: style = width = color = TRUE;
1.337 vatton 1450: else
1.370 vatton 1451: style = width = color = FALSE;
1.301 vatton 1452: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1453: {
1454: ptr = cssRule;
1455: cssRule = ParseCSSBorderStyleTop (element, tsch, context, cssRule, css, isHTML);
1456: if (ptr == cssRule)
1.327 vatton 1457: {
1458: cssRule = ParseCSSBorderTopWidth (element, tsch, context, cssRule, css, isHTML);
1459: if (ptr == cssRule)
1.370 vatton 1460: {
1461: cssRule = ParseCSSBorderColorTop (element, tsch, context, cssRule, css, isHTML);
1462: if (ptr != cssRule)
1463: color = TRUE;
1464: }
1.327 vatton 1465: else
1466: width = TRUE;
1467: if (ptr == cssRule)
1468: {
1469: /* rule not found */
1470: cssRule = SkipValue ("Invalid border value", cssRule);
1471: return (cssRule);
1472: }
1473: }
1.322 vatton 1474: else
1.327 vatton 1475: style = TRUE;
1.82 cvs 1476: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1477: }
1.322 vatton 1478:
1479: if (!width)
1480: ParseCSSBorderTopWidth (element, tsch, context, "medium", css, isHTML);
1481: if (!style)
1482: ParseCSSBorderStyleTop (element, tsch, context, "none", css, isHTML);
1.370 vatton 1483: if (!color && DoApply)
1484: {
1485: /* get the box color */
1486: best.typed_data.value = -1;
1487: best.typed_data.unit = UNIT_REL;
1488: best.typed_data.real = FALSE;
1489: TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
1490: }
1.42 cvs 1491: return (cssRule);
1492: }
1493:
1494: /*----------------------------------------------------------------------
1.327 vatton 1495: ParseCSSBorderLeft: parse a CSS BorderLeft
1496: attribute string.
1.42 cvs 1497: ----------------------------------------------------------------------*/
1.79 cvs 1498: static char *ParseCSSBorderLeft (Element element, PSchema tsch,
1.327 vatton 1499: PresentationContext context, char *cssRule,
1500: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1501: {
1.370 vatton 1502: PresentationValue best;
1503: char *ptr;
1504: ThotBool style, width, color;
1.43 cvs 1505:
1.82 cvs 1506: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1507: /* register given values */
1.337 vatton 1508: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1509: style = width = color = TRUE;
1.337 vatton 1510: else
1.370 vatton 1511: style = width = color = FALSE;
1.301 vatton 1512: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1513: {
1514: ptr = cssRule;
1515: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, cssRule, css, isHTML);
1516: if (ptr == cssRule)
1.327 vatton 1517: {
1518: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, cssRule, css, isHTML);
1519: if (ptr == cssRule)
1.370 vatton 1520: {
1521: cssRule = ParseCSSBorderColorLeft (element, tsch, context, cssRule, css, isHTML);
1522: if (ptr != cssRule)
1523: color = TRUE;
1524: }
1.327 vatton 1525: else
1526: width = TRUE;
1527: if (ptr == cssRule)
1528: {
1529: /* rule not found */
1530: cssRule = SkipValue ("Invalid border value", cssRule);
1531: return (cssRule);
1532: }
1533: }
1.322 vatton 1534: else
1.327 vatton 1535: style = TRUE;
1536: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1537: }
1.322 vatton 1538:
1539: if (!width)
1540: ParseCSSBorderLeftWidth (element, tsch, context, "medium", css, isHTML);
1541: if (!style)
1542: ParseCSSBorderStyleLeft (element, tsch, context, "none", css, isHTML);
1.370 vatton 1543: if (!color && DoApply)
1544: {
1545: /* get the box color */
1546: best.typed_data.value = -1;
1547: best.typed_data.unit = UNIT_REL;
1548: best.typed_data.real = FALSE;
1549: TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
1550: }
1.1 cvs 1551: return (cssRule);
1552: }
1553:
1554: /*----------------------------------------------------------------------
1.327 vatton 1555: ParseCSSBorderBottom: parse a CSS BorderBottom
1556: attribute string.
1.1 cvs 1557: ----------------------------------------------------------------------*/
1.79 cvs 1558: static char *ParseCSSBorderBottom (Element element, PSchema tsch,
1.327 vatton 1559: PresentationContext context, char *cssRule,
1560: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1561: {
1.370 vatton 1562: PresentationValue best;
1563: char *ptr;
1564: ThotBool style, width, color;
1.43 cvs 1565:
1.82 cvs 1566: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1567: /* register given values */
1.337 vatton 1568: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1569: style = width = color = TRUE;
1.337 vatton 1570: else
1.370 vatton 1571: style = width = color = FALSE;
1.301 vatton 1572: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1573: {
1574: ptr = cssRule;
1575: cssRule = ParseCSSBorderStyleBottom (element, tsch, context, cssRule, css, isHTML);
1576: if (ptr == cssRule)
1.327 vatton 1577: {
1578: cssRule = ParseCSSBorderBottomWidth (element, tsch, context, cssRule, css, isHTML);
1579: if (ptr == cssRule)
1.370 vatton 1580: {
1581: cssRule = ParseCSSBorderColorBottom (element, tsch, context, cssRule, css, isHTML);
1582: if (ptr != cssRule)
1583: color = TRUE;
1584: }
1.327 vatton 1585: else
1586: width = TRUE;
1587: if (ptr == cssRule)
1588: {
1589: /* rule not found */
1590: cssRule = SkipValue ("Invalid border value", cssRule);
1591: return (cssRule);
1592: }
1593: }
1.322 vatton 1594: else
1.327 vatton 1595: style = TRUE;
1.82 cvs 1596: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1597: }
1.322 vatton 1598:
1599: if (!width)
1600: ParseCSSBorderBottomWidth (element, tsch, context, "medium", css, isHTML);
1601: if (!style)
1602: ParseCSSBorderStyleBottom (element, tsch, context, "none", css, isHTML);
1.370 vatton 1603: if (!color && DoApply)
1604: {
1605: /* get the box color */
1606: best.typed_data.value = -1;
1607: best.typed_data.unit = UNIT_REL;
1608: best.typed_data.real = FALSE;
1609: TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
1610: }
1.1 cvs 1611: return (cssRule);
1612: }
1613:
1614: /*----------------------------------------------------------------------
1.327 vatton 1615: ParseCSSBorderRight: parse a CSS BorderRight
1616: attribute string.
1.1 cvs 1617: ----------------------------------------------------------------------*/
1.79 cvs 1618: static char *ParseCSSBorderRight (Element element, PSchema tsch,
1.327 vatton 1619: PresentationContext context, char *cssRule,
1620: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1621: {
1.370 vatton 1622: PresentationValue best;
1623: char *ptr;
1624: ThotBool style, width, color;
1.43 cvs 1625:
1.82 cvs 1626: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1627: /* register given values */
1.337 vatton 1628: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1629: style = width = color = TRUE;
1.337 vatton 1630: else
1.370 vatton 1631: style = width = color = FALSE;
1.301 vatton 1632: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1633: {
1634: ptr = cssRule;
1635: cssRule = ParseCSSBorderStyleRight (element, tsch, context, cssRule, css, isHTML);
1636: if (ptr == cssRule)
1.327 vatton 1637: {
1638: cssRule = ParseCSSBorderRightWidth (element, tsch, context, cssRule, css, isHTML);
1639: if (ptr == cssRule)
1.370 vatton 1640: {
1641: cssRule = ParseCSSBorderColorRight (element, tsch, context, cssRule, css, isHTML);
1642: if (ptr != cssRule)
1643: color = TRUE;
1644: }
1.327 vatton 1645: else
1646: width = TRUE;
1647: if (ptr == cssRule)
1648: {
1649: /* rule not found */
1650: cssRule = SkipValue ("Invalid border value", cssRule);
1651: return (cssRule);
1652: }
1653: }
1.322 vatton 1654: else
1.327 vatton 1655: style = TRUE;
1.82 cvs 1656: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1657: }
1.322 vatton 1658:
1659: if (!width)
1660: ParseCSSBorderRightWidth (element, tsch, context, "medium", css, isHTML);
1661: if (!style)
1662: ParseCSSBorderStyleRight (element, tsch, context, "none", css, isHTML);
1.370 vatton 1663: if (!color && DoApply)
1664: {
1665: /* get the box color */
1666: best.typed_data.value = -1;
1667: best.typed_data.unit = UNIT_REL;
1.374 vatton 1668: best.typed_data.real = FALSE;
1.370 vatton 1669: TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
1670: }
1.1 cvs 1671: return (cssRule);
1672: }
1673:
1674: /*----------------------------------------------------------------------
1.327 vatton 1675: ParseCSSBorder: parse a CSS border
1676: attribute string.
1.42 cvs 1677: ----------------------------------------------------------------------*/
1.79 cvs 1678: static char *ParseCSSBorder (Element element, PSchema tsch,
1.327 vatton 1679: PresentationContext context, char *cssRule,
1680: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1681: {
1.79 cvs 1682: char *ptrT, *ptrR;
1.366 vatton 1683: int skippedNL, n;
1.42 cvs 1684:
1.82 cvs 1685: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 1686: if (DoDialog)
1687: n = NumberOfValues (ptrT);
1688: if (DoDialog && n < 4)
1.42 cvs 1689: {
1.366 vatton 1690: // check if the border dialog must be updated
1691: All_sides = TRUE;
1692: ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1693: All_sides = FALSE;
1694: }
1695: else
1696: {
1697: /* First parse Border-Top */
1698: ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1699: ptrR = SkipBlanksAndComments (ptrR);
1700: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1701: {
1702: skippedNL = NewLineSkipped;
1703: cssRule = ptrR;
1704: /* apply the Border-Top to all */
1705: ptrR = ParseCSSBorderRight (element, tsch, context, ptrT, css, isHTML);
1706: NewLineSkipped = skippedNL;
1707: ptrR = ParseCSSBorderBottom (element, tsch, context, ptrT, css, isHTML);
1708: NewLineSkipped = skippedNL;
1709: ptrR = ParseCSSBorderLeft (element, tsch, context, ptrT, css, isHTML);
1710: }
1.42 cvs 1711: }
1712: return (cssRule);
1713: }
1714:
1.218 vatton 1715:
1.42 cvs 1716: /*----------------------------------------------------------------------
1.327 vatton 1717: ParseCSSFloat: parse a CSS float attribute string
1.184 vatton 1718: ----------------------------------------------------------------------*/
1719: static char *ParseCSSFloat (Element element, PSchema tsch,
1.327 vatton 1720: PresentationContext context, char *cssRule,
1721: CSSInfoPtr css, ThotBool isHTML)
1.184 vatton 1722: {
1.257 vatton 1723: DisplayMode dispMode;
1.184 vatton 1724: PresentationValue pval;
1.288 vatton 1725: char *ptr = cssRule;
1.184 vatton 1726:
1727: pval.typed_data.value = 0;
1.187 vatton 1728: pval.typed_data.unit = UNIT_BOX;
1.192 cvs 1729: pval.typed_data.real = FALSE;
1.190 vatton 1730: if (!strncasecmp (cssRule, "inherit", 7))
1731: {
1.293 quint 1732: pval.typed_data.unit = VALUE_INHERIT;
1.288 vatton 1733: cssRule += 7;
1.190 vatton 1734: }
1.184 vatton 1735: if (!strncasecmp (cssRule, "none", 4))
1.288 vatton 1736: {
1737: pval.typed_data.value = FloatNone;
1.293 quint 1738: cssRule += 4;
1.288 vatton 1739: }
1.184 vatton 1740: else if (!strncasecmp (cssRule, "left", 4))
1.288 vatton 1741: {
1742: pval.typed_data.value = FloatLeft;
1.293 quint 1743: cssRule += 4;
1.288 vatton 1744: }
1.184 vatton 1745: else if (!strncasecmp (cssRule, "right", 5))
1.288 vatton 1746: {
1747: pval.typed_data.value = FloatRight;
1.293 quint 1748: cssRule += 5;
1.288 vatton 1749: }
1.184 vatton 1750:
1.293 quint 1751: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
1.359 quint 1752: {
1753: if (!strncasecmp (cssRule, "top", 3) ||
1754: !strncasecmp (cssRule, "bottom", 6) ||
1755: !strncasecmp (cssRule, "inside", 6) ||
1756: !strncasecmp (cssRule, "outside", 7) ||
1757: !strncasecmp (cssRule, "start", 5) ||
1758: !strncasecmp (cssRule, "end", 3))
1759: cssRule = SkipValue ("Warning: CSS3 value not supported", cssRule);
1760: else
1761: cssRule = SkipValue ("Invalid float value", cssRule);
1762: }
1.184 vatton 1763: else
1764: {
1.366 vatton 1765: if (DoDialog)
1766: DisplayStyleValue ("float", ptr, cssRule);
1767: else if (DoApply)
1.327 vatton 1768: {
1769: dispMode = TtaGetDisplayMode (context->doc);
1770: if (dispMode != NoComputedDisplay)
1771: {
1772: /* force a redisplay of the whole document */
1773: TtaSetDisplayMode (context->doc, NoComputedDisplay);
1.257 vatton 1774: #ifdef AMAYA_DEBUG
1.327 vatton 1775: /*printf ("Force NoComputedDisplay doc=%d\n", context->doc);*/
1.257 vatton 1776: #endif /* AMAYA_DEBUG */
1.327 vatton 1777: }
1778: TtaSetStylePresentation (PRFloat, element, tsch, context, pval);
1779: }
1.288 vatton 1780: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid float value");
1.184 vatton 1781: }
1782: return (cssRule);
1783: }
1784:
1785: /*----------------------------------------------------------------------
1.327 vatton 1786: ParseCSSClear: parse a CSS clear rule
1.1 cvs 1787: ----------------------------------------------------------------------*/
1.79 cvs 1788: static char *ParseCSSClear (Element element, PSchema tsch,
1.327 vatton 1789: PresentationContext context, char *cssRule,
1790: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1791: {
1.184 vatton 1792: PresentationValue pval;
1.366 vatton 1793: char *start_value = cssRule;
1.184 vatton 1794:
1795: pval.typed_data.value = 0;
1.187 vatton 1796: pval.typed_data.unit = UNIT_BOX;
1.193 vatton 1797: pval.typed_data.real = FALSE;
1.190 vatton 1798: if (!strncasecmp (cssRule, "inherit", 7))
1.293 quint 1799: pval.typed_data.unit = VALUE_INHERIT;
1.184 vatton 1800: if (!strncasecmp (cssRule, "none", 4))
1801: pval.typed_data.value = ClearNone;
1802: else if (!strncasecmp (cssRule, "left", 4))
1803: pval.typed_data.value = ClearLeft;
1804: else if (!strncasecmp (cssRule, "right", 5))
1805: pval.typed_data.value = ClearRight;
1806: else if (!strncasecmp (cssRule, "both", 4))
1807: pval.typed_data.value = ClearBoth;
1808:
1.293 quint 1809: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
1.295 vatton 1810: {
1811: cssRule = SkipValue ("Invalid clear value", cssRule);
1812: cssRule = SkipValue (NULL, cssRule);
1813: }
1.184 vatton 1814: else
1815: {
1.295 vatton 1816: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 1817: if (DoDialog)
1818: DisplayStyleValue ("clear", start_value, cssRule);
1819: else if (DoApply)
1.327 vatton 1820: TtaSetStylePresentation (PRClear, element, tsch, context, pval);
1.184 vatton 1821: }
1822: return (cssRule);
1823: }
1824:
1825: /*----------------------------------------------------------------------
1.333 vatton 1826: ParseCSSVisibility: parse a CSS visibility attribute string
1827: ----------------------------------------------------------------------*/
1828: static char *ParseCSSVisibility(Element element, PSchema tsch,
1829: PresentationContext context, char *cssRule,
1830: CSSInfoPtr css, ThotBool isHTML)
1831: {
1832: PresentationValue pval;
1.366 vatton 1833: char *ptr;
1.333 vatton 1834:
1835: pval.typed_data.unit = UNIT_REL;
1836: pval.typed_data.real = FALSE;
1837: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1838: ptr = cssRule;
1.333 vatton 1839: if (!strncasecmp (cssRule, "hidden", 6))
1840: {
1841: cssRule += 6;
1842: pval.typed_data.value = VsHidden;
1843: }
1844: else if (!strncasecmp (cssRule, "visible", 7))
1845: {
1846: cssRule += 7;
1847: pval.typed_data.value = VsVisible;
1848: }
1849: else if (!strncasecmp (cssRule, "collapse", 8))
1850: {
1851: cssRule += 8;
1852: pval.typed_data.value = VsCollapse;
1853: }
1854: else if (!strncasecmp (cssRule, "inherit", 7))
1855: {
1856: cssRule += 7;
1857: pval.typed_data.value = VsInherit;
1858: }
1859: else
1860: {
1861: cssRule = SkipValue ("Invalid visibility value", cssRule);
1862: return (cssRule);
1863: }
1.366 vatton 1864: if (DoDialog)
1865: DisplayStyleValue ("visibility", ptr, cssRule);
1866: else if (DoApply)
1.333 vatton 1867: TtaSetStylePresentation (PRVis, element, tsch, context, pval);
1868: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid visibility value");
1869: return (cssRule);
1870: }
1871:
1872:
1873: /*----------------------------------------------------------------------
1.327 vatton 1874: ParseCSSDisplay: parse a CSS display attribute string
1.1 cvs 1875: ----------------------------------------------------------------------*/
1.79 cvs 1876: static char *ParseCSSDisplay (Element element, PSchema tsch,
1.327 vatton 1877: PresentationContext context, char *cssRule,
1878: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1879: {
1.184 vatton 1880: PresentationValue pval;
1.366 vatton 1881: char *ptr;
1.1 cvs 1882:
1.184 vatton 1883: pval.typed_data.unit = UNIT_REL;
1884: pval.typed_data.real = FALSE;
1885: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1886: ptr = cssRule;
1.184 vatton 1887: if (!strncasecmp (cssRule, "none", 4))
1.288 vatton 1888: {
1889: cssRule += 4;
1890: pval.typed_data.value = DisplayNone;
1891: }
1.277 quint 1892: else if (!strncasecmp (cssRule, "block", 5))
1.288 vatton 1893: {
1894: cssRule += 5;
1895: pval.typed_data.value = Block;
1896: }
1.303 vatton 1897: else if (!strncasecmp (cssRule, "inline-block", 12))
1898: {
1899: cssRule += 12;
1900: pval.typed_data.value = InlineBlock;
1901: }
1.277 quint 1902: else if (!strncasecmp (cssRule, "inline", 6))
1.288 vatton 1903: {
1904: cssRule += 6;
1905: pval.typed_data.value = Inline;
1906: }
1.277 quint 1907: else if (!strncasecmp (cssRule, "list-item", 9))
1.288 vatton 1908: {
1909: cssRule += 9;
1910: pval.typed_data.value = ListItem;
1911: }
1.277 quint 1912: else if (!strncasecmp (cssRule, "run-in", 6))
1.288 vatton 1913: {
1914: cssRule += 6;
1915: pval.typed_data.value = RunIn;
1916: }
1.293 quint 1917: else if (!strncasecmp (cssRule, "inherit", 7))
1918: {
1919: cssRule += 7;
1920: pval.typed_data.unit = VALUE_INHERIT;
1921: }
1.277 quint 1922: else
1.184 vatton 1923: {
1.277 quint 1924: if (strncasecmp (cssRule, "table-row-group", 15) &&
1.327 vatton 1925: strncasecmp (cssRule, "table-column-group", 18) &&
1926: strncasecmp (cssRule, "table-header-group", 5) &&
1927: strncasecmp (cssRule, "table-footer-group", 6) &&
1928: strncasecmp (cssRule, "table-row", 9) &&
1929: strncasecmp (cssRule, "table-column", 12) &&
1930: strncasecmp (cssRule, "table-cell", 10) &&
1931: strncasecmp (cssRule, "table-caption", 13) &&
1932: strncasecmp (cssRule, "inline-table", 12) &&
1933: strncasecmp (cssRule, "table", 5))
1934: cssRule = SkipValue ("Display value not supported", cssRule);
1.281 quint 1935: else
1.327 vatton 1936: cssRule = SkipWord (cssRule);
1.277 quint 1937: return (cssRule);
1.184 vatton 1938: }
1.277 quint 1939:
1.366 vatton 1940: if (DoDialog)
1941: DisplayStyleValue ("display", ptr, cssRule);
1942: else if (DoApply)
1.295 vatton 1943: TtaSetStylePresentation (PRDisplay, element, tsch, context, pval);
1.288 vatton 1944: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid display value");
1.1 cvs 1945: return (cssRule);
1946: }
1947:
1948: /*----------------------------------------------------------------------
1.327 vatton 1949: ParseCSSLetterSpacing: parse a CSS letter-spacing
1950: attribute string.
1.1 cvs 1951: ----------------------------------------------------------------------*/
1.79 cvs 1952: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
1.327 vatton 1953: PresentationContext context, char *cssRule,
1954: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1955: {
1.366 vatton 1956: char *start_value = cssRule;
1957:
1.168 vatton 1958: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 1959: if (DoDialog)
1960: DisplayStyleValue ("letter-spacing", start_value, cssRule);
1.1 cvs 1961: return (cssRule);
1962: }
1963:
1964: /*----------------------------------------------------------------------
1.327 vatton 1965: ParseACSSListStyleType: parse a CSS list-style-type
1966: attribute string.
1.1 cvs 1967: ----------------------------------------------------------------------*/
1.318 vatton 1968: static char *ParseACSSListStyleType (Element element, PSchema tsch,
1.327 vatton 1969: PresentationContext context, char *cssRule,
1970: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1971: {
1.281 quint 1972: PresentationValue pval;
1.366 vatton 1973: char *start_value;
1.281 quint 1974:
1975: pval.typed_data.unit = UNIT_REL;
1976: pval.typed_data.real = FALSE;
1977: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1978: start_value = cssRule;
1.281 quint 1979: if (!strncasecmp (cssRule, "disc", 4))
1.288 vatton 1980: {
1981: cssRule += 4;
1982: pval.typed_data.value = Disc;
1983: }
1.281 quint 1984: else if (!strncasecmp (cssRule, "circle", 6))
1.293 quint 1985: {
1.288 vatton 1986: cssRule += 6;
1987: pval.typed_data.value = Circle;
1.293 quint 1988: }
1.281 quint 1989: else if (!strncasecmp (cssRule, "square", 6))
1.293 quint 1990: {
1.288 vatton 1991: cssRule += 6;
1.293 quint 1992: pval.typed_data.value = Square;
1993: }
1.283 quint 1994: else if (!strncasecmp (cssRule, "decimal-leading-zero", 20))
1.293 quint 1995: {
1.288 vatton 1996: cssRule += 20;
1.293 quint 1997: pval.typed_data.value = DecimalLeadingZero;
1998: }
1.281 quint 1999: else if (!strncasecmp (cssRule, "decimal", 7))
1.293 quint 2000: {
1.288 vatton 2001: cssRule += 7;
1.293 quint 2002: pval.typed_data.value = Decimal;
2003: }
1.281 quint 2004: else if (!strncasecmp (cssRule, "lower-roman", 11))
1.293 quint 2005: {
1.288 vatton 2006: cssRule += 11;
1.293 quint 2007: pval.typed_data.value = LowerRoman;
2008: }
1.281 quint 2009: else if (!strncasecmp (cssRule, "upper-roman", 11))
1.293 quint 2010: {
1.288 vatton 2011: cssRule += 11;
1.293 quint 2012: pval.typed_data.value = UpperRoman;
2013: }
1.281 quint 2014: else if (!strncasecmp (cssRule, "lower-greek", 11))
1.293 quint 2015: {
1.288 vatton 2016: cssRule += 11;
1.293 quint 2017: pval.typed_data.value = LowerGreek;
2018: }
1.281 quint 2019: else if (!strncasecmp (cssRule, "lower-latin", 11))
1.293 quint 2020: {
1.288 vatton 2021: cssRule += 11;
1.293 quint 2022: pval.typed_data.value = LowerLatin;
2023: }
1.281 quint 2024: else if (!strncasecmp (cssRule, "lower-alpha", 11))
1.293 quint 2025: {
1.288 vatton 2026: cssRule += 11;
1.293 quint 2027: pval.typed_data.value = LowerLatin;
2028: }
1.281 quint 2029: else if (!strncasecmp (cssRule, "upper-latin", 11))
1.293 quint 2030: {
1.288 vatton 2031: cssRule += 11;
1.293 quint 2032: pval.typed_data.value = UpperLatin;
2033: }
1.281 quint 2034: else if (!strncasecmp (cssRule, "upper-alpha", 11))
1.293 quint 2035: {
1.288 vatton 2036: cssRule += 11;
1.293 quint 2037: pval.typed_data.value = UpperLatin;
2038: }
1.281 quint 2039: else if (!strncasecmp (cssRule, "armenian", 8))
1.293 quint 2040: {
1.288 vatton 2041: cssRule += 8;
1.293 quint 2042: pval.typed_data.value = Decimal;
2043: }
1.281 quint 2044: else if (!strncasecmp (cssRule, "georgian", 8))
1.293 quint 2045: {
1.288 vatton 2046: cssRule += 8;
1.293 quint 2047: pval.typed_data.value = Decimal;
2048: }
1.281 quint 2049: else if (!strncasecmp (cssRule, "none", 4))
1.293 quint 2050: {
1.288 vatton 2051: cssRule += 4;
1.293 quint 2052: pval.typed_data.value = ListStyleTypeNone;
2053: }
1.281 quint 2054: else if (!strncasecmp (cssRule, "inherit", 7))
2055: {
1.293 quint 2056: cssRule += 7;
2057: pval.typed_data.unit = VALUE_INHERIT;
1.281 quint 2058: }
2059: else
2060: {
2061: cssRule = SkipValue ("Invalid list-style-type value", cssRule);
2062: return (cssRule);
2063: }
2064:
1.366 vatton 2065: if (DoDialog)
2066: DisplayStyleValue ("list-style-type", start_value, cssRule);
2067: else if (DoApply)
1.295 vatton 2068: TtaSetStylePresentation (PRListStyleType, element, tsch, context, pval);
1.318 vatton 2069: return (cssRule);
2070: }
2071:
2072: /*----------------------------------------------------------------------
1.327 vatton 2073: ParseCSSListStyleType: parse a CSS list-style-type
2074: attribute string.
1.318 vatton 2075: ----------------------------------------------------------------------*/
2076: static char *ParseCSSListStyleType (Element element, PSchema tsch,
1.327 vatton 2077: PresentationContext context, char *cssRule,
2078: CSSInfoPtr css, ThotBool isHTML)
1.318 vatton 2079: {
2080: char *ptr = cssRule;
2081: cssRule = ParseACSSListStyleType (element, tsch, context, cssRule, css,
1.327 vatton 2082: isHTML);
1.288 vatton 2083: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-type value");
1.318 vatton 2084: return cssRule;
1.1 cvs 2085: }
2086:
2087: /*----------------------------------------------------------------------
1.281 quint 2088: ParseCSSUrl: parse an URL
1.375 vatton 2089: Parse the url content (don't start with "url")
2090: Return the next pointer in the CSS string
2091: If a correct URL is found, it's returned in url (this string must
2092: be freed)
1.281 quint 2093: ----------------------------------------------------------------------*/
2094: static char *ParseCSSUrl (char *cssRule, char **url)
2095: {
2096: char saved;
2097: char *base, *ptr;
2098:
2099: cssRule = SkipBlanksAndComments (cssRule);
2100: saved = *cssRule;
2101: if (*cssRule == '(')
2102: {
2103: cssRule++;
2104: cssRule = SkipBlanksAndComments (cssRule);
2105: /*** Escaped quotes are not handled. See function SkipQuotedString */
2106: if (*cssRule == '"')
1.327 vatton 2107: {
2108: cssRule++;
2109: base = cssRule;
2110: while (*cssRule != EOS && *cssRule != '"')
2111: cssRule++;
2112: }
1.281 quint 2113: else if (*cssRule == '\'')
1.327 vatton 2114: {
2115: cssRule++;
2116: base = cssRule;
2117: while (*cssRule != EOS && *cssRule != '\'')
2118: cssRule++;
2119: }
1.281 quint 2120: else
1.327 vatton 2121: {
2122: base = cssRule;
2123: while (*cssRule != EOS && *cssRule != ')')
2124: cssRule++;
2125: }
1.281 quint 2126: /* keep the current position */
2127: ptr = cssRule;
2128: if (saved == ')')
1.327 vatton 2129: {
2130: /* remove extra spaces */
2131: if (cssRule[-1] == SPACE)
2132: {
2133: *cssRule = SPACE;
2134: cssRule--;
2135: while (cssRule[-1] == SPACE)
2136: cssRule--;
2137: }
2138: }
1.281 quint 2139: saved = *cssRule;
2140: *cssRule = EOS;
2141: *url = TtaStrdup (base);
2142: *cssRule = saved;
2143: if (saved == '"' || saved == '\'')
1.327 vatton 2144: /* we need to skip the quote character and possible spaces */
2145: {
2146: cssRule++;
2147: cssRule = SkipBlanksAndComments (cssRule);
2148: }
1.281 quint 2149: else
1.327 vatton 2150: cssRule = ptr;
1.281 quint 2151: }
2152: cssRule++;
2153: return cssRule;
2154: }
2155:
2156: /*----------------------------------------------------------------------
1.302 quint 2157: ParseCSSImageCallback: Callback called asynchronously by
2158: FetchImage when a CSS image (background-image or list-style-image)
2159: has been fetched.
2160: ----------------------------------------------------------------------*/
2161: void ParseCSSImageCallback (Document doc, Element element, char *file,
1.327 vatton 2162: void *extra, ThotBool isnew)
1.302 quint 2163: {
2164: DisplayMode dispMode = DisplayImmediately;
2165: CSSImageCallbackPtr callblock;
2166: Element el;
2167: PSchema tsch;
2168: CSSInfoPtr css;
2169: PresentationContext ctxt;
2170: PresentationValue image;
2171: PresentationValue value;
2172:
2173: callblock = (CSSImageCallbackPtr) extra;
2174: if (callblock == NULL)
2175: return;
2176:
2177: css = NULL;
2178: el = callblock->el;
2179: tsch = callblock->tsch;
2180: ctxt = callblock->ctxt;
2181: if (doc == 0 && !isnew)
2182: /* apply to the current document only */
2183: doc = ctxt->doc;
2184: if (doc)
2185: {
2186: /* avoid too many redisplay */
2187: dispMode = TtaGetDisplayMode (doc);
2188: if (dispMode == DisplayImmediately)
1.327 vatton 2189: TtaSetDisplayMode (doc, DeferredDisplay);
1.302 quint 2190: }
2191: else
2192: {
1.330 cvs 2193: dispMode = TtaGetDisplayMode (RedisplayDoc);
1.302 quint 2194: /* check if the CSS still exists */
2195: css = CSSList;
2196: while (css && css != callblock->css)
1.327 vatton 2197: css = css->NextCSS;
1.302 quint 2198: if (css == NULL)
1.327 vatton 2199: tsch = NULL;
1.302 quint 2200: }
2201: if (el || tsch)
2202: {
2203: /* Ok the image was fetched */
2204: image.typed_data.unit = UNIT_REL;
2205: image.typed_data.real = FALSE;
2206: image.pointer = file;
2207: TtaSetStylePresentation (callblock->ruleType, el, tsch, ctxt, image);
2208:
2209: if (callblock->ruleType == PRBackgroundPicture)
1.327 vatton 2210: /* enforce the showbox */
2211: {
2212: value.typed_data.value = 1;
2213: value.typed_data.unit = UNIT_REL;
2214: value.typed_data.real = FALSE;
2215: TtaSetStylePresentation (PRShowBox, el, tsch, ctxt, value);
2216: }
1.302 quint 2217: /* check if the context can be freed */
2218: ctxt->uses -= 1;
2219: if (ctxt->uses == 0)
1.327 vatton 2220: /* no other image loading */
2221: TtaFreeMemory (ctxt);
1.302 quint 2222: }
2223:
2224: TtaFreeMemory (callblock);
1.330 cvs 2225: if (css)
2226: RedisplayImages--;
1.302 quint 2227: if (doc)
2228: {
2229: if (dispMode == DisplayImmediately)
1.327 vatton 2230: /* restore the display mode */
2231: TtaSetDisplayMode (doc, dispMode);
1.302 quint 2232: }
1.311 vatton 2233: else if (css && Style_parsing == 0 && RedisplayImages == 0 && RedisplayDoc)
1.302 quint 2234: {
1.310 vatton 2235: /* all background images are now loaded */
1.330 cvs 2236: if (css->infos[RedisplayDoc] &&
1.327 vatton 2237: /* don't manage a document used by make book */
1.330 cvs 2238: (DocumentMeta[RedisplayDoc] == NULL ||
2239: DocumentMeta[RedisplayDoc]->method != CE_MAKEBOOK))
1.327 vatton 2240: {
2241: /* Change the Display Mode to take into account the new
2242: presentation */
1.330 cvs 2243: dispMode = TtaGetDisplayMode (RedisplayDoc);
1.329 vatton 2244: #ifdef AMAYA_DEBUG
2245: //printf ("ParseCSSImageCallback Show BGimages\n");
2246: #endif /* AMAYA_DEBUG */
1.313 vatton 2247: /* force the redisplay of this box */
1.330 cvs 2248: TtaSetDisplayMode (RedisplayDoc, NoComputedDisplay);
2249: TtaSetDisplayMode (RedisplayDoc, dispMode);
1.327 vatton 2250: }
1.330 cvs 2251: RedisplayBGImage = FALSE;
1.302 quint 2252: }
1.310 vatton 2253: else
1.328 vatton 2254: RedisplayBGImage = TRUE;
1.302 quint 2255: }
2256:
2257: /*----------------------------------------------------------------------
2258: SetCSSImage fetch the image referred by a background-image or a
2259: list-style-image property.
2260: ----------------------------------------------------------------------*/
2261: static char *SetCSSImage (Element element, PSchema tsch,
1.327 vatton 2262: PresentationContext ctxt, char *cssRule,
2263: CSSInfoPtr css, unsigned int ruleType)
1.302 quint 2264: {
2265: CSSImageCallbackPtr callblock;
2266: Element el;
1.304 cvs 2267: PresentationValue image;
1.366 vatton 2268: char *url, *ptr;
1.302 quint 2269: char *bg_image;
2270: char tempname[MAX_LENGTH];
2271: char imgname[MAX_LENGTH];
2272:
2273: if (element)
2274: el = element;
2275: else
2276: /* default element for FetchImage */
2277: el = TtaGetMainRoot (ctxt->doc);
2278: url = NULL;
1.370 vatton 2279: image.typed_data.real = FALSE;
1.302 quint 2280: cssRule = ParseCSSUrl (cssRule, &url);
1.366 vatton 2281: ptr = cssRule;
1.302 quint 2282: if (ctxt->destroy)
2283: {
2284: /* remove the background image PRule */
2285: image.pointer = NULL;
1.366 vatton 2286: TtaSetStylePresentation (ruleType, element, tsch, ctxt, image);
1.302 quint 2287: }
1.366 vatton 2288: else if (url)
1.302 quint 2289: {
1.366 vatton 2290: if (css && css->url)
2291: /* the image concerns a CSS file */
2292: NormalizeURL (url, 0, tempname, imgname, css->url);
2293: else
2294: /* the image concerns a style element */
2295: NormalizeURL (url, ctxt->doc, tempname, imgname, NULL);
2296: if (DoDialog)
2297: {
2298: if (ruleType == PRBackgroundPicture)
2299: DisplayStyleValue ("background-image", tempname, &tempname[MAX_LENGTH-1]);
2300: else if (ruleType == PRListStyleImage)
2301: DisplayStyleValue ("list-style-image", tempname, &tempname[MAX_LENGTH-1]);
2302: else if (ruleType == PRContentURL)
2303: DisplayStyleValue ("", ptr, cssRule);
2304: }
2305: else if (DoApply)
2306: {
2307: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
2308: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
2309: /* background images are enabled */
2310: {
2311: callblock = (CSSImageCallbackPtr) TtaGetMemory (sizeof (CSSImageCallbackBlock));
2312: if (callblock)
2313: {
2314: callblock->el = element;
2315: callblock->tsch = tsch;
2316: callblock->css = css;
2317: callblock->ctxt = ctxt;
2318: callblock->ruleType = ruleType;
2319: /* new use of the context */
2320: ctxt->uses += 1;
2321: /* check if the image url is related to an external CSS */
2322: if (css)
2323: {
2324: RedisplayDoc = ctxt->doc;
2325: /* fetch and display background image of element */
2326: if (FetchImage (0, el, tempname, AMAYA_LOAD_IMAGE,
2327: ParseCSSImageCallback, callblock))
2328: RedisplayImages++;
2329: }
1.327 vatton 2330: else
1.366 vatton 2331: FetchImage (ctxt->doc, el, url, AMAYA_LOAD_IMAGE,
2332: ParseCSSImageCallback, callblock);
1.327 vatton 2333: }
2334: }
2335: }
1.366 vatton 2336: TtaFreeMemory (url);
1.302 quint 2337: }
2338: return (cssRule);
2339: }
2340:
2341: /*----------------------------------------------------------------------
1.327 vatton 2342: ParseACSSListStyleImage: parse a CSS list-style-image
2343: attribute string.
1.1 cvs 2344: ----------------------------------------------------------------------*/
1.318 vatton 2345: static char *ParseACSSListStyleImage (Element element, PSchema tsch,
1.327 vatton 2346: PresentationContext ctxt,
2347: char *cssRule, CSSInfoPtr css,
2348: ThotBool isHTML)
1.1 cvs 2349: {
1.288 vatton 2350: char *url;
1.366 vatton 2351: char *start_value;
1.293 quint 2352: PresentationValue pval;
1.281 quint 2353:
1.293 quint 2354: pval.typed_data.unit = UNIT_REL;
2355: pval.typed_data.real = FALSE;
1.281 quint 2356: url = NULL;
2357: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2358: start_value = cssRule;
1.281 quint 2359: if (!strncasecmp (cssRule, "none", 4))
2360: {
2361: cssRule += 4;
1.302 quint 2362: pval.typed_data.value = 0;
1.366 vatton 2363: if (DoDialog)
2364: DisplayStyleValue ("list-style-image", start_value, cssRule);
2365: else if (DoApply)
1.327 vatton 2366: TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
1.281 quint 2367: }
2368: else if (!strncasecmp (cssRule, "url", 3))
2369: {
2370: cssRule += 3;
1.302 quint 2371: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 2372: PRListStyleImage);
1.281 quint 2373: }
2374: else if (!strncasecmp (cssRule, "inherit", 7))
1.288 vatton 2375: {
2376: cssRule += 7;
1.293 quint 2377: pval.typed_data.unit = VALUE_INHERIT;
1.366 vatton 2378: if (DoDialog)
2379: DisplayStyleValue ("list-style-image", start_value, cssRule);
2380: else if (DoApply)
1.327 vatton 2381: TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
2382: }
1.281 quint 2383: else
1.295 vatton 2384: cssRule = SkipValue ("Invalid list-style-image value", cssRule);
1.1 cvs 2385: return (cssRule);
2386: }
2387:
2388: /*----------------------------------------------------------------------
1.327 vatton 2389: ParseCSSListStyleImage: parse a CSS list-style-image
2390: attribute string.
1.318 vatton 2391: ----------------------------------------------------------------------*/
2392: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1.327 vatton 2393: PresentationContext ctxt,
2394: char *cssRule, CSSInfoPtr css,
2395: ThotBool isHTML)
1.318 vatton 2396: {
2397: char *ptr = cssRule;
2398: cssRule = ParseACSSListStyleImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 2399: isHTML);
1.318 vatton 2400: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-image value");
2401: return cssRule;
2402: }
2403:
2404: /*----------------------------------------------------------------------
1.327 vatton 2405: ParseACSSListStylePosition: parse a CSS list-style-position
2406: attribute string.
1.1 cvs 2407: ----------------------------------------------------------------------*/
1.318 vatton 2408: static char *ParseACSSListStylePosition (Element element, PSchema tsch,
1.327 vatton 2409: PresentationContext context,
2410: char *cssRule, CSSInfoPtr css,
2411: ThotBool isHTML)
1.1 cvs 2412: {
1.281 quint 2413: PresentationValue pval;
1.366 vatton 2414: char *start_value;
1.281 quint 2415:
2416: pval.typed_data.unit = UNIT_REL;
2417: pval.typed_data.real = FALSE;
2418: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2419: start_value = cssRule;
1.281 quint 2420: if (!strncasecmp (cssRule, "inside", 6))
1.288 vatton 2421: {
2422: pval.typed_data.value = Inside;
2423: cssRule += 6;
2424: }
1.281 quint 2425: else if (!strncasecmp (cssRule, "outside", 7))
1.288 vatton 2426: {
2427: pval.typed_data.value = Outside;
2428: cssRule += 7;
2429: }
1.293 quint 2430: else if (!strncasecmp (cssRule, "inherit", 7))
2431: {
2432: pval.typed_data.unit = VALUE_INHERIT;
2433: cssRule += 7;
2434: }
1.281 quint 2435: else
2436: {
1.293 quint 2437: cssRule = SkipValue ("Invalid list-style-position value", cssRule);
1.281 quint 2438: return (cssRule);
2439: }
1.293 quint 2440:
1.366 vatton 2441: if (DoDialog)
2442: DisplayStyleValue ("list-style-position", start_value, cssRule);
2443: else if (DoApply)
1.295 vatton 2444: TtaSetStylePresentation (PRListStylePosition, element, tsch, context, pval);
1.327 vatton 2445: return (cssRule);
1.318 vatton 2446: }
2447:
2448: /*----------------------------------------------------------------------
1.327 vatton 2449: ParseCSSListStylePosition: parse a CSS list-style-position
2450: attribute string.
1.318 vatton 2451: ----------------------------------------------------------------------*/
2452: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
1.327 vatton 2453: PresentationContext context,
2454: char *cssRule, CSSInfoPtr css,
2455: ThotBool isHTML)
1.318 vatton 2456: {
2457: char *ptr = cssRule;
2458: cssRule = ParseACSSListStylePosition (element, tsch, context, cssRule, css,
1.327 vatton 2459: isHTML);
1.288 vatton 2460: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-position value");
1.318 vatton 2461: return cssRule;
1.1 cvs 2462: }
2463:
2464: /*----------------------------------------------------------------------
1.327 vatton 2465: ParseCSSListStyle: parse a CSS list-style value string.
1.1 cvs 2466: ----------------------------------------------------------------------*/
1.79 cvs 2467: static char *ParseCSSListStyle (Element element, PSchema tsch,
1.327 vatton 2468: PresentationContext ctxt, char *cssRule,
2469: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2470: {
1.318 vatton 2471: char *ptr = cssRule;
2472: int skippedNL;
1.281 quint 2473:
2474: cssRule = SkipBlanksAndComments (cssRule);
1.301 vatton 2475: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.281 quint 2476: {
1.316 quint 2477: skippedNL = NewLineSkipped;
1.281 quint 2478: /* perhaps a list-style-image */
2479: if (!strncasecmp (cssRule, "url", 3))
1.327 vatton 2480: cssRule = ParseACSSListStyleImage (element, tsch, ctxt, cssRule, css,
2481: isHTML);
1.281 quint 2482: /* perhaps a list-style-position */
2483: else if (!strncasecmp (cssRule, "inside", 6) ||
2484: !strncasecmp (cssRule, "outside", 7))
1.327 vatton 2485: cssRule = ParseACSSListStylePosition (element, tsch, ctxt, cssRule,
2486: css, isHTML);
1.281 quint 2487: /* perhaps a list-style-type */
2488: else if (!strncasecmp (cssRule, "disc", 4) ||
1.327 vatton 2489: !strncasecmp (cssRule, "circle", 6) ||
2490: !strncasecmp (cssRule, "square", 6) ||
2491: !strncasecmp (cssRule, "decimal", 7) ||
2492: !strncasecmp (cssRule, "decimal-leading-zero", 20) ||
2493: !strncasecmp (cssRule, "lower-roman", 11) ||
2494: !strncasecmp (cssRule, "upper-roman", 11) ||
2495: !strncasecmp (cssRule, "lower-greek", 11) ||
2496: !strncasecmp (cssRule, "lower-latin", 11) ||
2497: !strncasecmp (cssRule, "lower-alpha", 11) ||
2498: !strncasecmp (cssRule, "upper-latin", 11) ||
2499: !strncasecmp (cssRule, "upper-alpha", 11) ||
2500: !strncasecmp (cssRule, "armenian", 8) ||
2501: !strncasecmp (cssRule, "georgian", 8) ||
2502: !strncasecmp (cssRule, "none", 4) ||
2503: !strncasecmp (cssRule, "inherit", 7))
2504: cssRule = ParseACSSListStyleType (element, tsch, ctxt, cssRule, css,
2505: isHTML);
1.281 quint 2506: else
1.327 vatton 2507: {
2508: NewLineSkipped = skippedNL;
2509: /* rule not found */
2510: cssRule = SkipProperty (cssRule, FALSE);
2511: }
1.281 quint 2512: cssRule = SkipBlanksAndComments (cssRule);
2513: }
1.318 vatton 2514: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style value");
1.1 cvs 2515: return (cssRule);
2516: }
2517:
2518: /*----------------------------------------------------------------------
1.327 vatton 2519: ParseCSSTextAlign: parse a CSS text-align
2520: attribute string.
1.1 cvs 2521: ----------------------------------------------------------------------*/
1.79 cvs 2522: static char *ParseCSSTextAlign (Element element, PSchema tsch,
1.327 vatton 2523: PresentationContext context, char *cssRule,
2524: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2525: {
1.366 vatton 2526: char *ptr;
1.327 vatton 2527: PresentationValue align;
2528:
2529: align.typed_data.value = 0;
2530: align.typed_data.unit = UNIT_REL;
2531: align.typed_data.real = FALSE;
2532:
2533: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2534: ptr = cssRule;
1.327 vatton 2535: if (!strncasecmp (cssRule, "left", 4))
2536: {
2537: align.typed_data.value = AdjustLeft;
2538: cssRule += 4;
2539: }
2540: else if (!strncasecmp (cssRule, "right", 5))
2541: {
2542: align.typed_data.value = AdjustRight;
2543: cssRule += 5;
2544: }
2545: else if (!strncasecmp (cssRule, "center", 6))
2546: {
2547: align.typed_data.value = Centered;
2548: cssRule += 6;
2549: }
2550: else if (!strncasecmp (cssRule, "justify", 7))
2551: {
2552: align.typed_data.value = Justify;
2553: cssRule += 7;
2554: }
2555: else
2556: {
2557: cssRule = SkipValue ("Invalid text-align value", cssRule);
2558: return (cssRule);
2559: }
1.1 cvs 2560:
1.327 vatton 2561: /*
2562: * install the new presentation.
2563: */
1.366 vatton 2564: if (align.typed_data.value)
2565: {
2566: if (DoDialog)
2567: DisplayStyleValue ("text-align", ptr, cssRule);
2568: else if (DoApply)
2569: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
2570: }
1.327 vatton 2571: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-align value");
2572: return (cssRule);
1.1 cvs 2573: }
2574:
2575: /*----------------------------------------------------------------------
1.243 quint 2576: ParseCSSTextAnchor: parse a CSS text-anchor property (SVG property)
2577: We use the Thot Adjust PRule to represent the text-anchor property
2578: for CSS 1.0, as Adjust is not used otherwise in this context.
2579: ----------------------------------------------------------------------*/
2580: static char *ParseCSSTextAnchor (Element element, PSchema tsch,
1.327 vatton 2581: PresentationContext context, char *cssRule,
2582: CSSInfoPtr css, ThotBool isHTML)
1.243 quint 2583: {
1.327 vatton 2584: PresentationValue align;
1.366 vatton 2585: char *ptr;
1.327 vatton 2586:
2587: align.typed_data.value = 0;
2588: align.typed_data.unit = UNIT_REL;
2589: align.typed_data.real = FALSE;
1.243 quint 2590:
1.327 vatton 2591: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2592: ptr = cssRule;
1.327 vatton 2593: if (!strncasecmp (cssRule, "start", 5))
2594: {
2595: align.typed_data.value = AdjustLeft;
2596: cssRule += 5;
2597: }
2598: else if (!strncasecmp (cssRule, "middle", 6))
2599: {
2600: align.typed_data.value = Centered;
2601: cssRule += 6;
2602: }
2603: else if (!strncasecmp (cssRule, "end", 3))
2604: {
2605: align.typed_data.value = AdjustRight;
2606: cssRule += 3;
2607: }
2608: else if (!strncasecmp (cssRule, "inherit", 7))
2609: {
2610: align.typed_data.unit = VALUE_INHERIT;
2611: cssRule += 7;
2612: }
2613: else
2614: {
2615: cssRule = SkipValue ("Invalid text-anchor value", cssRule);
1.295 vatton 2616: return (cssRule);
1.327 vatton 2617: }
1.243 quint 2618:
1.327 vatton 2619: /*
2620: * install the new presentation.
2621: */
1.366 vatton 2622: if (align.typed_data.value || align.typed_data.unit == VALUE_INHERIT)
2623: {
2624: if (DoDialog)
2625: DisplayStyleValue ("text-anchor", ptr, cssRule);
2626: else if (DoApply)
2627: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
2628: }
1.327 vatton 2629: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-anchor value");
2630: return (cssRule);
1.243 quint 2631: }
2632:
2633: /*----------------------------------------------------------------------
1.327 vatton 2634: ParseCSSDirection: parse a CSS direction property
1.112 quint 2635: ----------------------------------------------------------------------*/
2636: static char *ParseCSSDirection (Element element, PSchema tsch,
1.327 vatton 2637: PresentationContext context, char *cssRule,
2638: CSSInfoPtr css, ThotBool isHTML)
1.112 quint 2639: {
1.327 vatton 2640: PresentationValue direction;
1.366 vatton 2641: char *ptr;
1.327 vatton 2642:
2643: direction.typed_data.value = 0;
2644: direction.typed_data.unit = UNIT_REL;
2645: direction.typed_data.real = FALSE;
2646:
2647: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2648: ptr = cssRule;
1.327 vatton 2649: if (!strncasecmp (cssRule, "ltr", 3))
2650: {
2651: direction.typed_data.value = LeftToRight;
2652: cssRule += 3;
2653: }
2654: else if (!strncasecmp (cssRule, "rtl", 3))
2655: {
2656: direction.typed_data.value = RightToLeft;
2657: cssRule += 3;
2658: }
2659: else if (!strncasecmp (cssRule, "inherit", 7))
2660: {
2661: direction.typed_data.unit = VALUE_INHERIT;
2662: cssRule += 7;
2663: }
2664: else
2665: {
2666: cssRule = SkipValue ("Invalid direction value", cssRule);
2667: return (cssRule);
2668: }
1.112 quint 2669:
1.327 vatton 2670: /*
2671: * install the new presentation.
2672: */
1.366 vatton 2673: if (direction.typed_data.value || direction.typed_data.unit == VALUE_INHERIT)
2674: {
2675: if (DoDialog)
2676: DisplayStyleValue ("direction", ptr, cssRule);
2677: else if (DoApply)
2678: TtaSetStylePresentation (PRDirection, element, tsch, context, direction);
2679: }
1.327 vatton 2680: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid direction value");
2681: return (cssRule);
1.112 quint 2682: }
2683:
2684: /*----------------------------------------------------------------------
1.327 vatton 2685: ParseCSSUnicodeBidi: parse a CSS unicode-bidi property
1.113 quint 2686: ----------------------------------------------------------------------*/
2687: static char *ParseCSSUnicodeBidi (Element element, PSchema tsch,
1.327 vatton 2688: PresentationContext context, char *cssRule,
2689: CSSInfoPtr css, ThotBool isHTML)
1.113 quint 2690: {
1.327 vatton 2691: PresentationValue bidi;
1.366 vatton 2692: char *ptr;
1.113 quint 2693:
1.327 vatton 2694: bidi.typed_data.value = 0;
2695: bidi.typed_data.unit = UNIT_REL;
2696: bidi.typed_data.real = FALSE;
2697:
2698: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2699: ptr = cssRule;
1.327 vatton 2700: if (!strncasecmp (cssRule, "normal", 6))
2701: {
2702: bidi.typed_data.value = Normal;
2703: cssRule += 6;
2704: }
2705: else if (!strncasecmp (cssRule, "embed", 5))
2706: {
2707: bidi.typed_data.value = Embed;
2708: cssRule += 5;
2709: }
2710: else if (!strncasecmp (cssRule, "bidi-override", 13))
2711: {
2712: bidi.typed_data.value = Override;
2713: cssRule += 13;
2714: }
2715: else if (!strncasecmp (cssRule, "inherit", 7))
2716: {
2717: bidi.typed_data.unit = VALUE_INHERIT;
2718: cssRule += 7;
2719: }
2720: else
2721: {
2722: cssRule = SkipValue ("Invalid unicode-bidi value", cssRule);
1.295 vatton 2723: return (cssRule);
1.327 vatton 2724: }
1.113 quint 2725:
1.327 vatton 2726: /*
2727: * install the new presentation.
2728: */
1.366 vatton 2729: if (bidi.typed_data.value || bidi.typed_data.unit == VALUE_INHERIT)
2730: {
2731: if (DoDialog)
2732: DisplayStyleValue ("unicode-bidi", ptr, cssRule);
2733: else if (DoApply)
2734: TtaSetStylePresentation (PRUnicodeBidi, element, tsch, context, bidi);
2735: }
1.327 vatton 2736: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid unicode-bidi value");
2737: return (cssRule);
1.113 quint 2738: }
2739:
2740: /*----------------------------------------------------------------------
1.327 vatton 2741: ParseCSSTextIndent: parse a CSS text-indent
2742: attribute string.
1.1 cvs 2743: ----------------------------------------------------------------------*/
1.79 cvs 2744: static char *ParseCSSTextIndent (Element element, PSchema tsch,
1.327 vatton 2745: PresentationContext context, char *cssRule,
2746: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2747: {
1.327 vatton 2748: PresentationValue pval;
2749: char *ptr;
1.1 cvs 2750:
1.370 vatton 2751: pval.typed_data.real = FALSE;
1.327 vatton 2752: cssRule = SkipBlanksAndComments (cssRule);
2753: ptr = cssRule;
2754: cssRule = ParseCSSUnit (cssRule, &pval);
1.387 quint 2755: if (pval.typed_data.value == 0 &&
2756: pval.typed_data.unit != UNIT_INVALID)
1.327 vatton 2757: pval.typed_data.unit = UNIT_PX;
2758: else if (pval.typed_data.unit == UNIT_INVALID ||
2759: pval.typed_data.unit == UNIT_BOX)
2760: {
2761: CSSParseError ("Invalid text-indent value", ptr, cssRule);
2762: return (cssRule);
2763: }
2764: /* install the attribute */
1.366 vatton 2765: if (DoDialog)
2766: DisplayStyleValue ("text-indent", ptr, cssRule);
2767: else if (DoApply)
1.327 vatton 2768: TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
2769: return (cssRule);
1.1 cvs 2770: }
2771:
2772: /*----------------------------------------------------------------------
1.327 vatton 2773: ParseCSSTextTransform: parse a CSS text-transform
2774: attribute string.
1.1 cvs 2775: ----------------------------------------------------------------------*/
1.79 cvs 2776: static char *ParseCSSTextTransform (Element element, PSchema tsch,
1.327 vatton 2777: PresentationContext context, char *cssRule,
2778: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2779: {
1.366 vatton 2780: char *ptr;
2781:
2782: cssRule = SkipBlanksAndComments (cssRule);
2783: ptr = cssRule;
1.168 vatton 2784: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 2785: if (DoDialog)
2786: DisplayStyleValue ("text-transform", ptr, cssRule);
1.1 cvs 2787: return (cssRule);
2788: }
2789:
2790: /*----------------------------------------------------------------------
1.327 vatton 2791: ParseCSSVerticalAlign: parse a CSS vertical-align
2792: attribute string.
1.1 cvs 2793: ----------------------------------------------------------------------*/
1.79 cvs 2794: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
1.327 vatton 2795: PresentationContext context, char *cssRule,
2796: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2797: {
1.273 quint 2798: char *ptr;
2799: PresentationValue pval;
2800:
2801: pval.typed_data.unit = UNIT_REL;
2802: pval.typed_data.real = FALSE;
2803: cssRule = SkipBlanksAndComments (cssRule);
1.288 vatton 2804: ptr = cssRule;
1.273 quint 2805: if (!strncasecmp (cssRule, "baseline", 8))
2806: {
2807: pval.typed_data.value = 0;
1.288 vatton 2808: cssRule += 8;
1.273 quint 2809: }
2810: else if (!strncasecmp (cssRule, "sub", 3))
2811: {
2812: pval.typed_data.value = -3;
1.288 vatton 2813: cssRule += 3;
1.273 quint 2814: }
2815: else if (!strncasecmp (cssRule, "super", 5))
2816: {
2817: pval.typed_data.value = 4;
1.288 vatton 2818: cssRule += 5;
1.273 quint 2819: }
2820: else if (!strncasecmp (cssRule, "top", 3))
2821: {
1.275 quint 2822: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2823: pval.typed_data.value = 0;
1.288 vatton 2824: cssRule += 3;
1.273 quint 2825: }
2826: else if (!strncasecmp (cssRule, "text-top", 8))
2827: {
1.275 quint 2828: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2829: pval.typed_data.value = 0;
1.288 vatton 2830: cssRule += 8;
1.273 quint 2831: }
2832: else if (!strncasecmp (cssRule, "middle", 6))
2833: {
1.275 quint 2834: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2835: pval.typed_data.value = 0;
1.288 vatton 2836: cssRule += 6;
1.273 quint 2837: }
2838: else if (!strncasecmp (cssRule, "bottom", 6))
2839: {
1.275 quint 2840: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2841: pval.typed_data.value = 0;
1.288 vatton 2842: cssRule += 6;
1.273 quint 2843: }
2844: else if (!strncasecmp (cssRule, "text-bottom", 11))
2845: {
1.275 quint 2846: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2847: pval.typed_data.value = 0;
1.288 vatton 2848: cssRule += 11;
1.273 quint 2849: }
2850: else if (!strncasecmp (cssRule, "inherit", 7))
2851: {
1.293 quint 2852: pval.typed_data.unit = VALUE_INHERIT;
1.274 vatton 2853: pval.typed_data.value = 0;
1.288 vatton 2854: cssRule +=7;
1.273 quint 2855: }
2856: else
2857: {
2858: /* parse <percentage> or <length> */
2859: cssRule = ParseCSSUnit (cssRule, &pval);
2860: if (pval.typed_data.unit == UNIT_INVALID)
1.327 vatton 2861: {
2862: pval.typed_data.value = 0;
2863: CSSParseError ("Invalid vertical-align value", ptr, cssRule);
2864: return (cssRule);
2865: }
1.273 quint 2866: else if (pval.typed_data.value == 0)
1.327 vatton 2867: pval.typed_data.unit = UNIT_PX;
1.273 quint 2868: else if (pval.typed_data.unit == UNIT_BOX)
1.327 vatton 2869: pval.typed_data.unit = UNIT_EM;
1.273 quint 2870: else if (pval.typed_data.unit == UNIT_PERCENT)
1.327 vatton 2871: /* it's a percentage */
2872: {
2873: /* convert it into a relative size */
2874: pval.typed_data.unit = UNIT_REL;
2875: pval.typed_data.value /= 10;
2876: }
1.273 quint 2877: }
1.295 vatton 2878:
1.366 vatton 2879: if (pval.typed_data.unit != UNIT_INVALID)
2880: {
2881: if (DoDialog)
2882: DisplayStyleValue ("vertical-align", ptr, cssRule);
2883: else if (DoApply)
2884: TtaSetStylePresentation (PRHorizRef, element, tsch, context, pval);
2885: }
1.288 vatton 2886: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid vertical-align value");
1.1 cvs 2887: return (cssRule);
2888: }
2889:
2890: /*----------------------------------------------------------------------
1.327 vatton 2891: ParseCSSWhiteSpace: parse a CSS white-space
2892: attribute string.
1.1 cvs 2893: ----------------------------------------------------------------------*/
1.79 cvs 2894: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
1.327 vatton 2895: PresentationContext context, char *cssRule,
2896: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2897: {
1.366 vatton 2898: char *ptr;
1.288 vatton 2899:
1.327 vatton 2900: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2901: ptr = cssRule;
1.327 vatton 2902: if (!strncasecmp (cssRule, "normal", 6))
2903: cssRule += 6;
2904: else if (!strncasecmp (cssRule, "pre", 3))
2905: cssRule += 3;
2906: else if (!strncasecmp (cssRule, "nowrap", 6))
2907: cssRule += 6;
2908: else if (!strncasecmp (cssRule, "pre-wrap", 8))
2909: cssRule += 8;
2910: else if (!strncasecmp (cssRule, "pre-line", 8))
2911: cssRule += 8;
2912: else if (!strncasecmp (cssRule, "inherit", 7))
2913: cssRule += 7;
2914: else
2915: cssRule = SkipValue ("Invalid white-space value", cssRule);
2916:
1.387 quint 2917: if (ptr != cssRule && DoDialog)
1.366 vatton 2918: DisplayStyleValue ("white-space", ptr, cssRule);
1.327 vatton 2919: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid white-space value");
2920: return (cssRule);
1.1 cvs 2921: }
2922:
2923: /*----------------------------------------------------------------------
1.327 vatton 2924: ParseCSSWordSpacing: parse a CSS word-spacing
2925: attribute string.
1.1 cvs 2926: ----------------------------------------------------------------------*/
1.79 cvs 2927: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
1.327 vatton 2928: PresentationContext context, char *cssRule,
2929: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2930: {
1.366 vatton 2931: char *ptr;
2932:
2933: cssRule = SkipBlanksAndComments (cssRule);
2934: ptr = cssRule;
1.168 vatton 2935: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 2936: if (DoDialog)
2937: DisplayStyleValue ("word-spacing", ptr, cssRule);
1.1 cvs 2938: return (cssRule);
2939: }
2940:
2941: /*----------------------------------------------------------------------
1.327 vatton 2942: ParseCSSLineHeight: parse a CSS line-height property
1.25 cvs 2943: ----------------------------------------------------------------------*/
1.162 quint 2944: static char *ParseCSSLineHeight (Element element, PSchema tsch,
1.327 vatton 2945: PresentationContext context, char *cssRule,
2946: CSSInfoPtr css, ThotBool isHTML)
1.25 cvs 2947: {
1.162 quint 2948: PresentationValue pval;
1.288 vatton 2949: char *ptr;
1.162 quint 2950:
1.370 vatton 2951: pval.typed_data.real = FALSE;
1.366 vatton 2952: cssRule = SkipBlanksAndComments (cssRule);
1.162 quint 2953: ptr = cssRule;
2954: if (!strncasecmp (cssRule, "normal", 6))
2955: {
1.184 vatton 2956: pval.typed_data.unit = UNIT_REL;
1.162 quint 2957: pval.typed_data.real = TRUE;
2958: pval.typed_data.value = 1100;
1.288 vatton 2959: cssRule += 6;
1.162 quint 2960: }
2961: else if (!strncasecmp (cssRule, "inherit", 7))
2962: {
1.293 quint 2963: pval.typed_data.unit = VALUE_INHERIT;
1.354 quint 2964: cssRule += 7;
1.162 quint 2965: }
2966: else
2967: cssRule = ParseCSSUnit (cssRule, &pval);
1.25 cvs 2968:
1.184 vatton 2969: if (pval.typed_data.unit == UNIT_INVALID)
1.168 vatton 2970: CSSParseError ("Invalid line-height value", ptr, cssRule);
1.387 quint 2971: else if (DoDialog)
1.366 vatton 2972: DisplayStyleValue ("line-height", ptr, cssRule);
1.162 quint 2973: else if (DoApply)
2974: {
1.166 vatton 2975: /* install the new presentation */
1.184 vatton 2976: if (pval.typed_data.unit == UNIT_BOX)
1.327 vatton 2977: pval.typed_data.unit = UNIT_EM;
1.162 quint 2978: TtaSetStylePresentation (PRLineSpacing, element, tsch, context, pval);
2979: }
2980: return (cssRule);
1.25 cvs 2981: }
2982:
2983: /*----------------------------------------------------------------------
1.327 vatton 2984: ParseCSSFontSizeAdjust: parse a CSS fontsizeAdjust attr string
2985: we expect the input string describing the attribute to be
2986: xx-small, x-small, small, medium, large, x-large, xx-large
2987: or an absolute size, or an imcrement relative to the parent
1.1 cvs 2988: ----------------------------------------------------------------------*/
1.219 vatton 2989: static char *ParseCSSFontSizeAdjust (Element element, PSchema tsch,
1.327 vatton 2990: PresentationContext context, char *cssRule,
2991: CSSInfoPtr css, ThotBool isHTML)
1.219 vatton 2992: {
1.366 vatton 2993:
2994: cssRule = SkipBlanksAndComments (cssRule);
1.234 vatton 2995: cssRule = SkipProperty (cssRule, FALSE);
1.222 quint 2996: return (cssRule);
1.219 vatton 2997: }
2998:
2999: /*----------------------------------------------------------------------
1.327 vatton 3000: ParseACSSFontSize: parse a CSS font size attr string
3001: we expect the input string describing the attribute to be
3002: xx-small, x-small, small, medium, large, x-large, xx-large
3003: or an absolute size, or an imcrement relative to the parent.
3004: The parameter check is TRUE if the rule is just checked.
1.219 vatton 3005: ----------------------------------------------------------------------*/
1.270 vatton 3006: static char *ParseACSSFontSize (Element element, PSchema tsch,
1.327 vatton 3007: PresentationContext context, char *cssRule,
3008: CSSInfoPtr css, ThotBool isHTML, ThotBool check)
1.1 cvs 3009: {
1.327 vatton 3010: ElementType elType;
3011: PresentationValue pval;
1.369 quint 3012: char *ptr = NULL, *ptr1 = NULL, *ptr2 = NULL;
1.366 vatton 3013: char *start_value;
1.369 quint 3014: ThotBool real, error, linespace = FALSE;
1.327 vatton 3015:
1.369 quint 3016: error = FALSE;
1.327 vatton 3017: pval.typed_data.real = FALSE;
3018: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3019: start_value = cssRule;
1.327 vatton 3020: /* look for a '/' within the current cssRule */
3021: ptr1 = strchr (cssRule, ';');
3022: ptr = strchr (cssRule, '/');
3023: if (ptr && (ptr1 == NULL || ptr < ptr1))
3024: {
3025: /* keep the line spacing rule */
3026: linespace = TRUE;
3027: ptr[0] = EOS;
3028: }
3029: else
3030: ptr = NULL;
3031: ptr1 = cssRule;
1.289 vatton 3032: /* relative size */
1.327 vatton 3033: if (!strncasecmp (cssRule, "larger", 6))
3034: {
3035: pval.typed_data.unit = UNIT_PERCENT;
3036: pval.typed_data.value = 130;
3037: cssRule += 6;
3038: }
3039: else if (!strncasecmp (cssRule, "smaller", 7))
3040: {
3041: pval.typed_data.unit = UNIT_PERCENT;
3042: pval.typed_data.value = 80;
3043: cssRule += 7;
3044: }
3045: /* absolute size */
3046: else if (!strncasecmp (cssRule, "xx-small", 8))
3047: {
3048: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3049: pval.typed_data.value = 6;
1.327 vatton 3050: cssRule += 8;
3051: }
3052: else if (!strncasecmp (cssRule, "x-small", 7))
3053: {
3054: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3055: pval.typed_data.value = 8;
1.327 vatton 3056: cssRule += 7;
3057: }
3058: else if (!strncasecmp (cssRule, "small", 5))
3059: {
3060: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3061: pval.typed_data.value = 10;
1.327 vatton 3062: cssRule += 5;
3063: }
3064: else if (!strncasecmp (cssRule, "medium", 6))
3065: {
3066: pval.typed_data.unit = UNIT_PT;
3067: pval.typed_data.value = 12;
3068: cssRule += 6;
3069: }
3070: else if (!strncasecmp (cssRule, "large", 5))
3071: {
3072: pval.typed_data.unit = UNIT_PT;
3073: pval.typed_data.value = 13;
3074: cssRule += 5;
3075: }
3076: else if (!strncasecmp (cssRule, "x-large", 7))
3077: {
3078: pval.typed_data.unit = UNIT_PT;
3079: pval.typed_data.value = 14;
3080: cssRule += 7;
3081: }
3082: else if (!strncasecmp (cssRule, "xx-large", 8))
3083: {
3084: pval.typed_data.unit = UNIT_PT;
3085: pval.typed_data.value = 16;
3086: cssRule += 8;
3087: }
3088: else if (!strncasecmp (cssRule, "inherit", 7))
3089: {
3090: pval.typed_data.unit = VALUE_INHERIT;
3091: pval.typed_data.value = 0;
3092: cssRule += 7;
3093: }
3094: /* length or percentage */
3095: else if (!isdigit (*cssRule) && *cssRule != '.')
3096: {
3097: if (!check)
1.360 vatton 3098: cssRule = SkipValue ("Invalid font-size value", cssRule);
1.369 quint 3099: error = TRUE;
1.327 vatton 3100: }
3101: else
3102: {
3103: cssRule = ParseCSSUnit (cssRule, &pval);
3104: if (pval.typed_data.unit == UNIT_BOX)
3105: /* no unit specified */
3106: {
3107: elType = TtaGetElementType(element);
3108: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
3109: /* we are working for an SVG element. No unit means pixels */
3110: pval.typed_data.unit = UNIT_PX;
3111: }
1.387 quint 3112: if (pval.typed_data.unit == UNIT_INVALID ||
3113: (pval.typed_data.value != 0 && pval.typed_data.unit == UNIT_BOX) ||
3114: pval.typed_data.value < 0)
1.327 vatton 3115: /* not a valid value */
1.369 quint 3116: {
3117: if (!check)
3118: {
3119: ptr2 = SkipWord (cssRule);
3120: CSSParseError ("Invalid font-size value", ptr1, ptr2);
3121: }
3122: error = TRUE;
3123: }
1.327 vatton 3124: else if (pval.typed_data.unit == UNIT_REL && pval.typed_data.value > 0)
3125: /* CSS relative sizes have to be higher than Thot ones */
3126: pval.typed_data.value += 1;
3127: else
3128: {
3129: real = pval.typed_data.real;
3130: if (pval.typed_data.unit == UNIT_EM)
3131: {
3132: if (real)
3133: {
3134: pval.typed_data.value /= 10;
3135: pval.typed_data.real = FALSE;
3136: real = FALSE;
3137: }
3138: else
3139: pval.typed_data.value *= 100;
3140: pval.typed_data.unit = UNIT_PERCENT;
3141: }
3142: else if (pval.typed_data.unit == UNIT_XHEIGHT)
3143: {
3144: /* a font size expressed in ex is converted into a percentage.
3145: For example, "3ex" is converted into "180%", supposing
3146: that 1ex is approximately 0.6 times the height of the
3147: current font */
3148: if (real)
3149: {
3150: pval.typed_data.value *= 6;
3151: pval.typed_data.value /= 100;
3152: pval.typed_data.real = FALSE;
3153: real = FALSE;
3154: }
3155: else
3156: pval.typed_data.value *= 60;
3157: pval.typed_data.unit = UNIT_PERCENT;
3158: }
3159: }
3160: }
3161:
3162: /* install the presentation style */
1.369 quint 3163: if (!check && !error)
1.366 vatton 3164: {
3165: if (DoDialog)
3166: DisplayStyleValue ("font-size", start_value, cssRule);
3167: else if (DoApply)
3168: TtaSetStylePresentation (PRSize, element, tsch, context, pval);
3169: }
1.327 vatton 3170: if (!check && ptr)
3171: cssRule = ParseCSSLineHeight (element, tsch, context, &ptr[1], css, isHTML);
3172: if (linespace)
3173: *ptr = '/';
3174:
3175: return (cssRule);
3176: }
3177:
3178: /*----------------------------------------------------------------------
3179: ParseCSSFontSize: parse a CSS font size attr string
3180: we expect the input string describing the attribute to be
3181: xx-small, x-small, small, medium, large, x-large, xx-large
3182: or an absolute size, or an imcrement relative to the parent
1.270 vatton 3183: ----------------------------------------------------------------------*/
3184: static char *ParseCSSFontSize (Element element, PSchema tsch,
1.327 vatton 3185: PresentationContext context, char *cssRule,
3186: CSSInfoPtr css, ThotBool isHTML)
1.270 vatton 3187: {
1.299 vatton 3188: char *ptr = cssRule;
1.295 vatton 3189: cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.299 vatton 3190: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid font-size value");
1.295 vatton 3191: return cssRule;
1.270 vatton 3192: }
3193:
3194: /*----------------------------------------------------------------------
1.327 vatton 3195: ParseACSSFontFamily: parse a CSS font family string
3196: we expect the input string describing the attribute to be
3197: a common generic font style name
1.1 cvs 3198: ----------------------------------------------------------------------*/
1.268 vatton 3199: static char *ParseACSSFontFamily (Element element, PSchema tsch,
1.327 vatton 3200: PresentationContext context, char *cssRule,
3201: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3202: {
3203: PresentationValue font;
1.252 vatton 3204: char quoteChar, *p;
1.1 cvs 3205:
3206: font.typed_data.value = 0;
1.184 vatton 3207: font.typed_data.unit = UNIT_REL;
1.1 cvs 3208: font.typed_data.real = FALSE;
1.82 cvs 3209: cssRule = SkipBlanksAndComments (cssRule);
3210: if (*cssRule == '"' || *cssRule == '\'')
1.327 vatton 3211: {
3212: quoteChar = *cssRule;
3213: cssRule++;
3214: }
1.1 cvs 3215: else
1.327 vatton 3216: quoteChar = EOS;
1.1 cvs 3217:
1.293 quint 3218: if (!strncasecmp (cssRule, "inherit", 7) && quoteChar == EOS)
3219: {
3220: font.typed_data.unit = VALUE_INHERIT;
3221: cssRule += 7;
3222: }
3223: else if (!strncasecmp (cssRule, "times", 5) &&
1.327 vatton 3224: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 3225: {
1.184 vatton 3226: font.typed_data.value = FontTimes;
1.86 cvs 3227: cssRule += 5;
3228: }
1.92 cvs 3229: else if (!strncasecmp (cssRule, "serif", 5) &&
1.327 vatton 3230: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 3231: {
1.184 vatton 3232: font.typed_data.value = FontTimes;
1.86 cvs 3233: cssRule += 5;
1.92 cvs 3234: if (quoteChar != EOS)
1.327 vatton 3235: cssRule++;
1.86 cvs 3236: }
1.92 cvs 3237: else if (!strncasecmp (cssRule, "helvetica", 9) &&
1.327 vatton 3238: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 3239: {
1.327 vatton 3240: font.typed_data.value = FontHelvetica;
1.86 cvs 3241: cssRule += 9;
1.92 cvs 3242: if (quoteChar != EOS)
1.327 vatton 3243: cssRule++;
1.86 cvs 3244: }
1.92 cvs 3245: else if (!strncasecmp (cssRule, "verdana", 7) &&
1.327 vatton 3246: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 3247: {
1.184 vatton 3248: font.typed_data.value = FontHelvetica;
1.86 cvs 3249: cssRule += 7;
1.92 cvs 3250: if (quoteChar != EOS)
1.327 vatton 3251: cssRule++;
1.86 cvs 3252: }
1.92 cvs 3253: else if (!strncasecmp (cssRule, "sans-serif", 10) &&
1.327 vatton 3254: (quoteChar == EOS || quoteChar == cssRule[10]))
1.86 cvs 3255: {
1.184 vatton 3256: font.typed_data.value = FontHelvetica;
1.86 cvs 3257: cssRule += 10;
1.92 cvs 3258: if (quoteChar != EOS)
1.327 vatton 3259: cssRule++;
1.86 cvs 3260: }
1.268 vatton 3261: else if (!strncasecmp (cssRule, "courier new", 11) &&
1.327 vatton 3262: (quoteChar == EOS || quoteChar == cssRule[11]))
1.268 vatton 3263: {
3264: font.typed_data.value = FontCourier;
3265: cssRule += 11;
3266: if (quoteChar != EOS)
1.327 vatton 3267: cssRule++;
1.268 vatton 3268: }
1.92 cvs 3269: else if (!strncasecmp (cssRule, "courier", 7) &&
1.327 vatton 3270: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 3271: {
1.184 vatton 3272: font.typed_data.value = FontCourier;
1.86 cvs 3273: cssRule += 7;
1.92 cvs 3274: if (quoteChar != EOS)
1.327 vatton 3275: cssRule++;
1.86 cvs 3276: }
1.92 cvs 3277: else if (!strncasecmp (cssRule, "monospace", 9) &&
1.327 vatton 3278: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 3279: {
1.184 vatton 3280: font.typed_data.value = FontCourier;
1.86 cvs 3281: cssRule += 9;
1.92 cvs 3282: if (quoteChar != EOS)
1.327 vatton 3283: cssRule++;
1.86 cvs 3284: }
1.1 cvs 3285: else
3286: /* unknown font name. Skip it */
3287: {
1.252 vatton 3288: p = cssRule;
1.92 cvs 3289: if (quoteChar != EOS)
1.327 vatton 3290: cssRule = SkipQuotedString (cssRule, quoteChar);
1.86 cvs 3291: else
1.383 quint 3292: /* unquoted font name. The name may contain spaces */
3293: {
3294: cssRule = SkipWord (cssRule);
3295: while (*cssRule == SPACE || *cssRule == BSPACE || *cssRule == EOL ||
3296: *cssRule == TAB || *cssRule == __CR__)
3297: {
3298: cssRule = SkipBlanksAndComments (cssRule);
3299: if (*cssRule != ',' && *cssRule != ';' && *cssRule != '}' &&
3300: *cssRule != EOS)
3301: cssRule = SkipWord (cssRule);
3302: }
3303: }
1.252 vatton 3304: while (p == cssRule &&
1.327 vatton 3305: *cssRule != ',' && *cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
3306: {
3307: cssRule++;
3308: p = cssRule;
3309: cssRule = SkipWord (cssRule);
3310: }
1.82 cvs 3311: cssRule = SkipBlanksAndComments (cssRule);
3312: if (*cssRule == ',')
1.327 vatton 3313: {
3314: /* recursive call to ParseCSSFontFamily */
3315: cssRule++;
3316: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3317: return (cssRule);
3318: }
1.1 cvs 3319: }
3320:
1.239 vatton 3321: /* skip other values */
3322: cssRule = SkipBlanksAndComments (cssRule);
3323: while (*cssRule == ',')
3324: {
3325: cssRule++;
3326: cssRule = SkipValue (NULL, cssRule);
3327: cssRule = SkipBlanksAndComments (cssRule);
3328: }
3329:
1.366 vatton 3330: if (font.typed_data.value != 0 || font.typed_data.unit == VALUE_INHERIT)
3331: {
3332: if (!DoDialog && DoApply)
3333: /* install the new presentation */
3334: TtaSetStylePresentation (PRFont, element, tsch, context, font);
3335: }
1.1 cvs 3336: return (cssRule);
3337: }
3338:
3339: /*----------------------------------------------------------------------
1.327 vatton 3340: ParseCSSFontFamily: parse a CSS font family string
3341: we expect the input string describing the attribute to be
3342: a common generic font style name
1.268 vatton 3343: ----------------------------------------------------------------------*/
3344: static char *ParseCSSFontFamily (Element element, PSchema tsch,
1.327 vatton 3345: PresentationContext context, char *cssRule,
3346: CSSInfoPtr css, ThotBool isHTML)
1.268 vatton 3347: {
1.366 vatton 3348: char *start_value;
3349:
3350: cssRule = SkipBlanksAndComments (cssRule);
3351: start_value = cssRule;
1.268 vatton 3352: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3353: /* skip extra values */
1.301 vatton 3354: while (cssRule && *cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.268 vatton 3355: cssRule++;
1.366 vatton 3356: if (DoDialog)
3357: DisplayStyleValue ("font-family", start_value, cssRule);
1.268 vatton 3358: return (cssRule);
3359: }
3360:
3361: /*----------------------------------------------------------------------
1.327 vatton 3362: ParseACSSFontWeight: parse a CSS font weight string
3363: we expect the input string describing the attribute to be
3364: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 3365: ----------------------------------------------------------------------*/
1.263 vatton 3366: static char *ParseACSSFontWeight (Element element, PSchema tsch,
1.327 vatton 3367: PresentationContext context, char *cssRule,
3368: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3369: {
1.327 vatton 3370: PresentationValue weight;
1.366 vatton 3371: char *ptr;
1.1 cvs 3372:
1.327 vatton 3373: weight.typed_data.value = 0;
3374: weight.typed_data.unit = UNIT_REL;
3375: weight.typed_data.real = FALSE;
3376: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3377: ptr = cssRule;
1.351 quint 3378: if (isdigit (*cssRule) && *cssRule != '0' &&
3379: cssRule[1] == '0' && cssRule[2] == '0' &&
3380: (cssRule[3] == EOS || cssRule[3] == SPACE || cssRule[3] == '/' ||
3381: cssRule[3] == ';' || cssRule[3] == '}' || cssRule[3] == EOL ||
3382: cssRule[3] == TAB || cssRule[3] == __CR__))
1.327 vatton 3383: {
1.351 quint 3384: if (!strncasecmp (cssRule, "100", 3))
3385: {
1.379 quint 3386: weight.typed_data.value = -4;
1.351 quint 3387: cssRule = SkipWord (cssRule);
3388: }
3389: else if (!strncasecmp (cssRule, "200", 3))
3390: {
1.379 quint 3391: weight.typed_data.value = -3;
1.351 quint 3392: cssRule = SkipWord (cssRule);
3393: }
3394: else if (!strncasecmp (cssRule, "300", 3))
3395: {
1.379 quint 3396: weight.typed_data.value = -2;
1.351 quint 3397: cssRule = SkipWord (cssRule);
3398: }
3399: else if (!strncasecmp (cssRule, "400", 3))
3400: {
1.379 quint 3401: weight.typed_data.value = -1;
1.351 quint 3402: cssRule = SkipWord (cssRule);
3403: }
3404: else if (!strncasecmp (cssRule, "500", 3))
3405: {
1.379 quint 3406: weight.typed_data.value = 0;
1.351 quint 3407: cssRule = SkipWord (cssRule);
3408: }
3409: else if (!strncasecmp (cssRule, "600", 3))
3410: {
1.379 quint 3411: weight.typed_data.value = +1;
1.351 quint 3412: cssRule = SkipWord (cssRule);
3413: }
3414: else if (!strncasecmp (cssRule, "700", 3))
3415: {
1.379 quint 3416: weight.typed_data.value = +2;
1.351 quint 3417: cssRule = SkipWord (cssRule);
3418: }
3419: else if (!strncasecmp (cssRule, "800", 3))
3420: {
1.379 quint 3421: weight.typed_data.value = +3;
1.351 quint 3422: cssRule = SkipWord (cssRule);
3423: }
3424: else if (!strncasecmp (cssRule, "900", 3))
3425: {
1.379 quint 3426: weight.typed_data.value = +4;
1.351 quint 3427: cssRule = SkipWord (cssRule);
3428: }
1.327 vatton 3429: }
1.351 quint 3430: else if (!strncasecmp (cssRule, "normal", 6))
1.327 vatton 3431: {
3432: weight.typed_data.value = 0;
3433: cssRule = SkipWord (cssRule);
3434: }
1.351 quint 3435: else if (!strncasecmp (cssRule, "bold", 4))
1.327 vatton 3436: {
3437: weight.typed_data.value = +3;
3438: cssRule = SkipWord (cssRule);
3439: }
3440: else if (!strncasecmp (cssRule, "inherit", 7))
3441: {
3442: weight.typed_data.unit = VALUE_INHERIT;
3443: cssRule += 7;
3444: }
1.379 quint 3445: else if (!strncasecmp (cssRule, "bolder", 6))
1.327 vatton 3446: {
1.379 quint 3447: weight.typed_data.value = +2;
3448: cssRule = SkipWord (cssRule);
3449: }
3450:
3451: else if (!strncasecmp (cssRule, "lighter", 7))
3452: {
3453: weight.typed_data.value = -1;
1.327 vatton 3454: cssRule = SkipWord (cssRule);
3455: }
3456: else
3457: return (cssRule);
3458:
3459: /*
3460: * Here we have to reduce since only two font weight values are supported
3461: * by the Thot presentation API.
3462: */
3463: if (weight.typed_data.unit != VALUE_INHERIT)
3464: {
3465: if (weight.typed_data.value > 0)
3466: weight.typed_data.value = WeightBold;
3467: else
3468: weight.typed_data.value = WeightNormal;
3469: }
3470:
3471: /* install the new presentation */
1.366 vatton 3472: if (cssRule != ptr && DoDialog)
3473: DisplayStyleValue ("font-weight", ptr, cssRule);
3474: else if (DoApply)
1.327 vatton 3475: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
3476: return (cssRule);
3477: }
3478:
3479: /*----------------------------------------------------------------------
3480: ParseCSSFontWeight: parse a CSS font weight string
3481: we expect the input string describing the attribute to be
3482: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.263 vatton 3483: ----------------------------------------------------------------------*/
3484: static char *ParseCSSFontWeight (Element element, PSchema tsch,
1.327 vatton 3485: PresentationContext context, char *cssRule,
3486: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3487: {
3488: char *ptr;
3489:
1.366 vatton 3490: cssRule = SkipBlanksAndComments (cssRule);
1.263 vatton 3491: ptr = cssRule;
3492: cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3493: if (ptr == cssRule)
3494: cssRule = SkipValue ("Invalid font-weight value", cssRule);
3495: return (cssRule);
3496: }
3497:
3498: /*----------------------------------------------------------------------
1.327 vatton 3499: ParseACSSFontVariant: parse a CSS font variant string
3500: we expect the input string describing the attribute to be
3501: normal or small-caps
1.1 cvs 3502: ----------------------------------------------------------------------*/
1.263 vatton 3503: static char *ParseACSSFontVariant (Element element, PSchema tsch,
1.327 vatton 3504: PresentationContext context, char *cssRule,
3505: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3506: {
1.327 vatton 3507: PresentationValue style;
1.366 vatton 3508: char *ptr;
1.1 cvs 3509:
1.327 vatton 3510: style.typed_data.value = 0;
3511: style.typed_data.unit = UNIT_REL;
3512: style.typed_data.real = FALSE;
3513: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3514: ptr = cssRule;
1.327 vatton 3515: if (!strncasecmp (cssRule, "small-caps", 10))
3516: {
1.381 quint 3517: style.typed_data.value = VariantSmallCaps;
1.327 vatton 3518: cssRule = SkipWord (cssRule);
3519: }
3520: else if (!strncasecmp (cssRule, "normal", 6))
3521: {
1.381 quint 3522: style.typed_data.value = VariantNormal;
1.327 vatton 3523: cssRule = SkipWord (cssRule);
3524: }
3525: else if (!strncasecmp (cssRule, "inherit", 7))
3526: {
1.381 quint 3527: style.typed_data.unit = VALUE_INHERIT;
1.327 vatton 3528: cssRule = SkipWord (cssRule);
3529: }
1.381 quint 3530: else
3531: /* invalid font-variant */
3532: return (cssRule);
3533:
3534: if (style.typed_data.value != 0 || style.typed_data.unit == VALUE_INHERIT)
3535: {
3536: if (DoDialog)
3537: DisplayStyleValue ("font-variant", ptr, cssRule);
3538: else if (DoApply)
3539: TtaSetStylePresentation (PRVariant, element, tsch, context, style);
3540: }
1.295 vatton 3541: return (cssRule);
1.263 vatton 3542: }
1.1 cvs 3543:
1.263 vatton 3544: /*----------------------------------------------------------------------
1.327 vatton 3545: ParseCSSFontVariant: parse a CSS font variant string
3546: we expect the input string describing the attribute to be
3547: normal or small-caps
1.263 vatton 3548: ----------------------------------------------------------------------*/
3549: static char *ParseCSSFontVariant (Element element, PSchema tsch,
1.327 vatton 3550: PresentationContext context, char *cssRule,
3551: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3552: {
3553: char *ptr;
3554:
3555: ptr = cssRule;
3556: cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3557: if (ptr == cssRule)
3558: cssRule = SkipValue ("Invalid font-variant value", cssRule);
3559: return (cssRule);
1.1 cvs 3560: }
3561:
3562:
3563: /*----------------------------------------------------------------------
1.327 vatton 3564: ParseACSSFontStyle: parse a CSS font style string
3565: we expect the input string describing the attribute to be
3566: normal, italic, oblique or inherit
1.1 cvs 3567: ----------------------------------------------------------------------*/
1.263 vatton 3568: static char *ParseACSSFontStyle (Element element, PSchema tsch,
1.327 vatton 3569: PresentationContext context, char *cssRule,
3570: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3571: {
1.327 vatton 3572: PresentationValue style;
3573: PresentationValue size;
1.366 vatton 3574: PresentationValue previous_size;
3575: char *ptr;
1.1 cvs 3576:
1.327 vatton 3577: style.typed_data.value = 0;
3578: style.typed_data.unit = UNIT_REL;
3579: style.typed_data.real = FALSE;
3580: size.typed_data.value = 0;
3581: size.typed_data.unit = UNIT_REL;
3582: size.typed_data.real = FALSE;
3583: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3584: ptr = cssRule;
1.327 vatton 3585: if (!strncasecmp (cssRule, "italic", 6))
3586: {
3587: style.typed_data.value = StyleItalics;
3588: cssRule = SkipWord (cssRule);
3589: }
3590: else if (!strncasecmp (cssRule, "oblique", 7))
3591: {
3592: style.typed_data.value = StyleOblique;
3593: cssRule = SkipWord (cssRule);
3594: }
3595: else if (!strncasecmp (cssRule, "normal", 6))
3596: {
3597: style.typed_data.value = StyleRoman;
3598: cssRule = SkipWord (cssRule);
3599: }
3600: else if (!strncasecmp (cssRule, "inherit", 7))
3601: {
3602: style.typed_data.unit = VALUE_INHERIT;
3603: cssRule = SkipWord (cssRule);
3604: }
3605: else
3606: /* invalid font style */
3607: return (cssRule);
3608:
3609: /*
3610: * install the new presentation.
3611: */
1.366 vatton 3612: if (style.typed_data.value != 0 || style.typed_data.unit == VALUE_INHERIT)
1.327 vatton 3613: {
1.366 vatton 3614: if (DoDialog)
3615: DisplayStyleValue ("font-style", ptr, cssRule);
3616: else if (DoApply)
3617: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.327 vatton 3618: }
1.366 vatton 3619: if (size.typed_data.value != 0)
1.327 vatton 3620: {
1.366 vatton 3621: if (DoDialog)
3622: DisplayStyleValue ("font-style", ptr, cssRule);
3623: else if (DoApply)
1.327 vatton 3624: {
1.366 vatton 3625: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
3626: {
3627: /* !!!!!!!!!!!!!!!!!!!!!!!! Unit + relative !!!!!!!!!!!!!!!! */
3628: size.typed_data.value += previous_size.typed_data.value;
3629: TtaSetStylePresentation (PRSize, element, tsch, context, size);
3630: }
3631: else
3632: {
3633: size.typed_data.value = 10;
3634: TtaSetStylePresentation (PRSize, element, tsch, context, size);
3635: }
1.327 vatton 3636: }
3637: }
3638: return (cssRule);
3639: }
3640:
3641: /*----------------------------------------------------------------------
3642: ParseCSSFontStyle: parse a CSS font style string
3643: we expect the input string describing the attribute to be
3644: italic, oblique or normal
1.263 vatton 3645: ----------------------------------------------------------------------*/
3646: static char *ParseCSSFontStyle (Element element, PSchema tsch,
1.327 vatton 3647: PresentationContext context, char *cssRule,
3648: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3649: {
3650: char *ptr;
3651:
3652: ptr = cssRule;
3653: cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3654: if (ptr == cssRule)
3655: cssRule = SkipValue ("Invalid font-style value", cssRule);
3656: return (cssRule);
3657: }
3658:
3659: /*----------------------------------------------------------------------
1.59 cvs 3660: ParseCSSFont: parse a CSS font attribute string
3661: we expect the input string describing the attribute to be
3662: !!!!!!
1.1 cvs 3663: ----------------------------------------------------------------------*/
1.79 cvs 3664: static char *ParseCSSFont (Element element, PSchema tsch,
1.327 vatton 3665: PresentationContext context, char *cssRule,
3666: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3667: {
1.270 vatton 3668: char *ptr, *p;
1.366 vatton 3669: char *start_value;
1.93 vatton 3670: int skippedNL;
1.272 vatton 3671: ThotBool variant = FALSE, style = FALSE, weight = FALSE, found;
1.1 cvs 3672:
1.82 cvs 3673: cssRule = SkipBlanksAndComments (cssRule);
3674: if (!strncasecmp (cssRule, "caption", 7))
1.263 vatton 3675: cssRule += 7;
1.82 cvs 3676: else if (!strncasecmp (cssRule, "icon", 4))
1.263 vatton 3677: cssRule += 4;
1.82 cvs 3678: else if (!strncasecmp (cssRule, "menu", 4))
1.263 vatton 3679: cssRule += 4;
1.82 cvs 3680: else if (!strncasecmp (cssRule, "message-box", 11))
1.263 vatton 3681: cssRule += 11;
1.82 cvs 3682: else if (!strncasecmp (cssRule, "small-caption", 13))
1.263 vatton 3683: cssRule += 13;
1.82 cvs 3684: else if (!strncasecmp (cssRule, "status-bar", 10))
1.263 vatton 3685: cssRule += 10;
3686: else if (!strncasecmp (cssRule, "inherit", 7))
1.293 quint 3687: {
3688: ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3689: ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3690: ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3691: ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.366 vatton 3692: cssRule = SkipBlanksAndComments (cssRule);
3693: start_value = cssRule;
1.293 quint 3694: ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3695: cssRule += 7;
1.366 vatton 3696: if (DoDialog)
3697: DisplayStyleValue ("font-family", start_value, cssRule);
1.293 quint 3698: }
1.1 cvs 3699: else
1.43 cvs 3700: {
1.270 vatton 3701: ptr = NULL;
3702: p = cssRule;
1.301 vatton 3703: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && p == cssRule)
1.327 vatton 3704: {
3705: found = FALSE;
3706: /* style, variant, weight can appear in any order */
3707: ptr = cssRule;
3708: skippedNL = NewLineSkipped;
3709: cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3710: if (ptr != cssRule)
3711: {
3712: skippedNL = NewLineSkipped;
3713: found = TRUE;
3714: style = TRUE;
3715: }
3716: else
3717: NewLineSkipped = skippedNL;
3718: ptr = cssRule;
3719: cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3720: if (ptr != cssRule)
3721: {
3722: skippedNL = NewLineSkipped;
3723: found = TRUE;
3724: variant = TRUE;
3725: }
3726: else
3727: NewLineSkipped = skippedNL;
3728: ptr = cssRule;
3729: cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3730: if (ptr != cssRule)
3731: {
3732: skippedNL = NewLineSkipped;
3733: found = TRUE;
3734: weight = TRUE;
3735: }
3736: else
3737: NewLineSkipped = skippedNL;
3738: cssRule = SkipBlanksAndComments (cssRule);
3739: p = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, TRUE);
3740: NewLineSkipped = skippedNL;
3741: if (!found)
3742: /* break the loop when the current value was not parsed */
3743: p = cssRule + 1;
3744: }
1.263 vatton 3745: ptr = cssRule;
1.270 vatton 3746: /* set default variant, style, weight */
3747: if (!variant)
1.327 vatton 3748: ParseACSSFontVariant (element, tsch, context, "normal", css, isHTML);
1.270 vatton 3749: if (!style)
1.327 vatton 3750: ParseACSSFontStyle (element, tsch, context, "normal", css, isHTML);
1.270 vatton 3751: if (!weight)
1.327 vatton 3752: ParseACSSFontWeight (element, tsch, context, "normal", css, isHTML);
1.270 vatton 3753: /* now parse the font size and the font family */
1.301 vatton 3754: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.327 vatton 3755: cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.301 vatton 3756: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.366 vatton 3757: {
3758: cssRule = SkipBlanksAndComments (cssRule);
3759: start_value = cssRule;
3760: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3761: if (DoDialog)
3762: DisplayStyleValue ("font-family", start_value, cssRule);
3763: }
1.263 vatton 3764: if (ptr == cssRule)
1.360 vatton 3765: cssRule = SkipValue ("Invalid font value", cssRule);
1.43 cvs 3766: }
1.263 vatton 3767: cssRule = SkipBlanksAndComments (cssRule);
1.301 vatton 3768: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.360 vatton 3769: cssRule = SkipValue ("Invalid font value", cssRule);
1.43 cvs 3770: return (cssRule);
1.1 cvs 3771: }
3772:
3773: /*----------------------------------------------------------------------
1.356 quint 3774: ParseCSSTextDecoration: parse a CSS text-decoration value.
3775: We expect the input string to be none, inherit or a combination of
3776: underline, overline, line-through, and blink.
1.1 cvs 3777: ----------------------------------------------------------------------*/
1.79 cvs 3778: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
1.327 vatton 3779: PresentationContext context, char *cssRule,
3780: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3781: {
1.327 vatton 3782: PresentationValue decor;
1.366 vatton 3783: char *ptr;
1.356 quint 3784: ThotBool ok;
1.327 vatton 3785:
3786: decor.typed_data.value = 0;
3787: decor.typed_data.unit = UNIT_REL;
3788: decor.typed_data.real = FALSE;
3789: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3790: ptr = cssRule;
1.356 quint 3791: ok = TRUE;
1.327 vatton 3792: if (!strncasecmp (cssRule, "none", 4))
3793: {
3794: decor.typed_data.value = NoUnderline;
3795: cssRule += 4;
3796: }
3797: else if (!strncasecmp (cssRule, "inherit", 7))
3798: {
3799: decor.typed_data.unit = VALUE_INHERIT;
3800: cssRule += 7;
3801: }
3802: else
3803: {
1.356 quint 3804: do
3805: {
3806: if (!strncasecmp (cssRule, "underline", 9))
3807: {
3808: decor.typed_data.value = Underline;
3809: cssRule += 9;
3810: }
3811: else if (!strncasecmp (cssRule, "overline", 8))
3812: {
3813: decor.typed_data.value = Overline;
3814: cssRule += 8;
3815: }
3816: else if (!strncasecmp (cssRule, "line-through", 12))
3817: {
3818: decor.typed_data.value = CrossOut;
3819: cssRule += 12;
3820: }
3821: else if (!strncasecmp (cssRule, "blink", 5))
3822: {
3823: /* the blink text-decoration attribute is not supported */
3824: cssRule += 5;
3825: }
3826: else
3827: ok = FALSE;
3828: if (ok)
3829: {
3830: cssRule = SkipBlanksAndComments (cssRule);
3831: }
3832: }
3833: while (ok && (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS));
3834: }
3835: if (!ok)
3836: {
1.327 vatton 3837: cssRule = SkipValue ("Invalid text-decoration value", cssRule);
3838: return (cssRule);
3839: }
1.1 cvs 3840:
1.327 vatton 3841: /*
3842: * install the new presentation.
3843: */
1.366 vatton 3844: if (decor.typed_data.value || decor.typed_data.unit == VALUE_INHERIT)
3845: {
3846: if (DoDialog)
3847: DisplayStyleValue ("text-decoration", ptr, cssRule);
3848: else if (DoApply)
3849: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
3850: }
1.327 vatton 3851: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-decoration value");
3852: return (cssRule);
1.1 cvs 3853: }
3854:
3855: /*----------------------------------------------------------------------
1.327 vatton 3856: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 3857: ----------------------------------------------------------------------*/
1.79 cvs 3858: static char *ParseCSSHeight (Element element, PSchema tsch,
1.327 vatton 3859: PresentationContext context, char *cssRule,
3860: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3861: {
1.117 vatton 3862: PresentationValue val;
1.168 vatton 3863: char *ptr;
1.93 vatton 3864:
1.370 vatton 3865: val.typed_data.real = FALSE;
1.117 vatton 3866: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 3867: ptr = cssRule;
1.117 vatton 3868: /* first parse the attribute string */
1.164 quint 3869: if (!strncasecmp (cssRule, "auto", 4))
3870: {
1.184 vatton 3871: val.typed_data.unit = VALUE_AUTO;
1.164 quint 3872: val.typed_data.value = 0;
1.288 vatton 3873: cssRule += 4;
3874: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
1.164 quint 3875: }
1.117 vatton 3876: else
1.168 vatton 3877: cssRule = ParseCSSUnit (cssRule, &val);
1.295 vatton 3878:
1.387 quint 3879: if (val.typed_data.unit == UNIT_INVALID ||
3880: (val.typed_data.value != 0 &&
1.184 vatton 3881: val.typed_data.unit == UNIT_BOX))
1.387 quint 3882: CSSParseError ("height value", ptr, cssRule);
3883: else if (DoDialog)
1.366 vatton 3884: DisplayStyleValue ("height", ptr, cssRule);
3885: else if (DoApply)
1.295 vatton 3886: /* install the new presentation */
3887: TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.117 vatton 3888: return (cssRule);
1.1 cvs 3889: }
3890:
3891: /*----------------------------------------------------------------------
1.382 vatton 3892: ParseCSSMaxHeight: parse a CSS height attribute
3893: ----------------------------------------------------------------------*/
3894: static char *ParseCSSMaxHeight (Element element, PSchema tsch,
3895: PresentationContext context, char *cssRule,
3896: CSSInfoPtr css, ThotBool isHTML)
3897: {
3898: PresentationValue val;
3899: char *ptr;
3900:
3901: val.typed_data.real = FALSE;
3902: cssRule = SkipBlanksAndComments (cssRule);
3903: ptr = cssRule;
3904: /* first parse the attribute string */
3905: if (!strncasecmp (cssRule, "auto", 4))
3906: {
3907: val.typed_data.unit = VALUE_AUTO;
3908: val.typed_data.value = 0;
3909: cssRule += 4;
3910: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
3911: }
3912: else
3913: cssRule = ParseCSSUnit (cssRule, &val);
3914:
1.387 quint 3915: if (val.typed_data.unit == UNIT_INVALID ||
3916: (val.typed_data.value != 0 &&
1.382 vatton 3917: val.typed_data.unit == UNIT_BOX))
1.387 quint 3918: CSSParseError ("height value", ptr, cssRule);
3919: else if (DoDialog)
1.382 vatton 3920: DisplayStyleValue ("max-height", ptr, cssRule);
1.390 vatton 3921: /*else if (DoApply)
3922: install the new presentation
3923: TtaSetStylePresentation (PRHeight, element, tsch, context, val)*/;
1.382 vatton 3924: return (cssRule);
3925: }
3926:
3927: /*----------------------------------------------------------------------
3928: ParseCSSMinHeight: parse a CSS height attribute
3929: ----------------------------------------------------------------------*/
3930: static char *ParseCSSMinHeight (Element element, PSchema tsch,
3931: PresentationContext context, char *cssRule,
3932: CSSInfoPtr css, ThotBool isHTML)
3933: {
3934: PresentationValue val;
3935: char *ptr;
3936:
3937: val.typed_data.real = FALSE;
3938: cssRule = SkipBlanksAndComments (cssRule);
3939: ptr = cssRule;
3940: /* first parse the attribute string */
3941: if (!strncasecmp (cssRule, "auto", 4))
3942: {
3943: val.typed_data.unit = VALUE_AUTO;
3944: val.typed_data.value = 0;
3945: cssRule += 4;
3946: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
3947: }
3948: else
3949: cssRule = ParseCSSUnit (cssRule, &val);
3950:
1.387 quint 3951: if (val.typed_data.unit == UNIT_INVALID ||
3952: (val.typed_data.value != 0 &&
1.382 vatton 3953: val.typed_data.unit == UNIT_BOX))
1.387 quint 3954: CSSParseError ("height value", ptr, cssRule);
3955: else if (DoDialog)
1.382 vatton 3956: DisplayStyleValue ("min-height", ptr, cssRule);
1.390 vatton 3957: /*else if (DoApply)*/
1.382 vatton 3958: /* install the new presentation */
1.384 vatton 3959: /*TtaSetStylePresentation (PRHeight, element, tsch, context, val)*/;
1.382 vatton 3960: return (cssRule);
3961: }
3962:
3963: /*----------------------------------------------------------------------
1.327 vatton 3964: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 3965: ----------------------------------------------------------------------*/
1.79 cvs 3966: static char *ParseCSSWidth (Element element, PSchema tsch,
1.327 vatton 3967: PresentationContext context,
3968: char *cssRule, CSSInfoPtr css,
3969: ThotBool isHTML)
1.1 cvs 3970: {
1.117 vatton 3971: PresentationValue val;
1.168 vatton 3972: char *ptr;
1.93 vatton 3973:
1.370 vatton 3974: val.typed_data.real = FALSE;
1.117 vatton 3975: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 3976: ptr = cssRule;
1.117 vatton 3977: /* first parse the attribute string */
1.164 quint 3978: if (!strncasecmp (cssRule, "auto", 4))
3979: {
1.184 vatton 3980: val.typed_data.unit = VALUE_AUTO;
1.164 quint 3981: val.typed_data.value = 0;
1.288 vatton 3982: cssRule += 4;
3983: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
1.164 quint 3984: }
1.117 vatton 3985: else
1.327 vatton 3986: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 3987: if (val.typed_data.unit == UNIT_INVALID ||
3988: (val.typed_data.value != 0 &&
1.184 vatton 3989: val.typed_data.unit == UNIT_BOX))
1.387 quint 3990: CSSParseError ("Invalid width value", ptr, cssRule);
3991: else if (DoDialog)
1.366 vatton 3992: DisplayStyleValue ("width", ptr, cssRule);
3993: else if (DoApply)
1.295 vatton 3994: /* install the new presentation */
3995: TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.117 vatton 3996: return (cssRule);
1.1 cvs 3997: }
3998:
3999: /*----------------------------------------------------------------------
1.382 vatton 4000: ParseCSSMaxWidth: parse a CSS width attribute
4001: ----------------------------------------------------------------------*/
4002: static char *ParseCSSMaxWidth (Element element, PSchema tsch,
4003: PresentationContext context,
4004: char *cssRule, CSSInfoPtr css,
4005: ThotBool isHTML)
4006: {
4007: PresentationValue val;
4008: char *ptr;
4009:
4010: val.typed_data.real = FALSE;
4011: cssRule = SkipBlanksAndComments (cssRule);
4012: ptr = cssRule;
4013: /* first parse the attribute string */
4014: if (!strncasecmp (cssRule, "auto", 4))
4015: {
4016: val.typed_data.unit = VALUE_AUTO;
4017: val.typed_data.value = 0;
4018: cssRule += 4;
4019: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
4020: }
4021: else
4022: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4023: if (val.typed_data.unit == UNIT_INVALID ||
4024: (val.typed_data.value != 0 &&
1.382 vatton 4025: val.typed_data.unit == UNIT_BOX))
4026: CSSParseError ("Invalid width value", ptr, cssRule);
1.387 quint 4027: else if (DoDialog)
1.382 vatton 4028: DisplayStyleValue ("max-width", ptr, cssRule);
4029: else if (DoApply)
4030: /* install the new presentation */
1.384 vatton 4031: /*TtaSetStylePresentation (PRWidth, element, tsch, context, val)*/;
1.382 vatton 4032: return (cssRule);
4033: }
4034:
4035: /*----------------------------------------------------------------------
4036: ParseCSSMinWidth: parse a CSS width attribute
4037: ----------------------------------------------------------------------*/
4038: static char *ParseCSSMinWidth (Element element, PSchema tsch,
4039: PresentationContext context,
4040: char *cssRule, CSSInfoPtr css,
4041: ThotBool isHTML)
4042: {
4043: PresentationValue val;
4044: char *ptr;
4045:
4046: val.typed_data.real = FALSE;
4047: cssRule = SkipBlanksAndComments (cssRule);
4048: ptr = cssRule;
4049: /* first parse the attribute string */
4050: if (!strncasecmp (cssRule, "auto", 4))
4051: {
4052: val.typed_data.unit = VALUE_AUTO;
4053: val.typed_data.value = 0;
4054: cssRule += 4;
4055: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
4056: }
4057: else
4058: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4059: if (val.typed_data.unit == UNIT_INVALID ||
4060: (val.typed_data.value != 0 &&
1.382 vatton 4061: val.typed_data.unit == UNIT_BOX))
1.387 quint 4062: CSSParseError ("Invalid width value", ptr, cssRule);
4063: else if (DoDialog)
1.382 vatton 4064: DisplayStyleValue ("min-width", ptr, cssRule);
4065: else if (DoApply)
4066: /* install the new presentation */
1.384 vatton 4067: /*TtaSetStylePresentation (PRWidth, element, tsch, context, val)*/;
1.382 vatton 4068: return (cssRule);
4069: }
4070:
4071: /*----------------------------------------------------------------------
1.391 ! vatton 4072: GetEmMarginValue returns the em value
! 4073: ----------------------------------------------------------------------*/
! 4074: int GetEmValue (char *data, Element el, Document doc)
! 4075: {
! 4076: PresentationValue val;
! 4077: char *ptr;
! 4078: int value;
! 4079:
! 4080: val.typed_data.real = FALSE;
! 4081: ptr = SkipBlanksAndComments (data);
! 4082: if (!strncasecmp (data, "auto", 4))
! 4083: value = TtaGetPixelValue (0, VALUE_AUTO, el, doc);
! 4084: else
! 4085: {
! 4086: ptr = ParseCSSUnit (data, &val);
! 4087: value = TtaGetPixelValue (val.typed_data.value, val.typed_data.unit,
! 4088: el, doc);
! 4089: }
! 4090: return TtaGetLogicalValue (value, UNIT_EM, el, doc);
! 4091: }
! 4092:
! 4093: /*----------------------------------------------------------------------
1.327 vatton 4094: ParseACSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 4095: ----------------------------------------------------------------------*/
1.296 vatton 4096: static char *ParseACSSMarginTop (Element element, PSchema tsch,
1.327 vatton 4097: PresentationContext context,
4098: char *cssRule, CSSInfoPtr css,
4099: ThotBool isHTML)
1.1 cvs 4100: {
4101: PresentationValue margin;
1.168 vatton 4102: char *ptr;
1.1 cvs 4103:
1.370 vatton 4104: margin.typed_data.real = FALSE;
1.82 cvs 4105: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4106: ptr = cssRule;
1.1 cvs 4107: /* first parse the attribute string */
1.164 quint 4108: if (!strncasecmp (cssRule, "auto", 4))
4109: {
1.184 vatton 4110: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4111: margin.typed_data.value = 0;
1.288 vatton 4112: cssRule += 4;
1.164 quint 4113: }
4114: else
1.168 vatton 4115: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4116:
1.387 quint 4117: if (margin.typed_data.unit == UNIT_INVALID ||
4118: (margin.typed_data.value != 0 &&
1.184 vatton 4119: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4120: CSSParseError ("Invalid margin-top value", ptr, cssRule);
1.366 vatton 4121: else if (DoDialog)
4122: {
4123: if (All_sides)
4124: DisplayStyleValue ("margin", ptr, cssRule);
4125: else
4126: DisplayStyleValue ("margin-top", ptr, cssRule);
4127: }
1.168 vatton 4128: else if (DoApply)
1.295 vatton 4129: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
1.1 cvs 4130: return (cssRule);
4131: }
4132:
4133: /*----------------------------------------------------------------------
1.327 vatton 4134: ParseCSSMarginTop: parse a CSS margin-top attribute
1.296 vatton 4135: ----------------------------------------------------------------------*/
4136: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.327 vatton 4137: PresentationContext context,
4138: char *cssRule, CSSInfoPtr css,
4139: ThotBool isHTML)
1.296 vatton 4140: {
4141: char *ptr = cssRule;
4142:
4143: cssRule = ParseACSSMarginTop (element, tsch, context, ptr, css, isHTML);
4144: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-top value");
4145: return (cssRule);
4146: }
4147:
4148: /*----------------------------------------------------------------------
4149: ParseACSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 4150: ----------------------------------------------------------------------*/
1.296 vatton 4151: static char *ParseACSSMarginBottom (Element element, PSchema tsch,
1.327 vatton 4152: PresentationContext context,
4153: char *cssRule, CSSInfoPtr css,
4154: ThotBool isHTML)
1.1 cvs 4155: {
4156: PresentationValue margin;
1.168 vatton 4157: char *ptr;
1.1 cvs 4158:
1.370 vatton 4159: margin.typed_data.real = FALSE;
1.82 cvs 4160: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4161: ptr = cssRule;
1.1 cvs 4162: /* first parse the attribute string */
1.164 quint 4163: if (!strncasecmp (cssRule, "auto", 4))
4164: {
1.184 vatton 4165: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4166: margin.typed_data.value = 0;
1.288 vatton 4167: cssRule += 4;
1.164 quint 4168: }
4169: else
1.168 vatton 4170: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4171:
1.387 quint 4172: if (margin.typed_data.unit == UNIT_INVALID ||
4173: (margin.typed_data.value != 0 &&
1.184 vatton 4174: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4175: CSSParseError ("Invalid margin-bottom value", ptr, cssRule);
1.366 vatton 4176: else if (DoDialog)
4177: DisplayStyleValue ("margin-bottom", ptr, cssRule);
1.168 vatton 4178: else if (DoApply)
1.295 vatton 4179: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
1.1 cvs 4180: return (cssRule);
4181: }
4182:
4183: /*----------------------------------------------------------------------
1.296 vatton 4184: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
4185: ----------------------------------------------------------------------*/
4186: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.327 vatton 4187: PresentationContext context,
4188: char *cssRule, CSSInfoPtr css,
4189: ThotBool isHTML)
1.296 vatton 4190: {
4191: char *ptr = cssRule;
4192:
4193: cssRule = ParseACSSMarginBottom (element, tsch, context, ptr, css, isHTML);
4194: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-bottom value");
4195: return (cssRule);
4196: }
4197:
4198: /*----------------------------------------------------------------------
4199: ParseACSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 4200: ----------------------------------------------------------------------*/
1.296 vatton 4201: static char *ParseACSSMarginLeft (Element element, PSchema tsch,
1.327 vatton 4202: PresentationContext context,
4203: char *cssRule, CSSInfoPtr css,
4204: ThotBool isHTML)
1.1 cvs 4205: {
4206: PresentationValue margin;
1.168 vatton 4207: char *ptr;
1.1 cvs 4208:
1.370 vatton 4209: margin.typed_data.real = FALSE;
1.82 cvs 4210: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4211: ptr = cssRule;
1.1 cvs 4212: /* first parse the attribute string */
1.164 quint 4213: if (!strncasecmp (cssRule, "auto", 4))
4214: {
1.184 vatton 4215: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4216: margin.typed_data.value = 0;
1.288 vatton 4217: cssRule += 4;
1.164 quint 4218: }
4219: else
1.168 vatton 4220: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4221:
1.387 quint 4222: if (margin.typed_data.unit == UNIT_INVALID ||
4223: (margin.typed_data.value != 0 &&
1.184 vatton 4224: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4225: CSSParseError ("Invalid margin-left value", ptr, cssRule);
1.366 vatton 4226: else if (DoDialog)
4227: DisplayStyleValue ("margin-left", ptr, cssRule);
1.295 vatton 4228: else if (DoApply && margin.typed_data.unit != UNIT_INVALID && DoApply)
1.327 vatton 4229: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
1.1 cvs 4230: return (cssRule);
4231: }
4232:
4233: /*----------------------------------------------------------------------
1.296 vatton 4234: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
4235: ----------------------------------------------------------------------*/
4236: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.327 vatton 4237: PresentationContext context,
4238: char *cssRule, CSSInfoPtr css,
4239: ThotBool isHTML)
1.296 vatton 4240: {
4241: char *ptr = cssRule;
4242:
4243: cssRule = ParseACSSMarginLeft (element, tsch, context, ptr, css, isHTML);
4244: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-left value");
4245: return (cssRule);
4246: }
4247:
4248:
4249: /*----------------------------------------------------------------------
4250: ParseACSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 4251: ----------------------------------------------------------------------*/
1.296 vatton 4252: static char *ParseACSSMarginRight (Element element, PSchema tsch,
1.327 vatton 4253: PresentationContext context,
4254: char *cssRule, CSSInfoPtr css,
4255: ThotBool isHTML)
1.1 cvs 4256: {
4257: PresentationValue margin;
1.168 vatton 4258: char *ptr;
1.1 cvs 4259:
1.370 vatton 4260: margin.typed_data.real = FALSE;
1.82 cvs 4261: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4262: ptr = cssRule;
1.1 cvs 4263: /* first parse the attribute string */
1.164 quint 4264: if (!strncasecmp (cssRule, "auto", 4))
4265: {
1.184 vatton 4266: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4267: margin.typed_data.value = 0;
1.288 vatton 4268: cssRule += 4;
1.164 quint 4269: }
4270: else
1.168 vatton 4271: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4272:
1.387 quint 4273: if (margin.typed_data.unit == UNIT_INVALID ||
4274: (margin.typed_data.value != 0 &&
1.184 vatton 4275: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4276: CSSParseError ("Invalid margin-right value", ptr, cssRule);
1.366 vatton 4277: else if (DoDialog)
4278: DisplayStyleValue ("margin-right", ptr, cssRule);
1.168 vatton 4279: else if (DoApply)
1.295 vatton 4280: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
1.1 cvs 4281: return (cssRule);
4282: }
4283:
4284: /*----------------------------------------------------------------------
1.296 vatton 4285: ParseCSSMarginRight: parse a CSS margin-right attribute string
4286: ----------------------------------------------------------------------*/
4287: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.327 vatton 4288: PresentationContext context,
4289: char *cssRule, CSSInfoPtr css,
4290: ThotBool isHTML)
1.296 vatton 4291: {
4292: char *ptr = cssRule;
4293:
1.297 vatton 4294: cssRule = ParseACSSMarginRight (element, tsch, context, ptr, css, isHTML);
1.296 vatton 4295: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-right value");
4296: return (cssRule);
4297: }
4298:
4299: /*----------------------------------------------------------------------
1.59 cvs 4300: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 4301: ----------------------------------------------------------------------*/
1.79 cvs 4302: static char *ParseCSSMargin (Element element, PSchema tsch,
1.327 vatton 4303: PresentationContext context,
4304: char *cssRule, CSSInfoPtr css,
4305: ThotBool isHTML)
1.1 cvs 4306: {
1.79 cvs 4307: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 4308: int skippedNL, n;
1.1 cvs 4309:
1.82 cvs 4310: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 4311: if (DoDialog)
4312: n = NumberOfValues (ptrT);
4313: if (DoDialog && n < 2)
1.1 cvs 4314: {
1.366 vatton 4315: // check if the margin dialog must be updated
4316: All_sides = TRUE;
4317: ptrR = ParseACSSMarginTop (element, tsch, context, ptrT, css, isHTML);
4318: All_sides = FALSE;
1.1 cvs 4319: }
4320: else
4321: {
1.366 vatton 4322: /* First parse Margin-Top */
4323: ptrR = ParseACSSMarginTop (element, tsch, context, ptrT, css, isHTML);
4324: ptrR = SkipBlanksAndComments (ptrR);
4325: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 4326: {
4327: skippedNL = NewLineSkipped;
1.366 vatton 4328: cssRule = ptrR;
4329: /* apply the Margin-Top to all */
4330: ptrR = ParseACSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4331: NewLineSkipped = skippedNL;
1.366 vatton 4332: ptrR = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
4333: NewLineSkipped = skippedNL;
4334: ptrR = ParseACSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4335: }
1.1 cvs 4336: else
1.327 vatton 4337: {
1.366 vatton 4338: /* parse Margin-Right */
4339: ptrB = ParseACSSMarginRight (element, tsch, context, ptrR, css, isHTML);
4340: ptrB = SkipBlanksAndComments (ptrB);
4341: if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 4342: {
1.366 vatton 4343: skippedNL = NewLineSkipped;
4344: cssRule = ptrB;
4345: /* apply the Margin-Top to Margin-Bottom */
4346: ptrB = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
4347: NewLineSkipped = skippedNL;
1.327 vatton 4348: /* apply the Margin-Right to Margin-Left */
1.366 vatton 4349: ptrB = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 4350: }
4351: else
1.366 vatton 4352: {
4353: /* parse Margin-Bottom */
4354: ptrL = ParseACSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
4355: ptrL = SkipBlanksAndComments (ptrL);
4356: if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
4357: {
4358: cssRule = ptrL;
4359: /* apply the Margin-Right to Margin-Left */
4360: ptrL = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
4361: }
4362: else
4363: /* parse Margin-Left */
4364: cssRule = ParseACSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
4365: cssRule = SkipBlanksAndComments (cssRule);
4366: }
1.327 vatton 4367: }
1.1 cvs 4368: }
4369: return (cssRule);
4370: }
4371:
4372: /*----------------------------------------------------------------------
1.327 vatton 4373: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 4374: ----------------------------------------------------------------------*/
1.79 cvs 4375: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.327 vatton 4376: PresentationContext context,
4377: char *cssRule, CSSInfoPtr css,
4378: ThotBool isHTML)
1.1 cvs 4379: {
1.43 cvs 4380: PresentationValue padding;
1.168 vatton 4381: char *ptr;
1.370 vatton 4382:
4383: padding.typed_data.real = FALSE;
1.82 cvs 4384: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4385: ptr = cssRule;
1.43 cvs 4386: /* first parse the attribute string */
4387: cssRule = ParseCSSUnit (cssRule, &padding);
1.295 vatton 4388:
1.387 quint 4389: if (padding.typed_data.unit == UNIT_INVALID ||
4390: (padding.typed_data.value != 0 &&
1.184 vatton 4391: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4392: CSSParseError ("Invalid padding-top value", ptr, cssRule);
1.366 vatton 4393: else if (DoDialog)
4394: {
4395: if (All_sides)
4396: DisplayStyleValue ("padding", ptr, cssRule);
4397: else
4398: DisplayStyleValue ("padding-top", ptr, cssRule);
4399: }
1.168 vatton 4400: else if (DoApply)
1.295 vatton 4401: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
1.1 cvs 4402: return (cssRule);
4403: }
4404:
4405: /*----------------------------------------------------------------------
1.59 cvs 4406: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 4407: ----------------------------------------------------------------------*/
1.79 cvs 4408: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.327 vatton 4409: PresentationContext context,
4410: char *cssRule, CSSInfoPtr css,
4411: ThotBool isHTML)
1.1 cvs 4412: {
1.43 cvs 4413: PresentationValue padding;
1.168 vatton 4414: char *ptr;
1.43 cvs 4415:
1.370 vatton 4416: padding.typed_data.real = FALSE;
1.82 cvs 4417: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4418: ptr = cssRule;
1.43 cvs 4419: /* first parse the attribute string */
4420: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4421: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4422: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4423:
1.387 quint 4424: if (padding.typed_data.unit == UNIT_INVALID ||
4425: (padding.typed_data.value != 0 &&
1.184 vatton 4426: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4427: CSSParseError ("Invalid padding-bottom value", ptr, cssRule);
1.366 vatton 4428: else if (DoDialog)
4429: DisplayStyleValue ("padding-bottom", ptr, cssRule);
1.168 vatton 4430: else if (DoApply)
1.295 vatton 4431: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
1.1 cvs 4432: return (cssRule);
4433: }
4434:
4435: /*----------------------------------------------------------------------
1.59 cvs 4436: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 4437: ----------------------------------------------------------------------*/
1.79 cvs 4438: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.327 vatton 4439: PresentationContext context,
4440: char *cssRule, CSSInfoPtr css,
4441: ThotBool isHTML)
1.1 cvs 4442: {
1.43 cvs 4443: PresentationValue padding;
1.168 vatton 4444: char *ptr;
1.43 cvs 4445:
1.370 vatton 4446: padding.typed_data.real = FALSE;
1.82 cvs 4447: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4448: ptr = cssRule;
1.43 cvs 4449: /* first parse the attribute string */
4450: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4451: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4452: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4453:
1.387 quint 4454: if (padding.typed_data.unit == UNIT_INVALID ||
4455: (padding.typed_data.value != 0 &&
1.184 vatton 4456: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 4457: {
1.169 vatton 4458: CSSParseError ("Invalid padding-left value", ptr, cssRule);
1.168 vatton 4459: padding.typed_data.value = 0;
4460: }
1.366 vatton 4461: else if (DoDialog)
4462: DisplayStyleValue ("padding-left", ptr, cssRule);
1.168 vatton 4463: else if (DoApply)
1.295 vatton 4464: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.1 cvs 4465: return (cssRule);
4466: }
4467:
4468: /*----------------------------------------------------------------------
1.59 cvs 4469: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 4470: ----------------------------------------------------------------------*/
1.79 cvs 4471: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.327 vatton 4472: PresentationContext context,
4473: char *cssRule, CSSInfoPtr css,
4474: ThotBool isHTML)
1.1 cvs 4475: {
1.43 cvs 4476: PresentationValue padding;
1.168 vatton 4477: char *ptr;
1.43 cvs 4478:
1.370 vatton 4479: padding.typed_data.real = FALSE;
1.82 cvs 4480: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4481: ptr = cssRule;
1.43 cvs 4482: /* first parse the attribute string */
4483: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4484: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4485: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4486:
1.387 quint 4487: if (padding.typed_data.unit == UNIT_INVALID ||
4488: (padding.typed_data.value != 0 &&
1.184 vatton 4489: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4490: CSSParseError ("Invalid padding-right value", ptr, cssRule);
1.366 vatton 4491: else if (DoDialog)
4492: DisplayStyleValue ("padding-right", ptr, cssRule);
1.168 vatton 4493: else if (DoApply)
1.295 vatton 4494: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.1 cvs 4495: return (cssRule);
4496: }
4497:
4498: /*----------------------------------------------------------------------
1.327 vatton 4499: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 4500: ----------------------------------------------------------------------*/
1.79 cvs 4501: static char *ParseCSSPadding (Element element, PSchema tsch,
1.327 vatton 4502: PresentationContext context,
4503: char *cssRule, CSSInfoPtr css,
4504: ThotBool isHTML)
1.1 cvs 4505: {
1.79 cvs 4506: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 4507: int skippedNL, n;
1.43 cvs 4508:
1.82 cvs 4509: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 4510: if (DoDialog)
4511: n = NumberOfValues (ptrT);
4512: if (DoDialog && n < 2)
1.43 cvs 4513: {
1.366 vatton 4514: // check if the padding dialog must be updated
4515: All_sides = TRUE;
4516: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
4517: All_sides = FALSE;
1.43 cvs 4518: }
4519: else
4520: {
1.366 vatton 4521: /* First parse Padding-Top */
4522: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
4523: ptrR = SkipBlanksAndComments (ptrR);
4524: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 4525: {
4526: skippedNL = NewLineSkipped;
1.366 vatton 4527: cssRule = ptrR;
4528: /* apply the Padding-Top to all */
4529: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4530: NewLineSkipped = skippedNL;
1.366 vatton 4531: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
4532: NewLineSkipped = skippedNL;
4533: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4534: }
1.43 cvs 4535: else
1.327 vatton 4536: {
1.366 vatton 4537: /* parse Padding-Right */
4538: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
4539: ptrB = SkipBlanksAndComments (ptrB);
4540: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 4541: {
1.366 vatton 4542: skippedNL = NewLineSkipped;
4543: cssRule = ptrB;
4544: /* apply the Padding-Top to Padding-Bottom */
4545: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
4546: NewLineSkipped = skippedNL;
1.327 vatton 4547: /* apply the Padding-Right to Padding-Left */
1.366 vatton 4548: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 4549: }
4550: else
1.366 vatton 4551: {
4552: /* parse Padding-Bottom */
4553: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
4554: ptrL = SkipBlanksAndComments (ptrL);
4555: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
4556: {
4557: cssRule = ptrL;
4558: /* apply the Padding-Right to Padding-Left */
4559: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
4560: }
4561: else
4562: /* parse Padding-Left */
4563: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
4564: cssRule = SkipBlanksAndComments (cssRule);
4565: }
1.327 vatton 4566: }
1.43 cvs 4567: }
1.1 cvs 4568: return (cssRule);
4569: }
4570:
4571: /*----------------------------------------------------------------------
1.327 vatton 4572: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 4573: ----------------------------------------------------------------------*/
1.79 cvs 4574: static char *ParseCSSForeground (Element element, PSchema tsch,
1.327 vatton 4575: PresentationContext context,
4576: char *cssRule,
4577: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 4578: {
1.117 vatton 4579: PresentationValue best;
1.262 vatton 4580: char *p;
1.1 cvs 4581:
1.370 vatton 4582: best.typed_data.real = FALSE;
1.366 vatton 4583: cssRule = SkipBlanksAndComments (cssRule);
1.262 vatton 4584: p = cssRule;
1.117 vatton 4585: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4586: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4587: {
4588: if (*cssRule != EOS && *cssRule !=';')
4589: {
4590: cssRule = SkipProperty (cssRule, FALSE);
1.366 vatton 4591: CSSParseError ("Invalid color value", p, cssRule);
1.327 vatton 4592: }
1.366 vatton 4593: else if (DoDialog)
4594: DisplayStyleValue ("color", p, cssRule);
4595: else if (DoApply)
1.327 vatton 4596: /* install the new presentation */
4597: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
4598: }
4599: return (cssRule);
1.1 cvs 4600: }
4601:
4602: /*----------------------------------------------------------------------
1.59 cvs 4603: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 4604: ----------------------------------------------------------------------*/
1.79 cvs 4605: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.327 vatton 4606: PresentationContext context,
4607: char *cssRule,
4608: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 4609: {
4610: PresentationValue best;
1.366 vatton 4611: char *ptr;
1.1 cvs 4612:
1.370 vatton 4613: best.typed_data.real = FALSE;
1.366 vatton 4614: cssRule = SkipBlanksAndComments (cssRule);
4615: ptr = cssRule;
1.184 vatton 4616: best.typed_data.unit = UNIT_INVALID;
1.1 cvs 4617: best.typed_data.real = FALSE;
1.198 vatton 4618: if (!strncasecmp (cssRule, "transparent", 11))
1.1 cvs 4619: {
1.184 vatton 4620: best.typed_data.value = PATTERN_NONE;
4621: best.typed_data.unit = UNIT_REL;
1.295 vatton 4622: cssRule = SkipWord (cssRule);
1.116 vatton 4623: if (DoApply)
1.327 vatton 4624: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4625: }
1.1 cvs 4626: else
4627: {
4628: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4629: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4630: {
1.366 vatton 4631: if (DoDialog)
4632: DisplayStyleValue ("background-color", ptr, cssRule);
4633: else if (DoApply)
4634: {
4635: /* install the new presentation. */
4636: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
4637: /* thot specificity: need to set fill pattern for background color */
4638: best.typed_data.value = PATTERN_BACKGROUND;
4639: best.typed_data.unit = UNIT_REL;
4640: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4641: best.typed_data.value = 1;
4642: best.typed_data.unit = UNIT_REL;
4643: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
4644: }
1.327 vatton 4645: }
1.1 cvs 4646: }
4647: return (cssRule);
4648: }
4649:
1.63 cvs 4650: /*----------------------------------------------------------------------
1.65 cvs 4651: ParseSVGStroke: parse a SVG stroke property
4652: ----------------------------------------------------------------------*/
1.79 cvs 4653: static char *ParseSVGStroke (Element element, PSchema tsch,
1.327 vatton 4654: PresentationContext context, char *cssRule,
4655: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 4656: {
4657: PresentationValue best;
1.245 quint 4658: char *url;
1.65 cvs 4659:
1.184 vatton 4660: best.typed_data.unit = UNIT_INVALID;
1.65 cvs 4661: best.typed_data.real = FALSE;
1.82 cvs 4662: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 4663: {
4664: best.typed_data.value = -2; /* -2 means transparent */
1.184 vatton 4665: best.typed_data.unit = UNIT_REL;
1.65 cvs 4666: cssRule = SkipWord (cssRule);
4667: }
1.245 quint 4668: else if (!strncasecmp (cssRule, "currentColor", 12))
4669: {
1.293 quint 4670: best.typed_data.unit = VALUE_INHERIT;
4671: cssRule = SkipWord (cssRule);
1.245 quint 4672: }
4673: else if (!strncasecmp (cssRule, "url", 3))
4674: {
4675: cssRule += 3;
4676: cssRule = ParseCSSUrl (cssRule, &url);
4677: /* **** do something with the url ***** */;
4678: TtaFreeMemory (url);
4679: /* **** caution: another color value may follow the uri (in case
1.327 vatton 4680: the uri could ne be dereferenced) *** */
1.245 quint 4681: }
1.65 cvs 4682: else
1.293 quint 4683: cssRule = ParseCSSColor (cssRule, &best);
4684:
4685: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.295 vatton 4686: /* install the new presentation */
4687: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.65 cvs 4688: return (cssRule);
4689: }
4690:
4691: /*----------------------------------------------------------------------
1.63 cvs 4692: ParseSVGFill: parse a SVG fill property
4693: ----------------------------------------------------------------------*/
1.79 cvs 4694: static char *ParseSVGFill (Element element, PSchema tsch,
1.327 vatton 4695: PresentationContext context, char *cssRule,
4696: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 4697: {
4698: PresentationValue best;
1.245 quint 4699: char *url;
1.63 cvs 4700:
1.184 vatton 4701: best.typed_data.unit = UNIT_INVALID;
1.63 cvs 4702: best.typed_data.real = FALSE;
1.82 cvs 4703: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 4704: {
1.184 vatton 4705: best.typed_data.value = PATTERN_NONE;
4706: best.typed_data.unit = UNIT_REL;
1.116 vatton 4707: if (DoApply)
1.327 vatton 4708: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 4709: cssRule = SkipWord (cssRule);
1.294 vatton 4710: return (cssRule);
1.63 cvs 4711: }
1.245 quint 4712: else if (!strncasecmp (cssRule, "currentColor", 12))
4713: {
1.293 quint 4714: best.typed_data.unit = VALUE_INHERIT;
4715: cssRule = SkipWord (cssRule);
1.245 quint 4716: }
4717: else if (!strncasecmp (cssRule, "url", 3))
4718: {
4719: cssRule += 3;
4720: cssRule = ParseCSSUrl (cssRule, &url);
4721: /* **** do something with the url ***** */;
4722: TtaFreeMemory (url);
4723: /* **** caution: another color value may follow the uri (in case
1.327 vatton 4724: the uri could ne be dereferenced) *** */
1.245 quint 4725: }
1.63 cvs 4726: else
1.327 vatton 4727: cssRule = ParseCSSColor (cssRule, &best);
1.293 quint 4728:
4729: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.63 cvs 4730: {
1.293 quint 4731: /* install the new presentation. */
4732: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
4733: /* thot specificity: need to set fill pattern for background color */
4734: best.typed_data.value = PATTERN_BACKGROUND;
4735: best.typed_data.unit = UNIT_REL;
4736: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.63 cvs 4737: }
4738: return (cssRule);
4739: }
1.161 quint 4740:
1.155 cheyroul 4741: /*----------------------------------------------------------------------
1.346 quint 4742: ParseSVGOpacity: parse a SVG opacity property
1.155 cheyroul 4743: ----------------------------------------------------------------------*/
4744: static char *ParseSVGOpacity (Element element, PSchema tsch,
1.327 vatton 4745: PresentationContext context, char *cssRule,
4746: CSSInfoPtr css, ThotBool isHTML)
1.155 cheyroul 4747: {
4748: PresentationValue best;
1.63 cvs 4749:
1.184 vatton 4750: best.typed_data.unit = UNIT_INVALID;
1.155 cheyroul 4751: best.typed_data.real = FALSE;
4752: cssRule = ParseClampedUnit (cssRule, &best);
4753: if (DoApply)
1.295 vatton 4754: /* install the new presentation. */
4755: TtaSetStylePresentation (PROpacity, element, tsch, context, best);
1.155 cheyroul 4756: return (cssRule);
4757: }
1.346 quint 4758:
1.170 cheyroul 4759: /*----------------------------------------------------------------------
1.346 quint 4760: ParseSVGStrokeOpacity: parse a SVG stroke-opacity property
1.170 cheyroul 4761: ----------------------------------------------------------------------*/
4762: static char *ParseSVGStrokeOpacity (Element element, PSchema tsch,
1.327 vatton 4763: PresentationContext context, char *cssRule,
4764: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 4765: {
4766: PresentationValue best;
1.161 quint 4767:
1.184 vatton 4768: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 4769: best.typed_data.real = FALSE;
4770: cssRule = ParseClampedUnit (cssRule, &best);
4771: if (DoApply)
1.295 vatton 4772: /* install the new presentation. */
4773: TtaSetStylePresentation (PRStrokeOpacity, element, tsch, context, best);
1.170 cheyroul 4774: return (cssRule);
4775: }
1.346 quint 4776:
1.170 cheyroul 4777: /*----------------------------------------------------------------------
1.346 quint 4778: ParseSVGFillOpacity: parse a SVG fil-opacityl property
1.170 cheyroul 4779: ----------------------------------------------------------------------*/
4780: static char *ParseSVGFillOpacity (Element element, PSchema tsch,
1.327 vatton 4781: PresentationContext context, char *cssRule,
4782: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 4783: {
4784: PresentationValue best;
4785:
1.184 vatton 4786: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 4787: best.typed_data.real = FALSE;
4788: cssRule = ParseClampedUnit (cssRule, &best);
4789: if (DoApply)
1.295 vatton 4790: /* install the new presentation. */
4791: TtaSetStylePresentation (PRFillOpacity, element, tsch, context, best);
1.170 cheyroul 4792: return (cssRule);
4793: }
1.207 vatton 4794:
1.1 cvs 4795: /*----------------------------------------------------------------------
1.327 vatton 4796: GetCSSBackgroundURL searches a CSS BackgroundImage url within
4797: the cssRule.
4798: Returns NULL or a new allocated url string.
1.217 vatton 4799: ----------------------------------------------------------------------*/
4800: char *GetCSSBackgroundURL (char *cssRule)
4801: {
4802: char *b, *url;
4803:
4804: url = NULL;
4805: b = strstr (cssRule, "url");
4806: if (b)
1.290 gully 4807: b = ParseCSSUrl (b, &url);
1.217 vatton 4808: return (url);
4809: }
4810:
4811: /*----------------------------------------------------------------------
1.327 vatton 4812: ParseCSSContent: parse the value of property "content"
1.217 vatton 4813: ----------------------------------------------------------------------*/
4814: static char *ParseCSSContent (Element element, PSchema tsch,
1.327 vatton 4815: PresentationContext ctxt, char *cssRule,
4816: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 4817: {
1.312 quint 4818: PresentationValue value;
1.353 quint 4819: char *last, *start, quoteChar, savedChar;
4820: int length, val;
1.366 vatton 4821: char *buffer, *p;
4822: char *start_value;
1.312 quint 4823: ThotBool repeat;
4824:
4825: value.typed_data.unit = UNIT_REL;
4826: value.typed_data.real = FALSE;
4827: value.typed_data.value = 0;
1.366 vatton 4828: if (!DoDialog && DoApply)
1.347 quint 4829: TtaSetStylePresentation (PRContent, element, tsch, ctxt, value);
1.217 vatton 4830: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 4831: start_value = cssRule;
1.312 quint 4832: repeat = TRUE;
4833: while (repeat)
4834: {
1.366 vatton 4835: p = cssRule;
1.312 quint 4836: if (!strncasecmp (cssRule, "normal", 6))
1.327 vatton 4837: /* The pseudo-element is not generated */
4838: {
4839: /* @@@@@@ */
4840: cssRule += 6;
4841: repeat = FALSE;
4842: }
1.331 quint 4843: else if (!strncasecmp (cssRule, "none", 4))
4844: /* The pseudo-element is not generated */
4845: {
4846: /* @@@@@@ */
4847: cssRule += 4;
4848: repeat = FALSE;
4849: }
1.312 quint 4850: else if (*cssRule == '"' || *cssRule == '\'')
1.327 vatton 4851: /* It's a string */
4852: {
4853: quoteChar = *cssRule;
1.353 quint 4854: /* how long is the string? */
4855: last = cssRule;
4856: last = SkipString (last);
4857: length = last - cssRule;
4858: /* get a buffer to store the string */
1.366 vatton 4859: buffer = (char *)TtaGetMemory (length);
1.353 quint 4860: p = buffer; /* beginning of the string */
1.327 vatton 4861: cssRule++;
4862: while (*cssRule != EOS && *cssRule != quoteChar)
1.353 quint 4863: {
4864: if (*cssRule == '\\')
4865: {
4866: cssRule++; /* skip the backslash */
4867: if ((*cssRule >= '0' && *cssRule <= '9') ||
4868: (*cssRule >= 'A' && *cssRule <= 'F') ||
4869: (*cssRule >= 'a' && *cssRule <= 'f'))
4870: {
4871: start = cssRule; /* first hex digit after the backslash*/
4872: cssRule++;
4873: while ((*cssRule >= '0' && *cssRule <= '9') ||
4874: (*cssRule >= 'A' && *cssRule <= 'F') ||
4875: (*cssRule >= 'a' && *cssRule <= 'f'))
4876: cssRule++;
4877: savedChar = *cssRule;
4878: *cssRule = EOS;
4879: sscanf (start, "%x", &val);
1.366 vatton 4880: TtaWCToMBstring ((wchar_t) val, (unsigned char **) &p);
1.353 quint 4881: *cssRule = savedChar;
4882: }
4883: else
4884: {
4885: *p = *cssRule;
4886: p++; cssRule++;
4887: }
4888: }
4889: else
4890: {
4891: *p = *cssRule;
4892: p++; cssRule++;
4893: }
4894: }
4895: *p = EOS;
1.366 vatton 4896: if (DoDialog)
4897: {
4898: DisplayStyleValue ("", start_value, p);
4899: start_value = p;
4900: }
4901: else if (*cssRule != quoteChar)
1.327 vatton 4902: cssRule = SkipProperty (cssRule, FALSE);
4903: else
4904: {
4905: *cssRule = EOS;
4906: value.typed_data.unit = UNIT_REL;
4907: value.typed_data.real = FALSE;
1.353 quint 4908: value.pointer = buffer;
1.347 quint 4909: if (DoApply)
4910: TtaSetStylePresentation (PRContentString, element, tsch, ctxt,
4911: value);
1.327 vatton 4912: *cssRule = quoteChar;
4913: cssRule++;
4914: }
1.353 quint 4915: TtaFreeMemory (buffer);
1.327 vatton 4916: }
1.312 quint 4917: else if (!strncasecmp (cssRule, "url", 3))
1.327 vatton 4918: {
4919: cssRule += 3;
1.347 quint 4920: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
4921: PRContentURL);
1.366 vatton 4922: if (DoDialog)
4923: {
4924: DisplayStyleValue ("", start_value, p);
4925: start_value = p;
4926: }
1.327 vatton 4927: }
1.312 quint 4928: else if (!strncasecmp (cssRule, "counter", 7))
1.327 vatton 4929: {
4930: cssRule += 7;
4931: /* @@@@@@ */
1.366 vatton 4932: if (DoDialog)
4933: {
4934: DisplayStyleValue ("", start_value, p);
4935: start_value = p;
4936: }
4937: else
4938: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 4939: }
1.312 quint 4940: else if (!strncasecmp (cssRule, "counters", 8))
1.327 vatton 4941: {
4942: cssRule += 8;
4943: /* @@@@@@ */
1.366 vatton 4944: if (DoDialog)
4945: {
4946: DisplayStyleValue ("", start_value, p);
4947: start_value = p;
4948: }
4949: else
4950: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 4951: }
1.312 quint 4952: else if (!strncasecmp (cssRule, "attr", 4))
1.327 vatton 4953: {
1.347 quint 4954: value.pointer = NULL;
1.327 vatton 4955: cssRule += 4;
1.347 quint 4956: cssRule = SkipBlanksAndComments (cssRule);
4957: if (*cssRule == '(')
4958: {
4959: cssRule++;
4960: cssRule = SkipBlanksAndComments (cssRule);
4961: start = cssRule;
4962: while (*cssRule != EOS && *cssRule != ')')
4963: cssRule++;
4964: if (*cssRule != ')')
4965: cssRule = start;
4966: else
4967: {
4968: last = cssRule;
4969: /* remove extra spaces */
4970: if (last[-1] == SPACE)
4971: {
4972: *last = SPACE;
4973: last--;
4974: while (last[-1] == SPACE)
4975: last--;
4976: }
4977: savedChar = *last;
4978: *last = EOS;
4979: value.typed_data.unit = UNIT_REL;
4980: value.typed_data.real = FALSE;
4981: value.pointer = start;
1.366 vatton 4982: if (DoDialog)
4983: {
4984: DisplayStyleValue ("", start_value, p);
4985: start_value = p;
4986: }
4987: else if (DoApply)
1.347 quint 4988: TtaSetStylePresentation (PRContentAttr, element, tsch,
4989: ctxt, value);
4990: *last = savedChar;
4991: }
4992: }
4993: if (value.pointer == NULL)
4994: {
1.353 quint 4995: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 4996: if (DoDialog)
4997: {
4998: DisplayStyleValue ("", start_value, p);
4999: start_value = p;
5000: }
5001: else
5002: cssRule = SkipProperty (cssRule, FALSE);
1.347 quint 5003: }
5004: cssRule++;
1.327 vatton 5005: }
1.312 quint 5006: else if (!strncasecmp (cssRule, "open-quote", 10))
1.327 vatton 5007: {
5008: cssRule += 10;
5009: /* @@@@@@ */
5010: }
1.312 quint 5011: else if (!strncasecmp (cssRule, "close-quote", 11))
1.327 vatton 5012: {
5013: cssRule += 11;
5014: /* @@@@@@ */
5015: }
1.312 quint 5016: else if (!strncasecmp (cssRule, "no-open-quote", 13))
1.327 vatton 5017: {
5018: cssRule += 13;
5019: /* @@@@@@ */
5020: }
1.312 quint 5021: else if (!strncasecmp (cssRule, "no-close-quote", 14))
1.327 vatton 5022: {
5023: cssRule += 14;
5024: /* @@@@@@ */
5025: }
1.312 quint 5026: else if (!strncasecmp (cssRule, "inherit", 7))
1.327 vatton 5027: {
5028: cssRule += 7;
5029: /* @@@@@@ */
5030: repeat = FALSE;
5031: }
1.312 quint 5032: else
1.327 vatton 5033: {
1.353 quint 5034: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 5035: if (DoDialog)
5036: {
5037: DisplayStyleValue ("", start_value, p);
5038: start_value = p;
5039: }
5040: else
5041: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5042: }
1.312 quint 5043: cssRule = SkipBlanksAndComments (cssRule);
5044: if (repeat)
1.327 vatton 5045: if (*cssRule == ';' || *cssRule == '}' || *cssRule == EOS ||
5046: *cssRule == '!')
5047: repeat = FALSE;
1.217 vatton 5048: }
5049: return (cssRule);
5050: }
1.1 cvs 5051:
5052: /*----------------------------------------------------------------------
1.59 cvs 5053: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 5054: ----------------------------------------------------------------------*/
1.79 cvs 5055: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
1.327 vatton 5056: PresentationContext ctxt,
5057: char *cssRule, CSSInfoPtr css,
5058: ThotBool isHTML)
1.1 cvs 5059: {
1.49 cvs 5060: PresentationValue image, value;
1.357 quint 5061: char *ptr;
1.148 vatton 5062:
1.370 vatton 5063: image.typed_data.real = FALSE;
5064: value.typed_data.real = FALSE;
1.82 cvs 5065: cssRule = SkipBlanksAndComments (cssRule);
1.357 quint 5066: ptr = cssRule;
1.161 quint 5067: if (!strncasecmp (cssRule, "none", 4))
5068: {
1.260 vatton 5069: cssRule += 4;
1.366 vatton 5070: if (DoDialog)
5071: DisplayStyleValue ("background-image", ptr, cssRule);
5072: else if (DoApply)
1.327 vatton 5073: {
5074: /* no background image */
5075: image.pointer = NULL;
5076: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt,
5077: image);
5078: }
1.161 quint 5079: }
1.357 quint 5080: else if (!strncasecmp (cssRule, "inherit", 7))
5081: {
5082: value.typed_data.unit = VALUE_INHERIT;
5083: cssRule += 7;
1.366 vatton 5084: if (DoDialog)
5085: DisplayStyleValue ("background-image", ptr, cssRule);
1.357 quint 5086: }
1.161 quint 5087: else if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 5088: {
5089: cssRule += 3;
1.302 quint 5090: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 5091: PRBackgroundPicture);
1.207 vatton 5092: if (ctxt->destroy)
1.327 vatton 5093: if (TtaGetStylePresentation (PRFillPattern, element, tsch, ctxt,
5094: &value) < 0)
5095: {
5096: /* there is no FillPattern rule -> remove ShowBox rule */
5097: value.typed_data.value = 1;
5098: value.typed_data.unit = UNIT_REL;
5099: value.typed_data.real = FALSE;
5100: TtaSetStylePresentation (PRShowBox, element, tsch, ctxt, value);
5101: }
1.18 cvs 5102: }
1.357 quint 5103: else
5104: {
5105: cssRule = SkipWord (cssRule);
5106: CSSParseError ("Invalid background-image value", ptr, cssRule);
5107: cssRule = SkipProperty (cssRule, FALSE);
5108: }
1.18 cvs 5109: return (cssRule);
5110: }
5111:
5112: /*----------------------------------------------------------------------
1.295 vatton 5113: ParseACSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 5114: ----------------------------------------------------------------------*/
1.295 vatton 5115: static char *ParseACSSBackgroundRepeat (Element element, PSchema tsch,
1.327 vatton 5116: PresentationContext ctxt,
5117: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5118: {
5119: PresentationValue repeat;
1.366 vatton 5120: char *start_value;
1.18 cvs 5121:
1.366 vatton 5122: cssRule = SkipBlanksAndComments (cssRule);
5123: start_value = cssRule;
1.184 vatton 5124: repeat.typed_data.value = REALSIZE;
1.191 vatton 5125: repeat.typed_data.unit = UNIT_BOX;
1.18 cvs 5126: repeat.typed_data.real = FALSE;
1.82 cvs 5127: cssRule = SkipBlanksAndComments (cssRule);
5128: if (!strncasecmp (cssRule, "no-repeat", 9))
1.184 vatton 5129: repeat.typed_data.value = REALSIZE;
1.82 cvs 5130: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.265 vatton 5131: repeat.typed_data.value = YREPEAT;
1.82 cvs 5132: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.265 vatton 5133: repeat.typed_data.value = XREPEAT;
1.82 cvs 5134: else if (!strncasecmp (cssRule, "repeat", 6))
1.184 vatton 5135: repeat.typed_data.value = REPEAT;
1.18 cvs 5136: else
5137: return (cssRule);
5138:
1.295 vatton 5139: cssRule = SkipWord (cssRule);
5140: /* check if it's an important rule */
1.366 vatton 5141: if (DoDialog)
5142: DisplayStyleValue ("background-repeat", start_value, cssRule);
5143: else if (DoApply)
1.295 vatton 5144: /* install the new presentation */
1.362 quint 5145: TtaSetStylePresentation (PRBackgroundRepeat, element, tsch, ctxt, repeat);
1.295 vatton 5146: return (cssRule);
5147: }
5148:
5149: /*----------------------------------------------------------------------
5150: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
5151: ----------------------------------------------------------------------*/
5152: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.315 gully 5153: PresentationContext ctxt,
5154: char *cssRule, CSSInfoPtr css,
5155: ThotBool isHTML)
1.295 vatton 5156: {
1.388 carcone 5157:
5158: char *ptr;
5159:
5160: ptr = cssRule;
1.295 vatton 5161: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
1.315 gully 5162: cssRule, css, isHTML);
1.388 carcone 5163:
5164: if (ptr == cssRule)
1.117 vatton 5165: {
1.295 vatton 5166: cssRule = SkipValue ("Invalid background-repeat value", cssRule);
1.117 vatton 5167: /* check if it's an important rule */
5168: }
1.295 vatton 5169: return cssRule;
1.18 cvs 5170: }
5171:
5172: /*----------------------------------------------------------------------
1.327 vatton 5173: ParseACSSBackgroundAttachment: parse a CSS BackgroundAttachment
5174: attribute string.
1.18 cvs 5175: ----------------------------------------------------------------------*/
1.295 vatton 5176: static char *ParseACSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5177: PresentationContext ctxt,
5178: char *cssRule, CSSInfoPtr css,
5179: ThotBool isHTML)
1.18 cvs 5180: {
1.366 vatton 5181: char *start_value;
5182:
1.163 quint 5183: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5184: start_value = cssRule;
1.163 quint 5185: if (!strncasecmp (cssRule, "scroll", 6))
1.199 vatton 5186: {
5187: cssRule = SkipWord (cssRule);
5188: }
1.163 quint 5189: else if (!strncasecmp (cssRule, "fixed", 5))
1.199 vatton 5190: {
5191: cssRule = SkipWord (cssRule);
5192: }
1.362 quint 5193: else if (!strncasecmp (cssRule, "inherit", 7))
5194: {
5195: cssRule = SkipWord (cssRule);
5196: }
1.366 vatton 5197: if (start_value != cssRule && DoDialog)
5198: DisplayStyleValue ("background-attachment", start_value, cssRule);
1.163 quint 5199: return (cssRule);
1.1 cvs 5200: }
5201:
5202: /*----------------------------------------------------------------------
1.327 vatton 5203: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
5204: attribute string.
1.295 vatton 5205: ----------------------------------------------------------------------*/
5206: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5207: PresentationContext ctxt,
5208: char *cssRule, CSSInfoPtr css,
5209: ThotBool isHTML)
1.295 vatton 5210: {
5211: char *ptr;
5212:
5213: ptr = cssRule;
5214: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.327 vatton 5215: cssRule, css, isHTML);
1.295 vatton 5216: if (ptr == cssRule)
1.366 vatton 5217: cssRule = SkipValue ("Invalid background-attachment value", cssRule);
1.295 vatton 5218: return cssRule;
5219: }
5220:
5221: /*----------------------------------------------------------------------
1.327 vatton 5222: ParseACSSBackgroundPosition: parse a CSS BackgroundPosition
5223: attribute string.
1.1 cvs 5224: ----------------------------------------------------------------------*/
1.279 vatton 5225: static char *ParseACSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5226: PresentationContext ctxt,
5227: char *cssRule, CSSInfoPtr css,
1.362 quint 5228: ThotBool isHTML, ThotBool *across)
1.1 cvs 5229: {
1.362 quint 5230: PresentationValue val;
5231: char *ptr;
1.1 cvs 5232:
1.163 quint 5233: cssRule = SkipBlanksAndComments (cssRule);
1.362 quint 5234: ptr = cssRule;
5235: val.typed_data.value = 0;
5236: val.typed_data.real = FALSE;
5237: val.typed_data.unit = UNIT_INVALID;
1.163 quint 5238: if (!strncasecmp (cssRule, "left", 4))
1.362 quint 5239: {
5240: val.typed_data.value = 0;
5241: val.typed_data.unit = UNIT_PERCENT;
5242: cssRule += 4;
5243: *across = TRUE;
5244: }
1.163 quint 5245: else if (!strncasecmp (cssRule, "right", 5))
1.362 quint 5246: {
5247: val.typed_data.value = 100;
5248: val.typed_data.unit = UNIT_PERCENT;
5249: cssRule += 5;
5250: *across = TRUE;
5251: }
1.163 quint 5252: else if (!strncasecmp (cssRule, "center", 6))
1.362 quint 5253: {
5254: val.typed_data.value = 50;
5255: val.typed_data.unit = UNIT_PERCENT;
5256: cssRule += 6;
5257: }
1.163 quint 5258: else if (!strncasecmp (cssRule, "top", 3))
1.362 quint 5259: {
5260: val.typed_data.value = 0;
5261: val.typed_data.unit = UNIT_PERCENT;
5262: cssRule += 3;
5263: *across = FALSE;
5264: }
1.163 quint 5265: else if (!strncasecmp (cssRule, "bottom", 6))
1.191 vatton 5266: {
1.362 quint 5267: val.typed_data.value = 100;
5268: val.typed_data.unit = UNIT_PERCENT;
5269: cssRule += 6;
5270: *across = FALSE;
5271: }
5272: else if (!strncasecmp (cssRule, "inherit", 7))
5273: {
5274: val.typed_data.unit = VALUE_INHERIT;
5275: cssRule += 7;
1.191 vatton 5276: }
1.163 quint 5277: else
1.362 quint 5278: /* <length> or <percentage> */
5279: {
5280: cssRule = ParseCSSUnit (cssRule, &val);
5281: if (val.typed_data.unit == UNIT_BOX && val.typed_data.value == 0)
5282: /* 0 with no unit. Accept */
5283: val.typed_data.unit = UNIT_PERCENT;
5284: }
1.163 quint 5285:
1.366 vatton 5286: if (val.typed_data.unit != UNIT_INVALID && val.typed_data.unit != UNIT_BOX)
1.362 quint 5287: {
1.366 vatton 5288: if (DoDialog)
5289: {
5290: if (val.typed_data.unit == VALUE_INHERIT)
5291: {
5292: DisplayStyleValue ("background-positionH", ptr, cssRule);
5293: DisplayStyleValue ("background-positionV", ptr, cssRule);
5294: }
5295: else if (*across)
5296: DisplayStyleValue ("background-positionH", ptr, cssRule);
5297: else
5298: DisplayStyleValue ("background-positionV", ptr, cssRule);
5299: }
5300: else if (DoApply)
1.362 quint 5301: /* install the new presentation */
5302: {
5303: if (val.typed_data.unit == VALUE_INHERIT)
5304: /* "inherit" applies to both dimensions */
5305: {
5306: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5307: ctxt, val);
5308: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5309: ctxt, val);
5310: }
5311: else if (*across)
5312: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5313: ctxt, val);
5314: else
5315: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5316: ctxt, val);
5317: }
5318: }
1.279 vatton 5319: return (cssRule);
5320: }
1.218 vatton 5321:
1.279 vatton 5322: /*----------------------------------------------------------------------
1.327 vatton 5323: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
5324: attribute string.
1.279 vatton 5325: ----------------------------------------------------------------------*/
5326: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5327: PresentationContext ctxt,
5328: char *cssRule, CSSInfoPtr css,
5329: ThotBool isHTML)
1.279 vatton 5330: {
1.295 vatton 5331: char *ptr;
1.362 quint 5332: ThotBool across;
1.295 vatton 5333:
5334: ptr = cssRule;
1.362 quint 5335: across = TRUE;
5336: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule, css,
5337: isHTML, &across);
1.295 vatton 5338: if (ptr == cssRule)
1.360 vatton 5339: cssRule = SkipValue ("Invalid background-position value", cssRule);
1.362 quint 5340: else
1.298 vatton 5341: {
1.362 quint 5342: cssRule = SkipBlanksAndComments (cssRule);
5343: if (*cssRule != ';' && *cssRule != '!' && *cssRule != EOS)
5344: {
5345: /* possible second value */
5346: ptr = cssRule;
5347: across = !across;
5348: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5349: css, isHTML, &across);
5350: if (ptr == cssRule)
5351: cssRule = SkipValue ("Invalid background-position value", cssRule);
5352: }
1.298 vatton 5353: }
1.163 quint 5354: return (cssRule);
1.18 cvs 5355: }
5356:
5357: /*----------------------------------------------------------------------
1.327 vatton 5358: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 5359: ----------------------------------------------------------------------*/
1.79 cvs 5360: static char *ParseCSSBackground (Element element, PSchema tsch,
1.327 vatton 5361: PresentationContext ctxt, char *cssRule,
5362: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5363: {
1.323 vatton 5364: char *ptr;
5365: int skippedNL;
1.362 quint 5366: ThotBool img, repeat, position, attach, color, across;
1.18 cvs 5367:
1.82 cvs 5368: cssRule = SkipBlanksAndComments (cssRule);
1.323 vatton 5369: img = repeat = position = attach = color = FALSE;
1.362 quint 5370: across = TRUE;
1.301 vatton 5371: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 5372: {
1.71 cvs 5373: /* perhaps a Background Image */
1.198 vatton 5374: if (!strncasecmp (cssRule, "url", 3) || !strncasecmp (cssRule, "none", 4))
1.327 vatton 5375: {
1.334 vatton 5376: if (!strncasecmp (cssRule, "none", 4))
5377: repeat = TRUE;
1.327 vatton 5378: cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
5379: css, isHTML);
5380: img = TRUE;
5381: }
1.18 cvs 5382: /* perhaps a Background Attachment */
1.82 cvs 5383: else if (!strncasecmp (cssRule, "scroll", 6) ||
5384: !strncasecmp (cssRule, "fixed", 5))
1.327 vatton 5385: {
5386: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
5387: cssRule, css, isHTML);
1.328 vatton 5388: attach = repeat = TRUE;
1.327 vatton 5389: }
1.18 cvs 5390: /* perhaps a Background Repeat */
1.82 cvs 5391: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
5392: !strncasecmp (cssRule, "repeat-y", 8) ||
5393: !strncasecmp (cssRule, "repeat-x", 8) ||
5394: !strncasecmp (cssRule, "repeat", 6))
1.327 vatton 5395: {
5396: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
5397: cssRule, css, isHTML);
5398: repeat = TRUE;
5399: }
1.18 cvs 5400: /* perhaps a Background Position */
1.82 cvs 5401: else if (!strncasecmp (cssRule, "left", 4) ||
5402: !strncasecmp (cssRule, "right", 5) ||
5403: !strncasecmp (cssRule, "center", 6) ||
5404: !strncasecmp (cssRule, "top", 3) ||
5405: !strncasecmp (cssRule, "bottom", 6) ||
1.279 vatton 5406: isdigit (*cssRule) || *cssRule == '.' || *cssRule == '-')
1.327 vatton 5407: {
1.362 quint 5408: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5409: css, isHTML, &across);
5410: across = !across;
1.328 vatton 5411: position = repeat = TRUE;
1.327 vatton 5412: }
1.18 cvs 5413: /* perhaps a Background Color */
1.323 vatton 5414: else if (!color)
1.327 vatton 5415: {
5416: skippedNL = NewLineSkipped;
5417: /* check if the rule has been found */
5418: ptr = cssRule;
5419: cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
5420: cssRule, css, isHTML);
5421: if (ptr == cssRule)
5422: {
5423: NewLineSkipped = skippedNL;
5424: /* rule not found */
5425: cssRule = SkipProperty (cssRule, FALSE);
5426: }
5427: else
5428: color = TRUE;
5429: }
1.328 vatton 5430: else
1.327 vatton 5431: cssRule = SkipProperty (cssRule, FALSE);
1.328 vatton 5432:
1.82 cvs 5433: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 5434: }
1.328 vatton 5435:
5436: if (color && !img)
5437: ParseCSSBackgroundImage (element, tsch, ctxt, "none", css, isHTML);
5438:
5439: if (img && !repeat)
5440: ParseACSSBackgroundRepeat (element, tsch, ctxt,
5441: "repeat", css, isHTML);
5442: if (img && !position)
5443: ParseACSSBackgroundPosition (element, tsch, ctxt,
1.362 quint 5444: "0% 0%", css, isHTML, &across);
1.328 vatton 5445: if (img && !attach)
5446: ParseACSSBackgroundAttachment (element, tsch, ctxt,
5447: "scroll", css, isHTML);
1.327 vatton 5448: return (cssRule);
1.18 cvs 5449: }
5450:
1.59 cvs 5451: /*----------------------------------------------------------------------
1.327 vatton 5452: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 5453: ----------------------------------------------------------------------*/
1.79 cvs 5454: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.327 vatton 5455: PresentationContext ctxt, char *cssRule,
5456: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 5457: {
5458: PresentationValue page;
1.366 vatton 5459: char *start_value;
1.59 cvs 5460:
1.184 vatton 5461: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5462: page.typed_data.real = FALSE;
1.82 cvs 5463: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5464: start_value = cssRule;
1.82 cvs 5465: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5466: page.typed_data.value = PageAuto;
1.82 cvs 5467: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5468: {
1.184 vatton 5469: page.typed_data.unit = UNIT_REL;
5470: page.typed_data.value = PageAlways;
1.59 cvs 5471: }
1.82 cvs 5472: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5473: {
1.184 vatton 5474: page.typed_data.unit = UNIT_REL;
5475: page.typed_data.value = PageAvoid;
1.59 cvs 5476: }
1.82 cvs 5477: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5478: {
1.184 vatton 5479: page.typed_data.unit = UNIT_REL;
5480: page.typed_data.value = PageLeft;
1.59 cvs 5481: }
1.82 cvs 5482: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5483: {
1.184 vatton 5484: page.typed_data.unit = UNIT_REL;
5485: page.typed_data.value = PageRight;
1.59 cvs 5486: }
1.82 cvs 5487: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5488: {
1.293 quint 5489: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5490: page.typed_data.value = PageInherit;
1.59 cvs 5491: }
5492: cssRule = SkipWord (cssRule);
5493: /* install the new presentation */
1.366 vatton 5494: if ((page.typed_data.unit == UNIT_REL && page.typed_data.value == PageAlways)
5495: || page.typed_data.unit == VALUE_INHERIT)
5496: {
5497: if (DoDialog)
5498: DisplayStyleValue ("page-break-before", start_value, cssRule);
5499: else if (DoApply)
5500: TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
5501: }
1.59 cvs 5502: return (cssRule);
5503: }
5504:
5505: /*----------------------------------------------------------------------
1.327 vatton 5506: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 5507: ----------------------------------------------------------------------*/
1.79 cvs 5508: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.327 vatton 5509: PresentationContext ctxt,
5510: char *cssRule, CSSInfoPtr css,
5511: ThotBool isHTML)
1.59 cvs 5512: {
5513: PresentationValue page;
1.366 vatton 5514: char *start_value;
1.59 cvs 5515:
1.184 vatton 5516: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5517: page.typed_data.real = FALSE;
1.82 cvs 5518: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5519: start_value = cssRule;
1.82 cvs 5520: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5521: page.typed_data.value = PageAuto;
1.82 cvs 5522: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5523: {
1.184 vatton 5524: page.typed_data.unit = UNIT_REL;
5525: page.typed_data.value = PageAlways;
1.59 cvs 5526: }
1.82 cvs 5527: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5528: {
1.184 vatton 5529: page.typed_data.unit = UNIT_REL;
5530: page.typed_data.value = PageAvoid;
1.59 cvs 5531: }
1.82 cvs 5532: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5533: {
1.184 vatton 5534: page.typed_data.unit = UNIT_REL;
5535: page.typed_data.value = PageLeft;
1.59 cvs 5536: }
1.82 cvs 5537: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5538: {
1.184 vatton 5539: page.typed_data.unit = UNIT_REL;
5540: page.typed_data.value = PageRight;
1.59 cvs 5541: }
1.82 cvs 5542: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5543: {
1.293 quint 5544: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5545: page.typed_data.value = PageInherit;
1.59 cvs 5546: }
5547: cssRule = SkipWord (cssRule);
5548: /* install the new presentation */
1.366 vatton 5549: if (page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT)
5550: {
5551: if (DoDialog)
5552: DisplayStyleValue ("page-break-after", start_value, cssRule);
1.367 cvs 5553: //else if (DoApply)
5554: // TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page);
1.366 vatton 5555: }
1.59 cvs 5556: return (cssRule);
5557: }
5558:
5559: /*----------------------------------------------------------------------
1.327 vatton 5560: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 5561: ----------------------------------------------------------------------*/
1.79 cvs 5562: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.327 vatton 5563: PresentationContext ctxt,
5564: char *cssRule, CSSInfoPtr css,
5565: ThotBool isHTML)
1.59 cvs 5566: {
5567: PresentationValue page;
1.366 vatton 5568: char *start_value;
1.59 cvs 5569:
1.184 vatton 5570: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5571: page.typed_data.real = FALSE;
1.82 cvs 5572: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5573: start_value = cssRule;
1.82 cvs 5574: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 5575: {
1.184 vatton 5576: /*page.typed_data.unit = UNIT_REL;*/
5577: page.typed_data.value = PageAuto;
1.59 cvs 5578: }
1.82 cvs 5579: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5580: {
1.184 vatton 5581: page.typed_data.unit = UNIT_REL;
5582: page.typed_data.value = PageAvoid;
1.59 cvs 5583: }
1.82 cvs 5584: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5585: {
1.293 quint 5586: /* page.typed_data.unit = VALUE_INHERIT; */
1.184 vatton 5587: page.typed_data.value = PageInherit;
1.59 cvs 5588: }
5589: cssRule = SkipWord (cssRule);
5590: /* install the new presentation */
1.366 vatton 5591: if ((page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT) &&
5592: page.typed_data.value == PageAvoid)
5593: {
5594: if (DoDialog)
5595: DisplayStyleValue ("page-break-inside", start_value, cssRule);
1.367 cvs 5596: //else if (DoApply)
5597: //TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);
1.366 vatton 5598: }
1.59 cvs 5599: return (cssRule);
5600: }
1.18 cvs 5601:
1.60 cvs 5602: /*----------------------------------------------------------------------
1.327 vatton 5603: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 5604: ----------------------------------------------------------------------*/
1.79 cvs 5605: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.327 vatton 5606: PresentationContext ctxt, char *cssRule,
5607: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 5608: {
5609: PresentationValue width;
5610:
1.82 cvs 5611: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 5612: width.typed_data.value = 0;
1.184 vatton 5613: width.typed_data.unit = UNIT_INVALID;
1.60 cvs 5614: width.typed_data.real = FALSE;
1.110 vatton 5615: if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 5616: {
1.327 vatton 5617: cssRule = ParseCSSUnit (cssRule, &width);
5618: if (width.typed_data.unit == UNIT_BOX)
5619: width.typed_data.unit = UNIT_PX;
1.166 vatton 5620: }
1.295 vatton 5621: else
5622: cssRule = SkipValue ("Invalid stroke-width value", cssRule);
5623:
1.184 vatton 5624: if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 5625: {
1.207 vatton 5626: TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117 vatton 5627: width.typed_data.value = 1;
1.184 vatton 5628: width.typed_data.unit = UNIT_REL;
1.117 vatton 5629: }
1.60 cvs 5630: return (cssRule);
5631: }
5632:
1.217 vatton 5633: /*----------------------------------------------------------------------
1.327 vatton 5634: ParseCSSPosition: parse a CSS Position attribute string.
1.217 vatton 5635: ----------------------------------------------------------------------*/
5636: static char *ParseCSSPosition (Element element, PSchema tsch,
1.327 vatton 5637: PresentationContext ctxt, char *cssRule,
5638: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5639: {
1.305 quint 5640: char *ptr;
5641: PresentationValue pval;
1.217 vatton 5642:
1.305 quint 5643: pval.typed_data.value = 0;
5644: pval.typed_data.unit = UNIT_BOX;
5645: pval.typed_data.real = FALSE;
1.217 vatton 5646: cssRule = SkipBlanksAndComments (cssRule);
5647: ptr = cssRule;
5648: if (!strncasecmp (cssRule, "static", 6))
1.337 vatton 5649: {
5650: pval.typed_data.value = PositionStatic;
5651: cssRule += 6;
5652: }
5653: else if (!strncasecmp (cssRule, "relative", 8))
5654: {
5655: pval.typed_data.value = PositionRelative;
5656: cssRule += 8;
5657: }
1.217 vatton 5658: else if (!strncasecmp (cssRule, "absolute", 8))
1.337 vatton 5659: {
5660: pval.typed_data.value = PositionAbsolute;
5661: cssRule += 8;
5662: }
1.217 vatton 5663: else if (!strncasecmp (cssRule, "fixed", 5))
1.337 vatton 5664: {
5665: pval.typed_data.value = PositionFixed;
5666: cssRule += 5;
5667: }
1.217 vatton 5668: else if (!strncasecmp (cssRule, "inherit", 7))
1.337 vatton 5669: {
5670: pval.typed_data.unit = VALUE_INHERIT;
5671: cssRule += 7;
5672: }
1.305 quint 5673:
5674: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
5675: {
5676: cssRule = SkipValue ("Invalid position value", ptr);
5677: cssRule = SkipValue (NULL, cssRule);
5678: }
1.217 vatton 5679: else
1.305 quint 5680: {
1.337 vatton 5681: cssRule = SkipBlanksAndComments (cssRule);
5682: if (*cssRule != EOS && *cssRule != ';')
5683: SkipValue ("Invalid position value", ptr);
1.366 vatton 5684: else if (DoDialog)
5685: DisplayStyleValue ("position", ptr, cssRule);
1.337 vatton 5686: else if (DoApply)
1.327 vatton 5687: TtaSetStylePresentation (PRPosition, element, tsch, ctxt, pval);
1.305 quint 5688: }
1.217 vatton 5689: return (cssRule);
5690: }
5691:
5692: /*----------------------------------------------------------------------
1.327 vatton 5693: ParseCSSTop: parse a CSS Top attribute
1.217 vatton 5694: ----------------------------------------------------------------------*/
5695: static char *ParseCSSTop (Element element, PSchema tsch,
1.327 vatton 5696: PresentationContext context, char *cssRule,
5697: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5698: {
5699: PresentationValue val;
5700: char *ptr;
5701:
1.370 vatton 5702: val.typed_data.real = FALSE;
1.217 vatton 5703: cssRule = SkipBlanksAndComments (cssRule);
5704: ptr = cssRule;
1.305 quint 5705: /* first parse the value */
5706: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5707: {
5708: val.typed_data.unit = VALUE_AUTO;
5709: val.typed_data.value = 0;
5710: cssRule = SkipWord (cssRule);
5711: }
1.305 quint 5712: else if (!strncasecmp (cssRule, "inherit", 7))
5713: {
5714: val.typed_data.unit = VALUE_INHERIT;
5715: cssRule = SkipWord (cssRule);
5716: }
1.217 vatton 5717: else
5718: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5719:
5720: if (val.typed_data.unit == UNIT_INVALID ||
5721: (val.typed_data.value != 0 &&
1.217 vatton 5722: val.typed_data.unit == UNIT_BOX))
5723: {
1.387 quint 5724: cssRule = SkipValue ("Invalid top value", ptr);
5725: if (val.typed_data.unit == UNIT_BOX)
5726: val.typed_data.unit = UNIT_PX;
5727: else
5728: return (cssRule);
1.217 vatton 5729: }
1.366 vatton 5730: if (DoDialog)
1.387 quint 5731: DisplayStyleValue ("top", ptr, cssRule);
1.366 vatton 5732: else if (DoApply)
1.305 quint 5733: TtaSetStylePresentation (PRTop, element, tsch, context, val);
1.217 vatton 5734: return (cssRule);
5735: }
5736:
5737: /*----------------------------------------------------------------------
1.327 vatton 5738: ParseCSSRight: parse a CSS Right attribute
1.217 vatton 5739: ----------------------------------------------------------------------*/
5740: static char *ParseCSSRight (Element element, PSchema tsch,
1.327 vatton 5741: PresentationContext context, char *cssRule,
5742: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5743: {
5744: PresentationValue val;
5745: char *ptr;
5746:
1.370 vatton 5747: val.typed_data.real = FALSE;
1.217 vatton 5748: cssRule = SkipBlanksAndComments (cssRule);
5749: ptr = cssRule;
5750: /* first parse the attribute string */
1.305 quint 5751: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5752: {
5753: val.typed_data.unit = VALUE_AUTO;
5754: val.typed_data.value = 0;
5755: cssRule = SkipWord (cssRule);
5756: }
1.305 quint 5757: else if (!strncasecmp (cssRule, "inherit", 7))
5758: {
5759: val.typed_data.unit = VALUE_INHERIT;
5760: cssRule = SkipWord (cssRule);
5761: }
1.217 vatton 5762: else
5763: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5764:
5765: if (val.typed_data.unit == UNIT_INVALID ||
5766: (val.typed_data.value != 0 &&
1.217 vatton 5767: val.typed_data.unit == UNIT_BOX))
5768: {
1.387 quint 5769: cssRule = SkipValue ("Invalid right value", ptr);
5770: if (val.typed_data.unit == UNIT_BOX)
5771: val.typed_data.unit = UNIT_PX;
5772: else
5773: return (cssRule);
1.217 vatton 5774: }
1.366 vatton 5775: if (DoDialog)
5776: DisplayStyleValue ("right", ptr, cssRule);
5777: else if (DoApply)
1.305 quint 5778: TtaSetStylePresentation (PRRight, element, tsch, context, val);
1.217 vatton 5779: return (cssRule);
5780: }
5781:
5782: /*----------------------------------------------------------------------
1.327 vatton 5783: ParseCSSBottom: parse a CSS Bottom attribute
1.217 vatton 5784: ----------------------------------------------------------------------*/
5785: static char *ParseCSSBottom (Element element, PSchema tsch,
1.327 vatton 5786: PresentationContext context, char *cssRule,
5787: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5788: {
5789: PresentationValue val;
5790: char *ptr;
5791:
1.370 vatton 5792: val.typed_data.real = FALSE;
1.217 vatton 5793: cssRule = SkipBlanksAndComments (cssRule);
5794: ptr = cssRule;
5795: /* first parse the attribute string */
1.305 quint 5796: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5797: {
5798: val.typed_data.unit = VALUE_AUTO;
5799: val.typed_data.value = 0;
5800: cssRule = SkipWord (cssRule);
5801: }
1.305 quint 5802: else if (!strncasecmp (cssRule, "inherit", 7))
5803: {
5804: val.typed_data.unit = VALUE_INHERIT;
5805: cssRule = SkipWord (cssRule);
5806: }
1.217 vatton 5807: else
5808: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5809:
5810: if (val.typed_data.unit == UNIT_INVALID ||
5811: (val.typed_data.value != 0 &&
1.217 vatton 5812: val.typed_data.unit == UNIT_BOX))
5813: {
1.387 quint 5814: cssRule = SkipValue ("Invalid bottom value", ptr);
5815: if (val.typed_data.unit == UNIT_BOX)
5816: val.typed_data.unit = UNIT_PX;
5817: else
5818: return (cssRule);
1.217 vatton 5819: }
1.366 vatton 5820: if (DoDialog)
5821: DisplayStyleValue ("bottom", ptr, cssRule);
5822: else if (DoApply)
1.305 quint 5823: TtaSetStylePresentation (PRBottom, element, tsch, context, val);
1.217 vatton 5824: return (cssRule);
5825: }
5826:
5827: /*----------------------------------------------------------------------
1.327 vatton 5828: ParseCSSLeft: parse a CSS Left attribute
1.217 vatton 5829: ----------------------------------------------------------------------*/
5830: static char *ParseCSSLeft (Element element, PSchema tsch,
1.327 vatton 5831: PresentationContext context, char *cssRule,
5832: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5833: {
5834: PresentationValue val;
5835: char *ptr;
5836:
1.370 vatton 5837: val.typed_data.real = FALSE;
1.217 vatton 5838: cssRule = SkipBlanksAndComments (cssRule);
5839: ptr = cssRule;
5840: /* first parse the attribute string */
1.305 quint 5841: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5842: {
5843: val.typed_data.unit = VALUE_AUTO;
5844: val.typed_data.value = 0;
5845: cssRule = SkipWord (cssRule);
5846: }
1.305 quint 5847: else if (!strncasecmp (cssRule, "inherit", 7))
5848: {
5849: val.typed_data.unit = VALUE_INHERIT;
5850: cssRule = SkipWord (cssRule);
5851: }
1.217 vatton 5852: else
5853: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5854:
5855: if (val.typed_data.unit == UNIT_INVALID ||
5856: (val.typed_data.value != 0 &&
1.217 vatton 5857: val.typed_data.unit == UNIT_BOX))
5858: {
1.387 quint 5859: cssRule = SkipValue ("Invalid left value", ptr);
5860: if (val.typed_data.unit == UNIT_BOX)
5861: val.typed_data.unit = UNIT_PX;
5862: else
5863: return (cssRule);
1.217 vatton 5864: }
1.366 vatton 5865: if (DoDialog)
5866: DisplayStyleValue ("left", ptr, cssRule);
5867: else if (DoApply)
1.305 quint 5868: TtaSetStylePresentation (PRLeft, element, tsch, context, val);
1.217 vatton 5869: return (cssRule);
5870: }
5871:
5872: /*----------------------------------------------------------------------
1.327 vatton 5873: ParseCSSZIndex: parse a CSS z-index attribute
1.217 vatton 5874: ----------------------------------------------------------------------*/
5875: static char *ParseCSSZIndex (Element element, PSchema tsch,
1.327 vatton 5876: PresentationContext context, char *cssRule,
5877: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5878: {
5879: PresentationValue val;
5880: char *ptr;
5881:
1.370 vatton 5882: val.typed_data.real = FALSE;
1.217 vatton 5883: cssRule = SkipBlanksAndComments (cssRule);
5884: ptr = cssRule;
5885: /* first parse the attribute string */
5886: if (!strncasecmp (cssRule, "auto", 4) ||
5887: !strncasecmp (cssRule, "inherit", 7))
5888: {
5889: val.typed_data.unit = VALUE_AUTO;
5890: val.typed_data.value = 0;
5891: cssRule = SkipWord (cssRule);
5892: }
5893: else
5894: {
5895: cssRule = ParseCSSUnit (cssRule, &val);
5896: if (val.typed_data.unit != UNIT_BOX)
1.327 vatton 5897: {
1.387 quint 5898: cssRule = SkipValue ("Invalid z-index value", ptr);
5899: return (cssRule);
1.327 vatton 5900: }
1.217 vatton 5901: }
1.366 vatton 5902: if (DoDialog)
5903: DisplayStyleValue ("z-index", ptr, cssRule);
1.217 vatton 5904: /***
1.387 quint 5905: else if (DoApply)
1.327 vatton 5906: TtaSetStylePresentation (PR, element, tsch, context, val);
1.217 vatton 5907: ***/
5908: return (cssRule);
5909: }
5910:
1.340 quint 5911: /*----------------------------------------------------------------------
5912: *
5913: * FUNCTIONS STYLE DECLARATIONS
5914: *
5915: *----------------------------------------------------------------------*/
1.18 cvs 5916: /*
1.59 cvs 5917: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 5918: * e.g. "FONT-SIZE" must be placed before "FONT"
5919: */
5920: static CSSProperty CSSProperties[] =
1.327 vatton 5921: {
5922: {"background-color", ParseCSSBackgroundColor},
5923: {"background-image", ParseCSSBackgroundImage},
5924: {"background-repeat", ParseCSSBackgroundRepeat},
5925: {"background-attachment", ParseCSSBackgroundAttachment},
5926: {"background-position", ParseCSSBackgroundPosition},
5927: {"background", ParseCSSBackground},
5928: {"border-top-width", ParseCSSBorderTopWidth},
5929: {"border-right-width", ParseCSSBorderRightWidth},
5930: {"border-bottom-width", ParseCSSBorderBottomWidth},
5931: {"border-left-width", ParseCSSBorderLeftWidth},
5932: {"border-width", ParseCSSBorderWidth},
5933: {"border-top-color", ParseCSSBorderColorTop},
5934: {"border-right-color", ParseCSSBorderColorRight},
5935: {"border-bottom-color", ParseCSSBorderColorBottom},
5936: {"border-left-color", ParseCSSBorderColorLeft},
5937: {"border-color", ParseCSSBorderColor},
5938: {"border-top-style", ParseCSSBorderStyleTop},
5939: {"border-right-style", ParseCSSBorderStyleRight},
5940: {"border-bottom-style", ParseCSSBorderStyleBottom},
5941: {"border-left-style", ParseCSSBorderStyleLeft},
5942: {"border-style", ParseCSSBorderStyle},
5943: {"border-top", ParseCSSBorderTop},
5944: {"border-right", ParseCSSBorderRight},
5945: {"border-bottom", ParseCSSBorderBottom},
5946: {"border-left", ParseCSSBorderLeft},
5947: {"border", ParseCSSBorder},
5948: {"bottom", ParseCSSBottom},
5949: {"clear", ParseCSSClear},
5950: {"color", ParseCSSForeground},
5951: {"content", ParseCSSContent},
5952: {"direction", ParseCSSDirection},
5953: {"display", ParseCSSDisplay},
5954: {"float", ParseCSSFloat},
5955: {"font-family", ParseCSSFontFamily},
5956: {"font-style", ParseCSSFontStyle},
5957: {"font-variant", ParseCSSFontVariant},
5958: {"font-weight", ParseCSSFontWeight},
5959: {"font-size-adjust", ParseCSSFontSizeAdjust},
5960: {"font-size", ParseCSSFontSize},
5961: {"font", ParseCSSFont},
1.382 vatton 5962: {"max-height", ParseCSSMaxHeight},
5963: {"min-height", ParseCSSMinHeight},
1.327 vatton 5964: {"height", ParseCSSHeight},
5965: {"left", ParseCSSLeft},
5966: {"letter-spacing", ParseCSSLetterSpacing},
5967: {"line-height", ParseCSSLineHeight},
5968: {"list-style-type", ParseCSSListStyleType},
5969: {"list-style-image", ParseCSSListStyleImage},
5970: {"list-style-position", ParseCSSListStylePosition},
5971: {"list-style", ParseCSSListStyle},
5972: {"margin-bottom", ParseCSSMarginBottom},
5973: {"margin-top", ParseCSSMarginTop},
5974: {"margin-right", ParseCSSMarginRight},
5975: {"margin-left", ParseCSSMarginLeft},
5976: {"margin", ParseCSSMargin},
5977: {"padding-top", ParseCSSPaddingTop},
5978: {"padding-right", ParseCSSPaddingRight},
5979: {"padding-bottom", ParseCSSPaddingBottom},
5980: {"padding-left", ParseCSSPaddingLeft},
5981: {"padding", ParseCSSPadding},
5982: {"page-break-before", ParseCSSPageBreakBefore},
5983: {"page-break-after", ParseCSSPageBreakAfter},
5984: {"page-break-inside", ParseCSSPageBreakInside},
5985: {"position", ParseCSSPosition},
5986: {"right", ParseCSSRight},
5987: {"text-align", ParseCSSTextAlign},
5988: {"text-anchor", ParseCSSTextAnchor},
5989: {"text-indent", ParseCSSTextIndent},
5990: {"text-decoration", ParseCSSTextDecoration},
5991: {"text-transform", ParseCSSTextTransform},
5992: {"top", ParseCSSTop},
5993: {"unicode-bidi", ParseCSSUnicodeBidi},
5994: {"vertical-align", ParseCSSVerticalAlign},
5995: {"white-space", ParseCSSWhiteSpace},
1.382 vatton 5996: {"max-width", ParseCSSMaxWidth},
5997: {"min-width", ParseCSSMinWidth},
1.327 vatton 5998: {"width", ParseCSSWidth},
1.333 vatton 5999: {"visibility", ParseCSSVisibility},
1.327 vatton 6000: {"word-spacing", ParseCSSWordSpacing},
6001: {"z-index", ParseCSSZIndex},
6002:
6003: /* SVG extensions */
6004: {"fill-opacity", ParseSVGFillOpacity},
6005: {"fill", ParseSVGFill},
6006: {"opacity", ParseSVGOpacity},
6007: {"stroke-opacity", ParseSVGStrokeOpacity},
6008: {"stroke-width", ParseSVGStrokeWidth},
6009: {"stroke", ParseSVGStroke}
6010: };
1.155 cheyroul 6011:
1.18 cvs 6012: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
6013:
6014: /*----------------------------------------------------------------------
1.327 vatton 6015: ParseCSSRule: parse a CSS Style string
6016: we expect the input string describing the style to be of the form
6017: property: value [ ; property: value ]*
6018: but tolerate incorrect or incomplete input
1.18 cvs 6019: ----------------------------------------------------------------------*/
1.366 vatton 6020: void ParseCSSRule (Element element, PSchema tsch, PresentationContext ctxt,
6021: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 6022: {
1.366 vatton 6023: DisplayMode dispMode = DisplayImmediately;
1.312 quint 6024: char *p = NULL, *next, *end;
1.214 quint 6025: char *valueStart;
1.18 cvs 6026: int lg;
1.34 cvs 6027: unsigned int i;
1.76 cvs 6028: ThotBool found;
1.18 cvs 6029:
1.34 cvs 6030: /* avoid too many redisplay */
1.366 vatton 6031: if (!DoDialog && ctxt->doc)
6032: {
6033: dispMode = TtaGetDisplayMode (ctxt->doc);
6034: if (dispMode == DisplayImmediately)
6035: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
6036: }
1.34 cvs 6037:
1.82 cvs 6038: while (*cssRule != EOS)
1.18 cvs 6039: {
1.82 cvs 6040: cssRule = SkipBlanksAndComments (cssRule);
1.371 vatton 6041: if (*cssRule == ';' || *cssRule < 0x20 ||
1.372 vatton 6042: ((unsigned char)*cssRule) == 0xA0)
1.371 vatton 6043: cssRule++;
6044: else if (*cssRule < 0x41 || *cssRule > 0x7A ||
6045: (*cssRule > 0x5A && *cssRule < 0x61))
1.352 vatton 6046: {
6047: end = SkipProperty (cssRule, FALSE);
1.385 vatton 6048: if (cssRule[0] != '-')
6049: CSSParseError ("Invalid property", cssRule, end);
1.352 vatton 6050: cssRule = end;
6051: }
1.194 vatton 6052: else if (*cssRule != EOS)
1.327 vatton 6053: {
6054: found = FALSE;
6055: /* look for the type of property */
6056: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
6057: {
6058: lg = strlen (CSSProperties[i].name);
6059: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
6060: {
6061: p = cssRule + lg;
6062: found = TRUE;
6063: i--;
6064: }
6065: }
6066:
1.360 vatton 6067: // check if it's an important rule
6068: CheckImportantRule (cssRule, ctxt);
1.327 vatton 6069: if (i < NB_CSSSTYLEATTRIBUTE &&
6070: !strcasecmp (CSSProperties[i].name, "content") &&
6071: ((GenericContext)ctxt)->pseudo != PbBefore &&
6072: ((GenericContext)ctxt)->pseudo != PbAfter)
1.340 quint 6073: /* property content is allowed only for pseudo-elements :before and
6074: :after */
1.327 vatton 6075: {
1.352 vatton 6076: end = SkipProperty (cssRule, FALSE);
1.327 vatton 6077: CSSParseError ("content is allowed only for pseudo-elements",
6078: cssRule, end);
1.352 vatton 6079: cssRule = end;
1.327 vatton 6080: }
1.352 vatton 6081: else if (i == NB_CSSSTYLEATTRIBUTE)
1.376 vatton 6082: cssRule = SkipProperty (cssRule, !ctxt->destroy);
1.327 vatton 6083: else
6084: {
6085: /* update index and skip the ":" indicator if present */
6086: p = SkipBlanksAndComments (p);
6087: if (*p == ':')
6088: {
6089: p++;
6090: p = SkipBlanksAndComments (p);
6091: /* try to parse the value associated with this property */
6092: if (CSSProperties[i].parsing_function != NULL)
6093: {
6094: valueStart = p;
6095: p = CSSProperties[i].parsing_function (element, tsch,
6096: ctxt, p, css, isHTML);
6097: if (!element && isHTML)
6098: {
6099: if (ctxt->type == HTML_EL_Input)
6100: /* it's a generic rule for the HTML element input.
6101: Generate a Thot Pres rule for each kind of
6102: input element */
6103: {
6104: ctxt->type = HTML_EL_Text_Input;
6105: p = CSSProperties[i].parsing_function (element,
6106: tsch, ctxt, valueStart, css, isHTML);
6107: ctxt->type = HTML_EL_Password_Input;
6108: p = CSSProperties[i].parsing_function (element,
6109: tsch, ctxt, valueStart, css, isHTML);
6110: ctxt->type = HTML_EL_File_Input;
6111: p = CSSProperties[i].parsing_function (element,
6112: tsch, ctxt, valueStart, css, isHTML);
6113: ctxt->type = HTML_EL_Checkbox_Input;
6114: p = CSSProperties[i].parsing_function (element,
6115: tsch, ctxt, valueStart, css, isHTML);
6116: ctxt->type = HTML_EL_Radio_Input;
6117: p = CSSProperties[i].parsing_function (element,
6118: tsch, ctxt, valueStart, css, isHTML);
6119: ctxt->type = HTML_EL_Submit_Input;
6120: p = CSSProperties[i].parsing_function (element,
6121: tsch, ctxt, valueStart, css, isHTML);
6122: ctxt->type = HTML_EL_Reset_Input;
6123: p = CSSProperties[i].parsing_function (element,
6124: tsch, ctxt, valueStart, css, isHTML);
6125: ctxt->type = HTML_EL_Button_Input;
6126: p = CSSProperties[i].parsing_function (element,
6127: tsch, ctxt, valueStart, css, isHTML);
6128: ctxt->type = HTML_EL_Input;
6129: }
6130: else if (ctxt->type == HTML_EL_ruby)
6131: /* it's a generic rule for the HTML element ruby.
6132: Generate a Thot Pres rule for each kind of
6133: ruby element. */
6134: {
6135: ctxt->type = HTML_EL_simple_ruby;
6136: p = CSSProperties[i].parsing_function (element,
6137: tsch, ctxt, valueStart, css, isHTML);
6138: ctxt->type = HTML_EL_complex_ruby;
6139: p = CSSProperties[i].parsing_function (element,
6140: tsch, ctxt, valueStart, css, isHTML);
6141: ctxt->type = HTML_EL_ruby;
6142: }
6143: }
6144: /* update index and skip the ";" separator if present */
6145: next = SkipBlanksAndComments (p);
6146: if (*next != EOS && *next != ';')
6147: CSSParseError ("Missing closing ';'", cssRule, p);
6148: cssRule = next;
6149: }
6150: }
6151: else
6152: cssRule = SkipProperty (cssRule, TRUE);
6153: }
1.360 vatton 6154: // skip important markup
6155: cssRule = SkipImportantRule (cssRule);
6156:
1.327 vatton 6157: }
1.18 cvs 6158: /* next property */
1.82 cvs 6159: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 6160: if (*cssRule == '}')
1.327 vatton 6161: {
6162: cssRule++;
6163: CSSPrintError ("Invalid character", "}");
6164: cssRule = SkipBlanksAndComments (cssRule);
6165: }
1.155 cheyroul 6166: if (*cssRule == ',' ||
1.327 vatton 6167: *cssRule == ';')
6168: {
6169: cssRule++;
6170: cssRule = SkipBlanksAndComments (cssRule);
6171: }
1.18 cvs 6172: }
1.34 cvs 6173:
6174: /* restore the display mode */
1.366 vatton 6175: if (!DoDialog && ctxt->doc && dispMode == DisplayImmediately)
1.207 vatton 6176: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 6177: }
1.1 cvs 6178:
1.111 cvs 6179: /*----------------------------------------------------------------------
1.327 vatton 6180: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
6181: This function must be called when a specific style is applied to an
6182: element.
6183: The parameter specificity is the specificity of the style, 0 if it is
6184: not really a CSS rule.
1.1 cvs 6185: ----------------------------------------------------------------------*/
1.79 cvs 6186: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.377 quint 6187: int specificity, ThotBool destroy)
1.1 cvs 6188: {
1.257 vatton 6189: DisplayMode dispMode;
1.207 vatton 6190: PresentationContext ctxt;
6191: ElementType elType;
6192: ThotBool isHTML;
1.1 cvs 6193:
1.207 vatton 6194: /* A rule applying to BODY is really meant to address HTML */
6195: elType = TtaGetElementType (el);
1.286 quint 6196: NewLineSkipped = 0;
1.207 vatton 6197: /* store the current line for eventually reported errors */
6198: LineNumber = TtaGetElementLineNumber (el);
6199: if (destroy)
6200: /* no reported errors */
6201: ParsedDoc = 0;
6202: else if (ParsedDoc != doc)
6203: {
6204: /* update the context for reported errors */
6205: ParsedDoc = doc;
1.348 vatton 6206: Error_DocURL = DocumentURLs[doc];
1.207 vatton 6207: }
6208: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
6209: /* create the context of the Specific presentation driver */
6210: ctxt = TtaGetSpecificStyleContext (doc);
6211: if (ctxt == NULL)
6212: return;
6213: ctxt->type = elType.ElTypeNum;
6214: ctxt->cssSpecificity = specificity;
1.236 quint 6215: ctxt->cssLine = LineNumber;
1.207 vatton 6216: ctxt->destroy = destroy;
6217: /* first use of the context */
6218: ctxt->uses = 1;
1.257 vatton 6219: /* save the current display mode */
6220: dispMode = TtaGetDisplayMode (doc);
1.207 vatton 6221: /* Call the parser */
1.366 vatton 6222: DoDialog = FALSE; // not parsing for CSS dialog
1.207 vatton 6223: ParseCSSRule (el, NULL, (PresentationContext) ctxt, cssRule, NULL, isHTML);
1.257 vatton 6224: /* restore the display mode if necessary */
6225: TtaSetDisplayMode (doc, dispMode);
1.207 vatton 6226: /* check if the context can be freed */
6227: ctxt->uses -= 1;
6228: if (ctxt->uses == 0)
6229: /* no image loading */
6230: TtaFreeMemory(ctxt);
1.1 cvs 6231: }
6232:
1.366 vatton 6233:
1.343 vatton 6234: /*----------------------------------------------------------------------
6235: AddClassName adds the class name into the class list of css if it's
6236: not already there.
6237: ----------------------------------------------------------------------*/
6238: static void AddClassName (char *name, CSSInfoPtr css)
6239: {
1.344 cvs 6240: int l, index, k, length, add;
1.343 vatton 6241: char *buf;
6242: ThotBool found, previous;
6243:
6244: l = strlen (name);
6245: if (l == 0 || css == NULL)
6246: return;
6247: if (css->class_list)
6248: {
6249: buf = css->class_list;
6250: length = strlen (css->class_list);
6251: }
6252: else
6253: {
6254: if (l > 200)
6255: length = l + 1;
6256: else
6257: length = 200;
6258: buf = (char *)TtaGetMemory (length * sizeof (char));
6259: memset (buf, 0, length);
6260: css->class_list = buf;
6261: css->lg_class_list = length;
6262: length = 0;
6263: }
6264:
6265: /* compare that name with all class names already known */
6266: index = 0;
6267: found = FALSE;
6268: previous = FALSE;
6269: while (index < length && !found && !previous)
6270: {
6271: k = 0;
6272: while (k < l && buf[index + k] != EOS && buf[index + k] != SPACE)
6273: {
6274: if (name[k] == buf[index+k])
6275: k++;
6276: else
6277: {
6278: previous = (name[k] < buf[index + k]);
6279: break;
6280: }
6281: }
6282: found = (k == l);
6283: if (!previous)
6284: {
6285: index += k;
6286: while (buf[index] != EOS && buf[index] != SPACE)
6287: index++;
6288: if (buf[index] == SPACE)
6289: index++;
6290: }
6291: }
6292:
6293: if (!found)
6294: /* this class name is not known, append it */
6295: {
6296: l++; /* add a space before */
6297: if (css->lg_class_list <= length + l)
6298: {
6299: // increase the list size
6300: if (l > 200)
6301: add = l + 1;
6302: else
6303: add = 200 ;
6304: buf = (char *)TtaRealloc (buf, css->lg_class_list + (add * sizeof (char)));
6305: if (buf == NULL)
6306: return;
6307: else
6308: {
6309: css->class_list = buf;
6310: memset (&buf[css->lg_class_list], 0, add);
6311: css->lg_class_list += add;
6312: }
6313: }
6314:
6315: if (previous)
6316: {
6317: // move the tail of the current list
6318: for (k = length; k >= index; k--)
6319: buf[k+l] = buf[k];
6320: /* add this new class name at the current position */
6321: strcpy (&buf[index], name);
6322: buf[index + l - 1] = SPACE;
6323: }
6324: else
6325: {
6326: /* add this new class name at the end */
6327: if (index != 0)
6328: buf[index++] = SPACE;
6329: strcpy (&buf[index], name);
6330: }
6331: }
6332: }
6333:
1.68 cvs 6334:
1.1 cvs 6335: /*----------------------------------------------------------------------
1.207 vatton 6336: ParseGenericSelector: Create a generic context for a given selector
6337: string.
6338: If the selector is made of multiple comma, it parses them one at a time
6339: and return the end of the selector string to be handled or NULL.
1.231 vatton 6340: The parameter ctxt gives the current style context which will be passed
6341: to Thotlib.
6342: The parameter css points to the current CSS context.
6343: The parameter link points to the link element.
6344: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 6345: ----------------------------------------------------------------------*/
1.207 vatton 6346: static char *ParseGenericSelector (char *selector, char *cssRule,
1.327 vatton 6347: GenericContext ctxt, Document doc,
6348: CSSInfoPtr css, Element link, char *url)
1.79 cvs 6349: {
6350: ElementType elType;
6351: PSchema tsch;
1.119 vatton 6352: AttributeType attrType;
1.240 quint 6353: char *deb, *cur, *sel, *next, c;
1.317 vatton 6354: char *schemaName, *mappedName, *saveURL;
1.79 cvs 6355: char *names[MAX_ANCESTORS];
1.355 quint 6356: ThotBool pseudoFirstChild[MAX_ANCESTORS];
1.340 quint 6357: ElemRel rel[MAX_ANCESTORS];
6358: char *attrnames[MAX_ANCESTORS];
6359: int attrnums[MAX_ANCESTORS];
6360: int attrlevels[MAX_ANCESTORS];
1.79 cvs 6361: char *attrvals[MAX_ANCESTORS];
1.133 vatton 6362: AttrMatch attrmatch[MAX_ANCESTORS];
1.340 quint 6363: int nbnames, nbattrs;
6364: int i, j;
1.256 vatton 6365: int att, kind;
1.118 vatton 6366: int specificity, xmlType;
1.217 vatton 6367: int skippedNL;
1.380 vatton 6368: ThotBool isHTML, noname;
1.347 quint 6369: ThotBool level, quoted, doubleColon;
1.340 quint 6370: #define ATTR_ID 1
6371: #define ATTR_CLASS 2
6372: #define ATTR_PSEUDO 3
1.1 cvs 6373:
1.207 vatton 6374: sel = ctxt->sel;
1.82 cvs 6375: sel[0] = EOS;
1.117 vatton 6376: specificity = 0;
1.1 cvs 6377: for (i = 0; i < MAX_ANCESTORS; i++)
6378: {
1.25 cvs 6379: names[i] = NULL;
1.355 quint 6380: pseudoFirstChild[i] = FALSE;
1.340 quint 6381: rel[i] = RelAncestor;
6382: attrnames[i] = NULL;
6383: attrnums[i] = 0;
6384: attrlevels[i] = 0;
1.25 cvs 6385: attrvals[i] = NULL;
1.133 vatton 6386: attrmatch[i] = Txtmatch;
1.25 cvs 6387: ctxt->name[i] = 0;
1.355 quint 6388: ctxt->firstChild[i] = FALSE;
1.25 cvs 6389: ctxt->attrType[i] = 0;
1.129 vatton 6390: ctxt->attrLevel[i] = 0;
1.25 cvs 6391: ctxt->attrText[i] = NULL;
1.178 quint 6392: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 6393: }
1.25 cvs 6394: ctxt->box = 0;
1.312 quint 6395: ctxt->var = 0;
1.306 quint 6396: ctxt->pseudo = PbNone;
1.25 cvs 6397: ctxt->type = 0;
1.366 vatton 6398: DoDialog = FALSE; // not arsing for CSS dialog
1.114 quint 6399: /* the specificity of the rule depends on the selector */
6400: ctxt->cssSpecificity = 0;
1.231 vatton 6401: /* localisation of the CSS rule */
6402: ctxt->cssLine = LineNumber + NewLineSkipped;
6403: ctxt->cssURL = url;
1.240 quint 6404:
1.286 quint 6405: skippedNL = NewLineSkipped;
1.82 cvs 6406: selector = SkipBlanksAndComments (selector);
1.286 quint 6407: NewLineSkipped = skippedNL;
1.27 cvs 6408: cur = &sel[0];
1.340 quint 6409: nbnames = 0;
6410: nbattrs = 0;
1.1 cvs 6411: while (1)
6412: {
1.85 cvs 6413: /* point to the following word in sel[] */
1.27 cvs 6414: deb = cur;
1.25 cvs 6415: /* copy an item of the selector into sel[] */
1.1 cvs 6416: /* put one word in the sel buffer */
1.82 cvs 6417: while (*selector != EOS && *selector != ',' &&
6418: *selector != '.' && *selector != ':' &&
1.118 vatton 6419: *selector != '#' && *selector != '[' &&
1.250 vatton 6420: *selector != '>' && *selector != '+' &&
1.327 vatton 6421: !TtaIsBlank (selector))
6422: *cur++ = *selector++;
1.82 cvs 6423: *cur++ = EOS; /* close the first string in sel[] */
1.380 vatton 6424: noname = TRUE;
1.82 cvs 6425: if (deb[0] != EOS)
1.340 quint 6426: /* the selector starts with an element name */
1.327 vatton 6427: {
6428: if (deb[0] <= 64 && deb[0] != '*')
6429: {
6430: CSSPrintError ("Invalid element", deb);
1.380 vatton 6431: names[0] = NULL; /* no element name */
6432: DoApply = FALSE;
1.327 vatton 6433: }
6434: else
6435: {
1.380 vatton 6436: noname = FALSE;
1.327 vatton 6437: names[0] = deb;
6438: if (!strcmp (names[0], "html"))
6439: /* give a greater priority to the backgoud color of html */
6440: specificity += 3;
6441: else
6442: /* selector "*" has specificity zero */
6443: if (strcmp (names[0], "*"))
6444: specificity += 1;
6445: }
6446: }
1.25 cvs 6447: else
1.340 quint 6448: names[0] = NULL; /* no element name */
1.226 quint 6449:
1.340 quint 6450: rel[0] = RelVoid;
1.27 cvs 6451: /* now names[0] points to the beginning of the parsed item
1.340 quint 6452: and cur to the next string to be parsed */
1.129 vatton 6453: while (*selector == '.' || *selector == ':' ||
1.327 vatton 6454: *selector == '#' || *selector == '[')
6455: {
6456: /* point to the following word in sel[] */
6457: deb = cur;
6458: if (*selector == '.')
1.340 quint 6459: /* class */
1.327 vatton 6460: {
6461: selector++;
1.340 quint 6462: while (*selector != '.' && *selector != ':' &&
6463: *selector != '#' && *selector != '[' &&
6464: *selector != EOS && *selector != ',' &&
6465: *selector != '+' && *selector != '>' &&
1.327 vatton 6466: !TtaIsBlank (selector))
6467: {
6468: if (*selector == '\\')
6469: {
6470: selector++;
6471: if (*selector != EOS)
6472: *cur++ = *selector++;
6473: }
6474: else
6475: *cur++ = *selector++;
6476: }
6477: /* close the word */
6478: *cur++ = EOS;
1.340 quint 6479: /* point to the class in sel[] if it's a valid name */
1.327 vatton 6480: if (deb[0] <= 64)
6481: {
6482: CSSPrintError ("Invalid class", deb);
6483: DoApply = FALSE;
6484: }
6485: else
6486: {
1.340 quint 6487: /* simulate selector [class ~= "xxx"] */
6488: nbattrs++;
6489: if (nbattrs == MAX_ANCESTORS)
6490: /* abort parsing */
6491: {
6492: CSSPrintError ("Selector too long", deb);
6493: return (selector);
6494: }
6495: for (i = nbattrs; i > 0; i--)
6496: {
6497: attrnames[i] = attrnames[i - 1];
6498: attrnums[i] = attrnums[i - 1];
6499: attrlevels[i] = attrlevels[i - 1];
6500: attrvals[i] = attrvals[i - 1];
6501: attrmatch[i] = attrmatch[i - 1];
6502: }
6503: attrnames[0] = NULL;
6504: attrnums[0] = ATTR_CLASS;
6505: attrlevels[0] = 0;
6506: attrmatch[0] = Txtword;
6507: attrvals[0] = deb;
1.327 vatton 6508: specificity += 10;
1.343 vatton 6509: }
1.327 vatton 6510: }
6511: else if (*selector == ':')
1.340 quint 6512: /* pseudo-class or pseudo-element */
1.327 vatton 6513: {
6514: selector++;
1.347 quint 6515: doubleColon = FALSE;
6516: if (*selector == ':')
6517: /* it's a double "::". Probably CSS3 syntax */
6518: {
6519: selector++;
6520: doubleColon = TRUE;
6521: }
1.340 quint 6522: while (*selector != '.' && *selector != ':' &&
6523: *selector != '#' && *selector != '[' &&
6524: *selector != EOS && *selector != ',' &&
6525: *selector != '+' && *selector != '>' &&
1.327 vatton 6526: !TtaIsBlank (selector))
6527: *cur++ = *selector++;
6528: /* close the word */
6529: *cur++ = EOS;
1.340 quint 6530: /* point to the pseudo-class or pseudo-element in sel[] if it's
6531: a valid name */
1.355 quint 6532: if (!strcmp (deb, "first-child"))
6533: /* first-child pseudo-class */
1.327 vatton 6534: {
1.355 quint 6535: pseudoFirstChild[0] = TRUE;
6536: specificity += 10;
1.327 vatton 6537: }
1.355 quint 6538: else if (!strcmp (deb, "link") || !strcmp (deb, "visited"))
6539: /* link or visited pseudo-classes */
1.327 vatton 6540: {
1.355 quint 6541: nbattrs++;
6542: if (nbattrs == MAX_ANCESTORS)
6543: /* abort parsing */
1.347 quint 6544: {
1.355 quint 6545: CSSPrintError ("Selector too long", deb);
6546: return (selector);
1.347 quint 6547: }
1.355 quint 6548: for (i = nbattrs; i > 0; i--)
1.347 quint 6549: {
1.355 quint 6550: attrnames[i] = attrnames[i - 1];
6551: attrnums[i] = attrnums[i - 1];
6552: attrlevels[i] = attrlevels[i - 1];
6553: attrvals[i] = attrvals[i - 1];
6554: attrmatch[i] = attrmatch[i - 1];
1.347 quint 6555: }
1.355 quint 6556: attrnames[0] = NULL;
6557: attrnums[0] = ATTR_PSEUDO;
6558: attrlevels[0] = 0;
6559: attrmatch[0] = Txtmatch;
6560: attrvals[0] = deb;
6561: specificity += 10;
6562: }
6563: else if (!strcmp (deb, "hover") || !strcmp (deb, "active") ||
6564: !strcmp (deb, "focus"))
6565: /* hover, active, focus pseudo-classes */
6566: {
6567: specificity += 10;
6568: /* not supported */
6569: DoApply = FALSE;
6570: }
6571: else if (!strncmp (deb, "lang", 4))
6572: /* it's the lang pseudo-class */
6573: {
6574: if (deb[4] != '(' || deb[strlen(deb)-1] != ')')
6575: /* at least one parenthesis is missing. Error */
1.327 vatton 6576: {
1.355 quint 6577: CSSPrintError ("Invalid :lang pseudo-class", deb);
6578: DoApply = FALSE;
1.327 vatton 6579: }
6580: else
1.355 quint 6581: /* simulate selector [lang|="xxx"] */
1.340 quint 6582: {
6583: nbattrs++;
6584: if (nbattrs == MAX_ANCESTORS)
6585: /* abort parsing */
6586: {
6587: CSSPrintError ("Selector too long", deb);
6588: return (selector);
6589: }
1.355 quint 6590: deb[strlen(deb)-1] = EOS;
6591: deb[4] = EOS;
1.340 quint 6592: for (i = nbattrs; i > 0; i--)
6593: {
6594: attrnames[i] = attrnames[i - 1];
6595: attrnums[i] = attrnums[i - 1];
6596: attrlevels[i] = attrlevels[i - 1];
6597: attrvals[i] = attrvals[i - 1];
6598: attrmatch[i] = attrmatch[i - 1];
6599: }
1.355 quint 6600: attrnames[0] = deb;
6601: attrnums[0] = 0;
1.340 quint 6602: attrlevels[0] = 0;
1.355 quint 6603: attrmatch[0] = Txtsubstring;
6604: attrvals[0] = &deb[5];
6605: specificity += 10;
1.340 quint 6606: }
1.327 vatton 6607: }
1.355 quint 6608: else if (!strcmp (deb, "first-line") ||
6609: !strcmp (deb, "first-letter"))
6610: /* pseudo-elements first-line or first-letter */
6611: {
6612: if (doubleColon)
6613: CSSPrintError ("Warning: \"::\" is CSS3 syntax", NULL);
6614: specificity += 1;
6615: /* not supported */
6616: DoApply = FALSE;
6617: }
6618: else if (!strncmp (deb, "before", 6))
6619: /* pseudo-element before */
6620: {
6621: if (doubleColon)
6622: CSSPrintError ("Warning: \"::before\" is CSS3 syntax",
6623: NULL);
6624: ctxt->pseudo = PbBefore;
6625: specificity += 1;
6626: }
6627: else if (!strncmp (deb, "after", 5))
6628: /* pseudo-element after */
6629: {
6630: if (doubleColon)
6631: CSSPrintError ("Warning: \"::after\" is CSS3 syntax",
6632: NULL);
6633: ctxt->pseudo = PbAfter;
6634: specificity += 1;
6635: }
6636: else
6637: {
6638: CSSPrintError ("Invalid pseudo-element", deb);
6639: DoApply = FALSE;
6640: }
6641: if (names[0] && !strcmp (names[0], "*"))
6642: names[0] = NULL;
1.327 vatton 6643: }
6644: else if (*selector == '#')
1.340 quint 6645: /* unique identifier */
1.327 vatton 6646: {
6647: selector++;
1.340 quint 6648: while (*selector != '.' && *selector != ':' &&
6649: *selector != '#' && *selector != '[' &&
6650: *selector != '+' && *selector != '>' &&
6651: *selector != EOS && *selector != ',' &&
1.327 vatton 6652: !TtaIsBlank (selector))
6653: *cur++ = *selector++;
6654: /* close the word */
6655: *cur++ = EOS;
6656: /* point to the attribute in sel[] if it's valid name */
6657: if (deb[0] <= 64)
6658: {
6659: CSSPrintError ("Invalid id", deb);
6660: DoApply = FALSE;
6661: }
6662: else
6663: {
1.340 quint 6664: nbattrs++;
6665: if (nbattrs == MAX_ANCESTORS)
6666: /* abort parsing */
6667: {
6668: CSSPrintError ("Selector too long", deb);
6669: return (selector);
6670: }
6671: for (i = nbattrs; i > 0; i--)
6672: {
6673: attrnames[i] = attrnames[i - 1];
6674: attrnums[i] = attrnums[i - 1];
6675: attrlevels[i] = attrlevels[i - 1];
6676: attrvals[i] = attrvals[i - 1];
6677: attrmatch[i] = attrmatch[i - 1];
6678: }
6679: attrnames[0] = NULL;
6680: attrnums[0] = ATTR_ID;
6681: attrlevels[0] = 0;
6682: attrmatch[0] = Txtmatch;
6683: attrvals[0] = deb;
6684: specificity += 100;
6685: if (names[0] && !strcmp (names[0], "*"))
6686: names[0] = NULL;
1.327 vatton 6687: }
6688: }
6689: else if (*selector == '[')
6690: {
6691: selector++;
1.341 quint 6692: selector = SkipBlanksAndComments (selector);
1.327 vatton 6693: while (*selector != EOS && *selector != ']' &&
6694: *selector != '=' && *selector != '~' &&
1.341 quint 6695: *selector != '|' && *selector != '^' &&
6696: !TtaIsBlank (selector))
1.327 vatton 6697: *cur++ = *selector++;
1.341 quint 6698: /* close the word (attribute name) */
1.327 vatton 6699: *cur++ = EOS;
6700: /* point to the attribute in sel[] if it's valid name */
6701: if (deb[0] <= 64)
6702: {
6703: CSSPrintError ("Invalid attribute", deb);
6704: DoApply = FALSE;
6705: }
6706: else
6707: {
1.340 quint 6708: nbattrs++;
6709: if (nbattrs == MAX_ANCESTORS)
6710: /* abort parsing */
6711: {
6712: CSSPrintError ("Selector too long", deb);
6713: return (selector);
6714: }
6715: for (i = nbattrs; i > 0; i--)
6716: {
6717: attrnames[i] = attrnames[i - 1];
6718: attrnums[i] = attrnums[i - 1];
6719: attrlevels[i] = attrlevels[i - 1];
6720: attrvals[i] = attrvals[i - 1];
6721: attrmatch[i] = attrmatch[i - 1];
6722: }
6723: attrnames[0] = deb;
6724: attrnums[0] = 0;
6725: attrlevels[0] = 0;
1.378 quint 6726: attrvals[0] = NULL;
6727: attrmatch[0] = Txtmatch;
1.327 vatton 6728: specificity += 10;
1.340 quint 6729: /* check matching */
1.341 quint 6730: selector = SkipBlanksAndComments (selector);
1.340 quint 6731: if (*selector == '~')
6732: {
6733: attrmatch[0] = Txtword;
6734: selector++;
6735: }
6736: else if (*selector == '|')
6737: {
6738: attrmatch[0] = Txtsubstring;
6739: selector++;
6740: }
1.341 quint 6741: else if (*selector == '^')
6742: {
6743: attrmatch[0] = Txtsubstring;
6744: selector++;
6745: }
1.340 quint 6746: else
6747: attrmatch[0] = Txtmatch;
1.327 vatton 6748: }
6749: if (*selector == '=')
6750: {
6751: /* look for a value "xxxx" */
6752: selector++;
1.341 quint 6753: selector = SkipBlanksAndComments (selector);
1.327 vatton 6754: if (*selector != '"')
6755: quoted = FALSE;
6756: else
6757: {
6758: quoted = TRUE;
6759: /* we are now parsing the attribute value */
6760: selector++;
6761: }
6762: deb = cur;
6763: while ((quoted &&
6764: (*selector != '"' ||
6765: (*selector == '"' && selector[-1] == '\\'))) ||
6766: (!quoted && *selector != ']'))
6767: {
6768: if (*selector == EOS)
6769: {
6770: CSSPrintError ("Invalid attribute value", deb);
6771: DoApply = FALSE;
6772: }
6773: else
6774: {
6775: if (attrmatch[0] == Txtword && TtaIsBlank (selector))
6776: {
6777: CSSPrintError ("No space allowed here: ", selector);
6778: DoApply = FALSE;
6779: }
6780: *cur++ = *selector;
6781: }
6782: selector++;
6783: }
6784: /* there is a value */
6785: if (quoted && *selector == '"')
6786: {
6787: selector++;
6788: quoted = FALSE;
6789: }
1.341 quint 6790: selector = SkipBlanksAndComments (selector);
1.327 vatton 6791: if (*selector != ']')
6792: {
6793: CSSPrintError ("Invalid attribute value", deb);
6794: DoApply = FALSE;
6795: }
6796: else
6797: {
6798: *cur++ = EOS;
6799: attrvals[0] = deb;
6800: selector++;
6801: }
6802: }
6803: /* end of the attribute */
6804: else if (*selector != ']')
6805: {
6806: selector[1] = EOS;
6807: CSSPrintError ("Invalid attribute", selector);
6808: selector += 2;
6809: DoApply = FALSE;
6810: }
6811: else
6812: {
6813: selector++;
6814: if (names[0] && !strcmp (names[0], "*"))
6815: names[0] = NULL;
6816: }
6817: }
6818: else
6819: {
6820: /* not supported selector */
1.340 quint 6821: while (*selector != '.' && *selector != ':' &&
6822: *selector != '#' && *selector != '[' &&
6823: *selector != EOS && *selector != ',' &&
6824: *selector != '+' && *selector != '>' &&
1.327 vatton 6825: !TtaIsBlank (selector))
6826: *cur++ = *selector++;
6827: /* close the word */
6828: *cur++ = EOS;
6829: CSSPrintError ("Selector not supported:", deb);
6830: DoApply = FALSE;
6831: }
6832: }
1.1 cvs 6833:
1.286 quint 6834: skippedNL = NewLineSkipped;
1.82 cvs 6835: selector = SkipBlanksAndComments (selector);
1.286 quint 6836: NewLineSkipped = skippedNL;
6837:
1.380 vatton 6838: if (noname && !pseudoFirstChild[0] && attrnums[0] == 0 && attrnames[0] == NULL)
6839: {
6840: *cur++ = EOS;
6841: CSSPrintError ("Invalid Selector", deb);
6842: DoApply = FALSE;
6843: }
1.25 cvs 6844: /* is it a multi-level selector? */
1.82 cvs 6845: if (*selector == EOS)
1.327 vatton 6846: /* end of the selector */
6847: break;
1.82 cvs 6848: else if (*selector == ',')
1.327 vatton 6849: {
6850: /* end of the current selector */
6851: selector++;
6852: skippedNL = NewLineSkipped;
6853: next = SkipBlanksAndComments (selector);
6854: NewLineSkipped = skippedNL;
6855: if (*next == EOS)
6856: /* nothing after the comma. Invalid selector */
6857: {
1.380 vatton 6858: CSSPrintError ("Syntax error:", selector);
6859: selector = NULL;
1.327 vatton 6860: }
6861: break;
6862: }
1.25 cvs 6863: else
1.327 vatton 6864: {
6865: if (*selector == '>')
6866: {
1.340 quint 6867: /* handle parent */
1.327 vatton 6868: selector++;
6869: skippedNL = NewLineSkipped;
6870: selector = SkipBlanksAndComments (selector);
6871: NewLineSkipped = skippedNL;
1.340 quint 6872: rel[0] = RelParent;
1.327 vatton 6873: }
6874: else if (*selector == '+')
6875: {
1.340 quint 6876: /* handle immediate sibling */
1.327 vatton 6877: selector++;
6878: skippedNL = NewLineSkipped;
6879: selector = SkipBlanksAndComments (selector);
6880: NewLineSkipped = skippedNL;
6881: rel[0] = RelPrevious;
6882: }
1.340 quint 6883: else
6884: rel[0] = RelAncestor;
6885: nbnames++; /* a new level in ancestor tables */
6886: if (nbnames == MAX_ANCESTORS)
6887: /* abort parsing */
6888: {
6889: CSSPrintError ("Selector too long", deb);
6890: return (selector);
6891: }
6892: /* shift the list to make room for the next part of the selector */
6893: for (i = nbnames; i > 0; i--)
1.327 vatton 6894: {
6895: names[i] = names[i - 1];
1.355 quint 6896: pseudoFirstChild[i] = pseudoFirstChild[i - 1];
1.327 vatton 6897: rel[i] = rel[i - 1];
6898: }
1.340 quint 6899: /* increase the level of all attributes */
6900: for (i = 0; i < nbattrs; i++)
6901: attrlevels[i]++;
1.327 vatton 6902: }
1.1 cvs 6903: }
6904:
1.343 vatton 6905: /* Now update the list of classes defined by the CSS */
6906: for (i = 0; i < nbattrs; i++)
6907: if (attrvals[i] && attrnums[i] == ATTR_CLASS)
6908: AddClassName (attrvals[i], css);
6909:
1.1 cvs 6910: /* Now set up the context block */
1.25 cvs 6911: i = 0;
6912: j = 0;
1.91 cvs 6913: /* default schema name */
1.119 vatton 6914: ctxt->schema = NULL;
1.340 quint 6915: ctxt->nbElem = nbnames;
1.122 vatton 6916: elType.ElSSchema = NULL;
1.355 quint 6917: elType.ElTypeNum = 0;
1.122 vatton 6918: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 6919: if (!strcmp (schemaName, "HTML"))
6920: xmlType = XHTML_TYPE;
6921: else if (!strcmp (schemaName, "MathML"))
6922: xmlType = MATH_TYPE;
6923: else if (!strcmp (schemaName, "SVG"))
6924: xmlType = SVG_TYPE;
6925: else if (!strcmp (schemaName, "XLink"))
6926: xmlType = XLINK_TYPE;
6927: else if (!strcmp (schemaName, "Annot"))
6928: xmlType = ANNOT_TYPE;
6929: else
6930: xmlType = XML_TYPE;
1.340 quint 6931: while (i <= nbnames)
1.25 cvs 6932: {
1.340 quint 6933: ctxt->rel[i] = rel[i];
1.355 quint 6934: ctxt->firstChild[i] = pseudoFirstChild[i];
6935: if (!names[i] && i > 0)
1.340 quint 6936: ctxt->name[i] = HTML_EL_ANY_TYPE;
6937: else
6938: /* store element information */
1.327 vatton 6939: {
6940: /* get the element type of this name in the current document */
6941: if (xmlType == XML_TYPE)
6942: /* it's a generic XML document. Check the main document schema */
6943: {
6944: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 6945: elType.ElTypeNum = 0;
6946: if (names[i])
6947: TtaGetXmlElementType (names[i], &elType, &mappedName, doc);
1.327 vatton 6948: if (!elType.ElTypeNum)
6949: {
1.355 quint 6950: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 6951: elType.ElTypeNum = HTML_EL_ANY_TYPE;
6952: else
6953: elType.ElSSchema = NULL;
6954: }
6955: }
6956: else
6957: {
1.355 quint 6958: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 6959: {
6960: elType.ElSSchema = TtaGetDocumentSSchema (doc);
6961: elType.ElTypeNum = HTML_EL_ANY_TYPE;
6962: }
6963: else
6964: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c,
6965: &level, doc);
6966: }
6967: if (i == 0)
1.340 quint 6968: /* rightmost part of the selector */
1.327 vatton 6969: {
6970: if (elType.ElSSchema == NULL)
6971: {
1.340 quint 6972: /* element name not found. Search in all loaded schemas */
1.355 quint 6973: if (names[i])
6974: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.327 vatton 6975: if (elType.ElSSchema)
6976: {
6977: /* the element type concerns an imported nature */
6978: schemaName = TtaGetSSchemaName(elType.ElSSchema);
6979: if (!strcmp (schemaName, "HTML"))
6980: {
6981: if (xmlType == XHTML_TYPE &&
6982: DocumentMeta[doc] && DocumentMeta[doc]->xmlformat)
6983: /* the selector was found but the case is not correct */
6984: elType.ElSSchema = NULL;
6985: else
6986: xmlType = XHTML_TYPE;
6987: }
6988: else if (!strcmp (schemaName, "MathML"))
6989: xmlType = MATH_TYPE;
6990: else if (!strcmp (schemaName, "SVG"))
6991: xmlType = SVG_TYPE;
6992: else if (!strcmp (schemaName, "XLink"))
6993: xmlType = XLINK_TYPE;
6994: else if (!strcmp (schemaName, "Annot"))
6995: xmlType = ANNOT_TYPE;
6996: else
6997: xmlType = XML_TYPE;
6998: }
1.118 vatton 6999: #ifdef XML_GENERIC
1.327 vatton 7000: else if (xmlType == XML_TYPE)
7001: {
7002: /* Creation of a new element type in the main schema */
7003: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7004: if (names[i])
7005: TtaAppendXmlElement (names[i], &elType, &mappedName,
7006: doc);
1.327 vatton 7007: }
1.118 vatton 7008: #endif /* XML_GENERIC */
1.327 vatton 7009: else
7010: {
7011: if (xmlType != XHTML_TYPE)
7012: {
7013: MapXMLElementType (XHTML_TYPE, names[i], &elType,
7014: &mappedName, &c, &level, doc);
7015: if (elType.ElSSchema)
7016: elType.ElSSchema = GetXHTMLSSchema (doc);
7017: }
7018: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
7019: {
7020: MapXMLElementType (MATH_TYPE, names[i], &elType,
7021: &mappedName, &c, &level, doc);
7022: if (elType.ElSSchema)
7023: elType.ElSSchema = GetMathMLSSchema (doc);
7024: }
7025: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
7026: {
7027: MapXMLElementType (SVG_TYPE, names[i], &elType,
7028: &mappedName, &c, &level, doc);
7029: if (elType.ElSSchema)
7030: elType.ElSSchema = GetSVGSSchema (doc);
7031: }
7032: }
7033: }
7034:
7035: if (elType.ElSSchema == NULL)
7036: /* cannot apply these CSS rules */
7037: DoApply = FALSE;
7038: else
7039: {
1.340 quint 7040: /* Store the element type contained in the rightmost part of
7041: the selector */
7042: ctxt->schema = elType.ElSSchema;
1.327 vatton 7043: ctxt->type = elType.ElTypeNum;
7044: ctxt->name[0] = elType.ElTypeNum;
1.340 quint 7045: ctxt->rel[0] = RelVoid;
1.327 vatton 7046: }
7047: }
1.340 quint 7048: else
7049: /* not the rightmost part of the selector */
1.327 vatton 7050: {
1.340 quint 7051: if (elType.ElTypeNum != 0)
7052: ctxt->name[i] = elType.ElTypeNum;
7053: #ifdef XML_GENERIC
7054: else if (xmlType == XML_TYPE)
1.327 vatton 7055: {
1.340 quint 7056: TtaGetXmlElementType (names[i], &elType, NULL, doc);
7057: if (elType.ElTypeNum == 0)
1.327 vatton 7058: {
1.340 quint 7059: /* Creation of a new element type in the main schema */
7060: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7061: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.327 vatton 7062: }
1.340 quint 7063: if (elType.ElTypeNum != 0)
7064: ctxt->name[i] = elType.ElTypeNum;
1.327 vatton 7065: }
1.340 quint 7066: #endif /* XML_GENERIC */
1.327 vatton 7067: }
1.340 quint 7068: }
7069:
7070: /* store attribute information for this element */
7071: while (j < nbattrs && attrlevels[j] <= i)
7072: {
7073: if (attrnames[j] || attrnums[j])
1.327 vatton 7074: {
1.340 quint 7075: if (attrnums[j] > 0)
1.327 vatton 7076: {
1.340 quint 7077: if (attrnums[j] == ATTR_CLASS)
1.327 vatton 7078: {
1.340 quint 7079: if (xmlType == SVG_TYPE)
7080: ctxt->attrType[j] = SVG_ATTR_class;
7081: else if (xmlType == MATH_TYPE)
7082: ctxt->attrType[j] = MathML_ATTR_class;
7083: else if (xmlType == XHTML_TYPE)
7084: ctxt->attrType[j] = HTML_ATTR_Class;
1.327 vatton 7085: else
1.119 vatton 7086: #ifdef XML_GENERIC
1.340 quint 7087: ctxt->attrType[j] = XML_ATTR_class;
1.107 cvs 7088: #else /* XML_GENERIC */
1.340 quint 7089: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 7090: #endif /* XML_GENERIC */
1.340 quint 7091: }
7092: else if (attrnums[j] == ATTR_PSEUDO)
7093: {
7094: if (xmlType == SVG_TYPE)
7095: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
7096: else if (xmlType == MATH_TYPE)
7097: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
7098: else if (xmlType == XHTML_TYPE)
7099: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
7100: else
1.119 vatton 7101: #ifdef XML_GENERIC
1.340 quint 7102: ctxt->attrType[j] = XML_ATTR_PseudoClass;
1.107 cvs 7103: #else /* XML_GENERIC */
1.340 quint 7104: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 7105: #endif /* XML_GENERIC */
1.340 quint 7106: }
7107: else if (attrnums[j] == ATTR_ID)
7108: {
7109: if (xmlType == SVG_TYPE)
7110: ctxt->attrType[j] = SVG_ATTR_id;
7111: else if (xmlType == MATH_TYPE)
7112: ctxt->attrType[j] = MathML_ATTR_id;
7113: else if (xmlType == XHTML_TYPE)
7114: ctxt->attrType[j] = HTML_ATTR_ID;
7115: else
1.119 vatton 7116: #ifdef XML_GENERIC
1.340 quint 7117: ctxt->attrType[j] = XML_ATTR_xmlid;
1.107 cvs 7118: #else /* XML_GENERIC */
1.340 quint 7119: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 7120: #endif /* XML_GENERIC */
1.340 quint 7121: }
7122: attrType.AttrTypeNum = ctxt->attrType[j];
7123: attrType.AttrSSchema = ctxt->schema;
7124: }
7125: else if (attrnames[j])
7126: {
7127: if (xmlType == XML_TYPE)
7128: {
7129: if (ctxt->schema)
7130: attrType.AttrSSchema = ctxt->schema;
7131: else
7132: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7133: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7134: att = attrType.AttrTypeNum;
7135: if (ctxt->schema == NULL && att != 0)
7136: ctxt->schema = attrType.AttrSSchema;
7137: }
7138: else
7139: {
7140: MapXMLAttribute (xmlType, attrnames[j], names[i], &level,
7141: doc, &att);
7142: if (ctxt->schema == NULL && att != 0)
7143: ctxt->schema = TtaGetDocumentSSchema (doc);
7144: }
7145: if (att == 0 && ctxt->schema == NULL)
7146: /* Attribute name not found: Search in the list of all
7147: schemas loaded for this document */
7148: {
7149: attrType.AttrSSchema = NULL;
7150: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7151: att = attrType.AttrTypeNum;
7152: if (att != 0)
7153: ctxt->schema = attrType.AttrSSchema;
7154: }
7155: attrType.AttrSSchema = ctxt->schema;
7156: attrType.AttrTypeNum = att;
7157: if (i == 0 && att == 0 && ctxt->schema == NULL)
7158: {
7159: /* Not found -> search in the list of loaded schemas */
7160: attrType.AttrSSchema = NULL;
7161: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7162: att = attrType.AttrTypeNum;
7163: if (attrType.AttrSSchema)
7164: /* the element type concerns an imported nature */
7165: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
1.119 vatton 7166: #ifdef XML_GENERIC
1.340 quint 7167: else if (xmlType == XML_TYPE)
7168: {
7169: /* The attribute is not yet present in the tree */
7170: /* Create a new global attribute */
7171: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7172: TtaAppendXmlAttribute (attrnames[j], &attrType, doc);
7173: }
7174: #endif /* XML_GENERIC */
7175: if (attrType.AttrSSchema == NULL)
7176: /* cannot apply these CSS rules */
7177: DoApply = FALSE;
7178: else if (elType.ElSSchema)
7179: ctxt->schema = elType.ElSSchema;
7180: else
7181: ctxt->schema = attrType.AttrSSchema;
7182: }
7183: if (att == 0)
7184: {
7185: CSSPrintError ("Unknown attribute", attrnames[j]);
7186: DoApply = FALSE;
7187: }
7188: else
1.345 quint 7189: {
7190: ctxt->attrType[j] = att;
7191: if (att == DummyAttribute && !strcmp (schemaName,"HTML"))
7192: /* it's the "type" attribute for an "input" element.
7193: In the tree, it is represented by the element type,
7194: not by an attribute */
7195: {
7196: ctxt->attrType[j] = 0;
7197: if (attrvals[j] && attrmatch[i] == Txtmatch)
7198: /* a value is specified for attribute type. This
7199: value provides the Thot element type */
7200: {
7201: MapXMLAttributeValue (xmlType, attrvals[j],
7202: &attrType, &kind);
7203: /* attrType contains the element type */
7204: if (i == 0)
7205: ctxt->type = kind;
7206: ctxt->name[i] = kind;
7207: }
7208: }
7209: }
1.340 quint 7210: }
7211: if (ctxt->attrType[j])
1.327 vatton 7212: {
1.340 quint 7213: /* check the attribute type */
7214: if (!strcmp (schemaName, "HTML"))
7215: xmlType = XHTML_TYPE;
7216: else if (!strcmp (schemaName, "MathML"))
7217: xmlType = MATH_TYPE;
7218: else if (!strcmp (schemaName, "SVG"))
7219: xmlType = SVG_TYPE;
7220: else if (!strcmp (schemaName, "XLink"))
7221: xmlType = XLINK_TYPE;
7222: else if (!strcmp (schemaName, "Annot"))
7223: xmlType = ANNOT_TYPE;
7224: else
7225: xmlType = XML_TYPE;
7226: kind = TtaGetAttributeKind (attrType);
7227: if (kind == 0 && attrvals[j])
7228: {
7229: /* enumerated value */
7230: MapXMLAttributeValue (xmlType, attrvals[j], &attrType,
7231: &kind);
7232: /* store the attribute value */
7233: ctxt->attrText[j] = (char *) kind;
7234: }
7235: else
7236: ctxt->attrText[j] = attrvals[j];
7237: /* update attrLevel */
7238: ctxt->attrMatch[j] = attrmatch[j];
7239: ctxt->attrLevel[j] = attrlevels[j];
7240: }
7241: j++;
1.327 vatton 7242: }
7243: }
1.340 quint 7244: /* add a new entry */
1.25 cvs 7245: i++;
1.119 vatton 7246: if (i == 1 && ctxt->schema == NULL)
1.327 vatton 7247: /* use the document schema */
7248: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 7249: }
1.340 quint 7250:
1.312 quint 7251: ctxt->important = FALSE;
1.117 vatton 7252: /* set the selector specificity */
7253: ctxt->cssSpecificity = specificity;
1.25 cvs 7254: /* Get the schema name of the main element */
1.119 vatton 7255: schemaName = TtaGetSSchemaName (ctxt->schema);
7256: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 7257: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.217 vatton 7258: skippedNL = NewLineSkipped;
1.380 vatton 7259: if (DoApply && tsch && cssRule)
1.317 vatton 7260: {
7261: if (css)
1.327 vatton 7262: {
7263: /* point the right URL for loaded images */
7264: saveURL = css->url;
7265: css->url = url;
7266: }
1.317 vatton 7267: else
1.327 vatton 7268: saveURL = NULL;
7269: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.317 vatton 7270: if (css)
1.327 vatton 7271: /* restore previous url */
7272: css->url = saveURL;
1.317 vatton 7273: }
1.116 vatton 7274: /* future CSS rules should apply */
7275: DoApply = TRUE;
1.217 vatton 7276: if (selector)
7277: NewLineSkipped = skippedNL;
1.1 cvs 7278: return (selector);
7279: }
7280:
7281: /*----------------------------------------------------------------------
1.206 vatton 7282: ParseStyleDeclaration: parse a style declaration stored in the style
7283: element of a document
7284: We expect the style string to be of the form:
7285: .pinky, .awful { color: pink; font-family: helvetica }
1.231 vatton 7286: The parameter css points to the current CSS context.
7287: The parameter link points to the link element.
7288: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 7289: ----------------------------------------------------------------------*/
1.206 vatton 7290: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
1.327 vatton 7291: CSSInfoPtr css, Element link, char *url,
7292: ThotBool destroy)
1.1 cvs 7293: {
1.79 cvs 7294: GenericContext ctxt;
7295: char *decl_end;
7296: char *sel_end;
7297: char *selector;
1.1 cvs 7298:
7299: /* separate the selectors string */
1.82 cvs 7300: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 7301: decl_end = cssRule;
1.82 cvs 7302: while (*decl_end != EOS && *decl_end != '{')
1.286 quint 7303: {
7304: if (*decl_end == EOL)
1.327 vatton 7305: NewLineSkipped++;
1.286 quint 7306: decl_end++;
7307: }
1.82 cvs 7308: if (*decl_end == EOS)
1.86 cvs 7309: {
1.168 vatton 7310: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 7311: return;
7312: }
1.1 cvs 7313: /* verify and clean the selector string */
7314: sel_end = decl_end - 1;
1.82 cvs 7315: while (*sel_end == SPACE || *sel_end == BSPACE ||
1.327 vatton 7316: *sel_end == EOL || *sel_end == CR)
1.1 cvs 7317: sel_end--;
7318: sel_end++;
1.82 cvs 7319: *sel_end = EOS;
1.1 cvs 7320: selector = cssRule;
7321:
7322: /* now, deal with the content ... */
7323: decl_end++;
7324: cssRule = decl_end;
1.137 vatton 7325: decl_end = &cssRule[strlen (cssRule) - 1];
7326: if (*decl_end != '{')
7327: *decl_end = EOS;
1.1 cvs 7328: /*
7329: * parse the style attribute string and install the corresponding
7330: * presentation attributes on the new element
7331: */
7332: ctxt = TtaGetGenericStyleContext (doc);
7333: if (ctxt == NULL)
7334: return;
7335: ctxt->destroy = destroy;
1.207 vatton 7336: /* first use of the context */
7337: ctxt->uses = 1;
1.197 vatton 7338: while (selector && *selector != EOS)
1.363 vatton 7339: {
7340: if (ctxt->uses > 1)
7341: {
7342: /* this context is waiting for a callback */
7343: ctxt = TtaGetGenericStyleContext (doc);
7344: if (ctxt == NULL)
7345: return;
7346: ctxt->destroy = destroy;
7347: /* first use of the context */
7348: ctxt->uses = 1;
7349: }
7350: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css,
7351: link, url);
7352: }
1.207 vatton 7353: /* check if the context can be freed */
7354: ctxt->uses -= 1;
7355: if (ctxt->uses == 0)
7356: /* no image loading */
7357: TtaFreeMemory (ctxt);
1.1 cvs 7358: }
7359:
7360: /************************************************************************
7361: * *
7362: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
7363: * *
7364: ************************************************************************/
7365:
7366: /*----------------------------------------------------------------------
1.327 vatton 7367: IsImplicitClassName: return wether the Class name is an
7368: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
7369: or an HTML context name.
1.1 cvs 7370: ----------------------------------------------------------------------*/
1.248 gully 7371: int IsImplicitClassName (char *class_, Document doc)
1.1 cvs 7372: {
1.327 vatton 7373: char name[200];
7374: char *cur = name;
7375: char *first;
7376: char save;
7377: SSchema schema;
7378:
7379: /* make a local copy */
7380: strncpy (name, class_, 199);
7381: name[199] = 0;
7382:
7383: /* loop looking if each word is a GI */
7384: while (*cur != 0)
7385: {
7386: first = cur;
7387: cur = SkipWord (cur);
7388: save = *cur;
7389: *cur = 0;
7390: schema = NULL;
7391: if (MapGI (first, &schema, doc) == -1)
7392: {
7393: return (0);
7394: }
7395: *cur = save;
7396: cur = SkipBlanksAndComments (cur);
7397: }
7398: return (1);
1.1 cvs 7399: }
7400:
7401: /************************************************************************
1.114 quint 7402: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 7403: ************************************************************************/
7404:
7405: /*----------------------------------------------------------------------
1.327 vatton 7406: HTMLSetBackgroundColor:
1.1 cvs 7407: ----------------------------------------------------------------------*/
1.264 vatton 7408: void HTMLSetBackgroundColor (Document doc, Element el, int specificity,
1.327 vatton 7409: char *color)
1.1 cvs 7410: {
1.350 vatton 7411: char css_command[1000];
1.1 cvs 7412:
1.327 vatton 7413: sprintf (css_command, "background-color: %s", color);
7414: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7415: }
7416:
7417: /*----------------------------------------------------------------------
1.327 vatton 7418: HTMLSetForegroundColor:
1.1 cvs 7419: ----------------------------------------------------------------------*/
1.264 vatton 7420: void HTMLSetForegroundColor (Document doc, Element el, int specificity,
1.327 vatton 7421: char *color)
1.1 cvs 7422: {
1.350 vatton 7423: char css_command[1000];
1.1 cvs 7424:
1.327 vatton 7425: sprintf (css_command, "color: %s", color);
7426: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7427: }
7428:
7429: /*----------------------------------------------------------------------
1.327 vatton 7430: HTMLResetBackgroundColor:
1.1 cvs 7431: ----------------------------------------------------------------------*/
1.97 vatton 7432: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 7433: {
1.350 vatton 7434: char css_command[1000];
1.1 cvs 7435:
1.327 vatton 7436: sprintf (css_command, "background: red");
7437: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7438: }
7439:
7440: /*----------------------------------------------------------------------
1.327 vatton 7441: HTMLResetBackgroundImage:
1.1 cvs 7442: ----------------------------------------------------------------------*/
1.97 vatton 7443: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 7444: {
1.327 vatton 7445: char css_command[1000];
1.1 cvs 7446:
1.327 vatton 7447: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
7448: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7449: }
7450:
7451: /*----------------------------------------------------------------------
1.327 vatton 7452: HTMLResetForegroundColor:
1.1 cvs 7453: ----------------------------------------------------------------------*/
1.97 vatton 7454: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 7455: {
1.350 vatton 7456: char css_command[1000];
1.1 cvs 7457:
1.327 vatton 7458: /* it's not necessary to well know the current color but it must be valid */
7459: sprintf (css_command, "color: red");
7460: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7461: }
7462:
7463: /*----------------------------------------------------------------------
1.327 vatton 7464: HTMLSetAlinkColor:
1.1 cvs 7465: ----------------------------------------------------------------------*/
1.208 vatton 7466: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 7467: {
1.350 vatton 7468: char css_command[1000];
1.1 cvs 7469:
1.327 vatton 7470: sprintf (css_command, ":link { color: %s }", color);
7471: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7472: }
7473:
7474: /*----------------------------------------------------------------------
1.327 vatton 7475: HTMLSetAactiveColor:
1.1 cvs 7476: ----------------------------------------------------------------------*/
1.208 vatton 7477: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 7478: {
1.350 vatton 7479: char css_command[1000];
1.1 cvs 7480:
1.327 vatton 7481: sprintf (css_command, ":active { color: %s }", color);
7482: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7483: }
7484:
7485: /*----------------------------------------------------------------------
1.327 vatton 7486: HTMLSetAvisitedColor:
1.1 cvs 7487: ----------------------------------------------------------------------*/
1.208 vatton 7488: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 7489: {
1.350 vatton 7490: char css_command[1000];
1.1 cvs 7491:
1.327 vatton 7492: sprintf (css_command, ":visited { color: %s }", color);
7493: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7494: }
7495:
7496: /*----------------------------------------------------------------------
1.327 vatton 7497: HTMLResetAlinkColor:
1.1 cvs 7498: ----------------------------------------------------------------------*/
1.208 vatton 7499: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 7500: {
1.350 vatton 7501: char css_command[1000];
1.1 cvs 7502:
1.327 vatton 7503: sprintf (css_command, ":link { color: red }");
7504: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7505: }
7506:
7507: /*----------------------------------------------------------------------
1.327 vatton 7508: HTMLResetAactiveColor:
1.1 cvs 7509: ----------------------------------------------------------------------*/
1.208 vatton 7510: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 7511: {
1.350 vatton 7512: char css_command[1000];
1.1 cvs 7513:
1.327 vatton 7514: sprintf (css_command, ":active { color: red }");
7515: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7516: }
7517:
7518: /*----------------------------------------------------------------------
1.327 vatton 7519: HTMLResetAvisitedColor:
1.1 cvs 7520: ----------------------------------------------------------------------*/
1.208 vatton 7521: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 7522: {
1.350 vatton 7523: char css_command[1000];
1.1 cvs 7524:
1.327 vatton 7525: sprintf (css_command, ":visited { color: red }");
7526: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7527: }
7528:
7529: /*----------------------------------------------------------------------
1.206 vatton 7530: ApplyCSSRules: parse a CSS Style description stored in the header of
7531: a HTML document.
1.1 cvs 7532: ----------------------------------------------------------------------*/
1.79 cvs 7533: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 7534: {
1.206 vatton 7535: CSSInfoPtr css;
7536: PInfoPtr pInfo;
1.207 vatton 7537: ThotBool loadcss;
7538:
7539: /* check if we have to load CSS */
7540: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
7541: if (!loadcss)
7542: return;
1.376 vatton 7543: LineNumber = TtaGetElementLineNumber (el);
1.206 vatton 7544: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 7545: if (css == NULL)
1.209 vatton 7546: {
7547: /* create the document css context */
7548: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
7549: pInfo = css->infos[doc];
7550: }
1.206 vatton 7551: else if (pInfo == NULL)
7552: /* create the entry into the css context */
7553: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 7554: if (pInfo->PiEnabled)
1.376 vatton 7555: ParseStyleDeclaration (el, cssRule, doc, css, el, NULL, destroy);
7556: LineNumber = -1;
1.1 cvs 7557: }
7558:
7559: /*----------------------------------------------------------------------
1.327 vatton 7560: ReadCSSRules: is the front-end function called by the document parser
7561: when detecting a <style type="text/css"> indicating it's the
7562: beginning of a CSS fragment or when reading a file .css.
1.1 cvs 7563:
1.327 vatton 7564: The CSS parser has to handle <!-- ... --> constructs used to
7565: prevent prehistoric browser from displaying the CSS as a text
7566: content. It will stop on any sequence "<x" where x is different
7567: from ! and will return x as to the caller. Theorically x should
7568: be equal to / for the </style> end of style.
7569: The parameter doc gives the document tree that contains CSS information.
7570: The parameter docRef gives the document to which CSS are to be applied.
7571: This function uses the current css context or creates it. It's able
7572: to work on the given buffer or call GetNextChar to read the parsed
7573: file.
7574: The parameter url gives the URL of the parsed style sheet.
7575: The parameter numberOfLinesRead gives the number of lines already
7576: read in the file.
7577: The parameter withUndo indicates whether the changes made in the document
7578: structure and content have to be registered in the Undo queue or not.
1.1 cvs 7579: ----------------------------------------------------------------------*/
1.133 vatton 7580: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.343 vatton 7581: int numberOfLinesRead, ThotBool withUndo, Element link)
1.1 cvs 7582: {
1.6 cvs 7583: DisplayMode dispMode;
1.206 vatton 7584: CSSInfoPtr refcss = NULL;
1.321 vatton 7585: CSSmedia css_media = CSS_ALL;
1.206 vatton 7586: PInfoPtr pInfo;
1.321 vatton 7587: char c;
1.138 vatton 7588: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 7589: int index;
1.1 cvs 7590: int CSSindex;
1.327 vatton 7591: int CSScomment;
1.1 cvs 7592: int import;
1.358 quint 7593: int openBlock;
1.93 vatton 7594: int newlines;
1.358 quint 7595: int page;
1.14 cvs 7596: ThotBool HTMLcomment;
1.342 vatton 7597: ThotBool toParse, eof, quoted, s_quoted;
1.358 quint 7598: ThotBool ignore, media, lineComment;
1.234 vatton 7599: ThotBool noRule, ignoreImport, fontface;
1.1 cvs 7600:
1.327 vatton 7601: CSScomment = MAX_CSS_LENGTH;
1.1 cvs 7602: HTMLcomment = FALSE;
7603: CSSindex = 0;
7604: toParse = FALSE;
7605: noRule = FALSE;
1.234 vatton 7606: media = FALSE;
1.88 cvs 7607: ignoreImport = FALSE;
1.342 vatton 7608: ignore = lineComment = FALSE;
1.358 quint 7609: page = 0;
1.342 vatton 7610: quoted = s_quoted = FALSE;
1.234 vatton 7611: fontface = FALSE;
1.1 cvs 7612: eof = FALSE;
1.358 quint 7613: openBlock = 0;
1.234 vatton 7614: import = MAX_CSS_LENGTH;
1.82 cvs 7615: c = SPACE;
1.1 cvs 7616: index = 0;
1.134 vatton 7617: base = NULL;
1.310 vatton 7618: /* entering the CSS parsing */
1.311 vatton 7619: Style_parsing++;
1.93 vatton 7620: /* number of new lines parsed */
7621: newlines = 0;
1.6 cvs 7622: /* avoid too many redisplay */
7623: dispMode = TtaGetDisplayMode (docRef);
7624: if (dispMode == DisplayImmediately)
7625: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 7626:
7627: /* look for the CSS context */
7628: if (css == NULL)
1.206 vatton 7629: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 7630: else
7631: pInfo = css->infos[docRef];
1.18 cvs 7632: if (css == NULL)
1.206 vatton 7633: {
7634: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
7635: pInfo = css->infos[docRef];
7636: }
7637: else if (pInfo == NULL)
7638: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 7639: /* look for the CSS descriptor that points to the extension schema */
7640: refcss = css;
1.224 vatton 7641: if (pInfo && pInfo->PiCategory == CSS_IMPORT)
1.173 cvs 7642: {
1.206 vatton 7643: while (refcss &&
1.327 vatton 7644: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
7645: refcss = refcss->NextCSS;
1.206 vatton 7646: if (refcss)
1.327 vatton 7647: pInfo = refcss->infos[docRef];
1.173 cvs 7648: }
7649:
1.343 vatton 7650: /* register parsed CSS file and the document to which CSS are to be applied */
1.86 cvs 7651: ParsedDoc = docRef;
1.343 vatton 7652: /* clean up the list of classes */
7653: TtaFreeMemory (refcss->class_list);
7654: refcss->class_list = NULL;
1.133 vatton 7655: if (url)
1.348 vatton 7656: Error_DocURL = url;
1.86 cvs 7657: else
7658: /* the CSS source in within the document itself */
1.348 vatton 7659: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 7660: LineNumber = numberOfLinesRead + 1;
1.93 vatton 7661: NewLineSkipped = 0;
1.217 vatton 7662: newlines = 0;
1.82 cvs 7663: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
7664: {
7665: c = buffer[index++];
7666: eof = (c == EOS);
7667: CSSbuffer[CSSindex] = c;
1.342 vatton 7668: if (!lineComment &&
7669: (CSScomment == MAX_CSS_LENGTH || c == '*' || c == '/' || c == '<' || c == EOL))
1.327 vatton 7670: {
7671: /* we're not within a comment or we're parsing * or / */
7672: switch (c)
7673: {
7674: case '@': /* perhaps an import primitive */
1.342 vatton 7675: if (!fontface && !page && !quoted && !s_quoted)
1.327 vatton 7676: import = CSSindex;
7677: break;
7678: case ';':
1.342 vatton 7679: if (!quoted && !s_quoted && !media && import != MAX_CSS_LENGTH)
1.327 vatton 7680: {
7681: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
7682: /* it's not an import */
7683: import = MAX_CSS_LENGTH;
7684: /* save the text */
7685: noRule = TRUE;
7686: }
7687: break;
7688: case '*':
1.342 vatton 7689: if (!quoted && !s_quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.327 vatton 7690: CSSbuffer[CSSindex - 1] == '/')
7691: /* start a comment */
7692: CSScomment = CSSindex - 1;
7693: break;
7694: case '/':
1.342 vatton 7695: if (!quoted && !s_quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.327 vatton 7696: CSSbuffer[CSSindex - 1] == '*')
7697: {
7698: while (CSSindex > 0 && CSSindex >= CSScomment)
7699: {
7700: if ( CSSbuffer[CSSindex] == EOL)
7701: {
7702: LineNumber ++;
7703: newlines --;
7704: }
7705: CSSindex--;
7706: }
7707: CSSindex = CSScomment - 1; /* will be incremented later */
7708: CSScomment = MAX_CSS_LENGTH;
7709: /* clean up the buffer */
7710: if (newlines && CSSindex > 0)
7711: while (CSSindex > 0 &&
7712: (CSSbuffer[CSSindex] == SPACE ||
7713: CSSbuffer[CSSindex] == BSPACE ||
7714: CSSbuffer[CSSindex] == EOL ||
7715: CSSbuffer[CSSindex] == TAB ||
7716: CSSbuffer[CSSindex] == __CR__))
7717: {
7718: if ( CSSbuffer[CSSindex] == EOL)
7719: {
7720: LineNumber ++;
7721: newlines --;
7722: }
7723: CSSindex--;
7724: }
7725: }
1.342 vatton 7726: else if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7727: CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
7728: CSSbuffer[CSSindex - 1] == '<')
7729: {
7730: /* this is the closing tag ! */
7731: CSSindex -= 2; /* remove </ from the CSS string */
7732: noRule = TRUE;
1.342 vatton 7733: }
7734: else if (!quoted && !s_quoted &&
7735: (CSSindex == 1 || (CSSindex > 1 && CSSbuffer[CSSindex - 2] == EOL)) &&
7736: CSScomment == MAX_CSS_LENGTH &&
7737: CSSbuffer[CSSindex - 1] == '/')
7738: {
7739: CSSindex--;
7740: lineComment = TRUE;
7741: }
7742:
1.327 vatton 7743: break;
7744: case '<':
1.342 vatton 7745: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7746: CSScomment == MAX_CSS_LENGTH)
7747: {
7748: /* only if we're not parsing a comment */
7749: c = buffer[index++];
7750: eof = (c == EOS);
7751: if (c == '!')
7752: {
7753: /* CSS within an HTML comment */
7754: HTMLcomment = TRUE;
7755: CSSindex++;
7756: CSSbuffer[CSSindex] = c;
7757: }
7758: else if (c == EOS)
7759: CSSindex++;
7760: }
7761: break;
7762: case '-':
1.342 vatton 7763: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7764: CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
7765: HTMLcomment)
7766: /* CSS within an HTML comment */
7767: noRule = TRUE;
7768: break;
7769: case '>':
1.342 vatton 7770: if (!fontface && !page && !quoted && !s_quoted && HTMLcomment)
1.327 vatton 7771: noRule = TRUE;
7772: break;
7773: case ' ':
1.358 quint 7774: if (!quoted && !s_quoted && import != MAX_CSS_LENGTH && openBlock == 0)
1.327 vatton 7775: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
7776: break;
7777: case '{':
1.342 vatton 7778: if (!quoted && !s_quoted)
1.327 vatton 7779: {
1.358 quint 7780: openBlock++;
1.327 vatton 7781: if (import != MAX_CSS_LENGTH)
7782: {
1.358 quint 7783: if (openBlock == 1 && media)
1.327 vatton 7784: {
7785: /* is it the screen concerned? */
7786: CSSbuffer[CSSindex+1] = EOS;
7787: css_media = CheckMediaCSS (&CSSbuffer[import+7]);
7788: if (TtaIsPrinting ())
7789: ignore = (css_media != CSS_ALL && css_media != CSS_PRINT);
7790: else
7791: ignore = (css_media != CSS_ALL && css_media != CSS_SCREEN);
7792: noRule = TRUE;
7793: }
7794: else if (!strncasecmp (&CSSbuffer[import+1], "page", 4))
1.358 quint 7795: /* it is a @page block */
1.327 vatton 7796: {
1.358 quint 7797: page = openBlock;/*remember the level of this block*/
1.327 vatton 7798: noRule = TRUE;
7799: }
7800: else if (!strncasecmp (&CSSbuffer[import+1], "font-face", 9))
7801: {
7802: fontface = TRUE;
7803: noRule = TRUE;
7804: }
7805: }
7806: }
7807: break;
7808: case '}':
1.342 vatton 7809: if (!quoted && !s_quoted)
1.327 vatton 7810: {
1.358 quint 7811: if (page == openBlock)
7812: /* closing the @page block */
1.327 vatton 7813: {
7814: noRule = TRUE;
1.358 quint 7815: page = 0; /* close the page section */
1.327 vatton 7816: }
7817: else if (fontface)
7818: {
7819: noRule = TRUE;
7820: fontface = FALSE; /* close the fontface section */
7821: }
1.358 quint 7822: else if (openBlock == 1 && import != MAX_CSS_LENGTH)
1.327 vatton 7823: {
7824: import = MAX_CSS_LENGTH;
7825: noRule = TRUE;
7826: ignore = FALSE;
7827: media = FALSE;
7828: }
1.358 quint 7829: else if (!page)
1.327 vatton 7830: toParse = TRUE;
1.358 quint 7831: openBlock--;
1.327 vatton 7832: }
7833: break;
7834: case '"':
7835: if (quoted)
7836: {
1.342 vatton 7837: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
1.327 vatton 7838: quoted = FALSE;
7839: }
1.342 vatton 7840: else if (!s_quoted)
1.327 vatton 7841: quoted = TRUE;
7842: break;
1.342 vatton 7843: case '\'':
7844: if (s_quoted)
7845: {
7846: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
7847: s_quoted = FALSE;
7848: }
7849: else if (!quoted)
7850: s_quoted = TRUE;
7851: break;
7852: default:
1.327 vatton 7853: if (c == EOL)
7854: {
7855: newlines++;
7856: }
7857: break;
7858: }
1.82 cvs 7859: }
1.93 vatton 7860: else if (c == EOL)
1.327 vatton 7861: {
7862: LineNumber++;
1.342 vatton 7863: lineComment = FALSE;
1.327 vatton 7864: c = CR;
7865: }
1.234 vatton 7866:
1.342 vatton 7867: if (!lineComment && c != CR)
1.327 vatton 7868: CSSindex++;
1.82 cvs 7869:
7870: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
1.327 vatton 7871: /* we're still parsing a comment: remove the text comment */
7872: CSSindex = CSScomment;
1.82 cvs 7873:
7874: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
1.327 vatton 7875: {
7876: CSSbuffer[CSSindex] = EOS;
7877: /* parse a not empty string */
7878: if (CSSindex > 0)
7879: {
1.50 cvs 7880: /* apply CSS rule if it's not just a saving of text */
1.234 vatton 7881: if (!noRule && !ignore)
1.327 vatton 7882: {
7883: /* future import rules must be ignored */
7884: ignoreImport = TRUE;
7885: NewLineSkipped = 0;
7886: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
7887: pInfo->PiLink, url, FALSE);
7888: LineNumber += newlines;
7889: newlines = 0;
7890: }
1.82 cvs 7891: else if (import != MAX_CSS_LENGTH &&
1.327 vatton 7892: !strncasecmp (&CSSbuffer[import+1], "import", 6))
7893: {
7894: /* import section */
7895: cssRule = &CSSbuffer[import+7];
7896: cssRule = TtaSkipBlanks (cssRule);
7897: /* save the current line number */
7898: newlines += LineNumber;
7899: if (!strncasecmp (cssRule, "url", 3))
7900: {
1.50 cvs 7901: cssRule = &cssRule[3];
1.82 cvs 7902: cssRule = TtaSkipBlanks (cssRule);
7903: if (*cssRule == '(')
1.327 vatton 7904: {
7905: cssRule++;
7906: cssRule = TtaSkipBlanks (cssRule);
7907: quoted = (*cssRule == '"' || *cssRule == '\'');
7908: if (quoted)
7909: cssRule++;
7910: base = cssRule;
7911: while (*cssRule != EOS && *cssRule != ')')
7912: cssRule++;
7913: if (quoted)
7914: {
7915: /* isolate the file name */
7916: cssRule[-1] = EOS;
7917: quoted = FALSE;
7918: }
7919: else
7920: {
7921: /* remove extra spaces */
7922: if (cssRule[-1] == SPACE)
7923: {
7924: *cssRule = SPACE;
7925: cssRule--;
7926: while (cssRule[-1] == SPACE)
7927: cssRule--;
7928: }
7929: }
7930: *cssRule = EOS;
7931: }
7932: }
7933: else if (*cssRule == '"')
7934: {
7935: /*
7936: Do we have to accept single quotes?
7937: Double quotes are accepted here.
7938: Escaped quotes are not handled. See function SkipQuotedString
7939: */
7940: cssRule++;
7941: cssRule = TtaSkipBlanks (cssRule);
7942: base = cssRule;
7943: while (*cssRule != EOS &&
7944: (*cssRule != '"' ||
7945: (*cssRule == '"' && cssRule[-1] == '\\')))
7946: cssRule++;
7947: /* isolate the file name */
7948: *cssRule = EOS;
7949: }
7950: /* check if a media is defined */
7951: cssRule++;
7952: cssRule = TtaSkipBlanks (cssRule);
7953: if (*cssRule != ';')
7954: {
7955: css_media = CheckMediaCSS (cssRule);
7956: if (TtaIsPrinting ())
7957: ignoreImport = (css_media != CSS_ALL && css_media != CSS_PRINT);
7958: else
7959: ignoreImport = (css_media != CSS_ALL && css_media != CSS_SCREEN);
7960: }
7961: if (!ignoreImport)
7962: {
7963: /* save the displayed URL when an error is reported */
1.348 vatton 7964: saveDocURL = Error_DocURL;
1.327 vatton 7965: ptr = TtaStrdup (base);
7966: /* get the CSS URI in UTF-8 */
7967: /*ptr = ReallocUTF8String (ptr, docRef);*/
7968: LoadStyleSheet (base, docRef, (Element) css, css,
7969: url, pInfo->PiMedia,
7970: pInfo->PiCategory == CSS_USER_STYLE);
7971: /* restore the displayed URL when an error is reported */
1.348 vatton 7972: Error_DocURL = saveDocURL;
1.327 vatton 7973: TtaFreeMemory (ptr);
7974: }
7975: /* restore the number of lines */
7976: LineNumber = newlines;
7977: newlines = 0;
7978: NewLineSkipped = 0;
7979: import = MAX_CSS_LENGTH;
7980: }
7981: else
7982: {
7983: LineNumber += newlines;
7984: newlines = 0;
7985: }
7986: }
7987: toParse = FALSE;
7988: noRule = FALSE;
7989: CSSindex = 0;
1.50 cvs 7990: }
1.82 cvs 7991: }
1.310 vatton 7992: /* closing the CSS parsing */
1.311 vatton 7993: Style_parsing--;
1.330 cvs 7994: if (RedisplayImages == 0 && RedisplayBGImage && Style_parsing == 0)
1.310 vatton 7995: {
1.311 vatton 7996: /* CSS parsing finishes after a BG image was loaded */
1.310 vatton 7997: RedisplayBGImage = FALSE;
1.330 cvs 7998: if (dispMode != NoComputedDisplay)
7999: {
8000: RedisplayDoc = 0;
8001: //printf ("ReadCSS Show BGimages\n");
8002: TtaSetDisplayMode (docRef, NoComputedDisplay);
8003: TtaSetDisplayMode (docRef, dispMode);
8004: }
1.310 vatton 8005: }
1.330 cvs 8006: else if (dispMode != NoComputedDisplay)
1.311 vatton 8007: /* restore the display mode */
8008: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 8009:
8010: /* Prepare the context for style attributes */
1.348 vatton 8011: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 8012: LineNumber = -1;
1.1 cvs 8013: return (c);
8014: }
Webmaster