Annotation of Amaya/amaya/styleparser.c, revision 1.401
1.1 cvs 1: /*
2: *
1.394 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2008
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 Style_parsing = 0; /* > 0 when parsing a set of CSS rules */
1.360 vatton 73: static char *ImportantPos = NULL;
1.310 vatton 74: static ThotBool RedisplayBGImage = FALSE; /* TRUE when a BG image is inserted */
1.116 vatton 75: static ThotBool DoApply = TRUE;
1.366 vatton 76: static ThotBool All_sides = FALSE; // TRUE when "boder valus must be displayed
77:
1.1 cvs 78:
79: /*----------------------------------------------------------------------
1.327 vatton 80: SkipWord:
1.1 cvs 81: ----------------------------------------------------------------------*/
1.79 cvs 82: static char *SkipWord (char *ptr)
1.1 cvs 83: {
1.168 vatton 84: while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '#' || *ptr == '%')
85: ptr++;
1.1 cvs 86: return (ptr);
87: }
88:
89: /*----------------------------------------------------------------------
1.327 vatton 90: SkipBlanksAndComments:
1.13 cvs 91: ----------------------------------------------------------------------*/
1.82 cvs 92: char *SkipBlanksAndComments (char *ptr)
1.13 cvs 93: {
1.93 vatton 94: /* skip spaces */
1.155 cheyroul 95: while (*ptr == SPACE ||
1.327 vatton 96: *ptr == BSPACE ||
97: *ptr == EOL ||
98: *ptr == TAB ||
99: *ptr == __CR__)
1.93 vatton 100: {
101: if (*ptr == EOL)
1.327 vatton 102: /* increment the number of newline skipped */
103: NewLineSkipped++;
1.93 vatton 104: ptr++;
105: }
1.399 vatton 106: while (ptr[0] == '/' && ptr[1] == '*')
1.13 cvs 107: {
108: /* look for the end of the comment */
109: ptr = &ptr[2];
110: while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
1.327 vatton 111: ptr++;
1.13 cvs 112: if (ptr[0] != EOS)
1.327 vatton 113: ptr = &ptr[2];
1.93 vatton 114: /* skip spaces */
115: while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
1.327 vatton 116: *ptr == TAB || *ptr == __CR__)
117: {
118: if (*ptr == EOL)
119: /* increment the number of newline skipped */
120: NewLineSkipped++;
121: ptr++;
122: }
1.13 cvs 123: }
124: return (ptr);
125: }
126:
1.366 vatton 127:
128: /*----------------------------------------------------------------------
129: Number of values
130: ----------------------------------------------------------------------*/
131: static int NumberOfValues (char *ptr)
132: {
133: int n = 0;
134: while (*ptr != EOS && *ptr != ';' && *ptr != '}')
135: {
136: ptr = SkipBlanksAndComments (ptr);
137: n++;
138: ptr = SkipWord (ptr);
139: }
140: return n;
141: }
142:
1.49 cvs 143: /*----------------------------------------------------------------------
1.327 vatton 144: SkipQuotedString
1.1 cvs 145: ----------------------------------------------------------------------*/
1.79 cvs 146: static char *SkipQuotedString (char *ptr, char quote)
1.1 cvs 147: {
1.14 cvs 148: ThotBool stop;
1.1 cvs 149:
150: stop = FALSE;
151: while (!stop)
152: {
1.327 vatton 153: if (*ptr == quote)
154: {
155: ptr++;
156: stop = TRUE;
157: }
158: else if (*ptr == EOS)
159: stop = TRUE;
160: else if (*ptr == '\\')
161: /* escape character */
162: {
163: ptr++;
1.82 cvs 164: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
1.327 vatton 165: (*ptr >= 'a' && *ptr <= 'f'))
166: {
167: ptr++;
168: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
169: (*ptr >= 'a' && *ptr <= 'f'))
170: ptr++;
171: }
172: else
173: ptr++;
174: }
175: else
176: ptr++;
1.1 cvs 177: }
178: return (ptr);
179: }
180:
181: /*----------------------------------------------------------------------
1.327 vatton 182: CSSPrintError
183: print the error message msg on stderr.
184: When the line is 0 ask to expat the current line number
1.86 cvs 185: ----------------------------------------------------------------------*/
1.389 vatton 186: static void CSSPrintError (const char *msg, const char *value)
1.86 cvs 187: {
1.366 vatton 188: if (!DoDialog && !TtaIsPrinting () && ParsedDoc > 0)
1.86 cvs 189: {
190: if (!ErrFile)
1.327 vatton 191: {
192: if (OpenParsingErrors (ParsedDoc) == FALSE)
193: return;
194: }
1.86 cvs 195:
1.308 vatton 196: /* check if a CSS error file shoulb be updated too */
197: if (ParsedCSS > 0 && !CSSErrFile)
1.327 vatton 198: OpenParsingErrors (ParsedCSS);
1.308 vatton 199:
1.348 vatton 200: if (Error_DocURL)
1.327 vatton 201: {
1.348 vatton 202: fprintf (ErrFile, "\n*** Errors/warnings in %s\n", Error_DocURL);
1.327 vatton 203: /* set to NULL as long as the CSS file doesn't change */
1.348 vatton 204: Error_DocURL = NULL;
1.327 vatton 205: }
1.89 cvs 206: CSSErrorsFound = TRUE;
1.86 cvs 207: if (LineNumber < 0)
1.347 quint 208: {
209: if (value)
210: fprintf (ErrFile, " In style attribute, %s \"%s\"\n", msg, value);
211: else
212: fprintf (ErrFile, " In style attribute, %s\n", msg);
213: }
1.86 cvs 214: else
1.327 vatton 215: {
1.347 quint 216: if (value)
217: fprintf (ErrFile, "@ line %d: %s \"%s\"\n",
218: LineNumber+NewLineSkipped, msg, value);
219: else
220: fprintf (ErrFile, "@ line %d: %s\n", LineNumber+NewLineSkipped,
221: msg);
1.327 vatton 222: if (CSSErrFile)
1.347 quint 223: {
224: if (value)
225: fprintf (CSSErrFile, "@ line %d: %s \"%s\"\n",
226: LineNumber+NewLineSkipped, msg, value);
227: else
228: fprintf (CSSErrFile, "@ line %d: %s\n",
229: LineNumber+NewLineSkipped, msg);
230: }
1.327 vatton 231: }
1.86 cvs 232: }
233: }
234:
1.168 vatton 235: /*----------------------------------------------------------------------
1.327 vatton 236: CSSParseError
237: print the error message msg on stderr.
1.168 vatton 238: ----------------------------------------------------------------------*/
1.389 vatton 239: static void CSSParseError (const char *msg, const char *value, char *endvalue)
1.168 vatton 240: {
1.230 quint 241: char c = EOS;
1.168 vatton 242:
243: if (endvalue)
244: {
245: /* close the string here */
246: c = *endvalue;
247: *endvalue = EOS;
248: }
249: CSSPrintError (msg, value);
250: if (endvalue)
251: *endvalue = c;
252: }
253:
1.288 vatton 254: /*----------------------------------------------------------------------
1.342 vatton 255: SkipString move to the end of the string
256: ----------------------------------------------------------------------*/
257: static char *SkipString (char *ptr)
258: {
259: char c = *ptr;
260:
261: ptr++;
262: while (*ptr != EOS &&
263: (*ptr != c || (*ptr == c && ptr[-1] == '\\')))
264: ptr++;
265: return ptr;
266: }
267:
268: /*----------------------------------------------------------------------
1.327 vatton 269: CSSCheckEndValue
270: print an error message if another character is found
1.288 vatton 271: ----------------------------------------------------------------------*/
272: static char *CSSCheckEndValue (char *cssRule, char *endvalue, char *msg)
273: {
274: char c = EOS;
275: if (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.316 quint 276: *endvalue != ';' && *endvalue != '}' && *endvalue != EOL &&
277: *endvalue != TAB && *endvalue != __CR__)
1.288 vatton 278: {
279: while (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.327 vatton 280: *endvalue != ';' && *endvalue != '}' && *endvalue != EOL &&
281: *endvalue != TAB && *endvalue != __CR__)
1.342 vatton 282: {
283: if (*endvalue == '"' || *endvalue == '\'')
284: endvalue = SkipString (endvalue);
285: if (*endvalue != EOS)
286: endvalue++;
287: }
1.288 vatton 288: /* close the string here */
289: c = *endvalue;
290: *endvalue = EOS;
291: CSSPrintError (msg, cssRule);
292: *endvalue = c;
293: }
294: return endvalue;
295: }
296:
1.89 cvs 297:
1.86 cvs 298: /*----------------------------------------------------------------------
1.327 vatton 299: SkipProperty skips a property and display and error message
1.86 cvs 300: ----------------------------------------------------------------------*/
1.234 vatton 301: static char *SkipProperty (char *ptr, ThotBool reportError)
1.86 cvs 302: {
303: char *deb;
304: char c;
305:
306: deb = ptr;
1.301 vatton 307: while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '}')
1.133 vatton 308: {
1.342 vatton 309: if (*ptr == '"' || *ptr == '\'')
310: ptr = SkipString (ptr);
311: if (*ptr != EOS)
312: ptr++;
1.133 vatton 313: }
1.95 cvs 314: /* print the skipped property */
1.86 cvs 315: c = *ptr;
1.386 vatton 316: if (*ptr != EOS)
317: *ptr = EOS;
1.366 vatton 318: if (DoDialog)
319: DisplayStyleValue ("", deb, ptr);
320: else if (reportError && *deb != EOS &&
321: strncasecmp (deb, "azimuth", 7) &&
322: strncasecmp (deb, "border-collapse", 15) &&
323: strncasecmp (deb, "border-spacing", 14) &&
324: strncasecmp (deb, "caption-side", 12) &&
325: strncasecmp (deb, "clip", 4) &&
326: strncasecmp (deb, "counter-increment", 16) &&
327: strncasecmp (deb, "counter-reset", 13) &&
328: strncasecmp (deb, "cue-after", 9) &&
329: strncasecmp (deb, "cue-before", 10) &&
330: strncasecmp (deb, "cue", 3) &&
331: strncasecmp (deb, "cursor", 6) &&
332: strncasecmp (deb, "elevation", 9) &&
333: strncasecmp (deb, "empty-cells", 11) &&
334: strncasecmp (deb, "font-strech", 11) &&
335: strncasecmp (deb, "letter-spacing", 14) &&
336: strncasecmp (deb, "marker-offset", 12) &&
337: strncasecmp (deb, "orphans", 7) &&
338: strncasecmp (deb, "outline-color", 13) &&
339: strncasecmp (deb, "outline-style", 13) &&
340: strncasecmp (deb, "outline-width", 13) &&
341: strncasecmp (deb, "outline", 7) &&
342: strncasecmp (deb, "overflow", 8) &&
343: strncasecmp (deb, "pause-after", 11) &&
344: strncasecmp (deb, "pause-before", 12) &&
345: strncasecmp (deb, "pause", 5) &&
346: strncasecmp (deb, "quotes", 6) &&
347: strncasecmp (deb, "richness", 8) &&
348: strncasecmp (deb, "speech-rate", 11) &&
349: strncasecmp (deb, "speak-header", 12) &&
350: strncasecmp (deb, "speak-punctuation", 17) &&
351: strncasecmp (deb, "speak-numeral", 13) &&
352: strncasecmp (deb, "speak", 5) &&
353: strncasecmp (deb, "pitch-range", 11) &&
354: strncasecmp (deb, "pitch", 5) &&
355: strncasecmp (deb, "stress", 6) &&
356: strncasecmp (deb, "table-layout", 12) &&
357: strncasecmp (deb, "text-shadow", 11) &&
358: strncasecmp (deb, "voice-family", 12) &&
359: strncasecmp (deb, "volume", 6) &&
360: strncasecmp (deb, "widows", 6))
1.205 quint 361: CSSPrintError ("CSS property ignored:", deb);
1.386 vatton 362: if (c != EOS)
363: *ptr = c;
1.86 cvs 364: return (ptr);
365: }
366:
367: /*----------------------------------------------------------------------
1.327 vatton 368: SkipValue
369: skips the value and display an error message if msg is not NULL
1.1 cvs 370: ----------------------------------------------------------------------*/
1.168 vatton 371: static char *SkipValue (char *msg, char *ptr)
1.1 cvs 372: {
1.86 cvs 373: char *deb;
374: char c;
375:
376: deb = ptr;
1.387 quint 377: while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '\n')
1.133 vatton 378: {
1.342 vatton 379: if (*ptr == '"' || *ptr == '\'')
380: ptr = SkipString (ptr);
381: if (*ptr != EOS)
382: ptr++;
1.133 vatton 383: }
1.95 cvs 384: /* print the skipped property */
1.86 cvs 385: c = *ptr;
1.397 vatton 386: if (c != EOS)
387: *ptr = EOS;
1.168 vatton 388: if (msg && *deb != EOS && *deb != ',')
389: CSSPrintError (msg, deb);
1.397 vatton 390: if (c != EOS)
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;
1.401 ! vatton 2168: Document redisplaydoc;
! 2169: PInfoPtr pInfo = NULL;
1.302 quint 2170: CSSInfoPtr css;
2171: PresentationContext ctxt;
2172: PresentationValue image;
2173: PresentationValue value;
1.400 vatton 2174: ThotBool found;
1.302 quint 2175:
2176: callblock = (CSSImageCallbackPtr) extra;
2177: if (callblock == NULL)
2178: return;
2179:
1.400 vatton 2180: css = callblock->css;
1.302 quint 2181: el = callblock->el;
2182: tsch = callblock->tsch;
2183: ctxt = callblock->ctxt;
1.401 ! vatton 2184: redisplaydoc = ctxt->doc;
1.302 quint 2185: if (doc == 0 && !isnew)
2186: /* apply to the current document only */
1.401 ! vatton 2187: doc = redisplaydoc;
1.302 quint 2188: if (doc)
1.401 ! vatton 2189: redisplaydoc = doc;
1.302 quint 2190: else
2191: {
2192: /* check if the CSS still exists */
2193: css = CSSList;
2194: while (css && css != callblock->css)
1.327 vatton 2195: css = css->NextCSS;
1.302 quint 2196: if (css == NULL)
1.400 vatton 2197: // the presentation schema doesn't exist anymore
1.327 vatton 2198: tsch = NULL;
1.302 quint 2199: }
1.400 vatton 2200:
1.401 ! vatton 2201: if (tsch && css && ctxt && redisplaydoc)
1.400 vatton 2202: {
2203: // check if the presentation schema is still there
1.401 ! vatton 2204: pInfo = css->infos[redisplaydoc];
! 2205: if (pInfo == NULL && DocumentURLs[redisplaydoc] == NULL)
! 2206: {
! 2207: // the redisplaydoc was probably an object
! 2208: while (redisplaydoc > 0 && pInfo == 0)
! 2209: pInfo = css->infos[--redisplaydoc];
! 2210: if (redisplaydoc)
! 2211: ctxt->doc = redisplaydoc;
! 2212: }
! 2213:
1.400 vatton 2214: found = FALSE;
2215: while (!found && pInfo)
2216: {
2217: found = (pInfo->PiSchemas && tsch == pInfo->PiSchemas->PiPSchema);
2218: pInfo = pInfo->PiNext;
2219: }
2220: if (!found)
2221: tsch = NULL;
2222: }
2223:
1.302 quint 2224: if (el || tsch)
2225: {
2226: /* Ok the image was fetched */
2227: image.typed_data.unit = UNIT_REL;
2228: image.typed_data.real = FALSE;
2229: image.pointer = file;
2230: TtaSetStylePresentation (callblock->ruleType, el, tsch, ctxt, image);
2231:
2232: if (callblock->ruleType == PRBackgroundPicture)
1.327 vatton 2233: /* enforce the showbox */
2234: {
2235: value.typed_data.value = 1;
2236: value.typed_data.unit = UNIT_REL;
2237: value.typed_data.real = FALSE;
2238: TtaSetStylePresentation (PRShowBox, el, tsch, ctxt, value);
2239: }
1.302 quint 2240: /* check if the context can be freed */
2241: ctxt->uses -= 1;
2242: if (ctxt->uses == 0)
1.327 vatton 2243: /* no other image loading */
2244: TtaFreeMemory (ctxt);
1.302 quint 2245: }
2246:
2247: TtaFreeMemory (callblock);
1.330 cvs 2248: if (css)
2249: RedisplayImages--;
1.401 ! vatton 2250: if (redisplaydoc &&
! 2251: /* check if all background images are now loaded */
! 2252: (css == NULL || (pInfo && Style_parsing == 0 && RedisplayImages == 0)))
! 2253: {
! 2254: /* don't manage a document used by make book */
! 2255: if (DocumentMeta[redisplaydoc] == NULL ||
! 2256: DocumentMeta[redisplaydoc]->method != CE_MAKEBOOK)
1.327 vatton 2257: {
2258: /* Change the Display Mode to take into account the new
2259: presentation */
1.401 ! vatton 2260: dispMode = TtaGetDisplayMode (redisplaydoc);
1.313 vatton 2261: /* force the redisplay of this box */
1.401 ! vatton 2262: TtaSetDisplayMode (redisplaydoc, NoComputedDisplay);
! 2263: TtaSetDisplayMode (redisplaydoc, dispMode);
1.327 vatton 2264: }
1.330 cvs 2265: RedisplayBGImage = FALSE;
1.302 quint 2266: }
1.310 vatton 2267: else
1.328 vatton 2268: RedisplayBGImage = TRUE;
1.302 quint 2269: }
2270:
2271: /*----------------------------------------------------------------------
2272: SetCSSImage fetch the image referred by a background-image or a
2273: list-style-image property.
2274: ----------------------------------------------------------------------*/
2275: static char *SetCSSImage (Element element, PSchema tsch,
1.327 vatton 2276: PresentationContext ctxt, char *cssRule,
2277: CSSInfoPtr css, unsigned int ruleType)
1.302 quint 2278: {
2279: CSSImageCallbackPtr callblock;
2280: Element el;
1.304 cvs 2281: PresentationValue image;
1.366 vatton 2282: char *url, *ptr;
1.302 quint 2283: char *bg_image;
2284: char tempname[MAX_LENGTH];
2285: char imgname[MAX_LENGTH];
2286:
2287: if (element)
2288: el = element;
2289: else
2290: /* default element for FetchImage */
2291: el = TtaGetMainRoot (ctxt->doc);
2292: url = NULL;
1.370 vatton 2293: image.typed_data.real = FALSE;
1.302 quint 2294: cssRule = ParseCSSUrl (cssRule, &url);
1.366 vatton 2295: ptr = cssRule;
1.302 quint 2296: if (ctxt->destroy)
2297: {
2298: /* remove the background image PRule */
2299: image.pointer = NULL;
1.366 vatton 2300: TtaSetStylePresentation (ruleType, element, tsch, ctxt, image);
1.302 quint 2301: }
1.366 vatton 2302: else if (url)
1.302 quint 2303: {
1.366 vatton 2304: if (css && css->url)
2305: /* the image concerns a CSS file */
2306: NormalizeURL (url, 0, tempname, imgname, css->url);
2307: else
2308: /* the image concerns a style element */
2309: NormalizeURL (url, ctxt->doc, tempname, imgname, NULL);
2310: if (DoDialog)
2311: {
2312: if (ruleType == PRBackgroundPicture)
2313: DisplayStyleValue ("background-image", tempname, &tempname[MAX_LENGTH-1]);
2314: else if (ruleType == PRListStyleImage)
2315: DisplayStyleValue ("list-style-image", tempname, &tempname[MAX_LENGTH-1]);
2316: else if (ruleType == PRContentURL)
2317: DisplayStyleValue ("", ptr, cssRule);
2318: }
2319: else if (DoApply)
2320: {
2321: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
2322: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
2323: /* background images are enabled */
2324: {
2325: callblock = (CSSImageCallbackPtr) TtaGetMemory (sizeof (CSSImageCallbackBlock));
2326: if (callblock)
2327: {
2328: callblock->el = element;
2329: callblock->tsch = tsch;
2330: callblock->css = css;
2331: callblock->ctxt = ctxt;
2332: callblock->ruleType = ruleType;
2333: /* new use of the context */
2334: ctxt->uses += 1;
2335: /* check if the image url is related to an external CSS */
2336: if (css)
2337: {
2338: /* fetch and display background image of element */
2339: if (FetchImage (0, el, tempname, AMAYA_LOAD_IMAGE,
2340: ParseCSSImageCallback, callblock))
2341: RedisplayImages++;
2342: }
1.327 vatton 2343: else
1.366 vatton 2344: FetchImage (ctxt->doc, el, url, AMAYA_LOAD_IMAGE,
2345: ParseCSSImageCallback, callblock);
1.327 vatton 2346: }
2347: }
2348: }
1.366 vatton 2349: TtaFreeMemory (url);
1.302 quint 2350: }
2351: return (cssRule);
2352: }
2353:
2354: /*----------------------------------------------------------------------
1.327 vatton 2355: ParseACSSListStyleImage: parse a CSS list-style-image
2356: attribute string.
1.1 cvs 2357: ----------------------------------------------------------------------*/
1.318 vatton 2358: static char *ParseACSSListStyleImage (Element element, PSchema tsch,
1.327 vatton 2359: PresentationContext ctxt,
2360: char *cssRule, CSSInfoPtr css,
2361: ThotBool isHTML)
1.1 cvs 2362: {
1.288 vatton 2363: char *url;
1.366 vatton 2364: char *start_value;
1.293 quint 2365: PresentationValue pval;
1.281 quint 2366:
1.293 quint 2367: pval.typed_data.unit = UNIT_REL;
2368: pval.typed_data.real = FALSE;
1.281 quint 2369: url = NULL;
2370: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2371: start_value = cssRule;
1.281 quint 2372: if (!strncasecmp (cssRule, "none", 4))
2373: {
2374: cssRule += 4;
1.302 quint 2375: pval.typed_data.value = 0;
1.366 vatton 2376: if (DoDialog)
2377: DisplayStyleValue ("list-style-image", start_value, cssRule);
2378: else if (DoApply)
1.327 vatton 2379: TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
1.281 quint 2380: }
2381: else if (!strncasecmp (cssRule, "url", 3))
2382: {
2383: cssRule += 3;
1.302 quint 2384: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 2385: PRListStyleImage);
1.281 quint 2386: }
2387: else if (!strncasecmp (cssRule, "inherit", 7))
1.288 vatton 2388: {
2389: cssRule += 7;
1.293 quint 2390: pval.typed_data.unit = VALUE_INHERIT;
1.366 vatton 2391: if (DoDialog)
2392: DisplayStyleValue ("list-style-image", start_value, cssRule);
2393: else if (DoApply)
1.327 vatton 2394: TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
2395: }
1.281 quint 2396: else
1.295 vatton 2397: cssRule = SkipValue ("Invalid list-style-image value", cssRule);
1.1 cvs 2398: return (cssRule);
2399: }
2400:
2401: /*----------------------------------------------------------------------
1.327 vatton 2402: ParseCSSListStyleImage: parse a CSS list-style-image
2403: attribute string.
1.318 vatton 2404: ----------------------------------------------------------------------*/
2405: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1.327 vatton 2406: PresentationContext ctxt,
2407: char *cssRule, CSSInfoPtr css,
2408: ThotBool isHTML)
1.318 vatton 2409: {
2410: char *ptr = cssRule;
2411: cssRule = ParseACSSListStyleImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 2412: isHTML);
1.318 vatton 2413: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-image value");
2414: return cssRule;
2415: }
2416:
2417: /*----------------------------------------------------------------------
1.327 vatton 2418: ParseACSSListStylePosition: parse a CSS list-style-position
2419: attribute string.
1.1 cvs 2420: ----------------------------------------------------------------------*/
1.318 vatton 2421: static char *ParseACSSListStylePosition (Element element, PSchema tsch,
1.327 vatton 2422: PresentationContext context,
2423: char *cssRule, CSSInfoPtr css,
2424: ThotBool isHTML)
1.1 cvs 2425: {
1.281 quint 2426: PresentationValue pval;
1.366 vatton 2427: char *start_value;
1.281 quint 2428:
2429: pval.typed_data.unit = UNIT_REL;
2430: pval.typed_data.real = FALSE;
2431: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2432: start_value = cssRule;
1.281 quint 2433: if (!strncasecmp (cssRule, "inside", 6))
1.288 vatton 2434: {
2435: pval.typed_data.value = Inside;
2436: cssRule += 6;
2437: }
1.281 quint 2438: else if (!strncasecmp (cssRule, "outside", 7))
1.288 vatton 2439: {
2440: pval.typed_data.value = Outside;
2441: cssRule += 7;
2442: }
1.293 quint 2443: else if (!strncasecmp (cssRule, "inherit", 7))
2444: {
2445: pval.typed_data.unit = VALUE_INHERIT;
2446: cssRule += 7;
2447: }
1.281 quint 2448: else
2449: {
1.293 quint 2450: cssRule = SkipValue ("Invalid list-style-position value", cssRule);
1.281 quint 2451: return (cssRule);
2452: }
1.293 quint 2453:
1.366 vatton 2454: if (DoDialog)
2455: DisplayStyleValue ("list-style-position", start_value, cssRule);
2456: else if (DoApply)
1.295 vatton 2457: TtaSetStylePresentation (PRListStylePosition, element, tsch, context, pval);
1.327 vatton 2458: return (cssRule);
1.318 vatton 2459: }
2460:
2461: /*----------------------------------------------------------------------
1.327 vatton 2462: ParseCSSListStylePosition: parse a CSS list-style-position
2463: attribute string.
1.318 vatton 2464: ----------------------------------------------------------------------*/
2465: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
1.327 vatton 2466: PresentationContext context,
2467: char *cssRule, CSSInfoPtr css,
2468: ThotBool isHTML)
1.318 vatton 2469: {
2470: char *ptr = cssRule;
2471: cssRule = ParseACSSListStylePosition (element, tsch, context, cssRule, css,
1.327 vatton 2472: isHTML);
1.288 vatton 2473: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-position value");
1.318 vatton 2474: return cssRule;
1.1 cvs 2475: }
2476:
2477: /*----------------------------------------------------------------------
1.327 vatton 2478: ParseCSSListStyle: parse a CSS list-style value string.
1.1 cvs 2479: ----------------------------------------------------------------------*/
1.79 cvs 2480: static char *ParseCSSListStyle (Element element, PSchema tsch,
1.327 vatton 2481: PresentationContext ctxt, char *cssRule,
2482: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2483: {
1.318 vatton 2484: char *ptr = cssRule;
2485: int skippedNL;
1.281 quint 2486:
2487: cssRule = SkipBlanksAndComments (cssRule);
1.301 vatton 2488: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.281 quint 2489: {
1.316 quint 2490: skippedNL = NewLineSkipped;
1.281 quint 2491: /* perhaps a list-style-image */
2492: if (!strncasecmp (cssRule, "url", 3))
1.327 vatton 2493: cssRule = ParseACSSListStyleImage (element, tsch, ctxt, cssRule, css,
2494: isHTML);
1.281 quint 2495: /* perhaps a list-style-position */
2496: else if (!strncasecmp (cssRule, "inside", 6) ||
2497: !strncasecmp (cssRule, "outside", 7))
1.327 vatton 2498: cssRule = ParseACSSListStylePosition (element, tsch, ctxt, cssRule,
2499: css, isHTML);
1.281 quint 2500: /* perhaps a list-style-type */
2501: else if (!strncasecmp (cssRule, "disc", 4) ||
1.327 vatton 2502: !strncasecmp (cssRule, "circle", 6) ||
2503: !strncasecmp (cssRule, "square", 6) ||
2504: !strncasecmp (cssRule, "decimal", 7) ||
2505: !strncasecmp (cssRule, "decimal-leading-zero", 20) ||
2506: !strncasecmp (cssRule, "lower-roman", 11) ||
2507: !strncasecmp (cssRule, "upper-roman", 11) ||
2508: !strncasecmp (cssRule, "lower-greek", 11) ||
2509: !strncasecmp (cssRule, "lower-latin", 11) ||
2510: !strncasecmp (cssRule, "lower-alpha", 11) ||
2511: !strncasecmp (cssRule, "upper-latin", 11) ||
2512: !strncasecmp (cssRule, "upper-alpha", 11) ||
2513: !strncasecmp (cssRule, "armenian", 8) ||
2514: !strncasecmp (cssRule, "georgian", 8) ||
2515: !strncasecmp (cssRule, "none", 4) ||
2516: !strncasecmp (cssRule, "inherit", 7))
2517: cssRule = ParseACSSListStyleType (element, tsch, ctxt, cssRule, css,
2518: isHTML);
1.281 quint 2519: else
1.327 vatton 2520: {
2521: NewLineSkipped = skippedNL;
2522: /* rule not found */
2523: cssRule = SkipProperty (cssRule, FALSE);
2524: }
1.281 quint 2525: cssRule = SkipBlanksAndComments (cssRule);
2526: }
1.318 vatton 2527: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style value");
1.1 cvs 2528: return (cssRule);
2529: }
2530:
2531: /*----------------------------------------------------------------------
1.327 vatton 2532: ParseCSSTextAlign: parse a CSS text-align
2533: attribute string.
1.1 cvs 2534: ----------------------------------------------------------------------*/
1.79 cvs 2535: static char *ParseCSSTextAlign (Element element, PSchema tsch,
1.327 vatton 2536: PresentationContext context, char *cssRule,
2537: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2538: {
1.366 vatton 2539: char *ptr;
1.327 vatton 2540: PresentationValue align;
2541:
2542: align.typed_data.value = 0;
2543: align.typed_data.unit = UNIT_REL;
2544: align.typed_data.real = FALSE;
2545:
2546: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2547: ptr = cssRule;
1.327 vatton 2548: if (!strncasecmp (cssRule, "left", 4))
2549: {
2550: align.typed_data.value = AdjustLeft;
2551: cssRule += 4;
2552: }
2553: else if (!strncasecmp (cssRule, "right", 5))
2554: {
2555: align.typed_data.value = AdjustRight;
2556: cssRule += 5;
2557: }
2558: else if (!strncasecmp (cssRule, "center", 6))
2559: {
2560: align.typed_data.value = Centered;
2561: cssRule += 6;
2562: }
2563: else if (!strncasecmp (cssRule, "justify", 7))
2564: {
2565: align.typed_data.value = Justify;
2566: cssRule += 7;
2567: }
2568: else
2569: {
2570: cssRule = SkipValue ("Invalid text-align value", cssRule);
2571: return (cssRule);
2572: }
1.1 cvs 2573:
1.327 vatton 2574: /*
2575: * install the new presentation.
2576: */
1.366 vatton 2577: if (align.typed_data.value)
2578: {
2579: if (DoDialog)
2580: DisplayStyleValue ("text-align", ptr, cssRule);
2581: else if (DoApply)
2582: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
2583: }
1.327 vatton 2584: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-align value");
2585: return (cssRule);
1.1 cvs 2586: }
2587:
2588: /*----------------------------------------------------------------------
1.243 quint 2589: ParseCSSTextAnchor: parse a CSS text-anchor property (SVG property)
2590: We use the Thot Adjust PRule to represent the text-anchor property
2591: for CSS 1.0, as Adjust is not used otherwise in this context.
2592: ----------------------------------------------------------------------*/
2593: static char *ParseCSSTextAnchor (Element element, PSchema tsch,
1.327 vatton 2594: PresentationContext context, char *cssRule,
2595: CSSInfoPtr css, ThotBool isHTML)
1.243 quint 2596: {
1.327 vatton 2597: PresentationValue align;
1.366 vatton 2598: char *ptr;
1.327 vatton 2599:
2600: align.typed_data.value = 0;
2601: align.typed_data.unit = UNIT_REL;
2602: align.typed_data.real = FALSE;
1.243 quint 2603:
1.327 vatton 2604: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2605: ptr = cssRule;
1.327 vatton 2606: if (!strncasecmp (cssRule, "start", 5))
2607: {
2608: align.typed_data.value = AdjustLeft;
2609: cssRule += 5;
2610: }
2611: else if (!strncasecmp (cssRule, "middle", 6))
2612: {
2613: align.typed_data.value = Centered;
2614: cssRule += 6;
2615: }
2616: else if (!strncasecmp (cssRule, "end", 3))
2617: {
2618: align.typed_data.value = AdjustRight;
2619: cssRule += 3;
2620: }
2621: else if (!strncasecmp (cssRule, "inherit", 7))
2622: {
2623: align.typed_data.unit = VALUE_INHERIT;
2624: cssRule += 7;
2625: }
2626: else
2627: {
2628: cssRule = SkipValue ("Invalid text-anchor value", cssRule);
1.295 vatton 2629: return (cssRule);
1.327 vatton 2630: }
1.243 quint 2631:
1.327 vatton 2632: /*
2633: * install the new presentation.
2634: */
1.366 vatton 2635: if (align.typed_data.value || align.typed_data.unit == VALUE_INHERIT)
2636: {
2637: if (DoDialog)
2638: DisplayStyleValue ("text-anchor", ptr, cssRule);
2639: else if (DoApply)
2640: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
2641: }
1.327 vatton 2642: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-anchor value");
2643: return (cssRule);
1.243 quint 2644: }
2645:
2646: /*----------------------------------------------------------------------
1.327 vatton 2647: ParseCSSDirection: parse a CSS direction property
1.112 quint 2648: ----------------------------------------------------------------------*/
2649: static char *ParseCSSDirection (Element element, PSchema tsch,
1.327 vatton 2650: PresentationContext context, char *cssRule,
2651: CSSInfoPtr css, ThotBool isHTML)
1.112 quint 2652: {
1.327 vatton 2653: PresentationValue direction;
1.366 vatton 2654: char *ptr;
1.327 vatton 2655:
2656: direction.typed_data.value = 0;
2657: direction.typed_data.unit = UNIT_REL;
2658: direction.typed_data.real = FALSE;
2659:
2660: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2661: ptr = cssRule;
1.327 vatton 2662: if (!strncasecmp (cssRule, "ltr", 3))
2663: {
2664: direction.typed_data.value = LeftToRight;
2665: cssRule += 3;
2666: }
2667: else if (!strncasecmp (cssRule, "rtl", 3))
2668: {
2669: direction.typed_data.value = RightToLeft;
2670: cssRule += 3;
2671: }
2672: else if (!strncasecmp (cssRule, "inherit", 7))
2673: {
2674: direction.typed_data.unit = VALUE_INHERIT;
2675: cssRule += 7;
2676: }
2677: else
2678: {
2679: cssRule = SkipValue ("Invalid direction value", cssRule);
2680: return (cssRule);
2681: }
1.112 quint 2682:
1.327 vatton 2683: /*
2684: * install the new presentation.
2685: */
1.366 vatton 2686: if (direction.typed_data.value || direction.typed_data.unit == VALUE_INHERIT)
2687: {
2688: if (DoDialog)
2689: DisplayStyleValue ("direction", ptr, cssRule);
2690: else if (DoApply)
2691: TtaSetStylePresentation (PRDirection, element, tsch, context, direction);
2692: }
1.327 vatton 2693: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid direction value");
2694: return (cssRule);
1.112 quint 2695: }
2696:
2697: /*----------------------------------------------------------------------
1.327 vatton 2698: ParseCSSUnicodeBidi: parse a CSS unicode-bidi property
1.113 quint 2699: ----------------------------------------------------------------------*/
2700: static char *ParseCSSUnicodeBidi (Element element, PSchema tsch,
1.327 vatton 2701: PresentationContext context, char *cssRule,
2702: CSSInfoPtr css, ThotBool isHTML)
1.113 quint 2703: {
1.327 vatton 2704: PresentationValue bidi;
1.366 vatton 2705: char *ptr;
1.113 quint 2706:
1.327 vatton 2707: bidi.typed_data.value = 0;
2708: bidi.typed_data.unit = UNIT_REL;
2709: bidi.typed_data.real = FALSE;
2710:
2711: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2712: ptr = cssRule;
1.327 vatton 2713: if (!strncasecmp (cssRule, "normal", 6))
2714: {
2715: bidi.typed_data.value = Normal;
2716: cssRule += 6;
2717: }
2718: else if (!strncasecmp (cssRule, "embed", 5))
2719: {
2720: bidi.typed_data.value = Embed;
2721: cssRule += 5;
2722: }
2723: else if (!strncasecmp (cssRule, "bidi-override", 13))
2724: {
2725: bidi.typed_data.value = Override;
2726: cssRule += 13;
2727: }
2728: else if (!strncasecmp (cssRule, "inherit", 7))
2729: {
2730: bidi.typed_data.unit = VALUE_INHERIT;
2731: cssRule += 7;
2732: }
2733: else
2734: {
2735: cssRule = SkipValue ("Invalid unicode-bidi value", cssRule);
1.295 vatton 2736: return (cssRule);
1.327 vatton 2737: }
1.113 quint 2738:
1.327 vatton 2739: /*
2740: * install the new presentation.
2741: */
1.366 vatton 2742: if (bidi.typed_data.value || bidi.typed_data.unit == VALUE_INHERIT)
2743: {
2744: if (DoDialog)
2745: DisplayStyleValue ("unicode-bidi", ptr, cssRule);
2746: else if (DoApply)
2747: TtaSetStylePresentation (PRUnicodeBidi, element, tsch, context, bidi);
2748: }
1.327 vatton 2749: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid unicode-bidi value");
2750: return (cssRule);
1.113 quint 2751: }
2752:
2753: /*----------------------------------------------------------------------
1.327 vatton 2754: ParseCSSTextIndent: parse a CSS text-indent
2755: attribute string.
1.1 cvs 2756: ----------------------------------------------------------------------*/
1.79 cvs 2757: static char *ParseCSSTextIndent (Element element, PSchema tsch,
1.327 vatton 2758: PresentationContext context, char *cssRule,
2759: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2760: {
1.327 vatton 2761: PresentationValue pval;
2762: char *ptr;
1.1 cvs 2763:
1.370 vatton 2764: pval.typed_data.real = FALSE;
1.327 vatton 2765: cssRule = SkipBlanksAndComments (cssRule);
2766: ptr = cssRule;
2767: cssRule = ParseCSSUnit (cssRule, &pval);
1.387 quint 2768: if (pval.typed_data.value == 0 &&
2769: pval.typed_data.unit != UNIT_INVALID)
1.327 vatton 2770: pval.typed_data.unit = UNIT_PX;
2771: else if (pval.typed_data.unit == UNIT_INVALID ||
2772: pval.typed_data.unit == UNIT_BOX)
2773: {
2774: CSSParseError ("Invalid text-indent value", ptr, cssRule);
2775: return (cssRule);
2776: }
2777: /* install the attribute */
1.366 vatton 2778: if (DoDialog)
2779: DisplayStyleValue ("text-indent", ptr, cssRule);
2780: else if (DoApply)
1.327 vatton 2781: TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
2782: return (cssRule);
1.1 cvs 2783: }
2784:
2785: /*----------------------------------------------------------------------
1.327 vatton 2786: ParseCSSTextTransform: parse a CSS text-transform
2787: attribute string.
1.1 cvs 2788: ----------------------------------------------------------------------*/
1.79 cvs 2789: static char *ParseCSSTextTransform (Element element, PSchema tsch,
1.327 vatton 2790: PresentationContext context, char *cssRule,
2791: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2792: {
1.366 vatton 2793: char *ptr;
2794:
2795: cssRule = SkipBlanksAndComments (cssRule);
2796: ptr = cssRule;
1.168 vatton 2797: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 2798: if (DoDialog)
2799: DisplayStyleValue ("text-transform", ptr, cssRule);
1.1 cvs 2800: return (cssRule);
2801: }
2802:
2803: /*----------------------------------------------------------------------
1.327 vatton 2804: ParseCSSVerticalAlign: parse a CSS vertical-align
2805: attribute string.
1.1 cvs 2806: ----------------------------------------------------------------------*/
1.79 cvs 2807: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
1.327 vatton 2808: PresentationContext context, char *cssRule,
2809: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2810: {
1.273 quint 2811: char *ptr;
2812: PresentationValue pval;
2813:
2814: pval.typed_data.unit = UNIT_REL;
2815: pval.typed_data.real = FALSE;
2816: cssRule = SkipBlanksAndComments (cssRule);
1.288 vatton 2817: ptr = cssRule;
1.273 quint 2818: if (!strncasecmp (cssRule, "baseline", 8))
2819: {
2820: pval.typed_data.value = 0;
1.288 vatton 2821: cssRule += 8;
1.273 quint 2822: }
2823: else if (!strncasecmp (cssRule, "sub", 3))
2824: {
2825: pval.typed_data.value = -3;
1.288 vatton 2826: cssRule += 3;
1.273 quint 2827: }
2828: else if (!strncasecmp (cssRule, "super", 5))
2829: {
2830: pval.typed_data.value = 4;
1.288 vatton 2831: cssRule += 5;
1.273 quint 2832: }
2833: else if (!strncasecmp (cssRule, "top", 3))
2834: {
1.275 quint 2835: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2836: pval.typed_data.value = 0;
1.288 vatton 2837: cssRule += 3;
1.273 quint 2838: }
2839: else if (!strncasecmp (cssRule, "text-top", 8))
2840: {
1.275 quint 2841: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2842: pval.typed_data.value = 0;
1.288 vatton 2843: cssRule += 8;
1.273 quint 2844: }
2845: else if (!strncasecmp (cssRule, "middle", 6))
2846: {
1.275 quint 2847: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2848: pval.typed_data.value = 0;
1.288 vatton 2849: cssRule += 6;
1.273 quint 2850: }
2851: else if (!strncasecmp (cssRule, "bottom", 6))
2852: {
1.275 quint 2853: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2854: pval.typed_data.value = 0;
1.288 vatton 2855: cssRule += 6;
1.273 quint 2856: }
2857: else if (!strncasecmp (cssRule, "text-bottom", 11))
2858: {
1.275 quint 2859: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2860: pval.typed_data.value = 0;
1.288 vatton 2861: cssRule += 11;
1.273 quint 2862: }
2863: else if (!strncasecmp (cssRule, "inherit", 7))
2864: {
1.293 quint 2865: pval.typed_data.unit = VALUE_INHERIT;
1.274 vatton 2866: pval.typed_data.value = 0;
1.288 vatton 2867: cssRule +=7;
1.273 quint 2868: }
2869: else
2870: {
2871: /* parse <percentage> or <length> */
2872: cssRule = ParseCSSUnit (cssRule, &pval);
2873: if (pval.typed_data.unit == UNIT_INVALID)
1.327 vatton 2874: {
2875: pval.typed_data.value = 0;
2876: CSSParseError ("Invalid vertical-align value", ptr, cssRule);
2877: return (cssRule);
2878: }
1.273 quint 2879: else if (pval.typed_data.value == 0)
1.327 vatton 2880: pval.typed_data.unit = UNIT_PX;
1.273 quint 2881: else if (pval.typed_data.unit == UNIT_BOX)
1.327 vatton 2882: pval.typed_data.unit = UNIT_EM;
1.273 quint 2883: else if (pval.typed_data.unit == UNIT_PERCENT)
1.327 vatton 2884: /* it's a percentage */
2885: {
2886: /* convert it into a relative size */
2887: pval.typed_data.unit = UNIT_REL;
2888: pval.typed_data.value /= 10;
2889: }
1.273 quint 2890: }
1.295 vatton 2891:
1.366 vatton 2892: if (pval.typed_data.unit != UNIT_INVALID)
2893: {
2894: if (DoDialog)
2895: DisplayStyleValue ("vertical-align", ptr, cssRule);
2896: else if (DoApply)
2897: TtaSetStylePresentation (PRHorizRef, element, tsch, context, pval);
2898: }
1.288 vatton 2899: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid vertical-align value");
1.1 cvs 2900: return (cssRule);
2901: }
2902:
2903: /*----------------------------------------------------------------------
1.327 vatton 2904: ParseCSSWhiteSpace: parse a CSS white-space
2905: attribute string.
1.1 cvs 2906: ----------------------------------------------------------------------*/
1.79 cvs 2907: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
1.327 vatton 2908: PresentationContext context, char *cssRule,
2909: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2910: {
1.366 vatton 2911: char *ptr;
1.288 vatton 2912:
1.327 vatton 2913: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2914: ptr = cssRule;
1.327 vatton 2915: if (!strncasecmp (cssRule, "normal", 6))
2916: cssRule += 6;
2917: else if (!strncasecmp (cssRule, "pre", 3))
2918: cssRule += 3;
2919: else if (!strncasecmp (cssRule, "nowrap", 6))
2920: cssRule += 6;
2921: else if (!strncasecmp (cssRule, "pre-wrap", 8))
2922: cssRule += 8;
2923: else if (!strncasecmp (cssRule, "pre-line", 8))
2924: cssRule += 8;
2925: else if (!strncasecmp (cssRule, "inherit", 7))
2926: cssRule += 7;
2927: else
2928: cssRule = SkipValue ("Invalid white-space value", cssRule);
2929:
1.387 quint 2930: if (ptr != cssRule && DoDialog)
1.366 vatton 2931: DisplayStyleValue ("white-space", ptr, cssRule);
1.327 vatton 2932: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid white-space value");
2933: return (cssRule);
1.1 cvs 2934: }
2935:
2936: /*----------------------------------------------------------------------
1.327 vatton 2937: ParseCSSWordSpacing: parse a CSS word-spacing
2938: attribute string.
1.1 cvs 2939: ----------------------------------------------------------------------*/
1.79 cvs 2940: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
1.327 vatton 2941: PresentationContext context, char *cssRule,
2942: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2943: {
1.366 vatton 2944: char *ptr;
2945:
2946: cssRule = SkipBlanksAndComments (cssRule);
2947: ptr = cssRule;
1.168 vatton 2948: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 2949: if (DoDialog)
2950: DisplayStyleValue ("word-spacing", ptr, cssRule);
1.1 cvs 2951: return (cssRule);
2952: }
2953:
2954: /*----------------------------------------------------------------------
1.327 vatton 2955: ParseCSSLineHeight: parse a CSS line-height property
1.25 cvs 2956: ----------------------------------------------------------------------*/
1.162 quint 2957: static char *ParseCSSLineHeight (Element element, PSchema tsch,
1.327 vatton 2958: PresentationContext context, char *cssRule,
2959: CSSInfoPtr css, ThotBool isHTML)
1.25 cvs 2960: {
1.162 quint 2961: PresentationValue pval;
1.288 vatton 2962: char *ptr;
1.162 quint 2963:
1.370 vatton 2964: pval.typed_data.real = FALSE;
1.366 vatton 2965: cssRule = SkipBlanksAndComments (cssRule);
1.162 quint 2966: ptr = cssRule;
2967: if (!strncasecmp (cssRule, "normal", 6))
2968: {
1.184 vatton 2969: pval.typed_data.unit = UNIT_REL;
1.162 quint 2970: pval.typed_data.real = TRUE;
2971: pval.typed_data.value = 1100;
1.288 vatton 2972: cssRule += 6;
1.162 quint 2973: }
2974: else if (!strncasecmp (cssRule, "inherit", 7))
2975: {
1.293 quint 2976: pval.typed_data.unit = VALUE_INHERIT;
1.354 quint 2977: cssRule += 7;
1.162 quint 2978: }
2979: else
2980: cssRule = ParseCSSUnit (cssRule, &pval);
1.25 cvs 2981:
1.184 vatton 2982: if (pval.typed_data.unit == UNIT_INVALID)
1.168 vatton 2983: CSSParseError ("Invalid line-height value", ptr, cssRule);
1.387 quint 2984: else if (DoDialog)
1.366 vatton 2985: DisplayStyleValue ("line-height", ptr, cssRule);
1.162 quint 2986: else if (DoApply)
2987: {
1.166 vatton 2988: /* install the new presentation */
1.184 vatton 2989: if (pval.typed_data.unit == UNIT_BOX)
1.327 vatton 2990: pval.typed_data.unit = UNIT_EM;
1.162 quint 2991: TtaSetStylePresentation (PRLineSpacing, element, tsch, context, pval);
2992: }
2993: return (cssRule);
1.25 cvs 2994: }
2995:
2996: /*----------------------------------------------------------------------
1.327 vatton 2997: ParseCSSFontSizeAdjust: parse a CSS fontsizeAdjust attr string
2998: we expect the input string describing the attribute to be
2999: xx-small, x-small, small, medium, large, x-large, xx-large
3000: or an absolute size, or an imcrement relative to the parent
1.1 cvs 3001: ----------------------------------------------------------------------*/
1.219 vatton 3002: static char *ParseCSSFontSizeAdjust (Element element, PSchema tsch,
1.327 vatton 3003: PresentationContext context, char *cssRule,
3004: CSSInfoPtr css, ThotBool isHTML)
1.219 vatton 3005: {
1.366 vatton 3006:
3007: cssRule = SkipBlanksAndComments (cssRule);
1.234 vatton 3008: cssRule = SkipProperty (cssRule, FALSE);
1.222 quint 3009: return (cssRule);
1.219 vatton 3010: }
3011:
3012: /*----------------------------------------------------------------------
1.327 vatton 3013: ParseACSSFontSize: parse a CSS font size attr string
3014: we expect the input string describing the attribute to be
3015: xx-small, x-small, small, medium, large, x-large, xx-large
3016: or an absolute size, or an imcrement relative to the parent.
3017: The parameter check is TRUE if the rule is just checked.
1.219 vatton 3018: ----------------------------------------------------------------------*/
1.270 vatton 3019: static char *ParseACSSFontSize (Element element, PSchema tsch,
1.327 vatton 3020: PresentationContext context, char *cssRule,
3021: CSSInfoPtr css, ThotBool isHTML, ThotBool check)
1.1 cvs 3022: {
1.327 vatton 3023: ElementType elType;
3024: PresentationValue pval;
1.369 quint 3025: char *ptr = NULL, *ptr1 = NULL, *ptr2 = NULL;
1.366 vatton 3026: char *start_value;
1.369 quint 3027: ThotBool real, error, linespace = FALSE;
1.327 vatton 3028:
1.369 quint 3029: error = FALSE;
1.327 vatton 3030: pval.typed_data.real = FALSE;
3031: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3032: start_value = cssRule;
1.327 vatton 3033: /* look for a '/' within the current cssRule */
3034: ptr1 = strchr (cssRule, ';');
3035: ptr = strchr (cssRule, '/');
3036: if (ptr && (ptr1 == NULL || ptr < ptr1))
3037: {
3038: /* keep the line spacing rule */
3039: linespace = TRUE;
3040: ptr[0] = EOS;
3041: }
3042: else
3043: ptr = NULL;
3044: ptr1 = cssRule;
1.289 vatton 3045: /* relative size */
1.327 vatton 3046: if (!strncasecmp (cssRule, "larger", 6))
3047: {
3048: pval.typed_data.unit = UNIT_PERCENT;
3049: pval.typed_data.value = 130;
3050: cssRule += 6;
3051: }
3052: else if (!strncasecmp (cssRule, "smaller", 7))
3053: {
3054: pval.typed_data.unit = UNIT_PERCENT;
3055: pval.typed_data.value = 80;
3056: cssRule += 7;
3057: }
3058: /* absolute size */
3059: else if (!strncasecmp (cssRule, "xx-small", 8))
3060: {
3061: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3062: pval.typed_data.value = 6;
1.327 vatton 3063: cssRule += 8;
3064: }
3065: else if (!strncasecmp (cssRule, "x-small", 7))
3066: {
3067: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3068: pval.typed_data.value = 8;
1.327 vatton 3069: cssRule += 7;
3070: }
3071: else if (!strncasecmp (cssRule, "small", 5))
3072: {
3073: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3074: pval.typed_data.value = 10;
1.327 vatton 3075: cssRule += 5;
3076: }
3077: else if (!strncasecmp (cssRule, "medium", 6))
3078: {
3079: pval.typed_data.unit = UNIT_PT;
3080: pval.typed_data.value = 12;
3081: cssRule += 6;
3082: }
3083: else if (!strncasecmp (cssRule, "large", 5))
3084: {
3085: pval.typed_data.unit = UNIT_PT;
3086: pval.typed_data.value = 13;
3087: cssRule += 5;
3088: }
3089: else if (!strncasecmp (cssRule, "x-large", 7))
3090: {
3091: pval.typed_data.unit = UNIT_PT;
3092: pval.typed_data.value = 14;
3093: cssRule += 7;
3094: }
3095: else if (!strncasecmp (cssRule, "xx-large", 8))
3096: {
3097: pval.typed_data.unit = UNIT_PT;
3098: pval.typed_data.value = 16;
3099: cssRule += 8;
3100: }
3101: else if (!strncasecmp (cssRule, "inherit", 7))
3102: {
3103: pval.typed_data.unit = VALUE_INHERIT;
3104: pval.typed_data.value = 0;
3105: cssRule += 7;
3106: }
3107: /* length or percentage */
3108: else if (!isdigit (*cssRule) && *cssRule != '.')
3109: {
3110: if (!check)
1.360 vatton 3111: cssRule = SkipValue ("Invalid font-size value", cssRule);
1.369 quint 3112: error = TRUE;
1.327 vatton 3113: }
3114: else
3115: {
3116: cssRule = ParseCSSUnit (cssRule, &pval);
3117: if (pval.typed_data.unit == UNIT_BOX)
3118: /* no unit specified */
3119: {
3120: elType = TtaGetElementType(element);
3121: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
3122: /* we are working for an SVG element. No unit means pixels */
3123: pval.typed_data.unit = UNIT_PX;
3124: }
1.387 quint 3125: if (pval.typed_data.unit == UNIT_INVALID ||
3126: (pval.typed_data.value != 0 && pval.typed_data.unit == UNIT_BOX) ||
3127: pval.typed_data.value < 0)
1.327 vatton 3128: /* not a valid value */
1.369 quint 3129: {
3130: if (!check)
3131: {
3132: ptr2 = SkipWord (cssRule);
3133: CSSParseError ("Invalid font-size value", ptr1, ptr2);
3134: }
3135: error = TRUE;
3136: }
1.327 vatton 3137: else if (pval.typed_data.unit == UNIT_REL && pval.typed_data.value > 0)
3138: /* CSS relative sizes have to be higher than Thot ones */
3139: pval.typed_data.value += 1;
3140: else
3141: {
3142: real = pval.typed_data.real;
3143: if (pval.typed_data.unit == UNIT_EM)
3144: {
3145: if (real)
3146: {
3147: pval.typed_data.value /= 10;
3148: pval.typed_data.real = FALSE;
3149: real = FALSE;
3150: }
3151: else
3152: pval.typed_data.value *= 100;
3153: pval.typed_data.unit = UNIT_PERCENT;
3154: }
3155: else if (pval.typed_data.unit == UNIT_XHEIGHT)
3156: {
3157: /* a font size expressed in ex is converted into a percentage.
3158: For example, "3ex" is converted into "180%", supposing
3159: that 1ex is approximately 0.6 times the height of the
3160: current font */
3161: if (real)
3162: {
3163: pval.typed_data.value *= 6;
3164: pval.typed_data.value /= 100;
3165: pval.typed_data.real = FALSE;
3166: real = FALSE;
3167: }
3168: else
3169: pval.typed_data.value *= 60;
3170: pval.typed_data.unit = UNIT_PERCENT;
3171: }
3172: }
3173: }
3174:
3175: /* install the presentation style */
1.369 quint 3176: if (!check && !error)
1.366 vatton 3177: {
3178: if (DoDialog)
3179: DisplayStyleValue ("font-size", start_value, cssRule);
3180: else if (DoApply)
3181: TtaSetStylePresentation (PRSize, element, tsch, context, pval);
3182: }
1.327 vatton 3183: if (!check && ptr)
3184: cssRule = ParseCSSLineHeight (element, tsch, context, &ptr[1], css, isHTML);
3185: if (linespace)
3186: *ptr = '/';
3187:
3188: return (cssRule);
3189: }
3190:
3191: /*----------------------------------------------------------------------
3192: ParseCSSFontSize: parse a CSS font size attr string
3193: we expect the input string describing the attribute to be
3194: xx-small, x-small, small, medium, large, x-large, xx-large
3195: or an absolute size, or an imcrement relative to the parent
1.270 vatton 3196: ----------------------------------------------------------------------*/
3197: static char *ParseCSSFontSize (Element element, PSchema tsch,
1.327 vatton 3198: PresentationContext context, char *cssRule,
3199: CSSInfoPtr css, ThotBool isHTML)
1.270 vatton 3200: {
1.299 vatton 3201: char *ptr = cssRule;
1.295 vatton 3202: cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.299 vatton 3203: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid font-size value");
1.295 vatton 3204: return cssRule;
1.270 vatton 3205: }
3206:
3207: /*----------------------------------------------------------------------
1.327 vatton 3208: ParseACSSFontFamily: parse a CSS font family string
3209: we expect the input string describing the attribute to be
3210: a common generic font style name
1.1 cvs 3211: ----------------------------------------------------------------------*/
1.268 vatton 3212: static char *ParseACSSFontFamily (Element element, PSchema tsch,
1.327 vatton 3213: PresentationContext context, char *cssRule,
3214: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3215: {
3216: PresentationValue font;
1.252 vatton 3217: char quoteChar, *p;
1.1 cvs 3218:
3219: font.typed_data.value = 0;
1.184 vatton 3220: font.typed_data.unit = UNIT_REL;
1.1 cvs 3221: font.typed_data.real = FALSE;
1.82 cvs 3222: cssRule = SkipBlanksAndComments (cssRule);
3223: if (*cssRule == '"' || *cssRule == '\'')
1.327 vatton 3224: {
3225: quoteChar = *cssRule;
3226: cssRule++;
3227: }
1.1 cvs 3228: else
1.327 vatton 3229: quoteChar = EOS;
1.1 cvs 3230:
1.293 quint 3231: if (!strncasecmp (cssRule, "inherit", 7) && quoteChar == EOS)
3232: {
3233: font.typed_data.unit = VALUE_INHERIT;
3234: cssRule += 7;
3235: }
3236: else if (!strncasecmp (cssRule, "times", 5) &&
1.327 vatton 3237: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 3238: {
1.184 vatton 3239: font.typed_data.value = FontTimes;
1.86 cvs 3240: cssRule += 5;
3241: }
1.92 cvs 3242: else if (!strncasecmp (cssRule, "serif", 5) &&
1.327 vatton 3243: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 3244: {
1.184 vatton 3245: font.typed_data.value = FontTimes;
1.86 cvs 3246: cssRule += 5;
1.92 cvs 3247: if (quoteChar != EOS)
1.327 vatton 3248: cssRule++;
1.86 cvs 3249: }
1.92 cvs 3250: else if (!strncasecmp (cssRule, "helvetica", 9) &&
1.327 vatton 3251: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 3252: {
1.327 vatton 3253: font.typed_data.value = FontHelvetica;
1.86 cvs 3254: cssRule += 9;
1.92 cvs 3255: if (quoteChar != EOS)
1.327 vatton 3256: cssRule++;
1.86 cvs 3257: }
1.92 cvs 3258: else if (!strncasecmp (cssRule, "verdana", 7) &&
1.327 vatton 3259: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 3260: {
1.184 vatton 3261: font.typed_data.value = FontHelvetica;
1.86 cvs 3262: cssRule += 7;
1.92 cvs 3263: if (quoteChar != EOS)
1.327 vatton 3264: cssRule++;
1.86 cvs 3265: }
1.92 cvs 3266: else if (!strncasecmp (cssRule, "sans-serif", 10) &&
1.327 vatton 3267: (quoteChar == EOS || quoteChar == cssRule[10]))
1.86 cvs 3268: {
1.184 vatton 3269: font.typed_data.value = FontHelvetica;
1.86 cvs 3270: cssRule += 10;
1.92 cvs 3271: if (quoteChar != EOS)
1.327 vatton 3272: cssRule++;
1.86 cvs 3273: }
1.268 vatton 3274: else if (!strncasecmp (cssRule, "courier new", 11) &&
1.327 vatton 3275: (quoteChar == EOS || quoteChar == cssRule[11]))
1.268 vatton 3276: {
3277: font.typed_data.value = FontCourier;
3278: cssRule += 11;
3279: if (quoteChar != EOS)
1.327 vatton 3280: cssRule++;
1.268 vatton 3281: }
1.92 cvs 3282: else if (!strncasecmp (cssRule, "courier", 7) &&
1.327 vatton 3283: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 3284: {
1.184 vatton 3285: font.typed_data.value = FontCourier;
1.86 cvs 3286: cssRule += 7;
1.92 cvs 3287: if (quoteChar != EOS)
1.327 vatton 3288: cssRule++;
1.86 cvs 3289: }
1.92 cvs 3290: else if (!strncasecmp (cssRule, "monospace", 9) &&
1.327 vatton 3291: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 3292: {
1.184 vatton 3293: font.typed_data.value = FontCourier;
1.86 cvs 3294: cssRule += 9;
1.92 cvs 3295: if (quoteChar != EOS)
1.327 vatton 3296: cssRule++;
1.86 cvs 3297: }
1.1 cvs 3298: else
3299: /* unknown font name. Skip it */
3300: {
1.252 vatton 3301: p = cssRule;
1.92 cvs 3302: if (quoteChar != EOS)
1.327 vatton 3303: cssRule = SkipQuotedString (cssRule, quoteChar);
1.86 cvs 3304: else
1.383 quint 3305: /* unquoted font name. The name may contain spaces */
3306: {
3307: cssRule = SkipWord (cssRule);
3308: while (*cssRule == SPACE || *cssRule == BSPACE || *cssRule == EOL ||
3309: *cssRule == TAB || *cssRule == __CR__)
3310: {
3311: cssRule = SkipBlanksAndComments (cssRule);
3312: if (*cssRule != ',' && *cssRule != ';' && *cssRule != '}' &&
3313: *cssRule != EOS)
3314: cssRule = SkipWord (cssRule);
3315: }
3316: }
1.252 vatton 3317: while (p == cssRule &&
1.327 vatton 3318: *cssRule != ',' && *cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
3319: {
3320: cssRule++;
3321: p = cssRule;
3322: cssRule = SkipWord (cssRule);
3323: }
1.82 cvs 3324: cssRule = SkipBlanksAndComments (cssRule);
3325: if (*cssRule == ',')
1.327 vatton 3326: {
3327: /* recursive call to ParseCSSFontFamily */
3328: cssRule++;
3329: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3330: return (cssRule);
3331: }
1.1 cvs 3332: }
3333:
1.239 vatton 3334: /* skip other values */
3335: cssRule = SkipBlanksAndComments (cssRule);
3336: while (*cssRule == ',')
3337: {
3338: cssRule++;
3339: cssRule = SkipValue (NULL, cssRule);
3340: cssRule = SkipBlanksAndComments (cssRule);
3341: }
3342:
1.366 vatton 3343: if (font.typed_data.value != 0 || font.typed_data.unit == VALUE_INHERIT)
3344: {
3345: if (!DoDialog && DoApply)
3346: /* install the new presentation */
3347: TtaSetStylePresentation (PRFont, element, tsch, context, font);
3348: }
1.1 cvs 3349: return (cssRule);
3350: }
3351:
3352: /*----------------------------------------------------------------------
1.327 vatton 3353: ParseCSSFontFamily: parse a CSS font family string
3354: we expect the input string describing the attribute to be
3355: a common generic font style name
1.268 vatton 3356: ----------------------------------------------------------------------*/
3357: static char *ParseCSSFontFamily (Element element, PSchema tsch,
1.327 vatton 3358: PresentationContext context, char *cssRule,
3359: CSSInfoPtr css, ThotBool isHTML)
1.268 vatton 3360: {
1.366 vatton 3361: char *start_value;
3362:
3363: cssRule = SkipBlanksAndComments (cssRule);
3364: start_value = cssRule;
1.268 vatton 3365: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3366: /* skip extra values */
1.301 vatton 3367: while (cssRule && *cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.268 vatton 3368: cssRule++;
1.366 vatton 3369: if (DoDialog)
3370: DisplayStyleValue ("font-family", start_value, cssRule);
1.268 vatton 3371: return (cssRule);
3372: }
3373:
3374: /*----------------------------------------------------------------------
1.327 vatton 3375: ParseACSSFontWeight: parse a CSS font weight string
3376: we expect the input string describing the attribute to be
3377: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 3378: ----------------------------------------------------------------------*/
1.263 vatton 3379: static char *ParseACSSFontWeight (Element element, PSchema tsch,
1.327 vatton 3380: PresentationContext context, char *cssRule,
3381: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3382: {
1.327 vatton 3383: PresentationValue weight;
1.366 vatton 3384: char *ptr;
1.1 cvs 3385:
1.327 vatton 3386: weight.typed_data.value = 0;
3387: weight.typed_data.unit = UNIT_REL;
3388: weight.typed_data.real = FALSE;
3389: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3390: ptr = cssRule;
1.351 quint 3391: if (isdigit (*cssRule) && *cssRule != '0' &&
3392: cssRule[1] == '0' && cssRule[2] == '0' &&
3393: (cssRule[3] == EOS || cssRule[3] == SPACE || cssRule[3] == '/' ||
3394: cssRule[3] == ';' || cssRule[3] == '}' || cssRule[3] == EOL ||
3395: cssRule[3] == TAB || cssRule[3] == __CR__))
1.327 vatton 3396: {
1.351 quint 3397: if (!strncasecmp (cssRule, "100", 3))
3398: {
1.379 quint 3399: weight.typed_data.value = -4;
1.351 quint 3400: cssRule = SkipWord (cssRule);
3401: }
3402: else if (!strncasecmp (cssRule, "200", 3))
3403: {
1.379 quint 3404: weight.typed_data.value = -3;
1.351 quint 3405: cssRule = SkipWord (cssRule);
3406: }
3407: else if (!strncasecmp (cssRule, "300", 3))
3408: {
1.379 quint 3409: weight.typed_data.value = -2;
1.351 quint 3410: cssRule = SkipWord (cssRule);
3411: }
3412: else if (!strncasecmp (cssRule, "400", 3))
3413: {
1.379 quint 3414: weight.typed_data.value = -1;
1.351 quint 3415: cssRule = SkipWord (cssRule);
3416: }
3417: else if (!strncasecmp (cssRule, "500", 3))
3418: {
1.379 quint 3419: weight.typed_data.value = 0;
1.351 quint 3420: cssRule = SkipWord (cssRule);
3421: }
3422: else if (!strncasecmp (cssRule, "600", 3))
3423: {
1.379 quint 3424: weight.typed_data.value = +1;
1.351 quint 3425: cssRule = SkipWord (cssRule);
3426: }
3427: else if (!strncasecmp (cssRule, "700", 3))
3428: {
1.379 quint 3429: weight.typed_data.value = +2;
1.351 quint 3430: cssRule = SkipWord (cssRule);
3431: }
3432: else if (!strncasecmp (cssRule, "800", 3))
3433: {
1.379 quint 3434: weight.typed_data.value = +3;
1.351 quint 3435: cssRule = SkipWord (cssRule);
3436: }
3437: else if (!strncasecmp (cssRule, "900", 3))
3438: {
1.379 quint 3439: weight.typed_data.value = +4;
1.351 quint 3440: cssRule = SkipWord (cssRule);
3441: }
1.327 vatton 3442: }
1.351 quint 3443: else if (!strncasecmp (cssRule, "normal", 6))
1.327 vatton 3444: {
3445: weight.typed_data.value = 0;
3446: cssRule = SkipWord (cssRule);
3447: }
1.351 quint 3448: else if (!strncasecmp (cssRule, "bold", 4))
1.327 vatton 3449: {
3450: weight.typed_data.value = +3;
3451: cssRule = SkipWord (cssRule);
3452: }
3453: else if (!strncasecmp (cssRule, "inherit", 7))
3454: {
3455: weight.typed_data.unit = VALUE_INHERIT;
3456: cssRule += 7;
3457: }
1.379 quint 3458: else if (!strncasecmp (cssRule, "bolder", 6))
1.327 vatton 3459: {
1.379 quint 3460: weight.typed_data.value = +2;
3461: cssRule = SkipWord (cssRule);
3462: }
3463:
3464: else if (!strncasecmp (cssRule, "lighter", 7))
3465: {
3466: weight.typed_data.value = -1;
1.327 vatton 3467: cssRule = SkipWord (cssRule);
3468: }
3469: else
3470: return (cssRule);
3471:
3472: /*
3473: * Here we have to reduce since only two font weight values are supported
3474: * by the Thot presentation API.
3475: */
3476: if (weight.typed_data.unit != VALUE_INHERIT)
3477: {
3478: if (weight.typed_data.value > 0)
3479: weight.typed_data.value = WeightBold;
3480: else
3481: weight.typed_data.value = WeightNormal;
3482: }
3483:
3484: /* install the new presentation */
1.366 vatton 3485: if (cssRule != ptr && DoDialog)
3486: DisplayStyleValue ("font-weight", ptr, cssRule);
3487: else if (DoApply)
1.327 vatton 3488: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
3489: return (cssRule);
3490: }
3491:
3492: /*----------------------------------------------------------------------
3493: ParseCSSFontWeight: parse a CSS font weight string
3494: we expect the input string describing the attribute to be
3495: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.263 vatton 3496: ----------------------------------------------------------------------*/
3497: static char *ParseCSSFontWeight (Element element, PSchema tsch,
1.327 vatton 3498: PresentationContext context, char *cssRule,
3499: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3500: {
3501: char *ptr;
3502:
1.366 vatton 3503: cssRule = SkipBlanksAndComments (cssRule);
1.263 vatton 3504: ptr = cssRule;
3505: cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3506: if (ptr == cssRule)
3507: cssRule = SkipValue ("Invalid font-weight value", cssRule);
3508: return (cssRule);
3509: }
3510:
3511: /*----------------------------------------------------------------------
1.327 vatton 3512: ParseACSSFontVariant: parse a CSS font variant string
3513: we expect the input string describing the attribute to be
3514: normal or small-caps
1.1 cvs 3515: ----------------------------------------------------------------------*/
1.263 vatton 3516: static char *ParseACSSFontVariant (Element element, PSchema tsch,
1.327 vatton 3517: PresentationContext context, char *cssRule,
3518: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3519: {
1.327 vatton 3520: PresentationValue style;
1.366 vatton 3521: char *ptr;
1.1 cvs 3522:
1.327 vatton 3523: style.typed_data.value = 0;
3524: style.typed_data.unit = UNIT_REL;
3525: style.typed_data.real = FALSE;
3526: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3527: ptr = cssRule;
1.327 vatton 3528: if (!strncasecmp (cssRule, "small-caps", 10))
3529: {
1.381 quint 3530: style.typed_data.value = VariantSmallCaps;
1.327 vatton 3531: cssRule = SkipWord (cssRule);
3532: }
3533: else if (!strncasecmp (cssRule, "normal", 6))
3534: {
1.381 quint 3535: style.typed_data.value = VariantNormal;
1.327 vatton 3536: cssRule = SkipWord (cssRule);
3537: }
3538: else if (!strncasecmp (cssRule, "inherit", 7))
3539: {
1.381 quint 3540: style.typed_data.unit = VALUE_INHERIT;
1.327 vatton 3541: cssRule = SkipWord (cssRule);
3542: }
1.381 quint 3543: else
3544: /* invalid font-variant */
3545: return (cssRule);
3546:
3547: if (style.typed_data.value != 0 || style.typed_data.unit == VALUE_INHERIT)
3548: {
3549: if (DoDialog)
3550: DisplayStyleValue ("font-variant", ptr, cssRule);
3551: else if (DoApply)
3552: TtaSetStylePresentation (PRVariant, element, tsch, context, style);
3553: }
1.295 vatton 3554: return (cssRule);
1.263 vatton 3555: }
1.1 cvs 3556:
1.263 vatton 3557: /*----------------------------------------------------------------------
1.327 vatton 3558: ParseCSSFontVariant: parse a CSS font variant string
3559: we expect the input string describing the attribute to be
3560: normal or small-caps
1.263 vatton 3561: ----------------------------------------------------------------------*/
3562: static char *ParseCSSFontVariant (Element element, PSchema tsch,
1.327 vatton 3563: PresentationContext context, char *cssRule,
3564: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3565: {
3566: char *ptr;
3567:
3568: ptr = cssRule;
3569: cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3570: if (ptr == cssRule)
3571: cssRule = SkipValue ("Invalid font-variant value", cssRule);
3572: return (cssRule);
1.1 cvs 3573: }
3574:
3575:
3576: /*----------------------------------------------------------------------
1.327 vatton 3577: ParseACSSFontStyle: parse a CSS font style string
3578: we expect the input string describing the attribute to be
3579: normal, italic, oblique or inherit
1.1 cvs 3580: ----------------------------------------------------------------------*/
1.263 vatton 3581: static char *ParseACSSFontStyle (Element element, PSchema tsch,
1.327 vatton 3582: PresentationContext context, char *cssRule,
3583: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3584: {
1.327 vatton 3585: PresentationValue style;
3586: PresentationValue size;
1.366 vatton 3587: PresentationValue previous_size;
3588: char *ptr;
1.1 cvs 3589:
1.327 vatton 3590: style.typed_data.value = 0;
3591: style.typed_data.unit = UNIT_REL;
3592: style.typed_data.real = FALSE;
3593: size.typed_data.value = 0;
3594: size.typed_data.unit = UNIT_REL;
3595: size.typed_data.real = FALSE;
3596: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3597: ptr = cssRule;
1.327 vatton 3598: if (!strncasecmp (cssRule, "italic", 6))
3599: {
3600: style.typed_data.value = StyleItalics;
3601: cssRule = SkipWord (cssRule);
3602: }
3603: else if (!strncasecmp (cssRule, "oblique", 7))
3604: {
3605: style.typed_data.value = StyleOblique;
3606: cssRule = SkipWord (cssRule);
3607: }
3608: else if (!strncasecmp (cssRule, "normal", 6))
3609: {
3610: style.typed_data.value = StyleRoman;
3611: cssRule = SkipWord (cssRule);
3612: }
3613: else if (!strncasecmp (cssRule, "inherit", 7))
3614: {
3615: style.typed_data.unit = VALUE_INHERIT;
3616: cssRule = SkipWord (cssRule);
3617: }
3618: else
3619: /* invalid font style */
3620: return (cssRule);
3621:
3622: /*
3623: * install the new presentation.
3624: */
1.366 vatton 3625: if (style.typed_data.value != 0 || style.typed_data.unit == VALUE_INHERIT)
1.327 vatton 3626: {
1.366 vatton 3627: if (DoDialog)
3628: DisplayStyleValue ("font-style", ptr, cssRule);
3629: else if (DoApply)
3630: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.327 vatton 3631: }
1.366 vatton 3632: if (size.typed_data.value != 0)
1.327 vatton 3633: {
1.366 vatton 3634: if (DoDialog)
3635: DisplayStyleValue ("font-style", ptr, cssRule);
3636: else if (DoApply)
1.327 vatton 3637: {
1.366 vatton 3638: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
3639: {
3640: /* !!!!!!!!!!!!!!!!!!!!!!!! Unit + relative !!!!!!!!!!!!!!!! */
3641: size.typed_data.value += previous_size.typed_data.value;
3642: TtaSetStylePresentation (PRSize, element, tsch, context, size);
3643: }
3644: else
3645: {
3646: size.typed_data.value = 10;
3647: TtaSetStylePresentation (PRSize, element, tsch, context, size);
3648: }
1.327 vatton 3649: }
3650: }
3651: return (cssRule);
3652: }
3653:
3654: /*----------------------------------------------------------------------
3655: ParseCSSFontStyle: parse a CSS font style string
3656: we expect the input string describing the attribute to be
3657: italic, oblique or normal
1.263 vatton 3658: ----------------------------------------------------------------------*/
3659: static char *ParseCSSFontStyle (Element element, PSchema tsch,
1.327 vatton 3660: PresentationContext context, char *cssRule,
3661: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3662: {
3663: char *ptr;
3664:
3665: ptr = cssRule;
3666: cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3667: if (ptr == cssRule)
3668: cssRule = SkipValue ("Invalid font-style value", cssRule);
3669: return (cssRule);
3670: }
3671:
3672: /*----------------------------------------------------------------------
1.59 cvs 3673: ParseCSSFont: parse a CSS font attribute string
3674: we expect the input string describing the attribute to be
3675: !!!!!!
1.1 cvs 3676: ----------------------------------------------------------------------*/
1.79 cvs 3677: static char *ParseCSSFont (Element element, PSchema tsch,
1.327 vatton 3678: PresentationContext context, char *cssRule,
3679: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3680: {
1.270 vatton 3681: char *ptr, *p;
1.366 vatton 3682: char *start_value;
1.93 vatton 3683: int skippedNL;
1.272 vatton 3684: ThotBool variant = FALSE, style = FALSE, weight = FALSE, found;
1.1 cvs 3685:
1.82 cvs 3686: cssRule = SkipBlanksAndComments (cssRule);
3687: if (!strncasecmp (cssRule, "caption", 7))
1.263 vatton 3688: cssRule += 7;
1.82 cvs 3689: else if (!strncasecmp (cssRule, "icon", 4))
1.263 vatton 3690: cssRule += 4;
1.82 cvs 3691: else if (!strncasecmp (cssRule, "menu", 4))
1.263 vatton 3692: cssRule += 4;
1.82 cvs 3693: else if (!strncasecmp (cssRule, "message-box", 11))
1.263 vatton 3694: cssRule += 11;
1.82 cvs 3695: else if (!strncasecmp (cssRule, "small-caption", 13))
1.263 vatton 3696: cssRule += 13;
1.82 cvs 3697: else if (!strncasecmp (cssRule, "status-bar", 10))
1.263 vatton 3698: cssRule += 10;
3699: else if (!strncasecmp (cssRule, "inherit", 7))
1.293 quint 3700: {
3701: ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3702: ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3703: ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3704: ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.366 vatton 3705: cssRule = SkipBlanksAndComments (cssRule);
3706: start_value = cssRule;
1.293 quint 3707: ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3708: cssRule += 7;
1.366 vatton 3709: if (DoDialog)
3710: DisplayStyleValue ("font-family", start_value, cssRule);
1.293 quint 3711: }
1.1 cvs 3712: else
1.43 cvs 3713: {
1.270 vatton 3714: ptr = NULL;
3715: p = cssRule;
1.301 vatton 3716: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && p == cssRule)
1.327 vatton 3717: {
3718: found = FALSE;
3719: /* style, variant, weight can appear in any order */
3720: ptr = cssRule;
3721: skippedNL = NewLineSkipped;
3722: cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3723: if (ptr != cssRule)
3724: {
3725: skippedNL = NewLineSkipped;
3726: found = TRUE;
3727: style = TRUE;
3728: }
3729: else
3730: NewLineSkipped = skippedNL;
3731: ptr = cssRule;
3732: cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3733: if (ptr != cssRule)
3734: {
3735: skippedNL = NewLineSkipped;
3736: found = TRUE;
3737: variant = TRUE;
3738: }
3739: else
3740: NewLineSkipped = skippedNL;
3741: ptr = cssRule;
3742: cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3743: if (ptr != cssRule)
3744: {
3745: skippedNL = NewLineSkipped;
3746: found = TRUE;
3747: weight = TRUE;
3748: }
3749: else
3750: NewLineSkipped = skippedNL;
3751: cssRule = SkipBlanksAndComments (cssRule);
3752: p = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, TRUE);
3753: NewLineSkipped = skippedNL;
3754: if (!found)
3755: /* break the loop when the current value was not parsed */
3756: p = cssRule + 1;
3757: }
1.263 vatton 3758: ptr = cssRule;
1.270 vatton 3759: /* set default variant, style, weight */
3760: if (!variant)
1.327 vatton 3761: ParseACSSFontVariant (element, tsch, context, "normal", css, isHTML);
1.270 vatton 3762: if (!style)
1.327 vatton 3763: ParseACSSFontStyle (element, tsch, context, "normal", css, isHTML);
1.270 vatton 3764: if (!weight)
1.327 vatton 3765: ParseACSSFontWeight (element, tsch, context, "normal", css, isHTML);
1.270 vatton 3766: /* now parse the font size and the font family */
1.301 vatton 3767: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.327 vatton 3768: cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.301 vatton 3769: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.366 vatton 3770: {
3771: cssRule = SkipBlanksAndComments (cssRule);
3772: start_value = cssRule;
3773: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3774: if (DoDialog)
3775: DisplayStyleValue ("font-family", start_value, cssRule);
3776: }
1.263 vatton 3777: if (ptr == cssRule)
1.360 vatton 3778: cssRule = SkipValue ("Invalid font value", cssRule);
1.43 cvs 3779: }
1.263 vatton 3780: cssRule = SkipBlanksAndComments (cssRule);
1.301 vatton 3781: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.360 vatton 3782: cssRule = SkipValue ("Invalid font value", cssRule);
1.43 cvs 3783: return (cssRule);
1.1 cvs 3784: }
3785:
3786: /*----------------------------------------------------------------------
1.356 quint 3787: ParseCSSTextDecoration: parse a CSS text-decoration value.
3788: We expect the input string to be none, inherit or a combination of
3789: underline, overline, line-through, and blink.
1.1 cvs 3790: ----------------------------------------------------------------------*/
1.79 cvs 3791: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
1.327 vatton 3792: PresentationContext context, char *cssRule,
3793: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3794: {
1.327 vatton 3795: PresentationValue decor;
1.366 vatton 3796: char *ptr;
1.356 quint 3797: ThotBool ok;
1.327 vatton 3798:
3799: decor.typed_data.value = 0;
3800: decor.typed_data.unit = UNIT_REL;
3801: decor.typed_data.real = FALSE;
3802: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3803: ptr = cssRule;
1.356 quint 3804: ok = TRUE;
1.327 vatton 3805: if (!strncasecmp (cssRule, "none", 4))
3806: {
3807: decor.typed_data.value = NoUnderline;
3808: cssRule += 4;
3809: }
3810: else if (!strncasecmp (cssRule, "inherit", 7))
3811: {
3812: decor.typed_data.unit = VALUE_INHERIT;
3813: cssRule += 7;
3814: }
3815: else
3816: {
1.356 quint 3817: do
3818: {
3819: if (!strncasecmp (cssRule, "underline", 9))
3820: {
3821: decor.typed_data.value = Underline;
3822: cssRule += 9;
3823: }
3824: else if (!strncasecmp (cssRule, "overline", 8))
3825: {
3826: decor.typed_data.value = Overline;
3827: cssRule += 8;
3828: }
3829: else if (!strncasecmp (cssRule, "line-through", 12))
3830: {
3831: decor.typed_data.value = CrossOut;
3832: cssRule += 12;
3833: }
3834: else if (!strncasecmp (cssRule, "blink", 5))
3835: {
3836: /* the blink text-decoration attribute is not supported */
3837: cssRule += 5;
3838: }
3839: else
3840: ok = FALSE;
3841: if (ok)
3842: {
3843: cssRule = SkipBlanksAndComments (cssRule);
3844: }
3845: }
3846: while (ok && (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS));
3847: }
3848: if (!ok)
3849: {
1.327 vatton 3850: cssRule = SkipValue ("Invalid text-decoration value", cssRule);
3851: return (cssRule);
3852: }
1.1 cvs 3853:
1.327 vatton 3854: /*
3855: * install the new presentation.
3856: */
1.366 vatton 3857: if (decor.typed_data.value || decor.typed_data.unit == VALUE_INHERIT)
3858: {
3859: if (DoDialog)
3860: DisplayStyleValue ("text-decoration", ptr, cssRule);
3861: else if (DoApply)
3862: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
3863: }
1.327 vatton 3864: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-decoration value");
3865: return (cssRule);
1.1 cvs 3866: }
3867:
3868: /*----------------------------------------------------------------------
1.327 vatton 3869: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 3870: ----------------------------------------------------------------------*/
1.79 cvs 3871: static char *ParseCSSHeight (Element element, PSchema tsch,
1.327 vatton 3872: PresentationContext context, char *cssRule,
3873: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3874: {
1.117 vatton 3875: PresentationValue val;
1.168 vatton 3876: char *ptr;
1.93 vatton 3877:
1.370 vatton 3878: val.typed_data.real = FALSE;
1.117 vatton 3879: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 3880: ptr = cssRule;
1.117 vatton 3881: /* first parse the attribute string */
1.164 quint 3882: if (!strncasecmp (cssRule, "auto", 4))
3883: {
1.184 vatton 3884: val.typed_data.unit = VALUE_AUTO;
1.164 quint 3885: val.typed_data.value = 0;
1.288 vatton 3886: cssRule += 4;
3887: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
1.164 quint 3888: }
1.117 vatton 3889: else
1.168 vatton 3890: cssRule = ParseCSSUnit (cssRule, &val);
1.295 vatton 3891:
1.387 quint 3892: if (val.typed_data.unit == UNIT_INVALID ||
3893: (val.typed_data.value != 0 &&
1.184 vatton 3894: val.typed_data.unit == UNIT_BOX))
1.387 quint 3895: CSSParseError ("height value", ptr, cssRule);
3896: else if (DoDialog)
1.366 vatton 3897: DisplayStyleValue ("height", ptr, cssRule);
3898: else if (DoApply)
1.295 vatton 3899: /* install the new presentation */
3900: TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.117 vatton 3901: return (cssRule);
1.1 cvs 3902: }
3903:
3904: /*----------------------------------------------------------------------
1.382 vatton 3905: ParseCSSMaxHeight: parse a CSS height attribute
3906: ----------------------------------------------------------------------*/
3907: static char *ParseCSSMaxHeight (Element element, PSchema tsch,
3908: PresentationContext context, char *cssRule,
3909: CSSInfoPtr css, ThotBool isHTML)
3910: {
3911: PresentationValue val;
3912: char *ptr;
3913:
3914: val.typed_data.real = FALSE;
3915: cssRule = SkipBlanksAndComments (cssRule);
3916: ptr = cssRule;
3917: /* first parse the attribute string */
3918: if (!strncasecmp (cssRule, "auto", 4))
3919: {
3920: val.typed_data.unit = VALUE_AUTO;
3921: val.typed_data.value = 0;
3922: cssRule += 4;
3923: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
3924: }
3925: else
3926: cssRule = ParseCSSUnit (cssRule, &val);
3927:
1.387 quint 3928: if (val.typed_data.unit == UNIT_INVALID ||
3929: (val.typed_data.value != 0 &&
1.382 vatton 3930: val.typed_data.unit == UNIT_BOX))
1.387 quint 3931: CSSParseError ("height value", ptr, cssRule);
3932: else if (DoDialog)
1.382 vatton 3933: DisplayStyleValue ("max-height", ptr, cssRule);
1.390 vatton 3934: /*else if (DoApply)
3935: install the new presentation
3936: TtaSetStylePresentation (PRHeight, element, tsch, context, val)*/;
1.382 vatton 3937: return (cssRule);
3938: }
3939:
3940: /*----------------------------------------------------------------------
3941: ParseCSSMinHeight: parse a CSS height attribute
3942: ----------------------------------------------------------------------*/
3943: static char *ParseCSSMinHeight (Element element, PSchema tsch,
3944: PresentationContext context, char *cssRule,
3945: CSSInfoPtr css, ThotBool isHTML)
3946: {
3947: PresentationValue val;
3948: char *ptr;
3949:
3950: val.typed_data.real = FALSE;
3951: cssRule = SkipBlanksAndComments (cssRule);
3952: ptr = cssRule;
3953: /* first parse the attribute string */
3954: if (!strncasecmp (cssRule, "auto", 4))
3955: {
3956: val.typed_data.unit = VALUE_AUTO;
3957: val.typed_data.value = 0;
3958: cssRule += 4;
3959: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
3960: }
3961: else
3962: cssRule = ParseCSSUnit (cssRule, &val);
3963:
1.387 quint 3964: if (val.typed_data.unit == UNIT_INVALID ||
3965: (val.typed_data.value != 0 &&
1.382 vatton 3966: val.typed_data.unit == UNIT_BOX))
1.387 quint 3967: CSSParseError ("height value", ptr, cssRule);
3968: else if (DoDialog)
1.382 vatton 3969: DisplayStyleValue ("min-height", ptr, cssRule);
1.390 vatton 3970: /*else if (DoApply)*/
1.382 vatton 3971: /* install the new presentation */
1.384 vatton 3972: /*TtaSetStylePresentation (PRHeight, element, tsch, context, val)*/;
1.382 vatton 3973: return (cssRule);
3974: }
3975:
3976: /*----------------------------------------------------------------------
1.327 vatton 3977: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 3978: ----------------------------------------------------------------------*/
1.79 cvs 3979: static char *ParseCSSWidth (Element element, PSchema tsch,
1.327 vatton 3980: PresentationContext context,
3981: char *cssRule, CSSInfoPtr css,
3982: ThotBool isHTML)
1.1 cvs 3983: {
1.117 vatton 3984: PresentationValue val;
1.168 vatton 3985: char *ptr;
1.93 vatton 3986:
1.370 vatton 3987: val.typed_data.real = FALSE;
1.117 vatton 3988: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 3989: ptr = cssRule;
1.117 vatton 3990: /* first parse the attribute string */
1.164 quint 3991: if (!strncasecmp (cssRule, "auto", 4))
3992: {
1.184 vatton 3993: val.typed_data.unit = VALUE_AUTO;
1.164 quint 3994: val.typed_data.value = 0;
1.288 vatton 3995: cssRule += 4;
3996: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
1.164 quint 3997: }
1.117 vatton 3998: else
1.327 vatton 3999: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4000: if (val.typed_data.unit == UNIT_INVALID ||
4001: (val.typed_data.value != 0 &&
1.184 vatton 4002: val.typed_data.unit == UNIT_BOX))
1.387 quint 4003: CSSParseError ("Invalid width value", ptr, cssRule);
4004: else if (DoDialog)
1.366 vatton 4005: DisplayStyleValue ("width", ptr, cssRule);
4006: else if (DoApply)
1.295 vatton 4007: /* install the new presentation */
4008: TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.117 vatton 4009: return (cssRule);
1.1 cvs 4010: }
4011:
4012: /*----------------------------------------------------------------------
1.382 vatton 4013: ParseCSSMaxWidth: parse a CSS width attribute
4014: ----------------------------------------------------------------------*/
4015: static char *ParseCSSMaxWidth (Element element, PSchema tsch,
4016: PresentationContext context,
4017: char *cssRule, CSSInfoPtr css,
4018: ThotBool isHTML)
4019: {
4020: PresentationValue val;
4021: char *ptr;
4022:
4023: val.typed_data.real = FALSE;
4024: cssRule = SkipBlanksAndComments (cssRule);
4025: ptr = cssRule;
4026: /* first parse the attribute string */
4027: if (!strncasecmp (cssRule, "auto", 4))
4028: {
4029: val.typed_data.unit = VALUE_AUTO;
4030: val.typed_data.value = 0;
4031: cssRule += 4;
4032: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
4033: }
4034: else
4035: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4036: if (val.typed_data.unit == UNIT_INVALID ||
4037: (val.typed_data.value != 0 &&
1.382 vatton 4038: val.typed_data.unit == UNIT_BOX))
4039: CSSParseError ("Invalid width value", ptr, cssRule);
1.387 quint 4040: else if (DoDialog)
1.382 vatton 4041: DisplayStyleValue ("max-width", ptr, cssRule);
4042: else if (DoApply)
4043: /* install the new presentation */
1.384 vatton 4044: /*TtaSetStylePresentation (PRWidth, element, tsch, context, val)*/;
1.382 vatton 4045: return (cssRule);
4046: }
4047:
4048: /*----------------------------------------------------------------------
4049: ParseCSSMinWidth: parse a CSS width attribute
4050: ----------------------------------------------------------------------*/
4051: static char *ParseCSSMinWidth (Element element, PSchema tsch,
4052: PresentationContext context,
4053: char *cssRule, CSSInfoPtr css,
4054: ThotBool isHTML)
4055: {
4056: PresentationValue val;
4057: char *ptr;
4058:
4059: val.typed_data.real = FALSE;
4060: cssRule = SkipBlanksAndComments (cssRule);
4061: ptr = cssRule;
4062: /* first parse the attribute string */
4063: if (!strncasecmp (cssRule, "auto", 4))
4064: {
4065: val.typed_data.unit = VALUE_AUTO;
4066: val.typed_data.value = 0;
4067: cssRule += 4;
4068: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
4069: }
4070: else
4071: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4072: if (val.typed_data.unit == UNIT_INVALID ||
4073: (val.typed_data.value != 0 &&
1.382 vatton 4074: val.typed_data.unit == UNIT_BOX))
1.387 quint 4075: CSSParseError ("Invalid width value", ptr, cssRule);
4076: else if (DoDialog)
1.382 vatton 4077: DisplayStyleValue ("min-width", ptr, cssRule);
4078: else if (DoApply)
4079: /* install the new presentation */
1.384 vatton 4080: /*TtaSetStylePresentation (PRWidth, element, tsch, context, val)*/;
1.382 vatton 4081: return (cssRule);
4082: }
4083:
4084: /*----------------------------------------------------------------------
1.391 vatton 4085: GetEmMarginValue returns the em value
4086: ----------------------------------------------------------------------*/
4087: int GetEmValue (char *data, Element el, Document doc)
4088: {
4089: PresentationValue val;
4090: char *ptr;
4091: int value;
4092:
4093: val.typed_data.real = FALSE;
4094: ptr = SkipBlanksAndComments (data);
4095: if (!strncasecmp (data, "auto", 4))
4096: value = TtaGetPixelValue (0, VALUE_AUTO, el, doc);
4097: else
4098: {
4099: ptr = ParseCSSUnit (data, &val);
4100: value = TtaGetPixelValue (val.typed_data.value, val.typed_data.unit,
4101: el, doc);
4102: }
4103: return TtaGetLogicalValue (value, UNIT_EM, el, doc);
4104: }
4105:
4106: /*----------------------------------------------------------------------
1.327 vatton 4107: ParseACSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 4108: ----------------------------------------------------------------------*/
1.296 vatton 4109: static char *ParseACSSMarginTop (Element element, PSchema tsch,
1.327 vatton 4110: PresentationContext context,
4111: char *cssRule, CSSInfoPtr css,
4112: ThotBool isHTML)
1.1 cvs 4113: {
4114: PresentationValue margin;
1.168 vatton 4115: char *ptr;
1.1 cvs 4116:
1.370 vatton 4117: margin.typed_data.real = FALSE;
1.82 cvs 4118: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4119: ptr = cssRule;
1.1 cvs 4120: /* first parse the attribute string */
1.164 quint 4121: if (!strncasecmp (cssRule, "auto", 4))
4122: {
1.184 vatton 4123: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4124: margin.typed_data.value = 0;
1.288 vatton 4125: cssRule += 4;
1.164 quint 4126: }
4127: else
1.168 vatton 4128: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4129:
1.387 quint 4130: if (margin.typed_data.unit == UNIT_INVALID ||
4131: (margin.typed_data.value != 0 &&
1.184 vatton 4132: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4133: CSSParseError ("Invalid margin-top value", ptr, cssRule);
1.366 vatton 4134: else if (DoDialog)
4135: {
4136: if (All_sides)
4137: DisplayStyleValue ("margin", ptr, cssRule);
4138: else
4139: DisplayStyleValue ("margin-top", ptr, cssRule);
4140: }
1.168 vatton 4141: else if (DoApply)
1.295 vatton 4142: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
1.1 cvs 4143: return (cssRule);
4144: }
4145:
4146: /*----------------------------------------------------------------------
1.327 vatton 4147: ParseCSSMarginTop: parse a CSS margin-top attribute
1.296 vatton 4148: ----------------------------------------------------------------------*/
4149: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.327 vatton 4150: PresentationContext context,
4151: char *cssRule, CSSInfoPtr css,
4152: ThotBool isHTML)
1.296 vatton 4153: {
4154: char *ptr = cssRule;
4155:
4156: cssRule = ParseACSSMarginTop (element, tsch, context, ptr, css, isHTML);
4157: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-top value");
4158: return (cssRule);
4159: }
4160:
4161: /*----------------------------------------------------------------------
4162: ParseACSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 4163: ----------------------------------------------------------------------*/
1.296 vatton 4164: static char *ParseACSSMarginBottom (Element element, PSchema tsch,
1.327 vatton 4165: PresentationContext context,
4166: char *cssRule, CSSInfoPtr css,
4167: ThotBool isHTML)
1.1 cvs 4168: {
4169: PresentationValue margin;
1.168 vatton 4170: char *ptr;
1.1 cvs 4171:
1.370 vatton 4172: margin.typed_data.real = FALSE;
1.82 cvs 4173: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4174: ptr = cssRule;
1.1 cvs 4175: /* first parse the attribute string */
1.164 quint 4176: if (!strncasecmp (cssRule, "auto", 4))
4177: {
1.184 vatton 4178: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4179: margin.typed_data.value = 0;
1.288 vatton 4180: cssRule += 4;
1.164 quint 4181: }
4182: else
1.168 vatton 4183: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4184:
1.387 quint 4185: if (margin.typed_data.unit == UNIT_INVALID ||
4186: (margin.typed_data.value != 0 &&
1.184 vatton 4187: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4188: CSSParseError ("Invalid margin-bottom value", ptr, cssRule);
1.366 vatton 4189: else if (DoDialog)
4190: DisplayStyleValue ("margin-bottom", ptr, cssRule);
1.168 vatton 4191: else if (DoApply)
1.295 vatton 4192: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
1.1 cvs 4193: return (cssRule);
4194: }
4195:
4196: /*----------------------------------------------------------------------
1.296 vatton 4197: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
4198: ----------------------------------------------------------------------*/
4199: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.327 vatton 4200: PresentationContext context,
4201: char *cssRule, CSSInfoPtr css,
4202: ThotBool isHTML)
1.296 vatton 4203: {
4204: char *ptr = cssRule;
4205:
4206: cssRule = ParseACSSMarginBottom (element, tsch, context, ptr, css, isHTML);
4207: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-bottom value");
4208: return (cssRule);
4209: }
4210:
4211: /*----------------------------------------------------------------------
4212: ParseACSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 4213: ----------------------------------------------------------------------*/
1.296 vatton 4214: static char *ParseACSSMarginLeft (Element element, PSchema tsch,
1.327 vatton 4215: PresentationContext context,
4216: char *cssRule, CSSInfoPtr css,
4217: ThotBool isHTML)
1.1 cvs 4218: {
4219: PresentationValue margin;
1.168 vatton 4220: char *ptr;
1.1 cvs 4221:
1.370 vatton 4222: margin.typed_data.real = FALSE;
1.82 cvs 4223: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4224: ptr = cssRule;
1.1 cvs 4225: /* first parse the attribute string */
1.164 quint 4226: if (!strncasecmp (cssRule, "auto", 4))
4227: {
1.184 vatton 4228: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4229: margin.typed_data.value = 0;
1.288 vatton 4230: cssRule += 4;
1.164 quint 4231: }
4232: else
1.168 vatton 4233: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4234:
1.387 quint 4235: if (margin.typed_data.unit == UNIT_INVALID ||
4236: (margin.typed_data.value != 0 &&
1.184 vatton 4237: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4238: CSSParseError ("Invalid margin-left value", ptr, cssRule);
1.366 vatton 4239: else if (DoDialog)
4240: DisplayStyleValue ("margin-left", ptr, cssRule);
1.295 vatton 4241: else if (DoApply && margin.typed_data.unit != UNIT_INVALID && DoApply)
1.327 vatton 4242: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
1.1 cvs 4243: return (cssRule);
4244: }
4245:
4246: /*----------------------------------------------------------------------
1.296 vatton 4247: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
4248: ----------------------------------------------------------------------*/
4249: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.327 vatton 4250: PresentationContext context,
4251: char *cssRule, CSSInfoPtr css,
4252: ThotBool isHTML)
1.296 vatton 4253: {
4254: char *ptr = cssRule;
4255:
4256: cssRule = ParseACSSMarginLeft (element, tsch, context, ptr, css, isHTML);
4257: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-left value");
4258: return (cssRule);
4259: }
4260:
4261:
4262: /*----------------------------------------------------------------------
4263: ParseACSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 4264: ----------------------------------------------------------------------*/
1.296 vatton 4265: static char *ParseACSSMarginRight (Element element, PSchema tsch,
1.327 vatton 4266: PresentationContext context,
4267: char *cssRule, CSSInfoPtr css,
4268: ThotBool isHTML)
1.1 cvs 4269: {
4270: PresentationValue margin;
1.168 vatton 4271: char *ptr;
1.1 cvs 4272:
1.370 vatton 4273: margin.typed_data.real = FALSE;
1.82 cvs 4274: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4275: ptr = cssRule;
1.1 cvs 4276: /* first parse the attribute string */
1.164 quint 4277: if (!strncasecmp (cssRule, "auto", 4))
4278: {
1.184 vatton 4279: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4280: margin.typed_data.value = 0;
1.288 vatton 4281: cssRule += 4;
1.164 quint 4282: }
4283: else
1.168 vatton 4284: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4285:
1.387 quint 4286: if (margin.typed_data.unit == UNIT_INVALID ||
4287: (margin.typed_data.value != 0 &&
1.184 vatton 4288: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4289: CSSParseError ("Invalid margin-right value", ptr, cssRule);
1.366 vatton 4290: else if (DoDialog)
4291: DisplayStyleValue ("margin-right", ptr, cssRule);
1.168 vatton 4292: else if (DoApply)
1.295 vatton 4293: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
1.1 cvs 4294: return (cssRule);
4295: }
4296:
4297: /*----------------------------------------------------------------------
1.296 vatton 4298: ParseCSSMarginRight: parse a CSS margin-right attribute string
4299: ----------------------------------------------------------------------*/
4300: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.327 vatton 4301: PresentationContext context,
4302: char *cssRule, CSSInfoPtr css,
4303: ThotBool isHTML)
1.296 vatton 4304: {
4305: char *ptr = cssRule;
4306:
1.297 vatton 4307: cssRule = ParseACSSMarginRight (element, tsch, context, ptr, css, isHTML);
1.296 vatton 4308: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-right value");
4309: return (cssRule);
4310: }
4311:
4312: /*----------------------------------------------------------------------
1.59 cvs 4313: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 4314: ----------------------------------------------------------------------*/
1.79 cvs 4315: static char *ParseCSSMargin (Element element, PSchema tsch,
1.327 vatton 4316: PresentationContext context,
4317: char *cssRule, CSSInfoPtr css,
4318: ThotBool isHTML)
1.1 cvs 4319: {
1.79 cvs 4320: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 4321: int skippedNL, n;
1.1 cvs 4322:
1.82 cvs 4323: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 4324: if (DoDialog)
4325: n = NumberOfValues (ptrT);
4326: if (DoDialog && n < 2)
1.1 cvs 4327: {
1.366 vatton 4328: // check if the margin dialog must be updated
4329: All_sides = TRUE;
4330: ptrR = ParseACSSMarginTop (element, tsch, context, ptrT, css, isHTML);
4331: All_sides = FALSE;
1.1 cvs 4332: }
4333: else
4334: {
1.366 vatton 4335: /* First parse Margin-Top */
4336: ptrR = ParseACSSMarginTop (element, tsch, context, ptrT, css, isHTML);
4337: ptrR = SkipBlanksAndComments (ptrR);
4338: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 4339: {
4340: skippedNL = NewLineSkipped;
1.366 vatton 4341: cssRule = ptrR;
4342: /* apply the Margin-Top to all */
4343: ptrR = ParseACSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4344: NewLineSkipped = skippedNL;
1.366 vatton 4345: ptrR = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
4346: NewLineSkipped = skippedNL;
4347: ptrR = ParseACSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4348: }
1.1 cvs 4349: else
1.327 vatton 4350: {
1.366 vatton 4351: /* parse Margin-Right */
4352: ptrB = ParseACSSMarginRight (element, tsch, context, ptrR, css, isHTML);
4353: ptrB = SkipBlanksAndComments (ptrB);
4354: if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 4355: {
1.366 vatton 4356: skippedNL = NewLineSkipped;
4357: cssRule = ptrB;
4358: /* apply the Margin-Top to Margin-Bottom */
4359: ptrB = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
4360: NewLineSkipped = skippedNL;
1.327 vatton 4361: /* apply the Margin-Right to Margin-Left */
1.366 vatton 4362: ptrB = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 4363: }
4364: else
1.366 vatton 4365: {
4366: /* parse Margin-Bottom */
4367: ptrL = ParseACSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
4368: ptrL = SkipBlanksAndComments (ptrL);
4369: if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
4370: {
4371: cssRule = ptrL;
4372: /* apply the Margin-Right to Margin-Left */
4373: ptrL = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
4374: }
4375: else
4376: /* parse Margin-Left */
4377: cssRule = ParseACSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
4378: cssRule = SkipBlanksAndComments (cssRule);
4379: }
1.327 vatton 4380: }
1.1 cvs 4381: }
4382: return (cssRule);
4383: }
4384:
4385: /*----------------------------------------------------------------------
1.327 vatton 4386: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 4387: ----------------------------------------------------------------------*/
1.79 cvs 4388: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.327 vatton 4389: PresentationContext context,
4390: char *cssRule, CSSInfoPtr css,
4391: ThotBool isHTML)
1.1 cvs 4392: {
1.43 cvs 4393: PresentationValue padding;
1.168 vatton 4394: char *ptr;
1.370 vatton 4395:
4396: padding.typed_data.real = FALSE;
1.82 cvs 4397: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4398: ptr = cssRule;
1.43 cvs 4399: /* first parse the attribute string */
4400: cssRule = ParseCSSUnit (cssRule, &padding);
1.295 vatton 4401:
1.387 quint 4402: if (padding.typed_data.unit == UNIT_INVALID ||
4403: (padding.typed_data.value != 0 &&
1.184 vatton 4404: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4405: CSSParseError ("Invalid padding-top value", ptr, cssRule);
1.366 vatton 4406: else if (DoDialog)
4407: {
4408: if (All_sides)
4409: DisplayStyleValue ("padding", ptr, cssRule);
4410: else
4411: DisplayStyleValue ("padding-top", ptr, cssRule);
4412: }
1.168 vatton 4413: else if (DoApply)
1.295 vatton 4414: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
1.1 cvs 4415: return (cssRule);
4416: }
4417:
4418: /*----------------------------------------------------------------------
1.59 cvs 4419: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 4420: ----------------------------------------------------------------------*/
1.79 cvs 4421: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.327 vatton 4422: PresentationContext context,
4423: char *cssRule, CSSInfoPtr css,
4424: ThotBool isHTML)
1.1 cvs 4425: {
1.43 cvs 4426: PresentationValue padding;
1.168 vatton 4427: char *ptr;
1.43 cvs 4428:
1.370 vatton 4429: padding.typed_data.real = FALSE;
1.82 cvs 4430: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4431: ptr = cssRule;
1.43 cvs 4432: /* first parse the attribute string */
4433: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4434: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4435: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4436:
1.387 quint 4437: if (padding.typed_data.unit == UNIT_INVALID ||
4438: (padding.typed_data.value != 0 &&
1.184 vatton 4439: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4440: CSSParseError ("Invalid padding-bottom value", ptr, cssRule);
1.366 vatton 4441: else if (DoDialog)
4442: DisplayStyleValue ("padding-bottom", ptr, cssRule);
1.168 vatton 4443: else if (DoApply)
1.295 vatton 4444: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
1.1 cvs 4445: return (cssRule);
4446: }
4447:
4448: /*----------------------------------------------------------------------
1.59 cvs 4449: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 4450: ----------------------------------------------------------------------*/
1.79 cvs 4451: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.327 vatton 4452: PresentationContext context,
4453: char *cssRule, CSSInfoPtr css,
4454: ThotBool isHTML)
1.1 cvs 4455: {
1.43 cvs 4456: PresentationValue padding;
1.168 vatton 4457: char *ptr;
1.43 cvs 4458:
1.370 vatton 4459: padding.typed_data.real = FALSE;
1.82 cvs 4460: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4461: ptr = cssRule;
1.43 cvs 4462: /* first parse the attribute string */
4463: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4464: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4465: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4466:
1.387 quint 4467: if (padding.typed_data.unit == UNIT_INVALID ||
4468: (padding.typed_data.value != 0 &&
1.184 vatton 4469: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 4470: {
1.169 vatton 4471: CSSParseError ("Invalid padding-left value", ptr, cssRule);
1.168 vatton 4472: padding.typed_data.value = 0;
4473: }
1.366 vatton 4474: else if (DoDialog)
4475: DisplayStyleValue ("padding-left", ptr, cssRule);
1.168 vatton 4476: else if (DoApply)
1.295 vatton 4477: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.1 cvs 4478: return (cssRule);
4479: }
4480:
4481: /*----------------------------------------------------------------------
1.59 cvs 4482: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 4483: ----------------------------------------------------------------------*/
1.79 cvs 4484: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.327 vatton 4485: PresentationContext context,
4486: char *cssRule, CSSInfoPtr css,
4487: ThotBool isHTML)
1.1 cvs 4488: {
1.43 cvs 4489: PresentationValue padding;
1.168 vatton 4490: char *ptr;
1.43 cvs 4491:
1.370 vatton 4492: padding.typed_data.real = FALSE;
1.82 cvs 4493: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4494: ptr = cssRule;
1.43 cvs 4495: /* first parse the attribute string */
4496: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4497: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4498: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4499:
1.387 quint 4500: if (padding.typed_data.unit == UNIT_INVALID ||
4501: (padding.typed_data.value != 0 &&
1.184 vatton 4502: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4503: CSSParseError ("Invalid padding-right value", ptr, cssRule);
1.366 vatton 4504: else if (DoDialog)
4505: DisplayStyleValue ("padding-right", ptr, cssRule);
1.168 vatton 4506: else if (DoApply)
1.295 vatton 4507: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.1 cvs 4508: return (cssRule);
4509: }
4510:
4511: /*----------------------------------------------------------------------
1.327 vatton 4512: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 4513: ----------------------------------------------------------------------*/
1.79 cvs 4514: static char *ParseCSSPadding (Element element, PSchema tsch,
1.327 vatton 4515: PresentationContext context,
4516: char *cssRule, CSSInfoPtr css,
4517: ThotBool isHTML)
1.1 cvs 4518: {
1.79 cvs 4519: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 4520: int skippedNL, n;
1.43 cvs 4521:
1.82 cvs 4522: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 4523: if (DoDialog)
4524: n = NumberOfValues (ptrT);
4525: if (DoDialog && n < 2)
1.43 cvs 4526: {
1.366 vatton 4527: // check if the padding dialog must be updated
4528: All_sides = TRUE;
4529: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
4530: All_sides = FALSE;
1.43 cvs 4531: }
4532: else
4533: {
1.366 vatton 4534: /* First parse Padding-Top */
4535: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
4536: ptrR = SkipBlanksAndComments (ptrR);
4537: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 4538: {
4539: skippedNL = NewLineSkipped;
1.366 vatton 4540: cssRule = ptrR;
4541: /* apply the Padding-Top to all */
4542: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4543: NewLineSkipped = skippedNL;
1.366 vatton 4544: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
4545: NewLineSkipped = skippedNL;
4546: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4547: }
1.43 cvs 4548: else
1.327 vatton 4549: {
1.366 vatton 4550: /* parse Padding-Right */
4551: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
4552: ptrB = SkipBlanksAndComments (ptrB);
4553: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 4554: {
1.366 vatton 4555: skippedNL = NewLineSkipped;
4556: cssRule = ptrB;
4557: /* apply the Padding-Top to Padding-Bottom */
4558: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
4559: NewLineSkipped = skippedNL;
1.327 vatton 4560: /* apply the Padding-Right to Padding-Left */
1.366 vatton 4561: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 4562: }
4563: else
1.366 vatton 4564: {
4565: /* parse Padding-Bottom */
4566: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
4567: ptrL = SkipBlanksAndComments (ptrL);
4568: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
4569: {
4570: cssRule = ptrL;
4571: /* apply the Padding-Right to Padding-Left */
4572: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
4573: }
4574: else
4575: /* parse Padding-Left */
4576: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
4577: cssRule = SkipBlanksAndComments (cssRule);
4578: }
1.327 vatton 4579: }
1.43 cvs 4580: }
1.1 cvs 4581: return (cssRule);
4582: }
4583:
4584: /*----------------------------------------------------------------------
1.327 vatton 4585: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 4586: ----------------------------------------------------------------------*/
1.79 cvs 4587: static char *ParseCSSForeground (Element element, PSchema tsch,
1.327 vatton 4588: PresentationContext context,
4589: char *cssRule,
4590: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 4591: {
1.117 vatton 4592: PresentationValue best;
1.262 vatton 4593: char *p;
1.1 cvs 4594:
1.370 vatton 4595: best.typed_data.real = FALSE;
1.366 vatton 4596: cssRule = SkipBlanksAndComments (cssRule);
1.262 vatton 4597: p = cssRule;
1.117 vatton 4598: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4599: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4600: {
4601: if (*cssRule != EOS && *cssRule !=';')
4602: {
4603: cssRule = SkipProperty (cssRule, FALSE);
1.366 vatton 4604: CSSParseError ("Invalid color value", p, cssRule);
1.327 vatton 4605: }
1.366 vatton 4606: else if (DoDialog)
4607: DisplayStyleValue ("color", p, cssRule);
4608: else if (DoApply)
1.327 vatton 4609: /* install the new presentation */
4610: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
4611: }
4612: return (cssRule);
1.1 cvs 4613: }
4614:
4615: /*----------------------------------------------------------------------
1.59 cvs 4616: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 4617: ----------------------------------------------------------------------*/
1.79 cvs 4618: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.327 vatton 4619: PresentationContext context,
4620: char *cssRule,
4621: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 4622: {
4623: PresentationValue best;
1.366 vatton 4624: char *ptr;
1.1 cvs 4625:
1.370 vatton 4626: best.typed_data.real = FALSE;
1.366 vatton 4627: cssRule = SkipBlanksAndComments (cssRule);
4628: ptr = cssRule;
1.184 vatton 4629: best.typed_data.unit = UNIT_INVALID;
1.1 cvs 4630: best.typed_data.real = FALSE;
1.198 vatton 4631: if (!strncasecmp (cssRule, "transparent", 11))
1.1 cvs 4632: {
1.184 vatton 4633: best.typed_data.value = PATTERN_NONE;
4634: best.typed_data.unit = UNIT_REL;
1.295 vatton 4635: cssRule = SkipWord (cssRule);
1.116 vatton 4636: if (DoApply)
1.327 vatton 4637: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4638: }
1.1 cvs 4639: else
4640: {
4641: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4642: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4643: {
1.366 vatton 4644: if (DoDialog)
4645: DisplayStyleValue ("background-color", ptr, cssRule);
4646: else if (DoApply)
4647: {
4648: /* install the new presentation. */
4649: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
4650: /* thot specificity: need to set fill pattern for background color */
4651: best.typed_data.value = PATTERN_BACKGROUND;
4652: best.typed_data.unit = UNIT_REL;
4653: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4654: best.typed_data.value = 1;
4655: best.typed_data.unit = UNIT_REL;
4656: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
4657: }
1.327 vatton 4658: }
1.1 cvs 4659: }
4660: return (cssRule);
4661: }
4662:
1.63 cvs 4663: /*----------------------------------------------------------------------
1.65 cvs 4664: ParseSVGStroke: parse a SVG stroke property
4665: ----------------------------------------------------------------------*/
1.79 cvs 4666: static char *ParseSVGStroke (Element element, PSchema tsch,
1.327 vatton 4667: PresentationContext context, char *cssRule,
4668: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 4669: {
4670: PresentationValue best;
1.245 quint 4671: char *url;
1.65 cvs 4672:
1.184 vatton 4673: best.typed_data.unit = UNIT_INVALID;
1.65 cvs 4674: best.typed_data.real = FALSE;
1.82 cvs 4675: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 4676: {
4677: best.typed_data.value = -2; /* -2 means transparent */
1.184 vatton 4678: best.typed_data.unit = UNIT_REL;
1.65 cvs 4679: cssRule = SkipWord (cssRule);
4680: }
1.245 quint 4681: else if (!strncasecmp (cssRule, "currentColor", 12))
4682: {
1.293 quint 4683: best.typed_data.unit = VALUE_INHERIT;
4684: cssRule = SkipWord (cssRule);
1.245 quint 4685: }
4686: else if (!strncasecmp (cssRule, "url", 3))
4687: {
4688: cssRule += 3;
4689: cssRule = ParseCSSUrl (cssRule, &url);
4690: /* **** do something with the url ***** */;
4691: TtaFreeMemory (url);
4692: /* **** caution: another color value may follow the uri (in case
1.327 vatton 4693: the uri could ne be dereferenced) *** */
1.245 quint 4694: }
1.65 cvs 4695: else
1.293 quint 4696: cssRule = ParseCSSColor (cssRule, &best);
4697:
4698: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.295 vatton 4699: /* install the new presentation */
4700: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.65 cvs 4701: return (cssRule);
4702: }
4703:
4704: /*----------------------------------------------------------------------
1.63 cvs 4705: ParseSVGFill: parse a SVG fill property
4706: ----------------------------------------------------------------------*/
1.79 cvs 4707: static char *ParseSVGFill (Element element, PSchema tsch,
1.327 vatton 4708: PresentationContext context, char *cssRule,
4709: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 4710: {
4711: PresentationValue best;
1.245 quint 4712: char *url;
1.63 cvs 4713:
1.184 vatton 4714: best.typed_data.unit = UNIT_INVALID;
1.63 cvs 4715: best.typed_data.real = FALSE;
1.82 cvs 4716: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 4717: {
1.184 vatton 4718: best.typed_data.value = PATTERN_NONE;
4719: best.typed_data.unit = UNIT_REL;
1.116 vatton 4720: if (DoApply)
1.327 vatton 4721: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 4722: cssRule = SkipWord (cssRule);
1.294 vatton 4723: return (cssRule);
1.63 cvs 4724: }
1.245 quint 4725: else if (!strncasecmp (cssRule, "currentColor", 12))
4726: {
1.293 quint 4727: best.typed_data.unit = VALUE_INHERIT;
4728: cssRule = SkipWord (cssRule);
1.245 quint 4729: }
4730: else if (!strncasecmp (cssRule, "url", 3))
4731: {
4732: cssRule += 3;
4733: cssRule = ParseCSSUrl (cssRule, &url);
4734: /* **** do something with the url ***** */;
4735: TtaFreeMemory (url);
4736: /* **** caution: another color value may follow the uri (in case
1.327 vatton 4737: the uri could ne be dereferenced) *** */
1.245 quint 4738: }
1.63 cvs 4739: else
1.327 vatton 4740: cssRule = ParseCSSColor (cssRule, &best);
1.293 quint 4741:
4742: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.63 cvs 4743: {
1.293 quint 4744: /* install the new presentation. */
4745: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
4746: /* thot specificity: need to set fill pattern for background color */
4747: best.typed_data.value = PATTERN_BACKGROUND;
4748: best.typed_data.unit = UNIT_REL;
4749: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.63 cvs 4750: }
4751: return (cssRule);
4752: }
1.161 quint 4753:
1.155 cheyroul 4754: /*----------------------------------------------------------------------
1.346 quint 4755: ParseSVGOpacity: parse a SVG opacity property
1.155 cheyroul 4756: ----------------------------------------------------------------------*/
4757: static char *ParseSVGOpacity (Element element, PSchema tsch,
1.327 vatton 4758: PresentationContext context, char *cssRule,
4759: CSSInfoPtr css, ThotBool isHTML)
1.155 cheyroul 4760: {
4761: PresentationValue best;
1.63 cvs 4762:
1.184 vatton 4763: best.typed_data.unit = UNIT_INVALID;
1.155 cheyroul 4764: best.typed_data.real = FALSE;
4765: cssRule = ParseClampedUnit (cssRule, &best);
4766: if (DoApply)
1.295 vatton 4767: /* install the new presentation. */
4768: TtaSetStylePresentation (PROpacity, element, tsch, context, best);
1.155 cheyroul 4769: return (cssRule);
4770: }
1.346 quint 4771:
1.170 cheyroul 4772: /*----------------------------------------------------------------------
1.346 quint 4773: ParseSVGStrokeOpacity: parse a SVG stroke-opacity property
1.170 cheyroul 4774: ----------------------------------------------------------------------*/
4775: static char *ParseSVGStrokeOpacity (Element element, PSchema tsch,
1.327 vatton 4776: PresentationContext context, char *cssRule,
4777: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 4778: {
4779: PresentationValue best;
1.161 quint 4780:
1.184 vatton 4781: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 4782: best.typed_data.real = FALSE;
4783: cssRule = ParseClampedUnit (cssRule, &best);
4784: if (DoApply)
1.295 vatton 4785: /* install the new presentation. */
4786: TtaSetStylePresentation (PRStrokeOpacity, element, tsch, context, best);
1.170 cheyroul 4787: return (cssRule);
4788: }
1.346 quint 4789:
1.170 cheyroul 4790: /*----------------------------------------------------------------------
1.346 quint 4791: ParseSVGFillOpacity: parse a SVG fil-opacityl property
1.170 cheyroul 4792: ----------------------------------------------------------------------*/
4793: static char *ParseSVGFillOpacity (Element element, PSchema tsch,
1.327 vatton 4794: PresentationContext context, char *cssRule,
4795: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 4796: {
4797: PresentationValue best;
4798:
1.184 vatton 4799: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 4800: best.typed_data.real = FALSE;
4801: cssRule = ParseClampedUnit (cssRule, &best);
4802: if (DoApply)
1.295 vatton 4803: /* install the new presentation. */
4804: TtaSetStylePresentation (PRFillOpacity, element, tsch, context, best);
1.170 cheyroul 4805: return (cssRule);
4806: }
1.207 vatton 4807:
1.1 cvs 4808: /*----------------------------------------------------------------------
1.327 vatton 4809: GetCSSBackgroundURL searches a CSS BackgroundImage url within
4810: the cssRule.
4811: Returns NULL or a new allocated url string.
1.217 vatton 4812: ----------------------------------------------------------------------*/
4813: char *GetCSSBackgroundURL (char *cssRule)
4814: {
4815: char *b, *url;
4816:
4817: url = NULL;
4818: b = strstr (cssRule, "url");
4819: if (b)
1.290 gully 4820: b = ParseCSSUrl (b, &url);
1.217 vatton 4821: return (url);
4822: }
4823:
4824: /*----------------------------------------------------------------------
1.327 vatton 4825: ParseCSSContent: parse the value of property "content"
1.217 vatton 4826: ----------------------------------------------------------------------*/
4827: static char *ParseCSSContent (Element element, PSchema tsch,
1.327 vatton 4828: PresentationContext ctxt, char *cssRule,
4829: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 4830: {
1.312 quint 4831: PresentationValue value;
1.353 quint 4832: char *last, *start, quoteChar, savedChar;
4833: int length, val;
1.366 vatton 4834: char *buffer, *p;
4835: char *start_value;
1.312 quint 4836: ThotBool repeat;
4837:
4838: value.typed_data.unit = UNIT_REL;
4839: value.typed_data.real = FALSE;
4840: value.typed_data.value = 0;
1.366 vatton 4841: if (!DoDialog && DoApply)
1.347 quint 4842: TtaSetStylePresentation (PRContent, element, tsch, ctxt, value);
1.217 vatton 4843: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 4844: start_value = cssRule;
1.312 quint 4845: repeat = TRUE;
4846: while (repeat)
4847: {
1.366 vatton 4848: p = cssRule;
1.312 quint 4849: if (!strncasecmp (cssRule, "normal", 6))
1.327 vatton 4850: /* The pseudo-element is not generated */
4851: {
4852: /* @@@@@@ */
4853: cssRule += 6;
4854: repeat = FALSE;
4855: }
1.331 quint 4856: else if (!strncasecmp (cssRule, "none", 4))
4857: /* The pseudo-element is not generated */
4858: {
4859: /* @@@@@@ */
4860: cssRule += 4;
4861: repeat = FALSE;
4862: }
1.312 quint 4863: else if (*cssRule == '"' || *cssRule == '\'')
1.327 vatton 4864: /* It's a string */
4865: {
4866: quoteChar = *cssRule;
1.353 quint 4867: /* how long is the string? */
4868: last = cssRule;
4869: last = SkipString (last);
4870: length = last - cssRule;
4871: /* get a buffer to store the string */
1.366 vatton 4872: buffer = (char *)TtaGetMemory (length);
1.353 quint 4873: p = buffer; /* beginning of the string */
1.327 vatton 4874: cssRule++;
4875: while (*cssRule != EOS && *cssRule != quoteChar)
1.353 quint 4876: {
4877: if (*cssRule == '\\')
4878: {
4879: cssRule++; /* skip the backslash */
4880: if ((*cssRule >= '0' && *cssRule <= '9') ||
4881: (*cssRule >= 'A' && *cssRule <= 'F') ||
4882: (*cssRule >= 'a' && *cssRule <= 'f'))
4883: {
4884: start = cssRule; /* first hex digit after the backslash*/
4885: cssRule++;
4886: while ((*cssRule >= '0' && *cssRule <= '9') ||
4887: (*cssRule >= 'A' && *cssRule <= 'F') ||
4888: (*cssRule >= 'a' && *cssRule <= 'f'))
4889: cssRule++;
4890: savedChar = *cssRule;
4891: *cssRule = EOS;
4892: sscanf (start, "%x", &val);
1.366 vatton 4893: TtaWCToMBstring ((wchar_t) val, (unsigned char **) &p);
1.353 quint 4894: *cssRule = savedChar;
4895: }
4896: else
4897: {
4898: *p = *cssRule;
4899: p++; cssRule++;
4900: }
4901: }
4902: else
4903: {
4904: *p = *cssRule;
4905: p++; cssRule++;
4906: }
4907: }
4908: *p = EOS;
1.366 vatton 4909: if (DoDialog)
4910: {
4911: DisplayStyleValue ("", start_value, p);
4912: start_value = p;
4913: }
4914: else if (*cssRule != quoteChar)
1.327 vatton 4915: cssRule = SkipProperty (cssRule, FALSE);
4916: else
4917: {
4918: *cssRule = EOS;
4919: value.typed_data.unit = UNIT_REL;
4920: value.typed_data.real = FALSE;
1.353 quint 4921: value.pointer = buffer;
1.347 quint 4922: if (DoApply)
4923: TtaSetStylePresentation (PRContentString, element, tsch, ctxt,
4924: value);
1.327 vatton 4925: *cssRule = quoteChar;
4926: cssRule++;
4927: }
1.353 quint 4928: TtaFreeMemory (buffer);
1.327 vatton 4929: }
1.312 quint 4930: else if (!strncasecmp (cssRule, "url", 3))
1.327 vatton 4931: {
4932: cssRule += 3;
1.347 quint 4933: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
4934: PRContentURL);
1.366 vatton 4935: if (DoDialog)
4936: {
4937: DisplayStyleValue ("", start_value, p);
4938: start_value = p;
4939: }
1.327 vatton 4940: }
1.312 quint 4941: else if (!strncasecmp (cssRule, "counter", 7))
1.327 vatton 4942: {
4943: cssRule += 7;
4944: /* @@@@@@ */
1.366 vatton 4945: if (DoDialog)
4946: {
4947: DisplayStyleValue ("", start_value, p);
4948: start_value = p;
4949: }
4950: else
4951: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 4952: }
1.312 quint 4953: else if (!strncasecmp (cssRule, "counters", 8))
1.327 vatton 4954: {
4955: cssRule += 8;
4956: /* @@@@@@ */
1.366 vatton 4957: if (DoDialog)
4958: {
4959: DisplayStyleValue ("", start_value, p);
4960: start_value = p;
4961: }
4962: else
4963: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 4964: }
1.312 quint 4965: else if (!strncasecmp (cssRule, "attr", 4))
1.327 vatton 4966: {
1.347 quint 4967: value.pointer = NULL;
1.327 vatton 4968: cssRule += 4;
1.347 quint 4969: cssRule = SkipBlanksAndComments (cssRule);
4970: if (*cssRule == '(')
4971: {
4972: cssRule++;
4973: cssRule = SkipBlanksAndComments (cssRule);
4974: start = cssRule;
4975: while (*cssRule != EOS && *cssRule != ')')
4976: cssRule++;
4977: if (*cssRule != ')')
4978: cssRule = start;
4979: else
4980: {
4981: last = cssRule;
4982: /* remove extra spaces */
4983: if (last[-1] == SPACE)
4984: {
4985: *last = SPACE;
4986: last--;
4987: while (last[-1] == SPACE)
4988: last--;
4989: }
4990: savedChar = *last;
4991: *last = EOS;
4992: value.typed_data.unit = UNIT_REL;
4993: value.typed_data.real = FALSE;
4994: value.pointer = start;
1.366 vatton 4995: if (DoDialog)
4996: {
4997: DisplayStyleValue ("", start_value, p);
4998: start_value = p;
4999: }
5000: else if (DoApply)
1.347 quint 5001: TtaSetStylePresentation (PRContentAttr, element, tsch,
5002: ctxt, value);
5003: *last = savedChar;
5004: }
5005: }
5006: if (value.pointer == NULL)
5007: {
1.353 quint 5008: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 5009: if (DoDialog)
5010: {
5011: DisplayStyleValue ("", start_value, p);
5012: start_value = p;
5013: }
5014: else
5015: cssRule = SkipProperty (cssRule, FALSE);
1.347 quint 5016: }
5017: cssRule++;
1.327 vatton 5018: }
1.312 quint 5019: else if (!strncasecmp (cssRule, "open-quote", 10))
1.327 vatton 5020: {
5021: cssRule += 10;
5022: /* @@@@@@ */
5023: }
1.312 quint 5024: else if (!strncasecmp (cssRule, "close-quote", 11))
1.327 vatton 5025: {
5026: cssRule += 11;
5027: /* @@@@@@ */
5028: }
1.312 quint 5029: else if (!strncasecmp (cssRule, "no-open-quote", 13))
1.327 vatton 5030: {
5031: cssRule += 13;
5032: /* @@@@@@ */
5033: }
1.312 quint 5034: else if (!strncasecmp (cssRule, "no-close-quote", 14))
1.327 vatton 5035: {
5036: cssRule += 14;
5037: /* @@@@@@ */
5038: }
1.312 quint 5039: else if (!strncasecmp (cssRule, "inherit", 7))
1.327 vatton 5040: {
5041: cssRule += 7;
5042: /* @@@@@@ */
5043: repeat = FALSE;
5044: }
1.312 quint 5045: else
1.327 vatton 5046: {
1.353 quint 5047: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 5048: if (DoDialog)
5049: {
5050: DisplayStyleValue ("", start_value, p);
5051: start_value = p;
5052: }
5053: else
5054: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5055: }
1.312 quint 5056: cssRule = SkipBlanksAndComments (cssRule);
5057: if (repeat)
1.327 vatton 5058: if (*cssRule == ';' || *cssRule == '}' || *cssRule == EOS ||
5059: *cssRule == '!')
5060: repeat = FALSE;
1.217 vatton 5061: }
5062: return (cssRule);
5063: }
1.1 cvs 5064:
5065: /*----------------------------------------------------------------------
1.59 cvs 5066: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 5067: ----------------------------------------------------------------------*/
1.79 cvs 5068: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
1.327 vatton 5069: PresentationContext ctxt,
5070: char *cssRule, CSSInfoPtr css,
5071: ThotBool isHTML)
1.1 cvs 5072: {
1.49 cvs 5073: PresentationValue image, value;
1.357 quint 5074: char *ptr;
1.148 vatton 5075:
1.370 vatton 5076: image.typed_data.real = FALSE;
5077: value.typed_data.real = FALSE;
1.82 cvs 5078: cssRule = SkipBlanksAndComments (cssRule);
1.357 quint 5079: ptr = cssRule;
1.161 quint 5080: if (!strncasecmp (cssRule, "none", 4))
5081: {
1.260 vatton 5082: cssRule += 4;
1.366 vatton 5083: if (DoDialog)
5084: DisplayStyleValue ("background-image", ptr, cssRule);
5085: else if (DoApply)
1.327 vatton 5086: {
5087: /* no background image */
5088: image.pointer = NULL;
5089: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt,
5090: image);
5091: }
1.161 quint 5092: }
1.357 quint 5093: else if (!strncasecmp (cssRule, "inherit", 7))
5094: {
5095: value.typed_data.unit = VALUE_INHERIT;
5096: cssRule += 7;
1.366 vatton 5097: if (DoDialog)
5098: DisplayStyleValue ("background-image", ptr, cssRule);
1.357 quint 5099: }
1.161 quint 5100: else if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 5101: {
5102: cssRule += 3;
1.302 quint 5103: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 5104: PRBackgroundPicture);
1.207 vatton 5105: if (ctxt->destroy)
1.327 vatton 5106: if (TtaGetStylePresentation (PRFillPattern, element, tsch, ctxt,
5107: &value) < 0)
5108: {
5109: /* there is no FillPattern rule -> remove ShowBox rule */
5110: value.typed_data.value = 1;
5111: value.typed_data.unit = UNIT_REL;
5112: value.typed_data.real = FALSE;
5113: TtaSetStylePresentation (PRShowBox, element, tsch, ctxt, value);
5114: }
1.18 cvs 5115: }
1.357 quint 5116: else
5117: {
5118: cssRule = SkipWord (cssRule);
5119: CSSParseError ("Invalid background-image value", ptr, cssRule);
5120: cssRule = SkipProperty (cssRule, FALSE);
5121: }
1.18 cvs 5122: return (cssRule);
5123: }
5124:
5125: /*----------------------------------------------------------------------
1.295 vatton 5126: ParseACSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 5127: ----------------------------------------------------------------------*/
1.295 vatton 5128: static char *ParseACSSBackgroundRepeat (Element element, PSchema tsch,
1.327 vatton 5129: PresentationContext ctxt,
5130: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5131: {
5132: PresentationValue repeat;
1.366 vatton 5133: char *start_value;
1.18 cvs 5134:
1.366 vatton 5135: cssRule = SkipBlanksAndComments (cssRule);
5136: start_value = cssRule;
1.184 vatton 5137: repeat.typed_data.value = REALSIZE;
1.191 vatton 5138: repeat.typed_data.unit = UNIT_BOX;
1.18 cvs 5139: repeat.typed_data.real = FALSE;
1.82 cvs 5140: cssRule = SkipBlanksAndComments (cssRule);
5141: if (!strncasecmp (cssRule, "no-repeat", 9))
1.184 vatton 5142: repeat.typed_data.value = REALSIZE;
1.82 cvs 5143: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.265 vatton 5144: repeat.typed_data.value = YREPEAT;
1.82 cvs 5145: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.265 vatton 5146: repeat.typed_data.value = XREPEAT;
1.82 cvs 5147: else if (!strncasecmp (cssRule, "repeat", 6))
1.184 vatton 5148: repeat.typed_data.value = REPEAT;
1.18 cvs 5149: else
5150: return (cssRule);
5151:
1.295 vatton 5152: cssRule = SkipWord (cssRule);
5153: /* check if it's an important rule */
1.366 vatton 5154: if (DoDialog)
5155: DisplayStyleValue ("background-repeat", start_value, cssRule);
5156: else if (DoApply)
1.295 vatton 5157: /* install the new presentation */
1.362 quint 5158: TtaSetStylePresentation (PRBackgroundRepeat, element, tsch, ctxt, repeat);
1.295 vatton 5159: return (cssRule);
5160: }
5161:
5162: /*----------------------------------------------------------------------
5163: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
5164: ----------------------------------------------------------------------*/
5165: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.315 gully 5166: PresentationContext ctxt,
5167: char *cssRule, CSSInfoPtr css,
5168: ThotBool isHTML)
1.295 vatton 5169: {
1.388 carcone 5170:
5171: char *ptr;
5172:
5173: ptr = cssRule;
1.295 vatton 5174: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
1.315 gully 5175: cssRule, css, isHTML);
1.388 carcone 5176:
5177: if (ptr == cssRule)
1.117 vatton 5178: {
1.295 vatton 5179: cssRule = SkipValue ("Invalid background-repeat value", cssRule);
1.117 vatton 5180: /* check if it's an important rule */
5181: }
1.295 vatton 5182: return cssRule;
1.18 cvs 5183: }
5184:
5185: /*----------------------------------------------------------------------
1.327 vatton 5186: ParseACSSBackgroundAttachment: parse a CSS BackgroundAttachment
5187: attribute string.
1.18 cvs 5188: ----------------------------------------------------------------------*/
1.295 vatton 5189: static char *ParseACSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5190: PresentationContext ctxt,
5191: char *cssRule, CSSInfoPtr css,
5192: ThotBool isHTML)
1.18 cvs 5193: {
1.366 vatton 5194: char *start_value;
5195:
1.163 quint 5196: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5197: start_value = cssRule;
1.163 quint 5198: if (!strncasecmp (cssRule, "scroll", 6))
1.199 vatton 5199: {
5200: cssRule = SkipWord (cssRule);
5201: }
1.163 quint 5202: else if (!strncasecmp (cssRule, "fixed", 5))
1.199 vatton 5203: {
5204: cssRule = SkipWord (cssRule);
5205: }
1.362 quint 5206: else if (!strncasecmp (cssRule, "inherit", 7))
5207: {
5208: cssRule = SkipWord (cssRule);
5209: }
1.366 vatton 5210: if (start_value != cssRule && DoDialog)
5211: DisplayStyleValue ("background-attachment", start_value, cssRule);
1.163 quint 5212: return (cssRule);
1.1 cvs 5213: }
5214:
5215: /*----------------------------------------------------------------------
1.327 vatton 5216: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
5217: attribute string.
1.295 vatton 5218: ----------------------------------------------------------------------*/
5219: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5220: PresentationContext ctxt,
5221: char *cssRule, CSSInfoPtr css,
5222: ThotBool isHTML)
1.295 vatton 5223: {
5224: char *ptr;
5225:
5226: ptr = cssRule;
5227: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.327 vatton 5228: cssRule, css, isHTML);
1.295 vatton 5229: if (ptr == cssRule)
1.366 vatton 5230: cssRule = SkipValue ("Invalid background-attachment value", cssRule);
1.295 vatton 5231: return cssRule;
5232: }
5233:
5234: /*----------------------------------------------------------------------
1.327 vatton 5235: ParseACSSBackgroundPosition: parse a CSS BackgroundPosition
5236: attribute string.
1.1 cvs 5237: ----------------------------------------------------------------------*/
1.279 vatton 5238: static char *ParseACSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5239: PresentationContext ctxt,
5240: char *cssRule, CSSInfoPtr css,
1.362 quint 5241: ThotBool isHTML, ThotBool *across)
1.1 cvs 5242: {
1.362 quint 5243: PresentationValue val;
5244: char *ptr;
1.1 cvs 5245:
1.163 quint 5246: cssRule = SkipBlanksAndComments (cssRule);
1.362 quint 5247: ptr = cssRule;
5248: val.typed_data.value = 0;
5249: val.typed_data.real = FALSE;
5250: val.typed_data.unit = UNIT_INVALID;
1.163 quint 5251: if (!strncasecmp (cssRule, "left", 4))
1.362 quint 5252: {
5253: val.typed_data.value = 0;
5254: val.typed_data.unit = UNIT_PERCENT;
5255: cssRule += 4;
5256: *across = TRUE;
5257: }
1.163 quint 5258: else if (!strncasecmp (cssRule, "right", 5))
1.362 quint 5259: {
5260: val.typed_data.value = 100;
5261: val.typed_data.unit = UNIT_PERCENT;
5262: cssRule += 5;
5263: *across = TRUE;
5264: }
1.163 quint 5265: else if (!strncasecmp (cssRule, "center", 6))
1.362 quint 5266: {
5267: val.typed_data.value = 50;
5268: val.typed_data.unit = UNIT_PERCENT;
5269: cssRule += 6;
5270: }
1.163 quint 5271: else if (!strncasecmp (cssRule, "top", 3))
1.362 quint 5272: {
5273: val.typed_data.value = 0;
5274: val.typed_data.unit = UNIT_PERCENT;
5275: cssRule += 3;
5276: *across = FALSE;
5277: }
1.163 quint 5278: else if (!strncasecmp (cssRule, "bottom", 6))
1.191 vatton 5279: {
1.362 quint 5280: val.typed_data.value = 100;
5281: val.typed_data.unit = UNIT_PERCENT;
5282: cssRule += 6;
5283: *across = FALSE;
5284: }
5285: else if (!strncasecmp (cssRule, "inherit", 7))
5286: {
5287: val.typed_data.unit = VALUE_INHERIT;
5288: cssRule += 7;
1.191 vatton 5289: }
1.163 quint 5290: else
1.362 quint 5291: /* <length> or <percentage> */
5292: {
5293: cssRule = ParseCSSUnit (cssRule, &val);
5294: if (val.typed_data.unit == UNIT_BOX && val.typed_data.value == 0)
5295: /* 0 with no unit. Accept */
5296: val.typed_data.unit = UNIT_PERCENT;
5297: }
1.163 quint 5298:
1.366 vatton 5299: if (val.typed_data.unit != UNIT_INVALID && val.typed_data.unit != UNIT_BOX)
1.362 quint 5300: {
1.366 vatton 5301: if (DoDialog)
5302: {
5303: if (val.typed_data.unit == VALUE_INHERIT)
5304: {
5305: DisplayStyleValue ("background-positionH", ptr, cssRule);
5306: DisplayStyleValue ("background-positionV", ptr, cssRule);
5307: }
5308: else if (*across)
5309: DisplayStyleValue ("background-positionH", ptr, cssRule);
5310: else
5311: DisplayStyleValue ("background-positionV", ptr, cssRule);
5312: }
5313: else if (DoApply)
1.362 quint 5314: /* install the new presentation */
5315: {
5316: if (val.typed_data.unit == VALUE_INHERIT)
5317: /* "inherit" applies to both dimensions */
5318: {
5319: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5320: ctxt, val);
5321: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5322: ctxt, val);
5323: }
5324: else if (*across)
5325: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5326: ctxt, val);
5327: else
5328: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5329: ctxt, val);
5330: }
5331: }
1.279 vatton 5332: return (cssRule);
5333: }
1.218 vatton 5334:
1.279 vatton 5335: /*----------------------------------------------------------------------
1.327 vatton 5336: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
5337: attribute string.
1.279 vatton 5338: ----------------------------------------------------------------------*/
5339: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5340: PresentationContext ctxt,
5341: char *cssRule, CSSInfoPtr css,
5342: ThotBool isHTML)
1.279 vatton 5343: {
1.295 vatton 5344: char *ptr;
1.362 quint 5345: ThotBool across;
1.295 vatton 5346:
5347: ptr = cssRule;
1.362 quint 5348: across = TRUE;
5349: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule, css,
5350: isHTML, &across);
1.295 vatton 5351: if (ptr == cssRule)
1.360 vatton 5352: cssRule = SkipValue ("Invalid background-position value", cssRule);
1.362 quint 5353: else
1.298 vatton 5354: {
1.362 quint 5355: cssRule = SkipBlanksAndComments (cssRule);
5356: if (*cssRule != ';' && *cssRule != '!' && *cssRule != EOS)
5357: {
5358: /* possible second value */
5359: ptr = cssRule;
5360: across = !across;
5361: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5362: css, isHTML, &across);
5363: if (ptr == cssRule)
5364: cssRule = SkipValue ("Invalid background-position value", cssRule);
5365: }
1.298 vatton 5366: }
1.163 quint 5367: return (cssRule);
1.18 cvs 5368: }
5369:
5370: /*----------------------------------------------------------------------
1.327 vatton 5371: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 5372: ----------------------------------------------------------------------*/
1.79 cvs 5373: static char *ParseCSSBackground (Element element, PSchema tsch,
1.327 vatton 5374: PresentationContext ctxt, char *cssRule,
5375: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5376: {
1.323 vatton 5377: char *ptr;
5378: int skippedNL;
1.362 quint 5379: ThotBool img, repeat, position, attach, color, across;
1.18 cvs 5380:
1.82 cvs 5381: cssRule = SkipBlanksAndComments (cssRule);
1.323 vatton 5382: img = repeat = position = attach = color = FALSE;
1.362 quint 5383: across = TRUE;
1.301 vatton 5384: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 5385: {
1.71 cvs 5386: /* perhaps a Background Image */
1.198 vatton 5387: if (!strncasecmp (cssRule, "url", 3) || !strncasecmp (cssRule, "none", 4))
1.327 vatton 5388: {
1.334 vatton 5389: if (!strncasecmp (cssRule, "none", 4))
5390: repeat = TRUE;
1.327 vatton 5391: cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
5392: css, isHTML);
5393: img = TRUE;
5394: }
1.18 cvs 5395: /* perhaps a Background Attachment */
1.82 cvs 5396: else if (!strncasecmp (cssRule, "scroll", 6) ||
5397: !strncasecmp (cssRule, "fixed", 5))
1.327 vatton 5398: {
5399: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
5400: cssRule, css, isHTML);
1.328 vatton 5401: attach = repeat = TRUE;
1.327 vatton 5402: }
1.18 cvs 5403: /* perhaps a Background Repeat */
1.82 cvs 5404: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
5405: !strncasecmp (cssRule, "repeat-y", 8) ||
5406: !strncasecmp (cssRule, "repeat-x", 8) ||
5407: !strncasecmp (cssRule, "repeat", 6))
1.327 vatton 5408: {
5409: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
5410: cssRule, css, isHTML);
5411: repeat = TRUE;
5412: }
1.18 cvs 5413: /* perhaps a Background Position */
1.82 cvs 5414: else if (!strncasecmp (cssRule, "left", 4) ||
5415: !strncasecmp (cssRule, "right", 5) ||
5416: !strncasecmp (cssRule, "center", 6) ||
5417: !strncasecmp (cssRule, "top", 3) ||
5418: !strncasecmp (cssRule, "bottom", 6) ||
1.279 vatton 5419: isdigit (*cssRule) || *cssRule == '.' || *cssRule == '-')
1.327 vatton 5420: {
1.362 quint 5421: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5422: css, isHTML, &across);
5423: across = !across;
1.328 vatton 5424: position = repeat = TRUE;
1.327 vatton 5425: }
1.18 cvs 5426: /* perhaps a Background Color */
1.323 vatton 5427: else if (!color)
1.327 vatton 5428: {
5429: skippedNL = NewLineSkipped;
5430: /* check if the rule has been found */
5431: ptr = cssRule;
5432: cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
5433: cssRule, css, isHTML);
5434: if (ptr == cssRule)
5435: {
5436: NewLineSkipped = skippedNL;
5437: /* rule not found */
5438: cssRule = SkipProperty (cssRule, FALSE);
5439: }
5440: else
5441: color = TRUE;
5442: }
1.328 vatton 5443: else
1.327 vatton 5444: cssRule = SkipProperty (cssRule, FALSE);
1.328 vatton 5445:
1.82 cvs 5446: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 5447: }
1.328 vatton 5448:
5449: if (color && !img)
5450: ParseCSSBackgroundImage (element, tsch, ctxt, "none", css, isHTML);
5451:
5452: if (img && !repeat)
5453: ParseACSSBackgroundRepeat (element, tsch, ctxt,
5454: "repeat", css, isHTML);
5455: if (img && !position)
5456: ParseACSSBackgroundPosition (element, tsch, ctxt,
1.362 quint 5457: "0% 0%", css, isHTML, &across);
1.328 vatton 5458: if (img && !attach)
5459: ParseACSSBackgroundAttachment (element, tsch, ctxt,
5460: "scroll", css, isHTML);
1.327 vatton 5461: return (cssRule);
1.18 cvs 5462: }
5463:
1.59 cvs 5464: /*----------------------------------------------------------------------
1.327 vatton 5465: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 5466: ----------------------------------------------------------------------*/
1.79 cvs 5467: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.327 vatton 5468: PresentationContext ctxt, char *cssRule,
5469: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 5470: {
5471: PresentationValue page;
1.366 vatton 5472: char *start_value;
1.59 cvs 5473:
1.184 vatton 5474: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5475: page.typed_data.real = FALSE;
1.82 cvs 5476: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5477: start_value = cssRule;
1.82 cvs 5478: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5479: page.typed_data.value = PageAuto;
1.82 cvs 5480: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5481: {
1.184 vatton 5482: page.typed_data.unit = UNIT_REL;
5483: page.typed_data.value = PageAlways;
1.59 cvs 5484: }
1.82 cvs 5485: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5486: {
1.184 vatton 5487: page.typed_data.unit = UNIT_REL;
5488: page.typed_data.value = PageAvoid;
1.59 cvs 5489: }
1.82 cvs 5490: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5491: {
1.184 vatton 5492: page.typed_data.unit = UNIT_REL;
5493: page.typed_data.value = PageLeft;
1.59 cvs 5494: }
1.82 cvs 5495: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5496: {
1.184 vatton 5497: page.typed_data.unit = UNIT_REL;
5498: page.typed_data.value = PageRight;
1.59 cvs 5499: }
1.82 cvs 5500: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5501: {
1.293 quint 5502: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5503: page.typed_data.value = PageInherit;
1.59 cvs 5504: }
5505: cssRule = SkipWord (cssRule);
5506: /* install the new presentation */
1.366 vatton 5507: if ((page.typed_data.unit == UNIT_REL && page.typed_data.value == PageAlways)
5508: || page.typed_data.unit == VALUE_INHERIT)
5509: {
5510: if (DoDialog)
5511: DisplayStyleValue ("page-break-before", start_value, cssRule);
5512: else if (DoApply)
5513: TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
5514: }
1.59 cvs 5515: return (cssRule);
5516: }
5517:
5518: /*----------------------------------------------------------------------
1.327 vatton 5519: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 5520: ----------------------------------------------------------------------*/
1.79 cvs 5521: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.327 vatton 5522: PresentationContext ctxt,
5523: char *cssRule, CSSInfoPtr css,
5524: ThotBool isHTML)
1.59 cvs 5525: {
5526: PresentationValue page;
1.366 vatton 5527: char *start_value;
1.59 cvs 5528:
1.184 vatton 5529: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5530: page.typed_data.real = FALSE;
1.82 cvs 5531: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5532: start_value = cssRule;
1.82 cvs 5533: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5534: page.typed_data.value = PageAuto;
1.82 cvs 5535: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5536: {
1.184 vatton 5537: page.typed_data.unit = UNIT_REL;
5538: page.typed_data.value = PageAlways;
1.59 cvs 5539: }
1.82 cvs 5540: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5541: {
1.184 vatton 5542: page.typed_data.unit = UNIT_REL;
5543: page.typed_data.value = PageAvoid;
1.59 cvs 5544: }
1.82 cvs 5545: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5546: {
1.184 vatton 5547: page.typed_data.unit = UNIT_REL;
5548: page.typed_data.value = PageLeft;
1.59 cvs 5549: }
1.82 cvs 5550: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5551: {
1.184 vatton 5552: page.typed_data.unit = UNIT_REL;
5553: page.typed_data.value = PageRight;
1.59 cvs 5554: }
1.82 cvs 5555: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5556: {
1.293 quint 5557: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5558: page.typed_data.value = PageInherit;
1.59 cvs 5559: }
5560: cssRule = SkipWord (cssRule);
5561: /* install the new presentation */
1.366 vatton 5562: if (page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT)
5563: {
5564: if (DoDialog)
5565: DisplayStyleValue ("page-break-after", start_value, cssRule);
1.367 cvs 5566: //else if (DoApply)
5567: // TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page);
1.366 vatton 5568: }
1.59 cvs 5569: return (cssRule);
5570: }
5571:
5572: /*----------------------------------------------------------------------
1.327 vatton 5573: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 5574: ----------------------------------------------------------------------*/
1.79 cvs 5575: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.327 vatton 5576: PresentationContext ctxt,
5577: char *cssRule, CSSInfoPtr css,
5578: ThotBool isHTML)
1.59 cvs 5579: {
5580: PresentationValue page;
1.366 vatton 5581: char *start_value;
1.59 cvs 5582:
1.184 vatton 5583: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5584: page.typed_data.real = FALSE;
1.82 cvs 5585: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5586: start_value = cssRule;
1.82 cvs 5587: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 5588: {
1.184 vatton 5589: /*page.typed_data.unit = UNIT_REL;*/
5590: page.typed_data.value = PageAuto;
1.59 cvs 5591: }
1.82 cvs 5592: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5593: {
1.184 vatton 5594: page.typed_data.unit = UNIT_REL;
5595: page.typed_data.value = PageAvoid;
1.59 cvs 5596: }
1.82 cvs 5597: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5598: {
1.293 quint 5599: /* page.typed_data.unit = VALUE_INHERIT; */
1.184 vatton 5600: page.typed_data.value = PageInherit;
1.59 cvs 5601: }
5602: cssRule = SkipWord (cssRule);
5603: /* install the new presentation */
1.366 vatton 5604: if ((page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT) &&
5605: page.typed_data.value == PageAvoid)
5606: {
5607: if (DoDialog)
5608: DisplayStyleValue ("page-break-inside", start_value, cssRule);
1.367 cvs 5609: //else if (DoApply)
5610: //TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);
1.366 vatton 5611: }
1.59 cvs 5612: return (cssRule);
5613: }
1.18 cvs 5614:
1.60 cvs 5615: /*----------------------------------------------------------------------
1.327 vatton 5616: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 5617: ----------------------------------------------------------------------*/
1.79 cvs 5618: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.327 vatton 5619: PresentationContext ctxt, char *cssRule,
5620: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 5621: {
5622: PresentationValue width;
5623:
1.82 cvs 5624: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 5625: width.typed_data.value = 0;
1.184 vatton 5626: width.typed_data.unit = UNIT_INVALID;
1.60 cvs 5627: width.typed_data.real = FALSE;
1.110 vatton 5628: if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 5629: {
1.327 vatton 5630: cssRule = ParseCSSUnit (cssRule, &width);
5631: if (width.typed_data.unit == UNIT_BOX)
5632: width.typed_data.unit = UNIT_PX;
1.166 vatton 5633: }
1.295 vatton 5634: else
5635: cssRule = SkipValue ("Invalid stroke-width value", cssRule);
5636:
1.184 vatton 5637: if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 5638: {
1.207 vatton 5639: TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117 vatton 5640: width.typed_data.value = 1;
1.184 vatton 5641: width.typed_data.unit = UNIT_REL;
1.117 vatton 5642: }
1.60 cvs 5643: return (cssRule);
5644: }
5645:
1.217 vatton 5646: /*----------------------------------------------------------------------
1.327 vatton 5647: ParseCSSPosition: parse a CSS Position attribute string.
1.217 vatton 5648: ----------------------------------------------------------------------*/
5649: static char *ParseCSSPosition (Element element, PSchema tsch,
1.327 vatton 5650: PresentationContext ctxt, char *cssRule,
5651: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5652: {
1.305 quint 5653: char *ptr;
5654: PresentationValue pval;
1.217 vatton 5655:
1.305 quint 5656: pval.typed_data.value = 0;
5657: pval.typed_data.unit = UNIT_BOX;
5658: pval.typed_data.real = FALSE;
1.217 vatton 5659: cssRule = SkipBlanksAndComments (cssRule);
5660: ptr = cssRule;
5661: if (!strncasecmp (cssRule, "static", 6))
1.337 vatton 5662: {
5663: pval.typed_data.value = PositionStatic;
5664: cssRule += 6;
5665: }
5666: else if (!strncasecmp (cssRule, "relative", 8))
5667: {
5668: pval.typed_data.value = PositionRelative;
5669: cssRule += 8;
5670: }
1.217 vatton 5671: else if (!strncasecmp (cssRule, "absolute", 8))
1.337 vatton 5672: {
5673: pval.typed_data.value = PositionAbsolute;
5674: cssRule += 8;
5675: }
1.217 vatton 5676: else if (!strncasecmp (cssRule, "fixed", 5))
1.337 vatton 5677: {
5678: pval.typed_data.value = PositionFixed;
5679: cssRule += 5;
5680: }
1.217 vatton 5681: else if (!strncasecmp (cssRule, "inherit", 7))
1.337 vatton 5682: {
5683: pval.typed_data.unit = VALUE_INHERIT;
5684: cssRule += 7;
5685: }
1.305 quint 5686:
5687: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
5688: {
5689: cssRule = SkipValue ("Invalid position value", ptr);
5690: cssRule = SkipValue (NULL, cssRule);
5691: }
1.217 vatton 5692: else
1.305 quint 5693: {
1.337 vatton 5694: cssRule = SkipBlanksAndComments (cssRule);
5695: if (*cssRule != EOS && *cssRule != ';')
5696: SkipValue ("Invalid position value", ptr);
1.366 vatton 5697: else if (DoDialog)
5698: DisplayStyleValue ("position", ptr, cssRule);
1.337 vatton 5699: else if (DoApply)
1.327 vatton 5700: TtaSetStylePresentation (PRPosition, element, tsch, ctxt, pval);
1.305 quint 5701: }
1.217 vatton 5702: return (cssRule);
5703: }
5704:
5705: /*----------------------------------------------------------------------
1.327 vatton 5706: ParseCSSTop: parse a CSS Top attribute
1.217 vatton 5707: ----------------------------------------------------------------------*/
5708: static char *ParseCSSTop (Element element, PSchema tsch,
1.327 vatton 5709: PresentationContext context, char *cssRule,
5710: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5711: {
5712: PresentationValue val;
5713: char *ptr;
5714:
1.370 vatton 5715: val.typed_data.real = FALSE;
1.217 vatton 5716: cssRule = SkipBlanksAndComments (cssRule);
5717: ptr = cssRule;
1.305 quint 5718: /* first parse the value */
5719: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5720: {
5721: val.typed_data.unit = VALUE_AUTO;
5722: val.typed_data.value = 0;
5723: cssRule = SkipWord (cssRule);
5724: }
1.305 quint 5725: else if (!strncasecmp (cssRule, "inherit", 7))
5726: {
5727: val.typed_data.unit = VALUE_INHERIT;
5728: cssRule = SkipWord (cssRule);
5729: }
1.217 vatton 5730: else
5731: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5732:
5733: if (val.typed_data.unit == UNIT_INVALID ||
5734: (val.typed_data.value != 0 &&
1.217 vatton 5735: val.typed_data.unit == UNIT_BOX))
5736: {
1.387 quint 5737: cssRule = SkipValue ("Invalid top value", ptr);
5738: if (val.typed_data.unit == UNIT_BOX)
5739: val.typed_data.unit = UNIT_PX;
5740: else
5741: return (cssRule);
1.217 vatton 5742: }
1.366 vatton 5743: if (DoDialog)
1.387 quint 5744: DisplayStyleValue ("top", ptr, cssRule);
1.366 vatton 5745: else if (DoApply)
1.305 quint 5746: TtaSetStylePresentation (PRTop, element, tsch, context, val);
1.217 vatton 5747: return (cssRule);
5748: }
5749:
5750: /*----------------------------------------------------------------------
1.327 vatton 5751: ParseCSSRight: parse a CSS Right attribute
1.217 vatton 5752: ----------------------------------------------------------------------*/
5753: static char *ParseCSSRight (Element element, PSchema tsch,
1.327 vatton 5754: PresentationContext context, char *cssRule,
5755: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5756: {
5757: PresentationValue val;
5758: char *ptr;
5759:
1.370 vatton 5760: val.typed_data.real = FALSE;
1.217 vatton 5761: cssRule = SkipBlanksAndComments (cssRule);
5762: ptr = cssRule;
5763: /* first parse the attribute string */
1.305 quint 5764: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5765: {
5766: val.typed_data.unit = VALUE_AUTO;
5767: val.typed_data.value = 0;
5768: cssRule = SkipWord (cssRule);
5769: }
1.305 quint 5770: else if (!strncasecmp (cssRule, "inherit", 7))
5771: {
5772: val.typed_data.unit = VALUE_INHERIT;
5773: cssRule = SkipWord (cssRule);
5774: }
1.217 vatton 5775: else
5776: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5777:
5778: if (val.typed_data.unit == UNIT_INVALID ||
5779: (val.typed_data.value != 0 &&
1.217 vatton 5780: val.typed_data.unit == UNIT_BOX))
5781: {
1.387 quint 5782: cssRule = SkipValue ("Invalid right value", ptr);
5783: if (val.typed_data.unit == UNIT_BOX)
5784: val.typed_data.unit = UNIT_PX;
5785: else
5786: return (cssRule);
1.217 vatton 5787: }
1.366 vatton 5788: if (DoDialog)
5789: DisplayStyleValue ("right", ptr, cssRule);
5790: else if (DoApply)
1.305 quint 5791: TtaSetStylePresentation (PRRight, element, tsch, context, val);
1.217 vatton 5792: return (cssRule);
5793: }
5794:
5795: /*----------------------------------------------------------------------
1.327 vatton 5796: ParseCSSBottom: parse a CSS Bottom attribute
1.217 vatton 5797: ----------------------------------------------------------------------*/
5798: static char *ParseCSSBottom (Element element, PSchema tsch,
1.327 vatton 5799: PresentationContext context, char *cssRule,
5800: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5801: {
5802: PresentationValue val;
5803: char *ptr;
5804:
1.370 vatton 5805: val.typed_data.real = FALSE;
1.217 vatton 5806: cssRule = SkipBlanksAndComments (cssRule);
5807: ptr = cssRule;
5808: /* first parse the attribute string */
1.305 quint 5809: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5810: {
5811: val.typed_data.unit = VALUE_AUTO;
5812: val.typed_data.value = 0;
5813: cssRule = SkipWord (cssRule);
5814: }
1.305 quint 5815: else if (!strncasecmp (cssRule, "inherit", 7))
5816: {
5817: val.typed_data.unit = VALUE_INHERIT;
5818: cssRule = SkipWord (cssRule);
5819: }
1.217 vatton 5820: else
5821: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5822:
5823: if (val.typed_data.unit == UNIT_INVALID ||
5824: (val.typed_data.value != 0 &&
1.217 vatton 5825: val.typed_data.unit == UNIT_BOX))
5826: {
1.387 quint 5827: cssRule = SkipValue ("Invalid bottom value", ptr);
5828: if (val.typed_data.unit == UNIT_BOX)
5829: val.typed_data.unit = UNIT_PX;
5830: else
5831: return (cssRule);
1.217 vatton 5832: }
1.366 vatton 5833: if (DoDialog)
5834: DisplayStyleValue ("bottom", ptr, cssRule);
5835: else if (DoApply)
1.305 quint 5836: TtaSetStylePresentation (PRBottom, element, tsch, context, val);
1.217 vatton 5837: return (cssRule);
5838: }
5839:
5840: /*----------------------------------------------------------------------
1.327 vatton 5841: ParseCSSLeft: parse a CSS Left attribute
1.217 vatton 5842: ----------------------------------------------------------------------*/
5843: static char *ParseCSSLeft (Element element, PSchema tsch,
1.327 vatton 5844: PresentationContext context, char *cssRule,
5845: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5846: {
5847: PresentationValue val;
5848: char *ptr;
5849:
1.370 vatton 5850: val.typed_data.real = FALSE;
1.217 vatton 5851: cssRule = SkipBlanksAndComments (cssRule);
5852: ptr = cssRule;
5853: /* first parse the attribute string */
1.305 quint 5854: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5855: {
5856: val.typed_data.unit = VALUE_AUTO;
5857: val.typed_data.value = 0;
5858: cssRule = SkipWord (cssRule);
5859: }
1.305 quint 5860: else if (!strncasecmp (cssRule, "inherit", 7))
5861: {
5862: val.typed_data.unit = VALUE_INHERIT;
5863: cssRule = SkipWord (cssRule);
5864: }
1.217 vatton 5865: else
5866: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5867:
5868: if (val.typed_data.unit == UNIT_INVALID ||
5869: (val.typed_data.value != 0 &&
1.217 vatton 5870: val.typed_data.unit == UNIT_BOX))
5871: {
1.387 quint 5872: cssRule = SkipValue ("Invalid left value", ptr);
5873: if (val.typed_data.unit == UNIT_BOX)
5874: val.typed_data.unit = UNIT_PX;
5875: else
5876: return (cssRule);
1.217 vatton 5877: }
1.366 vatton 5878: if (DoDialog)
5879: DisplayStyleValue ("left", ptr, cssRule);
5880: else if (DoApply)
1.305 quint 5881: TtaSetStylePresentation (PRLeft, element, tsch, context, val);
1.217 vatton 5882: return (cssRule);
5883: }
5884:
5885: /*----------------------------------------------------------------------
1.327 vatton 5886: ParseCSSZIndex: parse a CSS z-index attribute
1.217 vatton 5887: ----------------------------------------------------------------------*/
5888: static char *ParseCSSZIndex (Element element, PSchema tsch,
1.327 vatton 5889: PresentationContext context, char *cssRule,
5890: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5891: {
5892: PresentationValue val;
5893: char *ptr;
5894:
1.370 vatton 5895: val.typed_data.real = FALSE;
1.217 vatton 5896: cssRule = SkipBlanksAndComments (cssRule);
5897: ptr = cssRule;
5898: /* first parse the attribute string */
5899: if (!strncasecmp (cssRule, "auto", 4) ||
5900: !strncasecmp (cssRule, "inherit", 7))
5901: {
5902: val.typed_data.unit = VALUE_AUTO;
5903: val.typed_data.value = 0;
5904: cssRule = SkipWord (cssRule);
5905: }
5906: else
5907: {
5908: cssRule = ParseCSSUnit (cssRule, &val);
5909: if (val.typed_data.unit != UNIT_BOX)
1.327 vatton 5910: {
1.387 quint 5911: cssRule = SkipValue ("Invalid z-index value", ptr);
5912: return (cssRule);
1.327 vatton 5913: }
1.217 vatton 5914: }
1.366 vatton 5915: if (DoDialog)
5916: DisplayStyleValue ("z-index", ptr, cssRule);
1.217 vatton 5917: /***
1.387 quint 5918: else if (DoApply)
1.327 vatton 5919: TtaSetStylePresentation (PR, element, tsch, context, val);
1.217 vatton 5920: ***/
5921: return (cssRule);
5922: }
5923:
1.340 quint 5924: /*----------------------------------------------------------------------
5925: *
5926: * FUNCTIONS STYLE DECLARATIONS
5927: *
5928: *----------------------------------------------------------------------*/
1.18 cvs 5929: /*
1.59 cvs 5930: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 5931: * e.g. "FONT-SIZE" must be placed before "FONT"
5932: */
5933: static CSSProperty CSSProperties[] =
1.327 vatton 5934: {
5935: {"background-color", ParseCSSBackgroundColor},
5936: {"background-image", ParseCSSBackgroundImage},
5937: {"background-repeat", ParseCSSBackgroundRepeat},
5938: {"background-attachment", ParseCSSBackgroundAttachment},
5939: {"background-position", ParseCSSBackgroundPosition},
5940: {"background", ParseCSSBackground},
5941: {"border-top-width", ParseCSSBorderTopWidth},
5942: {"border-right-width", ParseCSSBorderRightWidth},
5943: {"border-bottom-width", ParseCSSBorderBottomWidth},
5944: {"border-left-width", ParseCSSBorderLeftWidth},
5945: {"border-width", ParseCSSBorderWidth},
5946: {"border-top-color", ParseCSSBorderColorTop},
5947: {"border-right-color", ParseCSSBorderColorRight},
5948: {"border-bottom-color", ParseCSSBorderColorBottom},
5949: {"border-left-color", ParseCSSBorderColorLeft},
5950: {"border-color", ParseCSSBorderColor},
5951: {"border-top-style", ParseCSSBorderStyleTop},
5952: {"border-right-style", ParseCSSBorderStyleRight},
5953: {"border-bottom-style", ParseCSSBorderStyleBottom},
5954: {"border-left-style", ParseCSSBorderStyleLeft},
5955: {"border-style", ParseCSSBorderStyle},
5956: {"border-top", ParseCSSBorderTop},
5957: {"border-right", ParseCSSBorderRight},
5958: {"border-bottom", ParseCSSBorderBottom},
5959: {"border-left", ParseCSSBorderLeft},
5960: {"border", ParseCSSBorder},
5961: {"bottom", ParseCSSBottom},
5962: {"clear", ParseCSSClear},
5963: {"color", ParseCSSForeground},
5964: {"content", ParseCSSContent},
5965: {"direction", ParseCSSDirection},
5966: {"display", ParseCSSDisplay},
5967: {"float", ParseCSSFloat},
5968: {"font-family", ParseCSSFontFamily},
5969: {"font-style", ParseCSSFontStyle},
5970: {"font-variant", ParseCSSFontVariant},
5971: {"font-weight", ParseCSSFontWeight},
5972: {"font-size-adjust", ParseCSSFontSizeAdjust},
5973: {"font-size", ParseCSSFontSize},
5974: {"font", ParseCSSFont},
1.382 vatton 5975: {"max-height", ParseCSSMaxHeight},
5976: {"min-height", ParseCSSMinHeight},
1.327 vatton 5977: {"height", ParseCSSHeight},
5978: {"left", ParseCSSLeft},
5979: {"letter-spacing", ParseCSSLetterSpacing},
5980: {"line-height", ParseCSSLineHeight},
5981: {"list-style-type", ParseCSSListStyleType},
5982: {"list-style-image", ParseCSSListStyleImage},
5983: {"list-style-position", ParseCSSListStylePosition},
5984: {"list-style", ParseCSSListStyle},
5985: {"margin-bottom", ParseCSSMarginBottom},
5986: {"margin-top", ParseCSSMarginTop},
5987: {"margin-right", ParseCSSMarginRight},
5988: {"margin-left", ParseCSSMarginLeft},
5989: {"margin", ParseCSSMargin},
5990: {"padding-top", ParseCSSPaddingTop},
5991: {"padding-right", ParseCSSPaddingRight},
5992: {"padding-bottom", ParseCSSPaddingBottom},
5993: {"padding-left", ParseCSSPaddingLeft},
5994: {"padding", ParseCSSPadding},
5995: {"page-break-before", ParseCSSPageBreakBefore},
5996: {"page-break-after", ParseCSSPageBreakAfter},
5997: {"page-break-inside", ParseCSSPageBreakInside},
5998: {"position", ParseCSSPosition},
5999: {"right", ParseCSSRight},
6000: {"text-align", ParseCSSTextAlign},
6001: {"text-anchor", ParseCSSTextAnchor},
6002: {"text-indent", ParseCSSTextIndent},
6003: {"text-decoration", ParseCSSTextDecoration},
6004: {"text-transform", ParseCSSTextTransform},
6005: {"top", ParseCSSTop},
6006: {"unicode-bidi", ParseCSSUnicodeBidi},
6007: {"vertical-align", ParseCSSVerticalAlign},
6008: {"white-space", ParseCSSWhiteSpace},
1.382 vatton 6009: {"max-width", ParseCSSMaxWidth},
6010: {"min-width", ParseCSSMinWidth},
1.327 vatton 6011: {"width", ParseCSSWidth},
1.333 vatton 6012: {"visibility", ParseCSSVisibility},
1.327 vatton 6013: {"word-spacing", ParseCSSWordSpacing},
6014: {"z-index", ParseCSSZIndex},
6015:
6016: /* SVG extensions */
6017: {"fill-opacity", ParseSVGFillOpacity},
6018: {"fill", ParseSVGFill},
6019: {"opacity", ParseSVGOpacity},
6020: {"stroke-opacity", ParseSVGStrokeOpacity},
6021: {"stroke-width", ParseSVGStrokeWidth},
6022: {"stroke", ParseSVGStroke}
6023: };
1.155 cheyroul 6024:
1.18 cvs 6025: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
6026:
6027: /*----------------------------------------------------------------------
1.327 vatton 6028: ParseCSSRule: parse a CSS Style string
6029: we expect the input string describing the style to be of the form
6030: property: value [ ; property: value ]*
6031: but tolerate incorrect or incomplete input
1.18 cvs 6032: ----------------------------------------------------------------------*/
1.366 vatton 6033: void ParseCSSRule (Element element, PSchema tsch, PresentationContext ctxt,
6034: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 6035: {
1.366 vatton 6036: DisplayMode dispMode = DisplayImmediately;
1.312 quint 6037: char *p = NULL, *next, *end;
1.214 quint 6038: char *valueStart;
1.18 cvs 6039: int lg;
1.34 cvs 6040: unsigned int i;
1.76 cvs 6041: ThotBool found;
1.18 cvs 6042:
1.34 cvs 6043: /* avoid too many redisplay */
1.366 vatton 6044: if (!DoDialog && ctxt->doc)
6045: {
6046: dispMode = TtaGetDisplayMode (ctxt->doc);
6047: if (dispMode == DisplayImmediately)
6048: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
6049: }
1.34 cvs 6050:
1.82 cvs 6051: while (*cssRule != EOS)
1.18 cvs 6052: {
1.82 cvs 6053: cssRule = SkipBlanksAndComments (cssRule);
1.371 vatton 6054: if (*cssRule == ';' || *cssRule < 0x20 ||
1.372 vatton 6055: ((unsigned char)*cssRule) == 0xA0)
1.371 vatton 6056: cssRule++;
6057: else if (*cssRule < 0x41 || *cssRule > 0x7A ||
6058: (*cssRule > 0x5A && *cssRule < 0x61))
1.352 vatton 6059: {
6060: end = SkipProperty (cssRule, FALSE);
1.385 vatton 6061: if (cssRule[0] != '-')
6062: CSSParseError ("Invalid property", cssRule, end);
1.352 vatton 6063: cssRule = end;
6064: }
1.194 vatton 6065: else if (*cssRule != EOS)
1.327 vatton 6066: {
6067: found = FALSE;
6068: /* look for the type of property */
6069: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
6070: {
6071: lg = strlen (CSSProperties[i].name);
6072: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
6073: {
6074: p = cssRule + lg;
6075: found = TRUE;
6076: i--;
6077: }
6078: }
6079:
1.360 vatton 6080: // check if it's an important rule
6081: CheckImportantRule (cssRule, ctxt);
1.327 vatton 6082: if (i < NB_CSSSTYLEATTRIBUTE &&
6083: !strcasecmp (CSSProperties[i].name, "content") &&
6084: ((GenericContext)ctxt)->pseudo != PbBefore &&
6085: ((GenericContext)ctxt)->pseudo != PbAfter)
1.340 quint 6086: /* property content is allowed only for pseudo-elements :before and
6087: :after */
1.327 vatton 6088: {
1.352 vatton 6089: end = SkipProperty (cssRule, FALSE);
1.327 vatton 6090: CSSParseError ("content is allowed only for pseudo-elements",
6091: cssRule, end);
1.352 vatton 6092: cssRule = end;
1.327 vatton 6093: }
1.352 vatton 6094: else if (i == NB_CSSSTYLEATTRIBUTE)
1.376 vatton 6095: cssRule = SkipProperty (cssRule, !ctxt->destroy);
1.327 vatton 6096: else
6097: {
6098: /* update index and skip the ":" indicator if present */
6099: p = SkipBlanksAndComments (p);
6100: if (*p == ':')
6101: {
6102: p++;
6103: p = SkipBlanksAndComments (p);
6104: /* try to parse the value associated with this property */
6105: if (CSSProperties[i].parsing_function != NULL)
6106: {
6107: valueStart = p;
6108: p = CSSProperties[i].parsing_function (element, tsch,
6109: ctxt, p, css, isHTML);
6110: if (!element && isHTML)
6111: {
6112: if (ctxt->type == HTML_EL_Input)
6113: /* it's a generic rule for the HTML element input.
6114: Generate a Thot Pres rule for each kind of
6115: input element */
6116: {
6117: ctxt->type = HTML_EL_Text_Input;
6118: p = CSSProperties[i].parsing_function (element,
6119: tsch, ctxt, valueStart, css, isHTML);
6120: ctxt->type = HTML_EL_Password_Input;
6121: p = CSSProperties[i].parsing_function (element,
6122: tsch, ctxt, valueStart, css, isHTML);
6123: ctxt->type = HTML_EL_File_Input;
6124: p = CSSProperties[i].parsing_function (element,
6125: tsch, ctxt, valueStart, css, isHTML);
6126: ctxt->type = HTML_EL_Checkbox_Input;
6127: p = CSSProperties[i].parsing_function (element,
6128: tsch, ctxt, valueStart, css, isHTML);
6129: ctxt->type = HTML_EL_Radio_Input;
6130: p = CSSProperties[i].parsing_function (element,
6131: tsch, ctxt, valueStart, css, isHTML);
6132: ctxt->type = HTML_EL_Submit_Input;
6133: p = CSSProperties[i].parsing_function (element,
6134: tsch, ctxt, valueStart, css, isHTML);
6135: ctxt->type = HTML_EL_Reset_Input;
6136: p = CSSProperties[i].parsing_function (element,
6137: tsch, ctxt, valueStart, css, isHTML);
6138: ctxt->type = HTML_EL_Button_Input;
6139: p = CSSProperties[i].parsing_function (element,
6140: tsch, ctxt, valueStart, css, isHTML);
6141: ctxt->type = HTML_EL_Input;
6142: }
6143: else if (ctxt->type == HTML_EL_ruby)
6144: /* it's a generic rule for the HTML element ruby.
6145: Generate a Thot Pres rule for each kind of
6146: ruby element. */
6147: {
6148: ctxt->type = HTML_EL_simple_ruby;
6149: p = CSSProperties[i].parsing_function (element,
6150: tsch, ctxt, valueStart, css, isHTML);
6151: ctxt->type = HTML_EL_complex_ruby;
6152: p = CSSProperties[i].parsing_function (element,
6153: tsch, ctxt, valueStart, css, isHTML);
6154: ctxt->type = HTML_EL_ruby;
6155: }
6156: }
6157: /* update index and skip the ";" separator if present */
6158: next = SkipBlanksAndComments (p);
6159: if (*next != EOS && *next != ';')
6160: CSSParseError ("Missing closing ';'", cssRule, p);
6161: cssRule = next;
6162: }
6163: }
6164: else
6165: cssRule = SkipProperty (cssRule, TRUE);
6166: }
1.360 vatton 6167: // skip important markup
6168: cssRule = SkipImportantRule (cssRule);
6169:
1.327 vatton 6170: }
1.18 cvs 6171: /* next property */
1.82 cvs 6172: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 6173: if (*cssRule == '}')
1.327 vatton 6174: {
6175: cssRule++;
6176: CSSPrintError ("Invalid character", "}");
6177: cssRule = SkipBlanksAndComments (cssRule);
6178: }
1.155 cheyroul 6179: if (*cssRule == ',' ||
1.327 vatton 6180: *cssRule == ';')
6181: {
6182: cssRule++;
6183: cssRule = SkipBlanksAndComments (cssRule);
6184: }
1.18 cvs 6185: }
1.34 cvs 6186:
6187: /* restore the display mode */
1.366 vatton 6188: if (!DoDialog && ctxt->doc && dispMode == DisplayImmediately)
1.207 vatton 6189: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 6190: }
1.1 cvs 6191:
1.111 cvs 6192: /*----------------------------------------------------------------------
1.327 vatton 6193: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
6194: This function must be called when a specific style is applied to an
6195: element.
6196: The parameter specificity is the specificity of the style, 0 if it is
6197: not really a CSS rule.
1.1 cvs 6198: ----------------------------------------------------------------------*/
1.79 cvs 6199: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.377 quint 6200: int specificity, ThotBool destroy)
1.1 cvs 6201: {
1.257 vatton 6202: DisplayMode dispMode;
1.207 vatton 6203: PresentationContext ctxt;
6204: ElementType elType;
6205: ThotBool isHTML;
1.1 cvs 6206:
1.207 vatton 6207: /* A rule applying to BODY is really meant to address HTML */
6208: elType = TtaGetElementType (el);
1.286 quint 6209: NewLineSkipped = 0;
1.207 vatton 6210: /* store the current line for eventually reported errors */
6211: LineNumber = TtaGetElementLineNumber (el);
6212: if (destroy)
6213: /* no reported errors */
6214: ParsedDoc = 0;
6215: else if (ParsedDoc != doc)
6216: {
6217: /* update the context for reported errors */
6218: ParsedDoc = doc;
1.348 vatton 6219: Error_DocURL = DocumentURLs[doc];
1.207 vatton 6220: }
6221: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
6222: /* create the context of the Specific presentation driver */
6223: ctxt = TtaGetSpecificStyleContext (doc);
6224: if (ctxt == NULL)
6225: return;
6226: ctxt->type = elType.ElTypeNum;
6227: ctxt->cssSpecificity = specificity;
1.236 quint 6228: ctxt->cssLine = LineNumber;
1.207 vatton 6229: ctxt->destroy = destroy;
6230: /* first use of the context */
6231: ctxt->uses = 1;
1.257 vatton 6232: /* save the current display mode */
6233: dispMode = TtaGetDisplayMode (doc);
1.207 vatton 6234: /* Call the parser */
1.366 vatton 6235: DoDialog = FALSE; // not parsing for CSS dialog
1.207 vatton 6236: ParseCSSRule (el, NULL, (PresentationContext) ctxt, cssRule, NULL, isHTML);
1.257 vatton 6237: /* restore the display mode if necessary */
6238: TtaSetDisplayMode (doc, dispMode);
1.207 vatton 6239: /* check if the context can be freed */
6240: ctxt->uses -= 1;
6241: if (ctxt->uses == 0)
6242: /* no image loading */
6243: TtaFreeMemory(ctxt);
1.1 cvs 6244: }
6245:
1.366 vatton 6246:
1.343 vatton 6247: /*----------------------------------------------------------------------
6248: AddClassName adds the class name into the class list of css if it's
6249: not already there.
6250: ----------------------------------------------------------------------*/
6251: static void AddClassName (char *name, CSSInfoPtr css)
6252: {
1.344 cvs 6253: int l, index, k, length, add;
1.343 vatton 6254: char *buf;
6255: ThotBool found, previous;
6256:
6257: l = strlen (name);
6258: if (l == 0 || css == NULL)
6259: return;
6260: if (css->class_list)
6261: {
6262: buf = css->class_list;
6263: length = strlen (css->class_list);
6264: }
6265: else
6266: {
6267: if (l > 200)
6268: length = l + 1;
6269: else
6270: length = 200;
6271: buf = (char *)TtaGetMemory (length * sizeof (char));
6272: memset (buf, 0, length);
6273: css->class_list = buf;
6274: css->lg_class_list = length;
6275: length = 0;
6276: }
6277:
6278: /* compare that name with all class names already known */
6279: index = 0;
6280: found = FALSE;
6281: previous = FALSE;
6282: while (index < length && !found && !previous)
6283: {
6284: k = 0;
6285: while (k < l && buf[index + k] != EOS && buf[index + k] != SPACE)
6286: {
6287: if (name[k] == buf[index+k])
6288: k++;
6289: else
6290: {
6291: previous = (name[k] < buf[index + k]);
6292: break;
6293: }
6294: }
6295: found = (k == l);
6296: if (!previous)
6297: {
6298: index += k;
6299: while (buf[index] != EOS && buf[index] != SPACE)
6300: index++;
6301: if (buf[index] == SPACE)
6302: index++;
6303: }
6304: }
6305:
6306: if (!found)
6307: /* this class name is not known, append it */
6308: {
6309: l++; /* add a space before */
6310: if (css->lg_class_list <= length + l)
6311: {
6312: // increase the list size
6313: if (l > 200)
6314: add = l + 1;
6315: else
6316: add = 200 ;
6317: buf = (char *)TtaRealloc (buf, css->lg_class_list + (add * sizeof (char)));
6318: if (buf == NULL)
6319: return;
6320: else
6321: {
6322: css->class_list = buf;
6323: memset (&buf[css->lg_class_list], 0, add);
6324: css->lg_class_list += add;
6325: }
6326: }
6327:
6328: if (previous)
6329: {
6330: // move the tail of the current list
6331: for (k = length; k >= index; k--)
6332: buf[k+l] = buf[k];
6333: /* add this new class name at the current position */
6334: strcpy (&buf[index], name);
6335: buf[index + l - 1] = SPACE;
6336: }
6337: else
6338: {
6339: /* add this new class name at the end */
6340: if (index != 0)
6341: buf[index++] = SPACE;
6342: strcpy (&buf[index], name);
6343: }
6344: }
6345: }
6346:
1.68 cvs 6347:
1.1 cvs 6348: /*----------------------------------------------------------------------
1.207 vatton 6349: ParseGenericSelector: Create a generic context for a given selector
6350: string.
6351: If the selector is made of multiple comma, it parses them one at a time
6352: and return the end of the selector string to be handled or NULL.
1.231 vatton 6353: The parameter ctxt gives the current style context which will be passed
6354: to Thotlib.
6355: The parameter css points to the current CSS context.
6356: The parameter link points to the link element.
6357: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 6358: ----------------------------------------------------------------------*/
1.207 vatton 6359: static char *ParseGenericSelector (char *selector, char *cssRule,
1.327 vatton 6360: GenericContext ctxt, Document doc,
6361: CSSInfoPtr css, Element link, char *url)
1.79 cvs 6362: {
6363: ElementType elType;
6364: PSchema tsch;
1.119 vatton 6365: AttributeType attrType;
1.398 vatton 6366: char *deb, *cur, *sel, *next, *limit, c;
1.317 vatton 6367: char *schemaName, *mappedName, *saveURL;
1.79 cvs 6368: char *names[MAX_ANCESTORS];
1.355 quint 6369: ThotBool pseudoFirstChild[MAX_ANCESTORS];
1.340 quint 6370: ElemRel rel[MAX_ANCESTORS];
6371: char *attrnames[MAX_ANCESTORS];
6372: int attrnums[MAX_ANCESTORS];
6373: int attrlevels[MAX_ANCESTORS];
1.79 cvs 6374: char *attrvals[MAX_ANCESTORS];
1.133 vatton 6375: AttrMatch attrmatch[MAX_ANCESTORS];
1.340 quint 6376: int nbnames, nbattrs;
6377: int i, j;
1.256 vatton 6378: int att, kind;
1.118 vatton 6379: int specificity, xmlType;
1.217 vatton 6380: int skippedNL;
1.380 vatton 6381: ThotBool isHTML, noname;
1.347 quint 6382: ThotBool level, quoted, doubleColon;
1.340 quint 6383: #define ATTR_ID 1
6384: #define ATTR_CLASS 2
6385: #define ATTR_PSEUDO 3
1.1 cvs 6386:
1.207 vatton 6387: sel = ctxt->sel;
1.82 cvs 6388: sel[0] = EOS;
1.398 vatton 6389: // get the limit of the string
6390: limit = &sel[MAX_ANCESTORS * 50 -1];
6391: *limit = EOS;
1.117 vatton 6392: specificity = 0;
1.1 cvs 6393: for (i = 0; i < MAX_ANCESTORS; i++)
6394: {
1.25 cvs 6395: names[i] = NULL;
1.355 quint 6396: pseudoFirstChild[i] = FALSE;
1.340 quint 6397: rel[i] = RelAncestor;
6398: attrnames[i] = NULL;
6399: attrnums[i] = 0;
6400: attrlevels[i] = 0;
1.25 cvs 6401: attrvals[i] = NULL;
1.133 vatton 6402: attrmatch[i] = Txtmatch;
1.25 cvs 6403: ctxt->name[i] = 0;
1.355 quint 6404: ctxt->firstChild[i] = FALSE;
1.25 cvs 6405: ctxt->attrType[i] = 0;
1.129 vatton 6406: ctxt->attrLevel[i] = 0;
1.25 cvs 6407: ctxt->attrText[i] = NULL;
1.178 quint 6408: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 6409: }
1.25 cvs 6410: ctxt->box = 0;
1.312 quint 6411: ctxt->var = 0;
1.306 quint 6412: ctxt->pseudo = PbNone;
1.25 cvs 6413: ctxt->type = 0;
1.366 vatton 6414: DoDialog = FALSE; // not arsing for CSS dialog
1.114 quint 6415: /* the specificity of the rule depends on the selector */
6416: ctxt->cssSpecificity = 0;
1.231 vatton 6417: /* localisation of the CSS rule */
6418: ctxt->cssLine = LineNumber + NewLineSkipped;
6419: ctxt->cssURL = url;
1.240 quint 6420:
1.286 quint 6421: skippedNL = NewLineSkipped;
1.82 cvs 6422: selector = SkipBlanksAndComments (selector);
1.286 quint 6423: NewLineSkipped = skippedNL;
1.27 cvs 6424: cur = &sel[0];
1.340 quint 6425: nbnames = 0;
6426: nbattrs = 0;
1.1 cvs 6427: while (1)
6428: {
1.85 cvs 6429: /* point to the following word in sel[] */
1.27 cvs 6430: deb = cur;
1.25 cvs 6431: /* copy an item of the selector into sel[] */
1.1 cvs 6432: /* put one word in the sel buffer */
1.82 cvs 6433: while (*selector != EOS && *selector != ',' &&
6434: *selector != '.' && *selector != ':' &&
1.118 vatton 6435: *selector != '#' && *selector != '[' &&
1.250 vatton 6436: *selector != '>' && *selector != '+' &&
1.398 vatton 6437: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6438: *cur++ = *selector++;
1.82 cvs 6439: *cur++ = EOS; /* close the first string in sel[] */
1.380 vatton 6440: noname = TRUE;
1.82 cvs 6441: if (deb[0] != EOS)
1.340 quint 6442: /* the selector starts with an element name */
1.327 vatton 6443: {
6444: if (deb[0] <= 64 && deb[0] != '*')
6445: {
6446: CSSPrintError ("Invalid element", deb);
1.380 vatton 6447: names[0] = NULL; /* no element name */
6448: DoApply = FALSE;
1.327 vatton 6449: }
6450: else
6451: {
1.380 vatton 6452: noname = FALSE;
1.327 vatton 6453: names[0] = deb;
6454: if (!strcmp (names[0], "html"))
6455: /* give a greater priority to the backgoud color of html */
6456: specificity += 3;
6457: else
6458: /* selector "*" has specificity zero */
6459: if (strcmp (names[0], "*"))
6460: specificity += 1;
6461: }
6462: }
1.25 cvs 6463: else
1.340 quint 6464: names[0] = NULL; /* no element name */
1.226 quint 6465:
1.340 quint 6466: rel[0] = RelVoid;
1.27 cvs 6467: /* now names[0] points to the beginning of the parsed item
1.340 quint 6468: and cur to the next string to be parsed */
1.129 vatton 6469: while (*selector == '.' || *selector == ':' ||
1.327 vatton 6470: *selector == '#' || *selector == '[')
6471: {
6472: /* point to the following word in sel[] */
6473: deb = cur;
6474: if (*selector == '.')
1.340 quint 6475: /* class */
1.327 vatton 6476: {
6477: selector++;
1.340 quint 6478: while (*selector != '.' && *selector != ':' &&
6479: *selector != '#' && *selector != '[' &&
6480: *selector != EOS && *selector != ',' &&
6481: *selector != '+' && *selector != '>' &&
1.398 vatton 6482: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6483: {
6484: if (*selector == '\\')
6485: {
6486: selector++;
6487: if (*selector != EOS)
6488: *cur++ = *selector++;
6489: }
6490: else
6491: *cur++ = *selector++;
6492: }
6493: /* close the word */
6494: *cur++ = EOS;
1.340 quint 6495: /* point to the class in sel[] if it's a valid name */
1.327 vatton 6496: if (deb[0] <= 64)
6497: {
6498: CSSPrintError ("Invalid class", deb);
6499: DoApply = FALSE;
6500: }
6501: else
6502: {
1.340 quint 6503: /* simulate selector [class ~= "xxx"] */
6504: nbattrs++;
6505: if (nbattrs == MAX_ANCESTORS)
6506: /* abort parsing */
6507: {
6508: CSSPrintError ("Selector too long", deb);
6509: return (selector);
6510: }
6511: for (i = nbattrs; i > 0; i--)
6512: {
6513: attrnames[i] = attrnames[i - 1];
6514: attrnums[i] = attrnums[i - 1];
6515: attrlevels[i] = attrlevels[i - 1];
6516: attrvals[i] = attrvals[i - 1];
6517: attrmatch[i] = attrmatch[i - 1];
6518: }
6519: attrnames[0] = NULL;
6520: attrnums[0] = ATTR_CLASS;
6521: attrlevels[0] = 0;
6522: attrmatch[0] = Txtword;
6523: attrvals[0] = deb;
1.327 vatton 6524: specificity += 10;
1.343 vatton 6525: }
1.327 vatton 6526: }
6527: else if (*selector == ':')
1.340 quint 6528: /* pseudo-class or pseudo-element */
1.327 vatton 6529: {
6530: selector++;
1.347 quint 6531: doubleColon = FALSE;
6532: if (*selector == ':')
6533: /* it's a double "::". Probably CSS3 syntax */
6534: {
6535: selector++;
6536: doubleColon = TRUE;
6537: }
1.340 quint 6538: while (*selector != '.' && *selector != ':' &&
6539: *selector != '#' && *selector != '[' &&
6540: *selector != EOS && *selector != ',' &&
6541: *selector != '+' && *selector != '>' &&
1.398 vatton 6542: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6543: *cur++ = *selector++;
6544: /* close the word */
6545: *cur++ = EOS;
1.340 quint 6546: /* point to the pseudo-class or pseudo-element in sel[] if it's
6547: a valid name */
1.355 quint 6548: if (!strcmp (deb, "first-child"))
6549: /* first-child pseudo-class */
1.327 vatton 6550: {
1.355 quint 6551: pseudoFirstChild[0] = TRUE;
6552: specificity += 10;
1.327 vatton 6553: }
1.355 quint 6554: else if (!strcmp (deb, "link") || !strcmp (deb, "visited"))
6555: /* link or visited pseudo-classes */
1.327 vatton 6556: {
1.355 quint 6557: nbattrs++;
6558: if (nbattrs == MAX_ANCESTORS)
6559: /* abort parsing */
1.347 quint 6560: {
1.355 quint 6561: CSSPrintError ("Selector too long", deb);
6562: return (selector);
1.347 quint 6563: }
1.355 quint 6564: for (i = nbattrs; i > 0; i--)
1.347 quint 6565: {
1.355 quint 6566: attrnames[i] = attrnames[i - 1];
6567: attrnums[i] = attrnums[i - 1];
6568: attrlevels[i] = attrlevels[i - 1];
6569: attrvals[i] = attrvals[i - 1];
6570: attrmatch[i] = attrmatch[i - 1];
1.347 quint 6571: }
1.355 quint 6572: attrnames[0] = NULL;
6573: attrnums[0] = ATTR_PSEUDO;
6574: attrlevels[0] = 0;
6575: attrmatch[0] = Txtmatch;
6576: attrvals[0] = deb;
6577: specificity += 10;
6578: }
6579: else if (!strcmp (deb, "hover") || !strcmp (deb, "active") ||
6580: !strcmp (deb, "focus"))
6581: /* hover, active, focus pseudo-classes */
6582: {
6583: specificity += 10;
6584: /* not supported */
6585: DoApply = FALSE;
6586: }
6587: else if (!strncmp (deb, "lang", 4))
6588: /* it's the lang pseudo-class */
6589: {
6590: if (deb[4] != '(' || deb[strlen(deb)-1] != ')')
6591: /* at least one parenthesis is missing. Error */
1.327 vatton 6592: {
1.355 quint 6593: CSSPrintError ("Invalid :lang pseudo-class", deb);
6594: DoApply = FALSE;
1.327 vatton 6595: }
6596: else
1.355 quint 6597: /* simulate selector [lang|="xxx"] */
1.340 quint 6598: {
6599: nbattrs++;
6600: if (nbattrs == MAX_ANCESTORS)
6601: /* abort parsing */
6602: {
6603: CSSPrintError ("Selector too long", deb);
6604: return (selector);
6605: }
1.355 quint 6606: deb[strlen(deb)-1] = EOS;
6607: deb[4] = EOS;
1.340 quint 6608: for (i = nbattrs; i > 0; i--)
6609: {
6610: attrnames[i] = attrnames[i - 1];
6611: attrnums[i] = attrnums[i - 1];
6612: attrlevels[i] = attrlevels[i - 1];
6613: attrvals[i] = attrvals[i - 1];
6614: attrmatch[i] = attrmatch[i - 1];
6615: }
1.355 quint 6616: attrnames[0] = deb;
6617: attrnums[0] = 0;
1.340 quint 6618: attrlevels[0] = 0;
1.355 quint 6619: attrmatch[0] = Txtsubstring;
6620: attrvals[0] = &deb[5];
6621: specificity += 10;
1.340 quint 6622: }
1.327 vatton 6623: }
1.355 quint 6624: else if (!strcmp (deb, "first-line") ||
6625: !strcmp (deb, "first-letter"))
6626: /* pseudo-elements first-line or first-letter */
6627: {
6628: if (doubleColon)
6629: CSSPrintError ("Warning: \"::\" is CSS3 syntax", NULL);
6630: specificity += 1;
6631: /* not supported */
6632: DoApply = FALSE;
6633: }
6634: else if (!strncmp (deb, "before", 6))
6635: /* pseudo-element before */
6636: {
6637: if (doubleColon)
6638: CSSPrintError ("Warning: \"::before\" is CSS3 syntax",
6639: NULL);
6640: ctxt->pseudo = PbBefore;
6641: specificity += 1;
6642: }
6643: else if (!strncmp (deb, "after", 5))
6644: /* pseudo-element after */
6645: {
6646: if (doubleColon)
6647: CSSPrintError ("Warning: \"::after\" is CSS3 syntax",
6648: NULL);
6649: ctxt->pseudo = PbAfter;
6650: specificity += 1;
6651: }
6652: else
6653: {
6654: CSSPrintError ("Invalid pseudo-element", deb);
6655: DoApply = FALSE;
6656: }
6657: if (names[0] && !strcmp (names[0], "*"))
6658: names[0] = NULL;
1.327 vatton 6659: }
6660: else if (*selector == '#')
1.340 quint 6661: /* unique identifier */
1.327 vatton 6662: {
6663: selector++;
1.340 quint 6664: while (*selector != '.' && *selector != ':' &&
6665: *selector != '#' && *selector != '[' &&
6666: *selector != '+' && *selector != '>' &&
6667: *selector != EOS && *selector != ',' &&
1.398 vatton 6668: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6669: *cur++ = *selector++;
6670: /* close the word */
6671: *cur++ = EOS;
6672: /* point to the attribute in sel[] if it's valid name */
6673: if (deb[0] <= 64)
6674: {
6675: CSSPrintError ("Invalid id", deb);
6676: DoApply = FALSE;
6677: }
6678: else
6679: {
1.340 quint 6680: nbattrs++;
6681: if (nbattrs == MAX_ANCESTORS)
6682: /* abort parsing */
6683: {
6684: CSSPrintError ("Selector too long", deb);
6685: return (selector);
6686: }
6687: for (i = nbattrs; i > 0; i--)
6688: {
6689: attrnames[i] = attrnames[i - 1];
6690: attrnums[i] = attrnums[i - 1];
6691: attrlevels[i] = attrlevels[i - 1];
6692: attrvals[i] = attrvals[i - 1];
6693: attrmatch[i] = attrmatch[i - 1];
6694: }
6695: attrnames[0] = NULL;
6696: attrnums[0] = ATTR_ID;
6697: attrlevels[0] = 0;
6698: attrmatch[0] = Txtmatch;
6699: attrvals[0] = deb;
6700: specificity += 100;
6701: if (names[0] && !strcmp (names[0], "*"))
6702: names[0] = NULL;
1.327 vatton 6703: }
6704: }
6705: else if (*selector == '[')
6706: {
6707: selector++;
1.341 quint 6708: selector = SkipBlanksAndComments (selector);
1.327 vatton 6709: while (*selector != EOS && *selector != ']' &&
6710: *selector != '=' && *selector != '~' &&
1.341 quint 6711: *selector != '|' && *selector != '^' &&
1.396 vatton 6712: *selector != '$' && *selector != '*' &&
1.398 vatton 6713: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6714: *cur++ = *selector++;
1.341 quint 6715: /* close the word (attribute name) */
1.327 vatton 6716: *cur++ = EOS;
6717: /* point to the attribute in sel[] if it's valid name */
6718: if (deb[0] <= 64)
6719: {
6720: CSSPrintError ("Invalid attribute", deb);
6721: DoApply = FALSE;
6722: }
6723: else
6724: {
1.340 quint 6725: nbattrs++;
6726: if (nbattrs == MAX_ANCESTORS)
6727: /* abort parsing */
6728: {
6729: CSSPrintError ("Selector too long", deb);
6730: return (selector);
6731: }
6732: for (i = nbattrs; i > 0; i--)
6733: {
6734: attrnames[i] = attrnames[i - 1];
6735: attrnums[i] = attrnums[i - 1];
6736: attrlevels[i] = attrlevels[i - 1];
6737: attrvals[i] = attrvals[i - 1];
6738: attrmatch[i] = attrmatch[i - 1];
6739: }
6740: attrnames[0] = deb;
6741: attrnums[0] = 0;
6742: attrlevels[0] = 0;
1.378 quint 6743: attrvals[0] = NULL;
6744: attrmatch[0] = Txtmatch;
1.327 vatton 6745: specificity += 10;
1.340 quint 6746: /* check matching */
1.341 quint 6747: selector = SkipBlanksAndComments (selector);
1.340 quint 6748: if (*selector == '~')
6749: {
6750: attrmatch[0] = Txtword;
6751: selector++;
6752: }
1.396 vatton 6753: else if (*selector == '|' || *selector == '$' || *selector == '*')
1.340 quint 6754: {
1.396 vatton 6755: if (*selector == '$')
6756: CSSPrintError ("Warning: \"$=\" is CSS3 syntax", NULL);
6757: if (*selector == '*')
6758: CSSPrintError ("Warning: \"*=\" is CSS3 syntax", NULL);
1.340 quint 6759: attrmatch[0] = Txtsubstring;
6760: selector++;
6761: }
1.341 quint 6762: else if (*selector == '^')
6763: {
6764: attrmatch[0] = Txtsubstring;
6765: selector++;
6766: }
1.340 quint 6767: else
6768: attrmatch[0] = Txtmatch;
1.327 vatton 6769: }
6770: if (*selector == '=')
6771: {
6772: /* look for a value "xxxx" */
6773: selector++;
1.341 quint 6774: selector = SkipBlanksAndComments (selector);
1.327 vatton 6775: if (*selector != '"')
6776: quoted = FALSE;
6777: else
6778: {
6779: quoted = TRUE;
6780: /* we are now parsing the attribute value */
6781: selector++;
6782: }
6783: deb = cur;
1.398 vatton 6784: while ((quoted && cur < limit &&
1.327 vatton 6785: (*selector != '"' ||
6786: (*selector == '"' && selector[-1] == '\\'))) ||
6787: (!quoted && *selector != ']'))
6788: {
6789: if (*selector == EOS)
6790: {
6791: CSSPrintError ("Invalid attribute value", deb);
6792: DoApply = FALSE;
6793: }
6794: else
6795: {
6796: if (attrmatch[0] == Txtword && TtaIsBlank (selector))
6797: {
6798: CSSPrintError ("No space allowed here: ", selector);
6799: DoApply = FALSE;
6800: }
6801: *cur++ = *selector;
6802: }
6803: selector++;
6804: }
6805: /* there is a value */
6806: if (quoted && *selector == '"')
6807: {
6808: selector++;
6809: quoted = FALSE;
6810: }
1.341 quint 6811: selector = SkipBlanksAndComments (selector);
1.327 vatton 6812: if (*selector != ']')
6813: {
6814: CSSPrintError ("Invalid attribute value", deb);
6815: DoApply = FALSE;
6816: }
6817: else
6818: {
6819: *cur++ = EOS;
6820: attrvals[0] = deb;
6821: selector++;
6822: }
6823: }
6824: /* end of the attribute */
6825: else if (*selector != ']')
6826: {
6827: selector[1] = EOS;
6828: CSSPrintError ("Invalid attribute", selector);
6829: selector += 2;
6830: DoApply = FALSE;
6831: }
6832: else
6833: {
6834: selector++;
6835: if (names[0] && !strcmp (names[0], "*"))
6836: names[0] = NULL;
6837: }
6838: }
6839: else
6840: {
6841: /* not supported selector */
1.340 quint 6842: while (*selector != '.' && *selector != ':' &&
6843: *selector != '#' && *selector != '[' &&
6844: *selector != EOS && *selector != ',' &&
6845: *selector != '+' && *selector != '>' &&
1.398 vatton 6846: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6847: *cur++ = *selector++;
6848: /* close the word */
6849: *cur++ = EOS;
6850: CSSPrintError ("Selector not supported:", deb);
6851: DoApply = FALSE;
6852: }
6853: }
1.1 cvs 6854:
1.286 quint 6855: skippedNL = NewLineSkipped;
1.82 cvs 6856: selector = SkipBlanksAndComments (selector);
1.286 quint 6857: NewLineSkipped = skippedNL;
6858:
1.380 vatton 6859: if (noname && !pseudoFirstChild[0] && attrnums[0] == 0 && attrnames[0] == NULL)
6860: {
6861: *cur++ = EOS;
6862: CSSPrintError ("Invalid Selector", deb);
6863: DoApply = FALSE;
6864: }
1.25 cvs 6865: /* is it a multi-level selector? */
1.82 cvs 6866: if (*selector == EOS)
1.327 vatton 6867: /* end of the selector */
6868: break;
1.82 cvs 6869: else if (*selector == ',')
1.327 vatton 6870: {
6871: /* end of the current selector */
6872: selector++;
6873: skippedNL = NewLineSkipped;
6874: next = SkipBlanksAndComments (selector);
6875: NewLineSkipped = skippedNL;
6876: if (*next == EOS)
6877: /* nothing after the comma. Invalid selector */
6878: {
1.380 vatton 6879: CSSPrintError ("Syntax error:", selector);
6880: selector = NULL;
1.327 vatton 6881: }
6882: break;
6883: }
1.25 cvs 6884: else
1.327 vatton 6885: {
6886: if (*selector == '>')
6887: {
1.340 quint 6888: /* handle parent */
1.327 vatton 6889: selector++;
6890: skippedNL = NewLineSkipped;
6891: selector = SkipBlanksAndComments (selector);
6892: NewLineSkipped = skippedNL;
1.340 quint 6893: rel[0] = RelParent;
1.327 vatton 6894: }
6895: else if (*selector == '+')
6896: {
1.340 quint 6897: /* handle immediate sibling */
1.327 vatton 6898: selector++;
6899: skippedNL = NewLineSkipped;
6900: selector = SkipBlanksAndComments (selector);
6901: NewLineSkipped = skippedNL;
6902: rel[0] = RelPrevious;
6903: }
1.340 quint 6904: else
6905: rel[0] = RelAncestor;
6906: nbnames++; /* a new level in ancestor tables */
6907: if (nbnames == MAX_ANCESTORS)
6908: /* abort parsing */
6909: {
6910: CSSPrintError ("Selector too long", deb);
6911: return (selector);
6912: }
6913: /* shift the list to make room for the next part of the selector */
6914: for (i = nbnames; i > 0; i--)
1.327 vatton 6915: {
6916: names[i] = names[i - 1];
1.355 quint 6917: pseudoFirstChild[i] = pseudoFirstChild[i - 1];
1.327 vatton 6918: rel[i] = rel[i - 1];
6919: }
1.340 quint 6920: /* increase the level of all attributes */
6921: for (i = 0; i < nbattrs; i++)
6922: attrlevels[i]++;
1.327 vatton 6923: }
1.1 cvs 6924: }
6925:
1.343 vatton 6926: /* Now update the list of classes defined by the CSS */
6927: for (i = 0; i < nbattrs; i++)
6928: if (attrvals[i] && attrnums[i] == ATTR_CLASS)
6929: AddClassName (attrvals[i], css);
6930:
1.1 cvs 6931: /* Now set up the context block */
1.25 cvs 6932: i = 0;
6933: j = 0;
1.91 cvs 6934: /* default schema name */
1.119 vatton 6935: ctxt->schema = NULL;
1.340 quint 6936: ctxt->nbElem = nbnames;
1.122 vatton 6937: elType.ElSSchema = NULL;
1.355 quint 6938: elType.ElTypeNum = 0;
1.122 vatton 6939: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 6940: if (!strcmp (schemaName, "HTML"))
6941: xmlType = XHTML_TYPE;
6942: else if (!strcmp (schemaName, "MathML"))
6943: xmlType = MATH_TYPE;
6944: else if (!strcmp (schemaName, "SVG"))
6945: xmlType = SVG_TYPE;
6946: else if (!strcmp (schemaName, "XLink"))
6947: xmlType = XLINK_TYPE;
6948: else if (!strcmp (schemaName, "Annot"))
6949: xmlType = ANNOT_TYPE;
6950: else
6951: xmlType = XML_TYPE;
1.340 quint 6952: while (i <= nbnames)
1.25 cvs 6953: {
1.340 quint 6954: ctxt->rel[i] = rel[i];
1.355 quint 6955: ctxt->firstChild[i] = pseudoFirstChild[i];
6956: if (!names[i] && i > 0)
1.340 quint 6957: ctxt->name[i] = HTML_EL_ANY_TYPE;
6958: else
6959: /* store element information */
1.327 vatton 6960: {
6961: /* get the element type of this name in the current document */
6962: if (xmlType == XML_TYPE)
6963: /* it's a generic XML document. Check the main document schema */
6964: {
6965: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 6966: elType.ElTypeNum = 0;
6967: if (names[i])
6968: TtaGetXmlElementType (names[i], &elType, &mappedName, doc);
1.327 vatton 6969: if (!elType.ElTypeNum)
6970: {
1.355 quint 6971: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 6972: elType.ElTypeNum = HTML_EL_ANY_TYPE;
6973: else
6974: elType.ElSSchema = NULL;
6975: }
6976: }
6977: else
6978: {
1.355 quint 6979: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 6980: {
6981: elType.ElSSchema = TtaGetDocumentSSchema (doc);
6982: elType.ElTypeNum = HTML_EL_ANY_TYPE;
6983: }
6984: else
6985: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c,
6986: &level, doc);
6987: }
6988: if (i == 0)
1.340 quint 6989: /* rightmost part of the selector */
1.327 vatton 6990: {
6991: if (elType.ElSSchema == NULL)
6992: {
1.340 quint 6993: /* element name not found. Search in all loaded schemas */
1.355 quint 6994: if (names[i])
6995: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.327 vatton 6996: if (elType.ElSSchema)
6997: {
6998: /* the element type concerns an imported nature */
6999: schemaName = TtaGetSSchemaName(elType.ElSSchema);
7000: if (!strcmp (schemaName, "HTML"))
7001: {
7002: if (xmlType == XHTML_TYPE &&
7003: DocumentMeta[doc] && DocumentMeta[doc]->xmlformat)
7004: /* the selector was found but the case is not correct */
7005: elType.ElSSchema = NULL;
7006: else
7007: xmlType = XHTML_TYPE;
7008: }
7009: else if (!strcmp (schemaName, "MathML"))
7010: xmlType = MATH_TYPE;
7011: else if (!strcmp (schemaName, "SVG"))
7012: xmlType = SVG_TYPE;
7013: else if (!strcmp (schemaName, "XLink"))
7014: xmlType = XLINK_TYPE;
7015: else if (!strcmp (schemaName, "Annot"))
7016: xmlType = ANNOT_TYPE;
7017: else
7018: xmlType = XML_TYPE;
7019: }
1.118 vatton 7020: #ifdef XML_GENERIC
1.327 vatton 7021: else if (xmlType == XML_TYPE)
7022: {
7023: /* Creation of a new element type in the main schema */
7024: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7025: if (names[i])
7026: TtaAppendXmlElement (names[i], &elType, &mappedName,
7027: doc);
1.327 vatton 7028: }
1.118 vatton 7029: #endif /* XML_GENERIC */
1.327 vatton 7030: else
7031: {
7032: if (xmlType != XHTML_TYPE)
7033: {
7034: MapXMLElementType (XHTML_TYPE, names[i], &elType,
7035: &mappedName, &c, &level, doc);
7036: if (elType.ElSSchema)
7037: elType.ElSSchema = GetXHTMLSSchema (doc);
7038: }
7039: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
7040: {
7041: MapXMLElementType (MATH_TYPE, names[i], &elType,
7042: &mappedName, &c, &level, doc);
7043: if (elType.ElSSchema)
7044: elType.ElSSchema = GetMathMLSSchema (doc);
7045: }
7046: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
7047: {
7048: MapXMLElementType (SVG_TYPE, names[i], &elType,
7049: &mappedName, &c, &level, doc);
7050: if (elType.ElSSchema)
7051: elType.ElSSchema = GetSVGSSchema (doc);
7052: }
7053: }
7054: }
7055:
7056: if (elType.ElSSchema == NULL)
7057: /* cannot apply these CSS rules */
7058: DoApply = FALSE;
7059: else
7060: {
1.340 quint 7061: /* Store the element type contained in the rightmost part of
7062: the selector */
7063: ctxt->schema = elType.ElSSchema;
1.327 vatton 7064: ctxt->type = elType.ElTypeNum;
7065: ctxt->name[0] = elType.ElTypeNum;
1.340 quint 7066: ctxt->rel[0] = RelVoid;
1.327 vatton 7067: }
7068: }
1.340 quint 7069: else
7070: /* not the rightmost part of the selector */
1.327 vatton 7071: {
1.340 quint 7072: if (elType.ElTypeNum != 0)
7073: ctxt->name[i] = elType.ElTypeNum;
7074: #ifdef XML_GENERIC
7075: else if (xmlType == XML_TYPE)
1.327 vatton 7076: {
1.340 quint 7077: TtaGetXmlElementType (names[i], &elType, NULL, doc);
7078: if (elType.ElTypeNum == 0)
1.327 vatton 7079: {
1.340 quint 7080: /* Creation of a new element type in the main schema */
7081: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7082: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.327 vatton 7083: }
1.340 quint 7084: if (elType.ElTypeNum != 0)
7085: ctxt->name[i] = elType.ElTypeNum;
1.327 vatton 7086: }
1.340 quint 7087: #endif /* XML_GENERIC */
1.327 vatton 7088: }
1.340 quint 7089: }
7090:
7091: /* store attribute information for this element */
7092: while (j < nbattrs && attrlevels[j] <= i)
7093: {
7094: if (attrnames[j] || attrnums[j])
1.327 vatton 7095: {
1.340 quint 7096: if (attrnums[j] > 0)
1.327 vatton 7097: {
1.340 quint 7098: if (attrnums[j] == ATTR_CLASS)
1.327 vatton 7099: {
1.340 quint 7100: if (xmlType == SVG_TYPE)
7101: ctxt->attrType[j] = SVG_ATTR_class;
7102: else if (xmlType == MATH_TYPE)
7103: ctxt->attrType[j] = MathML_ATTR_class;
7104: else if (xmlType == XHTML_TYPE)
7105: ctxt->attrType[j] = HTML_ATTR_Class;
1.327 vatton 7106: else
1.119 vatton 7107: #ifdef XML_GENERIC
1.340 quint 7108: ctxt->attrType[j] = XML_ATTR_class;
1.107 cvs 7109: #else /* XML_GENERIC */
1.340 quint 7110: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 7111: #endif /* XML_GENERIC */
1.340 quint 7112: }
7113: else if (attrnums[j] == ATTR_PSEUDO)
7114: {
7115: if (xmlType == SVG_TYPE)
7116: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
7117: else if (xmlType == MATH_TYPE)
7118: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
7119: else if (xmlType == XHTML_TYPE)
7120: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
7121: else
1.119 vatton 7122: #ifdef XML_GENERIC
1.340 quint 7123: ctxt->attrType[j] = XML_ATTR_PseudoClass;
1.107 cvs 7124: #else /* XML_GENERIC */
1.340 quint 7125: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 7126: #endif /* XML_GENERIC */
1.340 quint 7127: }
7128: else if (attrnums[j] == ATTR_ID)
7129: {
7130: if (xmlType == SVG_TYPE)
7131: ctxt->attrType[j] = SVG_ATTR_id;
7132: else if (xmlType == MATH_TYPE)
7133: ctxt->attrType[j] = MathML_ATTR_id;
7134: else if (xmlType == XHTML_TYPE)
7135: ctxt->attrType[j] = HTML_ATTR_ID;
7136: else
1.119 vatton 7137: #ifdef XML_GENERIC
1.340 quint 7138: ctxt->attrType[j] = XML_ATTR_xmlid;
1.107 cvs 7139: #else /* XML_GENERIC */
1.340 quint 7140: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 7141: #endif /* XML_GENERIC */
1.340 quint 7142: }
7143: attrType.AttrTypeNum = ctxt->attrType[j];
7144: attrType.AttrSSchema = ctxt->schema;
7145: }
7146: else if (attrnames[j])
7147: {
7148: if (xmlType == XML_TYPE)
7149: {
7150: if (ctxt->schema)
7151: attrType.AttrSSchema = ctxt->schema;
7152: else
7153: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7154: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7155: att = attrType.AttrTypeNum;
7156: if (ctxt->schema == NULL && att != 0)
7157: ctxt->schema = attrType.AttrSSchema;
7158: }
7159: else
7160: {
7161: MapXMLAttribute (xmlType, attrnames[j], names[i], &level,
7162: doc, &att);
7163: if (ctxt->schema == NULL && att != 0)
7164: ctxt->schema = TtaGetDocumentSSchema (doc);
7165: }
1.393 quint 7166: if (att == 0 && xmlType != XML_TYPE)
1.340 quint 7167: /* Attribute name not found: Search in the list of all
7168: schemas loaded for this document */
7169: {
7170: attrType.AttrSSchema = NULL;
7171: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7172: att = attrType.AttrTypeNum;
7173: if (att != 0)
1.393 quint 7174: {
7175: ctxt->schema = attrType.AttrSSchema;
7176: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
7177: }
1.340 quint 7178: }
7179: attrType.AttrSSchema = ctxt->schema;
7180: attrType.AttrTypeNum = att;
1.393 quint 7181: if (i == 0 && att == 0)
1.340 quint 7182: {
1.119 vatton 7183: #ifdef XML_GENERIC
1.393 quint 7184: if (xmlType == XML_TYPE)
1.340 quint 7185: {
7186: /* The attribute is not yet present in the tree */
7187: /* Create a new global attribute */
7188: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7189: TtaAppendXmlAttribute (attrnames[j], &attrType, doc);
1.393 quint 7190: att = attrType.AttrTypeNum;
1.340 quint 7191: }
7192: #endif /* XML_GENERIC */
7193: if (attrType.AttrSSchema == NULL)
7194: /* cannot apply these CSS rules */
7195: DoApply = FALSE;
7196: else if (elType.ElSSchema)
7197: ctxt->schema = elType.ElSSchema;
7198: else
7199: ctxt->schema = attrType.AttrSSchema;
7200: }
7201: if (att == 0)
7202: {
7203: CSSPrintError ("Unknown attribute", attrnames[j]);
7204: DoApply = FALSE;
7205: }
7206: else
1.345 quint 7207: {
7208: ctxt->attrType[j] = att;
7209: if (att == DummyAttribute && !strcmp (schemaName,"HTML"))
7210: /* it's the "type" attribute for an "input" element.
7211: In the tree, it is represented by the element type,
7212: not by an attribute */
7213: {
7214: ctxt->attrType[j] = 0;
7215: if (attrvals[j] && attrmatch[i] == Txtmatch)
7216: /* a value is specified for attribute type. This
7217: value provides the Thot element type */
7218: {
7219: MapXMLAttributeValue (xmlType, attrvals[j],
7220: &attrType, &kind);
7221: /* attrType contains the element type */
7222: if (i == 0)
7223: ctxt->type = kind;
7224: ctxt->name[i] = kind;
7225: }
7226: }
7227: }
1.340 quint 7228: }
7229: if (ctxt->attrType[j])
1.327 vatton 7230: {
1.340 quint 7231: /* check the attribute type */
7232: if (!strcmp (schemaName, "HTML"))
7233: xmlType = XHTML_TYPE;
7234: else if (!strcmp (schemaName, "MathML"))
7235: xmlType = MATH_TYPE;
7236: else if (!strcmp (schemaName, "SVG"))
7237: xmlType = SVG_TYPE;
7238: else if (!strcmp (schemaName, "XLink"))
7239: xmlType = XLINK_TYPE;
7240: else if (!strcmp (schemaName, "Annot"))
7241: xmlType = ANNOT_TYPE;
7242: else
7243: xmlType = XML_TYPE;
7244: kind = TtaGetAttributeKind (attrType);
7245: if (kind == 0 && attrvals[j])
7246: {
7247: /* enumerated value */
7248: MapXMLAttributeValue (xmlType, attrvals[j], &attrType,
7249: &kind);
7250: /* store the attribute value */
7251: ctxt->attrText[j] = (char *) kind;
7252: }
7253: else
7254: ctxt->attrText[j] = attrvals[j];
7255: /* update attrLevel */
7256: ctxt->attrMatch[j] = attrmatch[j];
7257: ctxt->attrLevel[j] = attrlevels[j];
7258: }
7259: j++;
1.327 vatton 7260: }
7261: }
1.340 quint 7262: /* add a new entry */
1.25 cvs 7263: i++;
1.119 vatton 7264: if (i == 1 && ctxt->schema == NULL)
1.327 vatton 7265: /* use the document schema */
7266: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 7267: }
1.340 quint 7268:
1.312 quint 7269: ctxt->important = FALSE;
1.117 vatton 7270: /* set the selector specificity */
7271: ctxt->cssSpecificity = specificity;
1.25 cvs 7272: /* Get the schema name of the main element */
1.119 vatton 7273: schemaName = TtaGetSSchemaName (ctxt->schema);
7274: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 7275: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.217 vatton 7276: skippedNL = NewLineSkipped;
1.380 vatton 7277: if (DoApply && tsch && cssRule)
1.317 vatton 7278: {
7279: if (css)
1.327 vatton 7280: {
7281: /* point the right URL for loaded images */
7282: saveURL = css->url;
7283: css->url = url;
7284: }
1.317 vatton 7285: else
1.327 vatton 7286: saveURL = NULL;
7287: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.317 vatton 7288: if (css)
1.327 vatton 7289: /* restore previous url */
7290: css->url = saveURL;
1.317 vatton 7291: }
1.116 vatton 7292: /* future CSS rules should apply */
7293: DoApply = TRUE;
1.217 vatton 7294: if (selector)
7295: NewLineSkipped = skippedNL;
1.1 cvs 7296: return (selector);
7297: }
7298:
7299: /*----------------------------------------------------------------------
1.206 vatton 7300: ParseStyleDeclaration: parse a style declaration stored in the style
7301: element of a document
7302: We expect the style string to be of the form:
7303: .pinky, .awful { color: pink; font-family: helvetica }
1.231 vatton 7304: The parameter css points to the current CSS context.
7305: The parameter link points to the link element.
7306: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 7307: ----------------------------------------------------------------------*/
1.206 vatton 7308: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
1.327 vatton 7309: CSSInfoPtr css, Element link, char *url,
7310: ThotBool destroy)
1.1 cvs 7311: {
1.79 cvs 7312: GenericContext ctxt;
7313: char *decl_end;
7314: char *sel_end;
7315: char *selector;
1.1 cvs 7316:
7317: /* separate the selectors string */
1.82 cvs 7318: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 7319: decl_end = cssRule;
1.82 cvs 7320: while (*decl_end != EOS && *decl_end != '{')
1.286 quint 7321: {
7322: if (*decl_end == EOL)
1.327 vatton 7323: NewLineSkipped++;
1.286 quint 7324: decl_end++;
7325: }
1.82 cvs 7326: if (*decl_end == EOS)
1.86 cvs 7327: {
1.168 vatton 7328: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 7329: return;
7330: }
1.1 cvs 7331: /* verify and clean the selector string */
7332: sel_end = decl_end - 1;
1.82 cvs 7333: while (*sel_end == SPACE || *sel_end == BSPACE ||
1.327 vatton 7334: *sel_end == EOL || *sel_end == CR)
1.1 cvs 7335: sel_end--;
7336: sel_end++;
1.82 cvs 7337: *sel_end = EOS;
1.1 cvs 7338: selector = cssRule;
7339:
7340: /* now, deal with the content ... */
7341: decl_end++;
7342: cssRule = decl_end;
1.137 vatton 7343: decl_end = &cssRule[strlen (cssRule) - 1];
1.398 vatton 7344: if (*decl_end != '{' && *decl_end != EOS)
1.137 vatton 7345: *decl_end = EOS;
1.1 cvs 7346: /*
7347: * parse the style attribute string and install the corresponding
7348: * presentation attributes on the new element
7349: */
7350: ctxt = TtaGetGenericStyleContext (doc);
7351: if (ctxt == NULL)
7352: return;
7353: ctxt->destroy = destroy;
1.207 vatton 7354: /* first use of the context */
7355: ctxt->uses = 1;
1.197 vatton 7356: while (selector && *selector != EOS)
1.363 vatton 7357: {
7358: if (ctxt->uses > 1)
7359: {
7360: /* this context is waiting for a callback */
7361: ctxt = TtaGetGenericStyleContext (doc);
7362: if (ctxt == NULL)
7363: return;
7364: ctxt->destroy = destroy;
7365: /* first use of the context */
7366: ctxt->uses = 1;
7367: }
7368: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css,
7369: link, url);
7370: }
1.207 vatton 7371: /* check if the context can be freed */
7372: ctxt->uses -= 1;
7373: if (ctxt->uses == 0)
7374: /* no image loading */
7375: TtaFreeMemory (ctxt);
1.1 cvs 7376: }
7377:
7378: /************************************************************************
7379: * *
7380: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
7381: * *
7382: ************************************************************************/
7383:
7384: /*----------------------------------------------------------------------
1.327 vatton 7385: IsImplicitClassName: return wether the Class name is an
7386: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
7387: or an HTML context name.
1.1 cvs 7388: ----------------------------------------------------------------------*/
1.248 gully 7389: int IsImplicitClassName (char *class_, Document doc)
1.1 cvs 7390: {
1.327 vatton 7391: char name[200];
7392: char *cur = name;
7393: char *first;
7394: char save;
7395: SSchema schema;
7396:
7397: /* make a local copy */
7398: strncpy (name, class_, 199);
7399: name[199] = 0;
7400:
7401: /* loop looking if each word is a GI */
7402: while (*cur != 0)
7403: {
7404: first = cur;
7405: cur = SkipWord (cur);
7406: save = *cur;
7407: *cur = 0;
7408: schema = NULL;
7409: if (MapGI (first, &schema, doc) == -1)
7410: {
7411: return (0);
7412: }
7413: *cur = save;
7414: cur = SkipBlanksAndComments (cur);
7415: }
7416: return (1);
1.1 cvs 7417: }
7418:
7419: /************************************************************************
1.114 quint 7420: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 7421: ************************************************************************/
7422:
7423: /*----------------------------------------------------------------------
1.327 vatton 7424: HTMLSetBackgroundColor:
1.1 cvs 7425: ----------------------------------------------------------------------*/
1.264 vatton 7426: void HTMLSetBackgroundColor (Document doc, Element el, int specificity,
1.327 vatton 7427: char *color)
1.1 cvs 7428: {
1.350 vatton 7429: char css_command[1000];
1.1 cvs 7430:
1.327 vatton 7431: sprintf (css_command, "background-color: %s", color);
7432: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7433: }
7434:
7435: /*----------------------------------------------------------------------
1.327 vatton 7436: HTMLSetForegroundColor:
1.1 cvs 7437: ----------------------------------------------------------------------*/
1.264 vatton 7438: void HTMLSetForegroundColor (Document doc, Element el, int specificity,
1.327 vatton 7439: char *color)
1.1 cvs 7440: {
1.350 vatton 7441: char css_command[1000];
1.1 cvs 7442:
1.327 vatton 7443: sprintf (css_command, "color: %s", color);
7444: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7445: }
7446:
7447: /*----------------------------------------------------------------------
1.327 vatton 7448: HTMLResetBackgroundColor:
1.1 cvs 7449: ----------------------------------------------------------------------*/
1.97 vatton 7450: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 7451: {
1.350 vatton 7452: char css_command[1000];
1.1 cvs 7453:
1.327 vatton 7454: sprintf (css_command, "background: red");
7455: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7456: }
7457:
7458: /*----------------------------------------------------------------------
1.327 vatton 7459: HTMLResetBackgroundImage:
1.1 cvs 7460: ----------------------------------------------------------------------*/
1.97 vatton 7461: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 7462: {
1.327 vatton 7463: char css_command[1000];
1.1 cvs 7464:
1.327 vatton 7465: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
7466: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7467: }
7468:
7469: /*----------------------------------------------------------------------
1.327 vatton 7470: HTMLResetForegroundColor:
1.1 cvs 7471: ----------------------------------------------------------------------*/
1.97 vatton 7472: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 7473: {
1.350 vatton 7474: char css_command[1000];
1.1 cvs 7475:
1.327 vatton 7476: /* it's not necessary to well know the current color but it must be valid */
7477: sprintf (css_command, "color: red");
7478: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7479: }
7480:
7481: /*----------------------------------------------------------------------
1.327 vatton 7482: HTMLSetAlinkColor:
1.1 cvs 7483: ----------------------------------------------------------------------*/
1.208 vatton 7484: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 7485: {
1.350 vatton 7486: char css_command[1000];
1.1 cvs 7487:
1.327 vatton 7488: sprintf (css_command, ":link { color: %s }", color);
7489: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7490: }
7491:
7492: /*----------------------------------------------------------------------
1.327 vatton 7493: HTMLSetAactiveColor:
1.1 cvs 7494: ----------------------------------------------------------------------*/
1.208 vatton 7495: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 7496: {
1.350 vatton 7497: char css_command[1000];
1.1 cvs 7498:
1.327 vatton 7499: sprintf (css_command, ":active { color: %s }", color);
7500: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7501: }
7502:
7503: /*----------------------------------------------------------------------
1.327 vatton 7504: HTMLSetAvisitedColor:
1.1 cvs 7505: ----------------------------------------------------------------------*/
1.208 vatton 7506: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 7507: {
1.350 vatton 7508: char css_command[1000];
1.1 cvs 7509:
1.327 vatton 7510: sprintf (css_command, ":visited { color: %s }", color);
7511: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7512: }
7513:
7514: /*----------------------------------------------------------------------
1.327 vatton 7515: HTMLResetAlinkColor:
1.1 cvs 7516: ----------------------------------------------------------------------*/
1.208 vatton 7517: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 7518: {
1.350 vatton 7519: char css_command[1000];
1.1 cvs 7520:
1.327 vatton 7521: sprintf (css_command, ":link { color: red }");
7522: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7523: }
7524:
7525: /*----------------------------------------------------------------------
1.327 vatton 7526: HTMLResetAactiveColor:
1.1 cvs 7527: ----------------------------------------------------------------------*/
1.208 vatton 7528: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 7529: {
1.350 vatton 7530: char css_command[1000];
1.1 cvs 7531:
1.327 vatton 7532: sprintf (css_command, ":active { color: red }");
7533: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7534: }
7535:
7536: /*----------------------------------------------------------------------
1.327 vatton 7537: HTMLResetAvisitedColor:
1.1 cvs 7538: ----------------------------------------------------------------------*/
1.208 vatton 7539: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 7540: {
1.350 vatton 7541: char css_command[1000];
1.1 cvs 7542:
1.327 vatton 7543: sprintf (css_command, ":visited { color: red }");
7544: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7545: }
7546:
7547: /*----------------------------------------------------------------------
1.206 vatton 7548: ApplyCSSRules: parse a CSS Style description stored in the header of
7549: a HTML document.
1.1 cvs 7550: ----------------------------------------------------------------------*/
1.79 cvs 7551: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 7552: {
1.206 vatton 7553: CSSInfoPtr css;
7554: PInfoPtr pInfo;
1.207 vatton 7555: ThotBool loadcss;
7556:
7557: /* check if we have to load CSS */
7558: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
7559: if (!loadcss)
7560: return;
1.376 vatton 7561: LineNumber = TtaGetElementLineNumber (el);
1.206 vatton 7562: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 7563: if (css == NULL)
1.209 vatton 7564: {
7565: /* create the document css context */
7566: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
7567: pInfo = css->infos[doc];
7568: }
1.206 vatton 7569: else if (pInfo == NULL)
7570: /* create the entry into the css context */
7571: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 7572: if (pInfo->PiEnabled)
1.376 vatton 7573: ParseStyleDeclaration (el, cssRule, doc, css, el, NULL, destroy);
7574: LineNumber = -1;
1.1 cvs 7575: }
7576:
7577: /*----------------------------------------------------------------------
1.327 vatton 7578: ReadCSSRules: is the front-end function called by the document parser
7579: when detecting a <style type="text/css"> indicating it's the
7580: beginning of a CSS fragment or when reading a file .css.
1.1 cvs 7581:
1.327 vatton 7582: The CSS parser has to handle <!-- ... --> constructs used to
7583: prevent prehistoric browser from displaying the CSS as a text
7584: content. It will stop on any sequence "<x" where x is different
7585: from ! and will return x as to the caller. Theorically x should
7586: be equal to / for the </style> end of style.
7587: The parameter doc gives the document tree that contains CSS information.
7588: The parameter docRef gives the document to which CSS are to be applied.
7589: This function uses the current css context or creates it. It's able
7590: to work on the given buffer or call GetNextChar to read the parsed
7591: file.
7592: The parameter url gives the URL of the parsed style sheet.
7593: The parameter numberOfLinesRead gives the number of lines already
7594: read in the file.
7595: The parameter withUndo indicates whether the changes made in the document
7596: structure and content have to be registered in the Undo queue or not.
1.1 cvs 7597: ----------------------------------------------------------------------*/
1.133 vatton 7598: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.343 vatton 7599: int numberOfLinesRead, ThotBool withUndo, Element link)
1.1 cvs 7600: {
1.6 cvs 7601: DisplayMode dispMode;
1.206 vatton 7602: CSSInfoPtr refcss = NULL;
1.321 vatton 7603: CSSmedia css_media = CSS_ALL;
1.206 vatton 7604: PInfoPtr pInfo;
1.321 vatton 7605: char c;
1.138 vatton 7606: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 7607: int index;
1.1 cvs 7608: int CSSindex;
1.327 vatton 7609: int CSScomment;
1.1 cvs 7610: int import;
1.358 quint 7611: int openBlock;
1.93 vatton 7612: int newlines;
1.358 quint 7613: int page;
1.14 cvs 7614: ThotBool HTMLcomment;
1.342 vatton 7615: ThotBool toParse, eof, quoted, s_quoted;
1.358 quint 7616: ThotBool ignore, media, lineComment;
1.234 vatton 7617: ThotBool noRule, ignoreImport, fontface;
1.1 cvs 7618:
1.327 vatton 7619: CSScomment = MAX_CSS_LENGTH;
1.1 cvs 7620: HTMLcomment = FALSE;
7621: CSSindex = 0;
7622: toParse = FALSE;
7623: noRule = FALSE;
1.234 vatton 7624: media = FALSE;
1.88 cvs 7625: ignoreImport = FALSE;
1.342 vatton 7626: ignore = lineComment = FALSE;
1.358 quint 7627: page = 0;
1.342 vatton 7628: quoted = s_quoted = FALSE;
1.234 vatton 7629: fontface = FALSE;
1.1 cvs 7630: eof = FALSE;
1.358 quint 7631: openBlock = 0;
1.234 vatton 7632: import = MAX_CSS_LENGTH;
1.82 cvs 7633: c = SPACE;
1.1 cvs 7634: index = 0;
1.134 vatton 7635: base = NULL;
1.310 vatton 7636: /* entering the CSS parsing */
1.311 vatton 7637: Style_parsing++;
1.93 vatton 7638: /* number of new lines parsed */
7639: newlines = 0;
1.6 cvs 7640: /* avoid too many redisplay */
7641: dispMode = TtaGetDisplayMode (docRef);
7642: if (dispMode == DisplayImmediately)
7643: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 7644:
7645: /* look for the CSS context */
7646: if (css == NULL)
1.206 vatton 7647: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 7648: else
7649: pInfo = css->infos[docRef];
1.18 cvs 7650: if (css == NULL)
1.206 vatton 7651: {
7652: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
7653: pInfo = css->infos[docRef];
7654: }
7655: else if (pInfo == NULL)
7656: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 7657: /* look for the CSS descriptor that points to the extension schema */
7658: refcss = css;
1.224 vatton 7659: if (pInfo && pInfo->PiCategory == CSS_IMPORT)
1.173 cvs 7660: {
1.206 vatton 7661: while (refcss &&
1.327 vatton 7662: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
7663: refcss = refcss->NextCSS;
1.206 vatton 7664: if (refcss)
1.327 vatton 7665: pInfo = refcss->infos[docRef];
1.173 cvs 7666: }
7667:
1.343 vatton 7668: /* register parsed CSS file and the document to which CSS are to be applied */
1.395 vatton 7669: if (DocumentMeta[docRef] == NULL || DocumentMeta[docRef]->method != CE_MAKEBOOK)
7670: ParsedDoc = docRef;
7671: else
7672: ParsedDoc = 0;
1.343 vatton 7673: /* clean up the list of classes */
7674: TtaFreeMemory (refcss->class_list);
7675: refcss->class_list = NULL;
1.133 vatton 7676: if (url)
1.348 vatton 7677: Error_DocURL = url;
1.86 cvs 7678: else
7679: /* the CSS source in within the document itself */
1.348 vatton 7680: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 7681: LineNumber = numberOfLinesRead + 1;
1.93 vatton 7682: NewLineSkipped = 0;
1.217 vatton 7683: newlines = 0;
1.392 carcone 7684:
7685: /* Search for an UTF-8 BOM character (EF BB BF) */
7686: if (index == 0 && strlen(buffer) > 2 &&
7687: (unsigned char) buffer[0] == 0xEF &&
7688: (unsigned char) buffer[1] == 0xBB &&
7689: (unsigned char) buffer[2] == 0xBF)
7690: {
7691: index = 3;
7692: }
7693:
7694: /* Search for an UTF-16 Big Endian BOM character (FE FF) */
7695: if (index == 0 && strlen(buffer) > 1 &&
7696: (unsigned char) buffer[0] == 0xFE &&
7697: (unsigned char) buffer[1] == 0xFF)
7698: {
7699: index = 2;
7700: }
7701:
7702: /* Search for an UTF-16 Little Endian BOM character (FF FE) */
7703: if (index == 0 && strlen(buffer) > 1 &&
7704: (unsigned char) buffer[0] == 0xFF &&
7705: (unsigned char) buffer[1] == 0xFE)
7706: {
7707: index = 2;
7708: }
7709:
1.82 cvs 7710: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
7711: {
7712: c = buffer[index++];
7713: eof = (c == EOS);
7714: CSSbuffer[CSSindex] = c;
1.342 vatton 7715: if (!lineComment &&
7716: (CSScomment == MAX_CSS_LENGTH || c == '*' || c == '/' || c == '<' || c == EOL))
1.327 vatton 7717: {
7718: /* we're not within a comment or we're parsing * or / */
7719: switch (c)
7720: {
7721: case '@': /* perhaps an import primitive */
1.342 vatton 7722: if (!fontface && !page && !quoted && !s_quoted)
1.327 vatton 7723: import = CSSindex;
7724: break;
7725: case ';':
1.342 vatton 7726: if (!quoted && !s_quoted && !media && import != MAX_CSS_LENGTH)
1.327 vatton 7727: {
7728: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
7729: /* it's not an import */
7730: import = MAX_CSS_LENGTH;
7731: /* save the text */
7732: noRule = TRUE;
7733: }
7734: break;
7735: case '*':
1.342 vatton 7736: if (!quoted && !s_quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.327 vatton 7737: CSSbuffer[CSSindex - 1] == '/')
7738: /* start a comment */
7739: CSScomment = CSSindex - 1;
7740: break;
7741: case '/':
1.342 vatton 7742: if (!quoted && !s_quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.399 vatton 7743: CSSbuffer[CSSindex - 1] == '*' && CSSindex != CSScomment + 2)
1.327 vatton 7744: {
7745: while (CSSindex > 0 && CSSindex >= CSScomment)
7746: {
7747: if ( CSSbuffer[CSSindex] == EOL)
7748: {
7749: LineNumber ++;
7750: newlines --;
7751: }
7752: CSSindex--;
7753: }
7754: CSSindex = CSScomment - 1; /* will be incremented later */
7755: CSScomment = MAX_CSS_LENGTH;
7756: /* clean up the buffer */
7757: if (newlines && CSSindex > 0)
7758: while (CSSindex > 0 &&
7759: (CSSbuffer[CSSindex] == SPACE ||
7760: CSSbuffer[CSSindex] == BSPACE ||
7761: CSSbuffer[CSSindex] == EOL ||
7762: CSSbuffer[CSSindex] == TAB ||
7763: CSSbuffer[CSSindex] == __CR__))
7764: {
7765: if ( CSSbuffer[CSSindex] == EOL)
7766: {
7767: LineNumber ++;
7768: newlines --;
7769: }
7770: CSSindex--;
7771: }
7772: }
1.342 vatton 7773: else if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7774: CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
7775: CSSbuffer[CSSindex - 1] == '<')
7776: {
7777: /* this is the closing tag ! */
7778: CSSindex -= 2; /* remove </ from the CSS string */
7779: noRule = TRUE;
1.342 vatton 7780: }
7781: else if (!quoted && !s_quoted &&
7782: (CSSindex == 1 || (CSSindex > 1 && CSSbuffer[CSSindex - 2] == EOL)) &&
7783: CSScomment == MAX_CSS_LENGTH &&
7784: CSSbuffer[CSSindex - 1] == '/')
7785: {
7786: CSSindex--;
7787: lineComment = TRUE;
7788: }
7789:
1.327 vatton 7790: break;
7791: case '<':
1.342 vatton 7792: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7793: CSScomment == MAX_CSS_LENGTH)
7794: {
7795: /* only if we're not parsing a comment */
7796: c = buffer[index++];
7797: eof = (c == EOS);
7798: if (c == '!')
7799: {
7800: /* CSS within an HTML comment */
7801: HTMLcomment = TRUE;
7802: CSSindex++;
7803: CSSbuffer[CSSindex] = c;
7804: }
7805: else if (c == EOS)
7806: CSSindex++;
7807: }
7808: break;
7809: case '-':
1.342 vatton 7810: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7811: CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
7812: HTMLcomment)
7813: /* CSS within an HTML comment */
7814: noRule = TRUE;
7815: break;
7816: case '>':
1.342 vatton 7817: if (!fontface && !page && !quoted && !s_quoted && HTMLcomment)
1.327 vatton 7818: noRule = TRUE;
7819: break;
7820: case ' ':
1.358 quint 7821: if (!quoted && !s_quoted && import != MAX_CSS_LENGTH && openBlock == 0)
1.327 vatton 7822: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
7823: break;
7824: case '{':
1.342 vatton 7825: if (!quoted && !s_quoted)
1.327 vatton 7826: {
1.358 quint 7827: openBlock++;
1.327 vatton 7828: if (import != MAX_CSS_LENGTH)
7829: {
1.358 quint 7830: if (openBlock == 1 && media)
1.327 vatton 7831: {
7832: /* is it the screen concerned? */
7833: CSSbuffer[CSSindex+1] = EOS;
7834: css_media = CheckMediaCSS (&CSSbuffer[import+7]);
7835: if (TtaIsPrinting ())
7836: ignore = (css_media != CSS_ALL && css_media != CSS_PRINT);
7837: else
7838: ignore = (css_media != CSS_ALL && css_media != CSS_SCREEN);
7839: noRule = TRUE;
7840: }
7841: else if (!strncasecmp (&CSSbuffer[import+1], "page", 4))
1.358 quint 7842: /* it is a @page block */
1.327 vatton 7843: {
1.358 quint 7844: page = openBlock;/*remember the level of this block*/
1.327 vatton 7845: noRule = TRUE;
7846: }
7847: else if (!strncasecmp (&CSSbuffer[import+1], "font-face", 9))
7848: {
7849: fontface = TRUE;
7850: noRule = TRUE;
7851: }
7852: }
7853: }
7854: break;
7855: case '}':
1.342 vatton 7856: if (!quoted && !s_quoted)
1.327 vatton 7857: {
1.358 quint 7858: if (page == openBlock)
7859: /* closing the @page block */
1.327 vatton 7860: {
7861: noRule = TRUE;
1.358 quint 7862: page = 0; /* close the page section */
1.327 vatton 7863: }
7864: else if (fontface)
7865: {
7866: noRule = TRUE;
7867: fontface = FALSE; /* close the fontface section */
7868: }
1.358 quint 7869: else if (openBlock == 1 && import != MAX_CSS_LENGTH)
1.327 vatton 7870: {
7871: import = MAX_CSS_LENGTH;
7872: noRule = TRUE;
7873: ignore = FALSE;
7874: media = FALSE;
7875: }
1.358 quint 7876: else if (!page)
1.327 vatton 7877: toParse = TRUE;
1.358 quint 7878: openBlock--;
1.327 vatton 7879: }
7880: break;
7881: case '"':
7882: if (quoted)
7883: {
1.342 vatton 7884: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
1.327 vatton 7885: quoted = FALSE;
7886: }
1.342 vatton 7887: else if (!s_quoted)
1.327 vatton 7888: quoted = TRUE;
7889: break;
1.342 vatton 7890: case '\'':
7891: if (s_quoted)
7892: {
7893: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
7894: s_quoted = FALSE;
7895: }
7896: else if (!quoted)
7897: s_quoted = TRUE;
7898: break;
7899: default:
1.327 vatton 7900: if (c == EOL)
7901: {
7902: newlines++;
7903: }
7904: break;
7905: }
1.82 cvs 7906: }
1.93 vatton 7907: else if (c == EOL)
1.327 vatton 7908: {
7909: LineNumber++;
1.342 vatton 7910: lineComment = FALSE;
1.327 vatton 7911: c = CR;
7912: }
1.234 vatton 7913:
1.342 vatton 7914: if (!lineComment && c != CR)
1.327 vatton 7915: CSSindex++;
1.82 cvs 7916:
7917: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
1.327 vatton 7918: /* we're still parsing a comment: remove the text comment */
7919: CSSindex = CSScomment;
1.82 cvs 7920:
7921: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
1.327 vatton 7922: {
7923: CSSbuffer[CSSindex] = EOS;
7924: /* parse a not empty string */
7925: if (CSSindex > 0)
7926: {
1.50 cvs 7927: /* apply CSS rule if it's not just a saving of text */
1.234 vatton 7928: if (!noRule && !ignore)
1.327 vatton 7929: {
7930: /* future import rules must be ignored */
7931: ignoreImport = TRUE;
7932: NewLineSkipped = 0;
7933: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
7934: pInfo->PiLink, url, FALSE);
7935: LineNumber += newlines;
7936: newlines = 0;
7937: }
1.82 cvs 7938: else if (import != MAX_CSS_LENGTH &&
1.327 vatton 7939: !strncasecmp (&CSSbuffer[import+1], "import", 6))
7940: {
7941: /* import section */
7942: cssRule = &CSSbuffer[import+7];
7943: cssRule = TtaSkipBlanks (cssRule);
7944: /* save the current line number */
7945: newlines += LineNumber;
7946: if (!strncasecmp (cssRule, "url", 3))
7947: {
1.50 cvs 7948: cssRule = &cssRule[3];
1.82 cvs 7949: cssRule = TtaSkipBlanks (cssRule);
7950: if (*cssRule == '(')
1.327 vatton 7951: {
7952: cssRule++;
7953: cssRule = TtaSkipBlanks (cssRule);
7954: quoted = (*cssRule == '"' || *cssRule == '\'');
7955: if (quoted)
7956: cssRule++;
7957: base = cssRule;
7958: while (*cssRule != EOS && *cssRule != ')')
7959: cssRule++;
7960: if (quoted)
7961: {
7962: /* isolate the file name */
7963: cssRule[-1] = EOS;
7964: quoted = FALSE;
7965: }
7966: else
7967: {
7968: /* remove extra spaces */
7969: if (cssRule[-1] == SPACE)
7970: {
7971: *cssRule = SPACE;
7972: cssRule--;
7973: while (cssRule[-1] == SPACE)
7974: cssRule--;
7975: }
7976: }
7977: *cssRule = EOS;
7978: }
7979: }
7980: else if (*cssRule == '"')
7981: {
7982: /*
7983: Do we have to accept single quotes?
7984: Double quotes are accepted here.
7985: Escaped quotes are not handled. See function SkipQuotedString
7986: */
7987: cssRule++;
7988: cssRule = TtaSkipBlanks (cssRule);
7989: base = cssRule;
7990: while (*cssRule != EOS &&
7991: (*cssRule != '"' ||
7992: (*cssRule == '"' && cssRule[-1] == '\\')))
7993: cssRule++;
7994: /* isolate the file name */
7995: *cssRule = EOS;
7996: }
7997: /* check if a media is defined */
7998: cssRule++;
7999: cssRule = TtaSkipBlanks (cssRule);
8000: if (*cssRule != ';')
8001: {
8002: css_media = CheckMediaCSS (cssRule);
8003: if (TtaIsPrinting ())
8004: ignoreImport = (css_media != CSS_ALL && css_media != CSS_PRINT);
8005: else
8006: ignoreImport = (css_media != CSS_ALL && css_media != CSS_SCREEN);
8007: }
8008: if (!ignoreImport)
8009: {
8010: /* save the displayed URL when an error is reported */
1.348 vatton 8011: saveDocURL = Error_DocURL;
1.327 vatton 8012: ptr = TtaStrdup (base);
8013: /* get the CSS URI in UTF-8 */
8014: /*ptr = ReallocUTF8String (ptr, docRef);*/
8015: LoadStyleSheet (base, docRef, (Element) css, css,
8016: url, pInfo->PiMedia,
8017: pInfo->PiCategory == CSS_USER_STYLE);
8018: /* restore the displayed URL when an error is reported */
1.348 vatton 8019: Error_DocURL = saveDocURL;
1.327 vatton 8020: TtaFreeMemory (ptr);
8021: }
8022: /* restore the number of lines */
8023: LineNumber = newlines;
8024: newlines = 0;
8025: NewLineSkipped = 0;
8026: import = MAX_CSS_LENGTH;
8027: }
8028: else
8029: {
8030: LineNumber += newlines;
8031: newlines = 0;
8032: }
8033: }
8034: toParse = FALSE;
8035: noRule = FALSE;
8036: CSSindex = 0;
1.50 cvs 8037: }
1.82 cvs 8038: }
1.310 vatton 8039: /* closing the CSS parsing */
1.311 vatton 8040: Style_parsing--;
1.330 cvs 8041: if (RedisplayImages == 0 && RedisplayBGImage && Style_parsing == 0)
1.310 vatton 8042: {
1.311 vatton 8043: /* CSS parsing finishes after a BG image was loaded */
1.310 vatton 8044: RedisplayBGImage = FALSE;
1.330 cvs 8045: if (dispMode != NoComputedDisplay)
8046: {
8047: //printf ("ReadCSS Show BGimages\n");
8048: TtaSetDisplayMode (docRef, NoComputedDisplay);
8049: TtaSetDisplayMode (docRef, dispMode);
8050: }
1.310 vatton 8051: }
1.330 cvs 8052: else if (dispMode != NoComputedDisplay)
1.311 vatton 8053: /* restore the display mode */
8054: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 8055:
8056: /* Prepare the context for style attributes */
1.348 vatton 8057: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 8058: LineNumber = -1;
1.1 cvs 8059: return (c);
8060: }
Webmaster