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