Annotation of Amaya/amaya/styleparser.c, revision 1.424
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.117 vatton 4680: PresentationValue best;
1.262 vatton 4681: char *p;
1.1 cvs 4682:
1.370 vatton 4683: best.typed_data.real = FALSE;
1.366 vatton 4684: cssRule = SkipBlanksAndComments (cssRule);
1.262 vatton 4685: p = cssRule;
1.117 vatton 4686: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4687: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4688: {
4689: if (*cssRule != EOS && *cssRule !=';')
4690: {
4691: cssRule = SkipProperty (cssRule, FALSE);
1.366 vatton 4692: CSSParseError ("Invalid color value", p, cssRule);
1.327 vatton 4693: }
1.366 vatton 4694: else if (DoDialog)
4695: DisplayStyleValue ("color", p, cssRule);
4696: else if (DoApply)
1.327 vatton 4697: /* install the new presentation */
4698: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
4699: }
4700: return (cssRule);
1.1 cvs 4701: }
4702:
4703: /*----------------------------------------------------------------------
1.59 cvs 4704: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 4705: ----------------------------------------------------------------------*/
1.79 cvs 4706: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.327 vatton 4707: PresentationContext context,
4708: char *cssRule,
4709: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 4710: {
4711: PresentationValue best;
1.366 vatton 4712: char *ptr;
1.1 cvs 4713:
1.370 vatton 4714: best.typed_data.real = FALSE;
1.366 vatton 4715: cssRule = SkipBlanksAndComments (cssRule);
4716: ptr = cssRule;
1.184 vatton 4717: best.typed_data.unit = UNIT_INVALID;
1.1 cvs 4718: best.typed_data.real = FALSE;
1.198 vatton 4719: if (!strncasecmp (cssRule, "transparent", 11))
1.1 cvs 4720: {
1.184 vatton 4721: best.typed_data.value = PATTERN_NONE;
4722: best.typed_data.unit = UNIT_REL;
1.295 vatton 4723: cssRule = SkipWord (cssRule);
1.116 vatton 4724: if (DoApply)
1.327 vatton 4725: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4726: }
1.1 cvs 4727: else
4728: {
4729: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4730: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4731: {
1.366 vatton 4732: if (DoDialog)
4733: DisplayStyleValue ("background-color", ptr, cssRule);
4734: else if (DoApply)
4735: {
4736: /* install the new presentation. */
4737: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
4738: /* thot specificity: need to set fill pattern for background color */
4739: best.typed_data.value = PATTERN_BACKGROUND;
4740: best.typed_data.unit = UNIT_REL;
4741: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4742: best.typed_data.value = 1;
4743: best.typed_data.unit = UNIT_REL;
4744: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
4745: }
1.327 vatton 4746: }
1.1 cvs 4747: }
4748: return (cssRule);
4749: }
4750:
1.63 cvs 4751: /*----------------------------------------------------------------------
1.65 cvs 4752: ParseSVGStroke: parse a SVG stroke property
4753: ----------------------------------------------------------------------*/
1.79 cvs 4754: static char *ParseSVGStroke (Element element, PSchema tsch,
1.327 vatton 4755: PresentationContext context, char *cssRule,
4756: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 4757: {
4758: PresentationValue best;
1.245 quint 4759: char *url;
1.65 cvs 4760:
1.184 vatton 4761: best.typed_data.unit = UNIT_INVALID;
1.65 cvs 4762: best.typed_data.real = FALSE;
1.82 cvs 4763: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 4764: {
4765: best.typed_data.value = -2; /* -2 means transparent */
1.184 vatton 4766: best.typed_data.unit = UNIT_REL;
1.65 cvs 4767: cssRule = SkipWord (cssRule);
4768: }
1.422 vatton 4769: else if (!strncasecmp (cssRule, "currentColor", 12) ||
4770: !strncasecmp (cssRule, "inherit", 7))
1.245 quint 4771: {
1.293 quint 4772: best.typed_data.unit = VALUE_INHERIT;
4773: cssRule = SkipWord (cssRule);
1.245 quint 4774: }
4775: else if (!strncasecmp (cssRule, "url", 3))
4776: {
4777: cssRule += 3;
4778: cssRule = ParseCSSUrl (cssRule, &url);
4779: /* **** do something with the url ***** */;
4780: TtaFreeMemory (url);
4781: /* **** caution: another color value may follow the uri (in case
1.327 vatton 4782: the uri could ne be dereferenced) *** */
1.245 quint 4783: }
1.65 cvs 4784: else
1.293 quint 4785: cssRule = ParseCSSColor (cssRule, &best);
4786:
4787: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.295 vatton 4788: /* install the new presentation */
4789: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.65 cvs 4790: return (cssRule);
4791: }
4792:
4793: /*----------------------------------------------------------------------
1.63 cvs 4794: ParseSVGFill: parse a SVG fill property
4795: ----------------------------------------------------------------------*/
1.79 cvs 4796: static char *ParseSVGFill (Element element, PSchema tsch,
1.327 vatton 4797: PresentationContext context, char *cssRule,
4798: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 4799: {
4800: PresentationValue best;
1.245 quint 4801: char *url;
1.63 cvs 4802:
1.184 vatton 4803: best.typed_data.unit = UNIT_INVALID;
1.63 cvs 4804: best.typed_data.real = FALSE;
1.82 cvs 4805: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 4806: {
1.184 vatton 4807: best.typed_data.value = PATTERN_NONE;
4808: best.typed_data.unit = UNIT_REL;
1.116 vatton 4809: if (DoApply)
1.327 vatton 4810: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 4811: cssRule = SkipWord (cssRule);
1.294 vatton 4812: return (cssRule);
1.63 cvs 4813: }
1.422 vatton 4814: else if (!strncasecmp (cssRule, "currentColor", 12) ||
4815: !strncasecmp (cssRule, "inherit", 7))
1.245 quint 4816: {
1.293 quint 4817: best.typed_data.unit = VALUE_INHERIT;
4818: cssRule = SkipWord (cssRule);
1.245 quint 4819: }
4820: else if (!strncasecmp (cssRule, "url", 3))
4821: {
4822: cssRule += 3;
4823: cssRule = ParseCSSUrl (cssRule, &url);
1.424 ! quint 4824: SVGhandleFillUrl (element, context->doc, url);
1.245 quint 4825: TtaFreeMemory (url);
4826: /* **** caution: another color value may follow the uri (in case
1.327 vatton 4827: the uri could ne be dereferenced) *** */
1.245 quint 4828: }
1.63 cvs 4829: else
1.327 vatton 4830: cssRule = ParseCSSColor (cssRule, &best);
1.293 quint 4831:
4832: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.63 cvs 4833: {
1.293 quint 4834: /* install the new presentation. */
4835: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
4836: /* thot specificity: need to set fill pattern for background color */
4837: best.typed_data.value = PATTERN_BACKGROUND;
4838: best.typed_data.unit = UNIT_REL;
4839: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.63 cvs 4840: }
4841: return (cssRule);
4842: }
1.161 quint 4843:
1.155 cheyroul 4844: /*----------------------------------------------------------------------
1.424 ! quint 4845: ParseSVGStopColor: parse a SVG stop-color property
! 4846: ----------------------------------------------------------------------*/
! 4847: static char *ParseSVGStopColor (Element element, PSchema tsch,
! 4848: PresentationContext context, char *cssRule,
! 4849: CSSInfoPtr css, ThotBool isHTML)
! 4850: {
! 4851: cssRule = SVGhandleStopColor (element, cssRule);
! 4852: return (cssRule);
! 4853: }
! 4854:
! 4855: /*----------------------------------------------------------------------
1.346 quint 4856: ParseSVGOpacity: parse a SVG opacity property
1.155 cheyroul 4857: ----------------------------------------------------------------------*/
4858: static char *ParseSVGOpacity (Element element, PSchema tsch,
1.327 vatton 4859: PresentationContext context, char *cssRule,
4860: CSSInfoPtr css, ThotBool isHTML)
1.155 cheyroul 4861: {
4862: PresentationValue best;
1.63 cvs 4863:
1.184 vatton 4864: best.typed_data.unit = UNIT_INVALID;
1.155 cheyroul 4865: best.typed_data.real = FALSE;
4866: cssRule = ParseClampedUnit (cssRule, &best);
4867: if (DoApply)
1.295 vatton 4868: /* install the new presentation. */
4869: TtaSetStylePresentation (PROpacity, element, tsch, context, best);
1.155 cheyroul 4870: return (cssRule);
4871: }
1.346 quint 4872:
1.170 cheyroul 4873: /*----------------------------------------------------------------------
1.346 quint 4874: ParseSVGStrokeOpacity: parse a SVG stroke-opacity property
1.170 cheyroul 4875: ----------------------------------------------------------------------*/
4876: static char *ParseSVGStrokeOpacity (Element element, PSchema tsch,
1.327 vatton 4877: PresentationContext context, char *cssRule,
4878: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 4879: {
4880: PresentationValue best;
1.161 quint 4881:
1.184 vatton 4882: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 4883: best.typed_data.real = FALSE;
4884: cssRule = ParseClampedUnit (cssRule, &best);
4885: if (DoApply)
1.295 vatton 4886: /* install the new presentation. */
4887: TtaSetStylePresentation (PRStrokeOpacity, element, tsch, context, best);
1.170 cheyroul 4888: return (cssRule);
4889: }
1.346 quint 4890:
1.170 cheyroul 4891: /*----------------------------------------------------------------------
1.420 vatton 4892: ParseSVGFillOpacity: parse a SVG fill-opacityl property
1.170 cheyroul 4893: ----------------------------------------------------------------------*/
4894: static char *ParseSVGFillOpacity (Element element, PSchema tsch,
1.327 vatton 4895: PresentationContext context, char *cssRule,
4896: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 4897: {
4898: PresentationValue best;
4899:
1.184 vatton 4900: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 4901: best.typed_data.real = FALSE;
4902: cssRule = ParseClampedUnit (cssRule, &best);
4903: if (DoApply)
1.295 vatton 4904: /* install the new presentation. */
4905: TtaSetStylePresentation (PRFillOpacity, element, tsch, context, best);
1.170 cheyroul 4906: return (cssRule);
4907: }
1.207 vatton 4908:
1.1 cvs 4909: /*----------------------------------------------------------------------
1.420 vatton 4910: ParseSVGFillRule: parse a SVG fill-rule property
4911: ----------------------------------------------------------------------*/
4912: static char *ParseSVGFillRule (Element element, PSchema tsch,
4913: PresentationContext context, char *cssRule,
4914: CSSInfoPtr css, ThotBool isHTML)
4915: {
4916: PresentationValue best;
4917:
4918: best.typed_data.unit = UNIT_INVALID;
4919: best.typed_data.real = FALSE;
4920: if (!strncasecmp (cssRule, "inherit", 7))
4921: {
4922: best.typed_data.unit = VALUE_INHERIT;
4923: best.typed_data.value = 0;
4924: cssRule = SkipWord (cssRule);
4925: }
4926: else if (!strncasecmp (cssRule, "nonzero", 7))
4927: {
4928: best.typed_data.unit = VALUE_AUTO;
1.421 quint 4929: best.typed_data.value = NonZero;
1.420 vatton 4930: cssRule = SkipWord (cssRule);
4931: }
4932: else if (!strncasecmp (cssRule, "evenodd", 7))
4933: {
4934: best.typed_data.unit = VALUE_AUTO;
1.421 quint 4935: best.typed_data.value = EvenOdd;
1.420 vatton 4936: cssRule = SkipWord (cssRule);
4937: }
4938:
4939: if (DoApply)
4940: /* install the new presentation. */
4941: TtaSetStylePresentation (PRFillRule, element, tsch, context, best);
4942: return (cssRule);
4943: }
4944:
4945: /*----------------------------------------------------------------------
1.327 vatton 4946: GetCSSBackgroundURL searches a CSS BackgroundImage url within
4947: the cssRule.
4948: Returns NULL or a new allocated url string.
1.217 vatton 4949: ----------------------------------------------------------------------*/
4950: char *GetCSSBackgroundURL (char *cssRule)
4951: {
4952: char *b, *url;
4953:
4954: url = NULL;
4955: b = strstr (cssRule, "url");
4956: if (b)
1.290 gully 4957: b = ParseCSSUrl (b, &url);
1.217 vatton 4958: return (url);
4959: }
4960:
4961: /*----------------------------------------------------------------------
1.327 vatton 4962: ParseCSSContent: parse the value of property "content"
1.217 vatton 4963: ----------------------------------------------------------------------*/
4964: static char *ParseCSSContent (Element element, PSchema tsch,
1.327 vatton 4965: PresentationContext ctxt, char *cssRule,
4966: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 4967: {
1.312 quint 4968: PresentationValue value;
1.353 quint 4969: char *last, *start, quoteChar, savedChar;
4970: int length, val;
1.366 vatton 4971: char *buffer, *p;
4972: char *start_value;
1.312 quint 4973: ThotBool repeat;
4974:
4975: value.typed_data.unit = UNIT_REL;
4976: value.typed_data.real = FALSE;
4977: value.typed_data.value = 0;
1.366 vatton 4978: if (!DoDialog && DoApply)
1.347 quint 4979: TtaSetStylePresentation (PRContent, element, tsch, ctxt, value);
1.217 vatton 4980: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 4981: start_value = cssRule;
1.312 quint 4982: repeat = TRUE;
4983: while (repeat)
4984: {
1.366 vatton 4985: p = cssRule;
1.312 quint 4986: if (!strncasecmp (cssRule, "normal", 6))
1.327 vatton 4987: /* The pseudo-element is not generated */
4988: {
4989: /* @@@@@@ */
4990: cssRule += 6;
4991: repeat = FALSE;
4992: }
1.331 quint 4993: else if (!strncasecmp (cssRule, "none", 4))
4994: /* The pseudo-element is not generated */
4995: {
4996: /* @@@@@@ */
4997: cssRule += 4;
4998: repeat = FALSE;
4999: }
1.312 quint 5000: else if (*cssRule == '"' || *cssRule == '\'')
1.327 vatton 5001: /* It's a string */
5002: {
5003: quoteChar = *cssRule;
1.353 quint 5004: /* how long is the string? */
5005: last = cssRule;
5006: last = SkipString (last);
5007: length = last - cssRule;
5008: /* get a buffer to store the string */
1.366 vatton 5009: buffer = (char *)TtaGetMemory (length);
1.353 quint 5010: p = buffer; /* beginning of the string */
1.327 vatton 5011: cssRule++;
5012: while (*cssRule != EOS && *cssRule != quoteChar)
1.353 quint 5013: {
5014: if (*cssRule == '\\')
5015: {
5016: cssRule++; /* skip the backslash */
5017: if ((*cssRule >= '0' && *cssRule <= '9') ||
5018: (*cssRule >= 'A' && *cssRule <= 'F') ||
5019: (*cssRule >= 'a' && *cssRule <= 'f'))
5020: {
5021: start = cssRule; /* first hex digit after the backslash*/
5022: cssRule++;
5023: while ((*cssRule >= '0' && *cssRule <= '9') ||
5024: (*cssRule >= 'A' && *cssRule <= 'F') ||
5025: (*cssRule >= 'a' && *cssRule <= 'f'))
5026: cssRule++;
5027: savedChar = *cssRule;
5028: *cssRule = EOS;
5029: sscanf (start, "%x", &val);
1.366 vatton 5030: TtaWCToMBstring ((wchar_t) val, (unsigned char **) &p);
1.353 quint 5031: *cssRule = savedChar;
5032: }
5033: else
5034: {
5035: *p = *cssRule;
5036: p++; cssRule++;
5037: }
5038: }
5039: else
5040: {
5041: *p = *cssRule;
5042: p++; cssRule++;
5043: }
5044: }
5045: *p = EOS;
1.366 vatton 5046: if (DoDialog)
5047: {
5048: DisplayStyleValue ("", start_value, p);
5049: start_value = p;
5050: }
5051: else if (*cssRule != quoteChar)
1.327 vatton 5052: cssRule = SkipProperty (cssRule, FALSE);
5053: else
5054: {
5055: *cssRule = EOS;
5056: value.typed_data.unit = UNIT_REL;
5057: value.typed_data.real = FALSE;
1.353 quint 5058: value.pointer = buffer;
1.347 quint 5059: if (DoApply)
5060: TtaSetStylePresentation (PRContentString, element, tsch, ctxt,
5061: value);
1.327 vatton 5062: *cssRule = quoteChar;
5063: cssRule++;
5064: }
1.353 quint 5065: TtaFreeMemory (buffer);
1.327 vatton 5066: }
1.312 quint 5067: else if (!strncasecmp (cssRule, "url", 3))
1.327 vatton 5068: {
5069: cssRule += 3;
1.347 quint 5070: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
5071: PRContentURL);
1.366 vatton 5072: if (DoDialog)
5073: {
5074: DisplayStyleValue ("", start_value, p);
5075: start_value = p;
5076: }
1.327 vatton 5077: }
1.312 quint 5078: else if (!strncasecmp (cssRule, "counter", 7))
1.327 vatton 5079: {
5080: cssRule += 7;
5081: /* @@@@@@ */
1.366 vatton 5082: if (DoDialog)
5083: {
5084: DisplayStyleValue ("", start_value, p);
5085: start_value = p;
5086: }
5087: else
5088: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5089: }
1.312 quint 5090: else if (!strncasecmp (cssRule, "counters", 8))
1.327 vatton 5091: {
5092: cssRule += 8;
5093: /* @@@@@@ */
1.366 vatton 5094: if (DoDialog)
5095: {
5096: DisplayStyleValue ("", start_value, p);
5097: start_value = p;
5098: }
5099: else
5100: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5101: }
1.312 quint 5102: else if (!strncasecmp (cssRule, "attr", 4))
1.327 vatton 5103: {
1.347 quint 5104: value.pointer = NULL;
1.327 vatton 5105: cssRule += 4;
1.347 quint 5106: cssRule = SkipBlanksAndComments (cssRule);
5107: if (*cssRule == '(')
5108: {
5109: cssRule++;
5110: cssRule = SkipBlanksAndComments (cssRule);
5111: start = cssRule;
5112: while (*cssRule != EOS && *cssRule != ')')
5113: cssRule++;
5114: if (*cssRule != ')')
5115: cssRule = start;
5116: else
5117: {
5118: last = cssRule;
5119: /* remove extra spaces */
5120: if (last[-1] == SPACE)
5121: {
5122: *last = SPACE;
5123: last--;
5124: while (last[-1] == SPACE)
5125: last--;
5126: }
5127: savedChar = *last;
5128: *last = EOS;
5129: value.typed_data.unit = UNIT_REL;
5130: value.typed_data.real = FALSE;
5131: value.pointer = start;
1.366 vatton 5132: if (DoDialog)
5133: {
5134: DisplayStyleValue ("", start_value, p);
5135: start_value = p;
5136: }
5137: else if (DoApply)
1.347 quint 5138: TtaSetStylePresentation (PRContentAttr, element, tsch,
5139: ctxt, value);
5140: *last = savedChar;
5141: }
5142: }
5143: if (value.pointer == NULL)
5144: {
1.353 quint 5145: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 5146: if (DoDialog)
5147: {
5148: DisplayStyleValue ("", start_value, p);
5149: start_value = p;
5150: }
5151: else
5152: cssRule = SkipProperty (cssRule, FALSE);
1.347 quint 5153: }
5154: cssRule++;
1.327 vatton 5155: }
1.312 quint 5156: else if (!strncasecmp (cssRule, "open-quote", 10))
1.327 vatton 5157: {
5158: cssRule += 10;
5159: /* @@@@@@ */
5160: }
1.312 quint 5161: else if (!strncasecmp (cssRule, "close-quote", 11))
1.327 vatton 5162: {
5163: cssRule += 11;
5164: /* @@@@@@ */
5165: }
1.312 quint 5166: else if (!strncasecmp (cssRule, "no-open-quote", 13))
1.327 vatton 5167: {
5168: cssRule += 13;
5169: /* @@@@@@ */
5170: }
1.312 quint 5171: else if (!strncasecmp (cssRule, "no-close-quote", 14))
1.327 vatton 5172: {
5173: cssRule += 14;
5174: /* @@@@@@ */
5175: }
1.312 quint 5176: else if (!strncasecmp (cssRule, "inherit", 7))
1.327 vatton 5177: {
5178: cssRule += 7;
5179: /* @@@@@@ */
5180: repeat = FALSE;
5181: }
1.312 quint 5182: else
1.327 vatton 5183: {
1.353 quint 5184: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 5185: if (DoDialog)
5186: {
5187: DisplayStyleValue ("", start_value, p);
5188: start_value = p;
5189: }
5190: else
5191: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5192: }
1.312 quint 5193: cssRule = SkipBlanksAndComments (cssRule);
5194: if (repeat)
1.327 vatton 5195: if (*cssRule == ';' || *cssRule == '}' || *cssRule == EOS ||
5196: *cssRule == '!')
5197: repeat = FALSE;
1.217 vatton 5198: }
5199: return (cssRule);
5200: }
1.1 cvs 5201:
5202: /*----------------------------------------------------------------------
1.59 cvs 5203: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 5204: ----------------------------------------------------------------------*/
1.79 cvs 5205: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
1.327 vatton 5206: PresentationContext ctxt,
5207: char *cssRule, CSSInfoPtr css,
5208: ThotBool isHTML)
1.1 cvs 5209: {
1.49 cvs 5210: PresentationValue image, value;
1.357 quint 5211: char *ptr;
1.148 vatton 5212:
1.370 vatton 5213: image.typed_data.real = FALSE;
5214: value.typed_data.real = FALSE;
1.82 cvs 5215: cssRule = SkipBlanksAndComments (cssRule);
1.357 quint 5216: ptr = cssRule;
1.161 quint 5217: if (!strncasecmp (cssRule, "none", 4))
5218: {
1.260 vatton 5219: cssRule += 4;
1.366 vatton 5220: if (DoDialog)
5221: DisplayStyleValue ("background-image", ptr, cssRule);
5222: else if (DoApply)
1.327 vatton 5223: {
5224: /* no background image */
5225: image.pointer = NULL;
5226: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt,
5227: image);
5228: }
1.161 quint 5229: }
1.357 quint 5230: else if (!strncasecmp (cssRule, "inherit", 7))
5231: {
5232: value.typed_data.unit = VALUE_INHERIT;
5233: cssRule += 7;
1.366 vatton 5234: if (DoDialog)
5235: DisplayStyleValue ("background-image", ptr, cssRule);
1.357 quint 5236: }
1.161 quint 5237: else if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 5238: {
5239: cssRule += 3;
1.302 quint 5240: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 5241: PRBackgroundPicture);
1.207 vatton 5242: if (ctxt->destroy)
1.327 vatton 5243: if (TtaGetStylePresentation (PRFillPattern, element, tsch, ctxt,
5244: &value) < 0)
5245: {
5246: /* there is no FillPattern rule -> remove ShowBox rule */
5247: value.typed_data.value = 1;
5248: value.typed_data.unit = UNIT_REL;
5249: value.typed_data.real = FALSE;
5250: TtaSetStylePresentation (PRShowBox, element, tsch, ctxt, value);
5251: }
1.18 cvs 5252: }
1.357 quint 5253: else
5254: {
5255: cssRule = SkipWord (cssRule);
5256: CSSParseError ("Invalid background-image value", ptr, cssRule);
5257: cssRule = SkipProperty (cssRule, FALSE);
5258: }
1.18 cvs 5259: return (cssRule);
5260: }
5261:
5262: /*----------------------------------------------------------------------
1.295 vatton 5263: ParseACSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 5264: ----------------------------------------------------------------------*/
1.295 vatton 5265: static char *ParseACSSBackgroundRepeat (Element element, PSchema tsch,
1.327 vatton 5266: PresentationContext ctxt,
5267: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5268: {
5269: PresentationValue repeat;
1.366 vatton 5270: char *start_value;
1.18 cvs 5271:
1.366 vatton 5272: cssRule = SkipBlanksAndComments (cssRule);
5273: start_value = cssRule;
1.184 vatton 5274: repeat.typed_data.value = REALSIZE;
1.191 vatton 5275: repeat.typed_data.unit = UNIT_BOX;
1.18 cvs 5276: repeat.typed_data.real = FALSE;
1.82 cvs 5277: cssRule = SkipBlanksAndComments (cssRule);
5278: if (!strncasecmp (cssRule, "no-repeat", 9))
1.184 vatton 5279: repeat.typed_data.value = REALSIZE;
1.82 cvs 5280: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.265 vatton 5281: repeat.typed_data.value = YREPEAT;
1.82 cvs 5282: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.265 vatton 5283: repeat.typed_data.value = XREPEAT;
1.82 cvs 5284: else if (!strncasecmp (cssRule, "repeat", 6))
1.184 vatton 5285: repeat.typed_data.value = REPEAT;
1.18 cvs 5286: else
5287: return (cssRule);
5288:
1.295 vatton 5289: cssRule = SkipWord (cssRule);
5290: /* check if it's an important rule */
1.366 vatton 5291: if (DoDialog)
5292: DisplayStyleValue ("background-repeat", start_value, cssRule);
5293: else if (DoApply)
1.295 vatton 5294: /* install the new presentation */
1.362 quint 5295: TtaSetStylePresentation (PRBackgroundRepeat, element, tsch, ctxt, repeat);
1.295 vatton 5296: return (cssRule);
5297: }
5298:
5299: /*----------------------------------------------------------------------
5300: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
5301: ----------------------------------------------------------------------*/
5302: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.315 gully 5303: PresentationContext ctxt,
5304: char *cssRule, CSSInfoPtr css,
5305: ThotBool isHTML)
1.295 vatton 5306: {
1.388 carcone 5307:
5308: char *ptr;
5309:
5310: ptr = cssRule;
1.295 vatton 5311: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
1.315 gully 5312: cssRule, css, isHTML);
1.388 carcone 5313:
5314: if (ptr == cssRule)
1.117 vatton 5315: {
1.295 vatton 5316: cssRule = SkipValue ("Invalid background-repeat value", cssRule);
1.117 vatton 5317: /* check if it's an important rule */
5318: }
1.295 vatton 5319: return cssRule;
1.18 cvs 5320: }
5321:
5322: /*----------------------------------------------------------------------
1.327 vatton 5323: ParseACSSBackgroundAttachment: parse a CSS BackgroundAttachment
5324: attribute string.
1.18 cvs 5325: ----------------------------------------------------------------------*/
1.295 vatton 5326: static char *ParseACSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5327: PresentationContext ctxt,
5328: char *cssRule, CSSInfoPtr css,
5329: ThotBool isHTML)
1.18 cvs 5330: {
1.366 vatton 5331: char *start_value;
5332:
1.163 quint 5333: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5334: start_value = cssRule;
1.163 quint 5335: if (!strncasecmp (cssRule, "scroll", 6))
1.199 vatton 5336: {
5337: cssRule = SkipWord (cssRule);
5338: }
1.163 quint 5339: else if (!strncasecmp (cssRule, "fixed", 5))
1.199 vatton 5340: {
5341: cssRule = SkipWord (cssRule);
5342: }
1.362 quint 5343: else if (!strncasecmp (cssRule, "inherit", 7))
5344: {
5345: cssRule = SkipWord (cssRule);
5346: }
1.366 vatton 5347: if (start_value != cssRule && DoDialog)
5348: DisplayStyleValue ("background-attachment", start_value, cssRule);
1.163 quint 5349: return (cssRule);
1.1 cvs 5350: }
5351:
5352: /*----------------------------------------------------------------------
1.327 vatton 5353: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
5354: attribute string.
1.295 vatton 5355: ----------------------------------------------------------------------*/
5356: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5357: PresentationContext ctxt,
5358: char *cssRule, CSSInfoPtr css,
5359: ThotBool isHTML)
1.295 vatton 5360: {
5361: char *ptr;
5362:
5363: ptr = cssRule;
5364: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.327 vatton 5365: cssRule, css, isHTML);
1.295 vatton 5366: if (ptr == cssRule)
1.366 vatton 5367: cssRule = SkipValue ("Invalid background-attachment value", cssRule);
1.295 vatton 5368: return cssRule;
5369: }
5370:
5371: /*----------------------------------------------------------------------
1.327 vatton 5372: ParseACSSBackgroundPosition: parse a CSS BackgroundPosition
5373: attribute string.
1.1 cvs 5374: ----------------------------------------------------------------------*/
1.279 vatton 5375: static char *ParseACSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5376: PresentationContext ctxt,
5377: char *cssRule, CSSInfoPtr css,
1.362 quint 5378: ThotBool isHTML, ThotBool *across)
1.1 cvs 5379: {
1.362 quint 5380: PresentationValue val;
5381: char *ptr;
1.1 cvs 5382:
1.163 quint 5383: cssRule = SkipBlanksAndComments (cssRule);
1.362 quint 5384: ptr = cssRule;
5385: val.typed_data.value = 0;
5386: val.typed_data.real = FALSE;
5387: val.typed_data.unit = UNIT_INVALID;
1.163 quint 5388: if (!strncasecmp (cssRule, "left", 4))
1.362 quint 5389: {
5390: val.typed_data.value = 0;
5391: val.typed_data.unit = UNIT_PERCENT;
5392: cssRule += 4;
5393: *across = TRUE;
5394: }
1.163 quint 5395: else if (!strncasecmp (cssRule, "right", 5))
1.362 quint 5396: {
5397: val.typed_data.value = 100;
5398: val.typed_data.unit = UNIT_PERCENT;
5399: cssRule += 5;
5400: *across = TRUE;
5401: }
1.163 quint 5402: else if (!strncasecmp (cssRule, "center", 6))
1.362 quint 5403: {
5404: val.typed_data.value = 50;
5405: val.typed_data.unit = UNIT_PERCENT;
5406: cssRule += 6;
5407: }
1.163 quint 5408: else if (!strncasecmp (cssRule, "top", 3))
1.362 quint 5409: {
5410: val.typed_data.value = 0;
5411: val.typed_data.unit = UNIT_PERCENT;
5412: cssRule += 3;
5413: *across = FALSE;
5414: }
1.163 quint 5415: else if (!strncasecmp (cssRule, "bottom", 6))
1.191 vatton 5416: {
1.362 quint 5417: val.typed_data.value = 100;
5418: val.typed_data.unit = UNIT_PERCENT;
5419: cssRule += 6;
5420: *across = FALSE;
5421: }
5422: else if (!strncasecmp (cssRule, "inherit", 7))
5423: {
5424: val.typed_data.unit = VALUE_INHERIT;
5425: cssRule += 7;
1.191 vatton 5426: }
1.163 quint 5427: else
1.362 quint 5428: /* <length> or <percentage> */
5429: {
5430: cssRule = ParseCSSUnit (cssRule, &val);
5431: if (val.typed_data.unit == UNIT_BOX && val.typed_data.value == 0)
5432: /* 0 with no unit. Accept */
5433: val.typed_data.unit = UNIT_PERCENT;
5434: }
1.163 quint 5435:
1.366 vatton 5436: if (val.typed_data.unit != UNIT_INVALID && val.typed_data.unit != UNIT_BOX)
1.362 quint 5437: {
1.366 vatton 5438: if (DoDialog)
5439: {
5440: if (val.typed_data.unit == VALUE_INHERIT)
5441: {
5442: DisplayStyleValue ("background-positionH", ptr, cssRule);
5443: DisplayStyleValue ("background-positionV", ptr, cssRule);
5444: }
5445: else if (*across)
5446: DisplayStyleValue ("background-positionH", ptr, cssRule);
5447: else
5448: DisplayStyleValue ("background-positionV", ptr, cssRule);
5449: }
5450: else if (DoApply)
1.362 quint 5451: /* install the new presentation */
5452: {
5453: if (val.typed_data.unit == VALUE_INHERIT)
5454: /* "inherit" applies to both dimensions */
5455: {
5456: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5457: ctxt, val);
5458: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5459: ctxt, val);
5460: }
5461: else if (*across)
5462: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5463: ctxt, val);
5464: else
5465: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5466: ctxt, val);
5467: }
5468: }
1.279 vatton 5469: return (cssRule);
5470: }
1.218 vatton 5471:
1.279 vatton 5472: /*----------------------------------------------------------------------
1.327 vatton 5473: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
5474: attribute string.
1.279 vatton 5475: ----------------------------------------------------------------------*/
5476: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5477: PresentationContext ctxt,
5478: char *cssRule, CSSInfoPtr css,
5479: ThotBool isHTML)
1.279 vatton 5480: {
1.295 vatton 5481: char *ptr;
1.362 quint 5482: ThotBool across;
1.295 vatton 5483:
5484: ptr = cssRule;
1.362 quint 5485: across = TRUE;
5486: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule, css,
5487: isHTML, &across);
1.295 vatton 5488: if (ptr == cssRule)
1.360 vatton 5489: cssRule = SkipValue ("Invalid background-position value", cssRule);
1.362 quint 5490: else
1.298 vatton 5491: {
1.362 quint 5492: cssRule = SkipBlanksAndComments (cssRule);
5493: if (*cssRule != ';' && *cssRule != '!' && *cssRule != EOS)
5494: {
5495: /* possible second value */
5496: ptr = cssRule;
5497: across = !across;
5498: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5499: css, isHTML, &across);
5500: if (ptr == cssRule)
5501: cssRule = SkipValue ("Invalid background-position value", cssRule);
5502: }
1.298 vatton 5503: }
1.163 quint 5504: return (cssRule);
1.18 cvs 5505: }
5506:
5507: /*----------------------------------------------------------------------
1.327 vatton 5508: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 5509: ----------------------------------------------------------------------*/
1.79 cvs 5510: static char *ParseCSSBackground (Element element, PSchema tsch,
1.327 vatton 5511: PresentationContext ctxt, char *cssRule,
5512: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5513: {
1.323 vatton 5514: char *ptr;
5515: int skippedNL;
1.362 quint 5516: ThotBool img, repeat, position, attach, color, across;
1.18 cvs 5517:
1.82 cvs 5518: cssRule = SkipBlanksAndComments (cssRule);
1.323 vatton 5519: img = repeat = position = attach = color = FALSE;
1.362 quint 5520: across = TRUE;
1.301 vatton 5521: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 5522: {
1.71 cvs 5523: /* perhaps a Background Image */
1.198 vatton 5524: if (!strncasecmp (cssRule, "url", 3) || !strncasecmp (cssRule, "none", 4))
1.327 vatton 5525: {
1.334 vatton 5526: if (!strncasecmp (cssRule, "none", 4))
1.423 vatton 5527: {
5528: repeat = TRUE;
5529: ParseCSSBackgroundColor (element, tsch, ctxt, "transparent",
5530: css, isHTML);
5531: }
1.327 vatton 5532: cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
5533: css, isHTML);
5534: img = TRUE;
5535: }
1.18 cvs 5536: /* perhaps a Background Attachment */
1.82 cvs 5537: else if (!strncasecmp (cssRule, "scroll", 6) ||
5538: !strncasecmp (cssRule, "fixed", 5))
1.327 vatton 5539: {
5540: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
5541: cssRule, css, isHTML);
1.328 vatton 5542: attach = repeat = TRUE;
1.327 vatton 5543: }
1.18 cvs 5544: /* perhaps a Background Repeat */
1.82 cvs 5545: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
5546: !strncasecmp (cssRule, "repeat-y", 8) ||
5547: !strncasecmp (cssRule, "repeat-x", 8) ||
5548: !strncasecmp (cssRule, "repeat", 6))
1.327 vatton 5549: {
5550: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
5551: cssRule, css, isHTML);
5552: repeat = TRUE;
5553: }
1.18 cvs 5554: /* perhaps a Background Position */
1.82 cvs 5555: else if (!strncasecmp (cssRule, "left", 4) ||
5556: !strncasecmp (cssRule, "right", 5) ||
5557: !strncasecmp (cssRule, "center", 6) ||
5558: !strncasecmp (cssRule, "top", 3) ||
5559: !strncasecmp (cssRule, "bottom", 6) ||
1.279 vatton 5560: isdigit (*cssRule) || *cssRule == '.' || *cssRule == '-')
1.327 vatton 5561: {
1.362 quint 5562: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5563: css, isHTML, &across);
5564: across = !across;
1.328 vatton 5565: position = repeat = TRUE;
1.327 vatton 5566: }
1.18 cvs 5567: /* perhaps a Background Color */
1.323 vatton 5568: else if (!color)
1.327 vatton 5569: {
5570: skippedNL = NewLineSkipped;
5571: /* check if the rule has been found */
5572: ptr = cssRule;
5573: cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
5574: cssRule, css, isHTML);
5575: if (ptr == cssRule)
5576: {
5577: NewLineSkipped = skippedNL;
5578: /* rule not found */
5579: cssRule = SkipProperty (cssRule, FALSE);
5580: }
5581: else
5582: color = TRUE;
5583: }
1.328 vatton 5584: else
1.327 vatton 5585: cssRule = SkipProperty (cssRule, FALSE);
1.328 vatton 5586:
1.82 cvs 5587: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 5588: }
1.328 vatton 5589:
5590: if (color && !img)
1.405 kia 5591: ParseCSSBackgroundImage (element, tsch, ctxt, (char*)
5592: "none", css, isHTML);
1.328 vatton 5593:
5594: if (img && !repeat)
5595: ParseACSSBackgroundRepeat (element, tsch, ctxt,
1.405 kia 5596: (char*)"repeat", css, isHTML);
1.328 vatton 5597: if (img && !position)
5598: ParseACSSBackgroundPosition (element, tsch, ctxt,
1.405 kia 5599: (char*)"0% 0%", css, isHTML, &across);
1.328 vatton 5600: if (img && !attach)
5601: ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.405 kia 5602: (char*)"scroll", css, isHTML);
1.327 vatton 5603: return (cssRule);
1.18 cvs 5604: }
5605:
1.59 cvs 5606: /*----------------------------------------------------------------------
1.327 vatton 5607: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 5608: ----------------------------------------------------------------------*/
1.79 cvs 5609: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.327 vatton 5610: PresentationContext ctxt, char *cssRule,
5611: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 5612: {
5613: PresentationValue page;
1.366 vatton 5614: char *start_value;
1.59 cvs 5615:
1.184 vatton 5616: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5617: page.typed_data.real = FALSE;
1.82 cvs 5618: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5619: start_value = cssRule;
1.82 cvs 5620: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5621: page.typed_data.value = PageAuto;
1.82 cvs 5622: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5623: {
1.184 vatton 5624: page.typed_data.unit = UNIT_REL;
5625: page.typed_data.value = PageAlways;
1.59 cvs 5626: }
1.82 cvs 5627: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5628: {
1.184 vatton 5629: page.typed_data.unit = UNIT_REL;
5630: page.typed_data.value = PageAvoid;
1.59 cvs 5631: }
1.82 cvs 5632: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5633: {
1.184 vatton 5634: page.typed_data.unit = UNIT_REL;
5635: page.typed_data.value = PageLeft;
1.59 cvs 5636: }
1.82 cvs 5637: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5638: {
1.184 vatton 5639: page.typed_data.unit = UNIT_REL;
5640: page.typed_data.value = PageRight;
1.59 cvs 5641: }
1.82 cvs 5642: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5643: {
1.293 quint 5644: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5645: page.typed_data.value = PageInherit;
1.59 cvs 5646: }
5647: cssRule = SkipWord (cssRule);
5648: /* install the new presentation */
1.366 vatton 5649: if ((page.typed_data.unit == UNIT_REL && page.typed_data.value == PageAlways)
5650: || page.typed_data.unit == VALUE_INHERIT)
5651: {
5652: if (DoDialog)
5653: DisplayStyleValue ("page-break-before", start_value, cssRule);
5654: else if (DoApply)
5655: TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
5656: }
1.59 cvs 5657: return (cssRule);
5658: }
5659:
5660: /*----------------------------------------------------------------------
1.327 vatton 5661: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 5662: ----------------------------------------------------------------------*/
1.79 cvs 5663: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.327 vatton 5664: PresentationContext ctxt,
5665: char *cssRule, CSSInfoPtr css,
5666: ThotBool isHTML)
1.59 cvs 5667: {
5668: PresentationValue page;
1.366 vatton 5669: char *start_value;
1.59 cvs 5670:
1.184 vatton 5671: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5672: page.typed_data.real = FALSE;
1.82 cvs 5673: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5674: start_value = cssRule;
1.82 cvs 5675: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5676: page.typed_data.value = PageAuto;
1.82 cvs 5677: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5678: {
1.184 vatton 5679: page.typed_data.unit = UNIT_REL;
5680: page.typed_data.value = PageAlways;
1.59 cvs 5681: }
1.82 cvs 5682: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5683: {
1.184 vatton 5684: page.typed_data.unit = UNIT_REL;
5685: page.typed_data.value = PageAvoid;
1.59 cvs 5686: }
1.82 cvs 5687: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5688: {
1.184 vatton 5689: page.typed_data.unit = UNIT_REL;
5690: page.typed_data.value = PageLeft;
1.59 cvs 5691: }
1.82 cvs 5692: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5693: {
1.184 vatton 5694: page.typed_data.unit = UNIT_REL;
5695: page.typed_data.value = PageRight;
1.59 cvs 5696: }
1.82 cvs 5697: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5698: {
1.293 quint 5699: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5700: page.typed_data.value = PageInherit;
1.59 cvs 5701: }
5702: cssRule = SkipWord (cssRule);
5703: /* install the new presentation */
1.366 vatton 5704: if (page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT)
5705: {
5706: if (DoDialog)
5707: DisplayStyleValue ("page-break-after", start_value, cssRule);
1.367 cvs 5708: //else if (DoApply)
5709: // TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page);
1.366 vatton 5710: }
1.59 cvs 5711: return (cssRule);
5712: }
5713:
5714: /*----------------------------------------------------------------------
1.327 vatton 5715: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 5716: ----------------------------------------------------------------------*/
1.79 cvs 5717: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.327 vatton 5718: PresentationContext ctxt,
5719: char *cssRule, CSSInfoPtr css,
5720: ThotBool isHTML)
1.59 cvs 5721: {
5722: PresentationValue page;
1.366 vatton 5723: char *start_value;
1.59 cvs 5724:
1.184 vatton 5725: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5726: page.typed_data.real = FALSE;
1.82 cvs 5727: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5728: start_value = cssRule;
1.82 cvs 5729: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 5730: {
1.184 vatton 5731: /*page.typed_data.unit = UNIT_REL;*/
5732: page.typed_data.value = PageAuto;
1.59 cvs 5733: }
1.82 cvs 5734: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5735: {
1.184 vatton 5736: page.typed_data.unit = UNIT_REL;
5737: page.typed_data.value = PageAvoid;
1.59 cvs 5738: }
1.82 cvs 5739: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5740: {
1.293 quint 5741: /* page.typed_data.unit = VALUE_INHERIT; */
1.184 vatton 5742: page.typed_data.value = PageInherit;
1.59 cvs 5743: }
5744: cssRule = SkipWord (cssRule);
5745: /* install the new presentation */
1.366 vatton 5746: if ((page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT) &&
5747: page.typed_data.value == PageAvoid)
5748: {
5749: if (DoDialog)
5750: DisplayStyleValue ("page-break-inside", start_value, cssRule);
1.367 cvs 5751: //else if (DoApply)
5752: //TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);
1.366 vatton 5753: }
1.59 cvs 5754: return (cssRule);
5755: }
1.18 cvs 5756:
1.60 cvs 5757: /*----------------------------------------------------------------------
1.327 vatton 5758: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 5759: ----------------------------------------------------------------------*/
1.79 cvs 5760: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.327 vatton 5761: PresentationContext ctxt, char *cssRule,
5762: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 5763: {
5764: PresentationValue width;
5765:
1.82 cvs 5766: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 5767: width.typed_data.value = 0;
1.184 vatton 5768: width.typed_data.unit = UNIT_INVALID;
1.60 cvs 5769: width.typed_data.real = FALSE;
1.110 vatton 5770: if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 5771: {
1.327 vatton 5772: cssRule = ParseCSSUnit (cssRule, &width);
5773: if (width.typed_data.unit == UNIT_BOX)
5774: width.typed_data.unit = UNIT_PX;
1.166 vatton 5775: }
1.295 vatton 5776: else
5777: cssRule = SkipValue ("Invalid stroke-width value", cssRule);
5778:
1.184 vatton 5779: if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 5780: {
1.207 vatton 5781: TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117 vatton 5782: width.typed_data.value = 1;
1.184 vatton 5783: width.typed_data.unit = UNIT_REL;
1.117 vatton 5784: }
1.60 cvs 5785: return (cssRule);
5786: }
5787:
1.217 vatton 5788: /*----------------------------------------------------------------------
1.327 vatton 5789: ParseCSSPosition: parse a CSS Position attribute string.
1.217 vatton 5790: ----------------------------------------------------------------------*/
5791: static char *ParseCSSPosition (Element element, PSchema tsch,
1.327 vatton 5792: PresentationContext ctxt, char *cssRule,
5793: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5794: {
1.305 quint 5795: char *ptr;
5796: PresentationValue pval;
1.217 vatton 5797:
1.305 quint 5798: pval.typed_data.value = 0;
5799: pval.typed_data.unit = UNIT_BOX;
5800: pval.typed_data.real = FALSE;
1.217 vatton 5801: cssRule = SkipBlanksAndComments (cssRule);
5802: ptr = cssRule;
5803: if (!strncasecmp (cssRule, "static", 6))
1.337 vatton 5804: {
5805: pval.typed_data.value = PositionStatic;
5806: cssRule += 6;
5807: }
5808: else if (!strncasecmp (cssRule, "relative", 8))
5809: {
5810: pval.typed_data.value = PositionRelative;
5811: cssRule += 8;
5812: }
1.217 vatton 5813: else if (!strncasecmp (cssRule, "absolute", 8))
1.337 vatton 5814: {
5815: pval.typed_data.value = PositionAbsolute;
5816: cssRule += 8;
5817: }
1.217 vatton 5818: else if (!strncasecmp (cssRule, "fixed", 5))
1.337 vatton 5819: {
5820: pval.typed_data.value = PositionFixed;
5821: cssRule += 5;
5822: }
1.217 vatton 5823: else if (!strncasecmp (cssRule, "inherit", 7))
1.337 vatton 5824: {
5825: pval.typed_data.unit = VALUE_INHERIT;
5826: cssRule += 7;
5827: }
1.305 quint 5828:
5829: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
5830: {
5831: cssRule = SkipValue ("Invalid position value", ptr);
5832: cssRule = SkipValue (NULL, cssRule);
5833: }
1.217 vatton 5834: else
1.305 quint 5835: {
1.337 vatton 5836: cssRule = SkipBlanksAndComments (cssRule);
5837: if (*cssRule != EOS && *cssRule != ';')
5838: SkipValue ("Invalid position value", ptr);
1.366 vatton 5839: else if (DoDialog)
5840: DisplayStyleValue ("position", ptr, cssRule);
1.337 vatton 5841: else if (DoApply)
1.327 vatton 5842: TtaSetStylePresentation (PRPosition, element, tsch, ctxt, pval);
1.305 quint 5843: }
1.217 vatton 5844: return (cssRule);
5845: }
5846:
5847: /*----------------------------------------------------------------------
1.327 vatton 5848: ParseCSSTop: parse a CSS Top attribute
1.217 vatton 5849: ----------------------------------------------------------------------*/
5850: static char *ParseCSSTop (Element element, PSchema tsch,
1.327 vatton 5851: PresentationContext context, char *cssRule,
5852: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5853: {
5854: PresentationValue val;
5855: char *ptr;
5856:
1.370 vatton 5857: val.typed_data.real = FALSE;
1.217 vatton 5858: cssRule = SkipBlanksAndComments (cssRule);
5859: ptr = cssRule;
1.305 quint 5860: /* first parse the value */
5861: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5862: {
5863: val.typed_data.unit = VALUE_AUTO;
5864: val.typed_data.value = 0;
5865: cssRule = SkipWord (cssRule);
5866: }
1.305 quint 5867: else if (!strncasecmp (cssRule, "inherit", 7))
5868: {
5869: val.typed_data.unit = VALUE_INHERIT;
5870: cssRule = SkipWord (cssRule);
5871: }
1.217 vatton 5872: else
5873: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5874:
5875: if (val.typed_data.unit == UNIT_INVALID ||
5876: (val.typed_data.value != 0 &&
1.217 vatton 5877: val.typed_data.unit == UNIT_BOX))
5878: {
1.387 quint 5879: cssRule = SkipValue ("Invalid top value", ptr);
5880: if (val.typed_data.unit == UNIT_BOX)
5881: val.typed_data.unit = UNIT_PX;
5882: else
5883: return (cssRule);
1.217 vatton 5884: }
1.366 vatton 5885: if (DoDialog)
1.387 quint 5886: DisplayStyleValue ("top", ptr, cssRule);
1.366 vatton 5887: else if (DoApply)
1.305 quint 5888: TtaSetStylePresentation (PRTop, element, tsch, context, val);
1.217 vatton 5889: return (cssRule);
5890: }
5891:
5892: /*----------------------------------------------------------------------
1.327 vatton 5893: ParseCSSRight: parse a CSS Right attribute
1.217 vatton 5894: ----------------------------------------------------------------------*/
5895: static char *ParseCSSRight (Element element, PSchema tsch,
1.327 vatton 5896: PresentationContext context, char *cssRule,
5897: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5898: {
5899: PresentationValue val;
5900: char *ptr;
5901:
1.370 vatton 5902: val.typed_data.real = FALSE;
1.217 vatton 5903: cssRule = SkipBlanksAndComments (cssRule);
5904: ptr = cssRule;
5905: /* first parse the attribute string */
1.305 quint 5906: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5907: {
5908: val.typed_data.unit = VALUE_AUTO;
5909: val.typed_data.value = 0;
5910: cssRule = SkipWord (cssRule);
5911: }
1.305 quint 5912: else if (!strncasecmp (cssRule, "inherit", 7))
5913: {
5914: val.typed_data.unit = VALUE_INHERIT;
5915: cssRule = SkipWord (cssRule);
5916: }
1.217 vatton 5917: else
5918: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5919:
5920: if (val.typed_data.unit == UNIT_INVALID ||
5921: (val.typed_data.value != 0 &&
1.217 vatton 5922: val.typed_data.unit == UNIT_BOX))
5923: {
1.387 quint 5924: cssRule = SkipValue ("Invalid right value", ptr);
5925: if (val.typed_data.unit == UNIT_BOX)
5926: val.typed_data.unit = UNIT_PX;
5927: else
5928: return (cssRule);
1.217 vatton 5929: }
1.366 vatton 5930: if (DoDialog)
5931: DisplayStyleValue ("right", ptr, cssRule);
5932: else if (DoApply)
1.305 quint 5933: TtaSetStylePresentation (PRRight, element, tsch, context, val);
1.217 vatton 5934: return (cssRule);
5935: }
5936:
5937: /*----------------------------------------------------------------------
1.327 vatton 5938: ParseCSSBottom: parse a CSS Bottom attribute
1.217 vatton 5939: ----------------------------------------------------------------------*/
5940: static char *ParseCSSBottom (Element element, PSchema tsch,
1.327 vatton 5941: PresentationContext context, char *cssRule,
5942: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5943: {
5944: PresentationValue val;
5945: char *ptr;
5946:
1.370 vatton 5947: val.typed_data.real = FALSE;
1.217 vatton 5948: cssRule = SkipBlanksAndComments (cssRule);
5949: ptr = cssRule;
5950: /* first parse the attribute string */
1.305 quint 5951: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5952: {
5953: val.typed_data.unit = VALUE_AUTO;
5954: val.typed_data.value = 0;
5955: cssRule = SkipWord (cssRule);
5956: }
1.305 quint 5957: else if (!strncasecmp (cssRule, "inherit", 7))
5958: {
5959: val.typed_data.unit = VALUE_INHERIT;
5960: cssRule = SkipWord (cssRule);
5961: }
1.217 vatton 5962: else
5963: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5964:
5965: if (val.typed_data.unit == UNIT_INVALID ||
5966: (val.typed_data.value != 0 &&
1.217 vatton 5967: val.typed_data.unit == UNIT_BOX))
5968: {
1.387 quint 5969: cssRule = SkipValue ("Invalid bottom value", ptr);
5970: if (val.typed_data.unit == UNIT_BOX)
5971: val.typed_data.unit = UNIT_PX;
5972: else
5973: return (cssRule);
1.217 vatton 5974: }
1.366 vatton 5975: if (DoDialog)
5976: DisplayStyleValue ("bottom", ptr, cssRule);
5977: else if (DoApply)
1.305 quint 5978: TtaSetStylePresentation (PRBottom, element, tsch, context, val);
1.217 vatton 5979: return (cssRule);
5980: }
5981:
5982: /*----------------------------------------------------------------------
1.327 vatton 5983: ParseCSSLeft: parse a CSS Left attribute
1.217 vatton 5984: ----------------------------------------------------------------------*/
5985: static char *ParseCSSLeft (Element element, PSchema tsch,
1.327 vatton 5986: PresentationContext context, char *cssRule,
5987: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5988: {
5989: PresentationValue val;
5990: char *ptr;
5991:
1.370 vatton 5992: val.typed_data.real = FALSE;
1.217 vatton 5993: cssRule = SkipBlanksAndComments (cssRule);
5994: ptr = cssRule;
5995: /* first parse the attribute string */
1.305 quint 5996: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5997: {
5998: val.typed_data.unit = VALUE_AUTO;
5999: val.typed_data.value = 0;
6000: cssRule = SkipWord (cssRule);
6001: }
1.305 quint 6002: else if (!strncasecmp (cssRule, "inherit", 7))
6003: {
6004: val.typed_data.unit = VALUE_INHERIT;
6005: cssRule = SkipWord (cssRule);
6006: }
1.217 vatton 6007: else
6008: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 6009:
6010: if (val.typed_data.unit == UNIT_INVALID ||
6011: (val.typed_data.value != 0 &&
1.217 vatton 6012: val.typed_data.unit == UNIT_BOX))
6013: {
1.387 quint 6014: cssRule = SkipValue ("Invalid left value", ptr);
6015: if (val.typed_data.unit == UNIT_BOX)
6016: val.typed_data.unit = UNIT_PX;
6017: else
6018: return (cssRule);
1.217 vatton 6019: }
1.366 vatton 6020: if (DoDialog)
6021: DisplayStyleValue ("left", ptr, cssRule);
6022: else if (DoApply)
1.305 quint 6023: TtaSetStylePresentation (PRLeft, element, tsch, context, val);
1.217 vatton 6024: return (cssRule);
6025: }
6026:
6027: /*----------------------------------------------------------------------
1.327 vatton 6028: ParseCSSZIndex: parse a CSS z-index attribute
1.217 vatton 6029: ----------------------------------------------------------------------*/
6030: static char *ParseCSSZIndex (Element element, PSchema tsch,
1.327 vatton 6031: PresentationContext context, char *cssRule,
6032: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 6033: {
6034: PresentationValue val;
6035: char *ptr;
6036:
1.370 vatton 6037: val.typed_data.real = FALSE;
1.217 vatton 6038: cssRule = SkipBlanksAndComments (cssRule);
6039: ptr = cssRule;
6040: /* first parse the attribute string */
1.420 vatton 6041: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 6042: {
6043: val.typed_data.unit = VALUE_AUTO;
6044: val.typed_data.value = 0;
6045: cssRule = SkipWord (cssRule);
6046: }
1.420 vatton 6047: else if (!strncasecmp (cssRule, "inherit", 7))
6048: {
6049: val.typed_data.unit = VALUE_INHERIT;
6050: val.typed_data.value = 0;
6051: cssRule = SkipWord (cssRule);
6052: }
1.217 vatton 6053: else
6054: {
6055: cssRule = ParseCSSUnit (cssRule, &val);
6056: if (val.typed_data.unit != UNIT_BOX)
1.327 vatton 6057: {
1.387 quint 6058: cssRule = SkipValue ("Invalid z-index value", ptr);
6059: return (cssRule);
1.327 vatton 6060: }
1.420 vatton 6061: val.typed_data.value = - val.typed_data.value;
1.217 vatton 6062: }
1.366 vatton 6063: if (DoDialog)
1.420 vatton 6064: DisplayStyleValue ("z-index", ptr, cssRule);
6065: else if (DoApply)
6066: TtaSetStylePresentation (PRDepth, element, tsch, context, val);
1.217 vatton 6067: return (cssRule);
6068: }
6069:
1.340 quint 6070: /*----------------------------------------------------------------------
6071: *
6072: * FUNCTIONS STYLE DECLARATIONS
6073: *
6074: *----------------------------------------------------------------------*/
1.18 cvs 6075: /*
1.59 cvs 6076: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 6077: * e.g. "FONT-SIZE" must be placed before "FONT"
6078: */
6079: static CSSProperty CSSProperties[] =
1.327 vatton 6080: {
6081: {"background-color", ParseCSSBackgroundColor},
6082: {"background-image", ParseCSSBackgroundImage},
6083: {"background-repeat", ParseCSSBackgroundRepeat},
6084: {"background-attachment", ParseCSSBackgroundAttachment},
6085: {"background-position", ParseCSSBackgroundPosition},
6086: {"background", ParseCSSBackground},
6087: {"border-top-width", ParseCSSBorderTopWidth},
6088: {"border-right-width", ParseCSSBorderRightWidth},
6089: {"border-bottom-width", ParseCSSBorderBottomWidth},
6090: {"border-left-width", ParseCSSBorderLeftWidth},
6091: {"border-width", ParseCSSBorderWidth},
6092: {"border-top-color", ParseCSSBorderColorTop},
6093: {"border-right-color", ParseCSSBorderColorRight},
6094: {"border-bottom-color", ParseCSSBorderColorBottom},
6095: {"border-left-color", ParseCSSBorderColorLeft},
6096: {"border-color", ParseCSSBorderColor},
6097: {"border-top-style", ParseCSSBorderStyleTop},
6098: {"border-right-style", ParseCSSBorderStyleRight},
6099: {"border-bottom-style", ParseCSSBorderStyleBottom},
6100: {"border-left-style", ParseCSSBorderStyleLeft},
6101: {"border-style", ParseCSSBorderStyle},
6102: {"border-top", ParseCSSBorderTop},
6103: {"border-right", ParseCSSBorderRight},
6104: {"border-bottom", ParseCSSBorderBottom},
6105: {"border-left", ParseCSSBorderLeft},
6106: {"border", ParseCSSBorder},
6107: {"bottom", ParseCSSBottom},
6108: {"clear", ParseCSSClear},
6109: {"color", ParseCSSForeground},
6110: {"content", ParseCSSContent},
6111: {"direction", ParseCSSDirection},
6112: {"display", ParseCSSDisplay},
6113: {"float", ParseCSSFloat},
6114: {"font-family", ParseCSSFontFamily},
6115: {"font-style", ParseCSSFontStyle},
6116: {"font-variant", ParseCSSFontVariant},
6117: {"font-weight", ParseCSSFontWeight},
6118: {"font-size-adjust", ParseCSSFontSizeAdjust},
6119: {"font-size", ParseCSSFontSize},
6120: {"font", ParseCSSFont},
1.382 vatton 6121: {"max-height", ParseCSSMaxHeight},
6122: {"min-height", ParseCSSMinHeight},
1.327 vatton 6123: {"height", ParseCSSHeight},
6124: {"left", ParseCSSLeft},
6125: {"letter-spacing", ParseCSSLetterSpacing},
6126: {"line-height", ParseCSSLineHeight},
6127: {"list-style-type", ParseCSSListStyleType},
6128: {"list-style-image", ParseCSSListStyleImage},
6129: {"list-style-position", ParseCSSListStylePosition},
6130: {"list-style", ParseCSSListStyle},
6131: {"margin-bottom", ParseCSSMarginBottom},
6132: {"margin-top", ParseCSSMarginTop},
6133: {"margin-right", ParseCSSMarginRight},
6134: {"margin-left", ParseCSSMarginLeft},
6135: {"margin", ParseCSSMargin},
1.418 quint 6136: {"opacity", ParseCSSOpacity},
1.327 vatton 6137: {"padding-top", ParseCSSPaddingTop},
6138: {"padding-right", ParseCSSPaddingRight},
6139: {"padding-bottom", ParseCSSPaddingBottom},
6140: {"padding-left", ParseCSSPaddingLeft},
6141: {"padding", ParseCSSPadding},
6142: {"page-break-before", ParseCSSPageBreakBefore},
6143: {"page-break-after", ParseCSSPageBreakAfter},
6144: {"page-break-inside", ParseCSSPageBreakInside},
6145: {"position", ParseCSSPosition},
6146: {"right", ParseCSSRight},
6147: {"text-align", ParseCSSTextAlign},
6148: {"text-anchor", ParseCSSTextAnchor},
6149: {"text-indent", ParseCSSTextIndent},
6150: {"text-decoration", ParseCSSTextDecoration},
6151: {"text-transform", ParseCSSTextTransform},
6152: {"top", ParseCSSTop},
6153: {"unicode-bidi", ParseCSSUnicodeBidi},
6154: {"vertical-align", ParseCSSVerticalAlign},
6155: {"white-space", ParseCSSWhiteSpace},
1.382 vatton 6156: {"max-width", ParseCSSMaxWidth},
6157: {"min-width", ParseCSSMinWidth},
1.327 vatton 6158: {"width", ParseCSSWidth},
1.333 vatton 6159: {"visibility", ParseCSSVisibility},
1.327 vatton 6160: {"word-spacing", ParseCSSWordSpacing},
6161: {"z-index", ParseCSSZIndex},
6162:
6163: /* SVG extensions */
6164: {"fill-opacity", ParseSVGFillOpacity},
1.420 vatton 6165: {"fill-rule", ParseSVGFillRule},
1.327 vatton 6166: {"fill", ParseSVGFill},
6167: {"opacity", ParseSVGOpacity},
1.424 ! quint 6168: {"stop-color", ParseSVGStopColor},
1.327 vatton 6169: {"stroke-opacity", ParseSVGStrokeOpacity},
6170: {"stroke-width", ParseSVGStrokeWidth},
6171: {"stroke", ParseSVGStroke}
6172: };
1.155 cheyroul 6173:
1.18 cvs 6174: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
6175:
6176: /*----------------------------------------------------------------------
1.327 vatton 6177: ParseCSSRule: parse a CSS Style string
6178: we expect the input string describing the style to be of the form
6179: property: value [ ; property: value ]*
6180: but tolerate incorrect or incomplete input
1.18 cvs 6181: ----------------------------------------------------------------------*/
1.366 vatton 6182: void ParseCSSRule (Element element, PSchema tsch, PresentationContext ctxt,
6183: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 6184: {
1.366 vatton 6185: DisplayMode dispMode = DisplayImmediately;
1.312 quint 6186: char *p = NULL, *next, *end;
1.214 quint 6187: char *valueStart;
1.18 cvs 6188: int lg;
1.34 cvs 6189: unsigned int i;
1.76 cvs 6190: ThotBool found;
1.18 cvs 6191:
1.34 cvs 6192: /* avoid too many redisplay */
1.366 vatton 6193: if (!DoDialog && ctxt->doc)
6194: {
6195: dispMode = TtaGetDisplayMode (ctxt->doc);
6196: if (dispMode == DisplayImmediately)
6197: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
6198: }
1.34 cvs 6199:
1.82 cvs 6200: while (*cssRule != EOS)
1.18 cvs 6201: {
1.82 cvs 6202: cssRule = SkipBlanksAndComments (cssRule);
1.371 vatton 6203: if (*cssRule == ';' || *cssRule < 0x20 ||
1.372 vatton 6204: ((unsigned char)*cssRule) == 0xA0)
1.371 vatton 6205: cssRule++;
6206: else if (*cssRule < 0x41 || *cssRule > 0x7A ||
6207: (*cssRule > 0x5A && *cssRule < 0x61))
1.352 vatton 6208: {
6209: end = SkipProperty (cssRule, FALSE);
1.385 vatton 6210: if (cssRule[0] != '-')
6211: CSSParseError ("Invalid property", cssRule, end);
1.352 vatton 6212: cssRule = end;
6213: }
1.194 vatton 6214: else if (*cssRule != EOS)
1.327 vatton 6215: {
6216: found = FALSE;
6217: /* look for the type of property */
6218: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
6219: {
6220: lg = strlen (CSSProperties[i].name);
6221: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
6222: {
6223: p = cssRule + lg;
6224: found = TRUE;
6225: i--;
6226: }
6227: }
6228:
1.360 vatton 6229: // check if it's an important rule
6230: CheckImportantRule (cssRule, ctxt);
1.327 vatton 6231: if (i < NB_CSSSTYLEATTRIBUTE &&
6232: !strcasecmp (CSSProperties[i].name, "content") &&
6233: ((GenericContext)ctxt)->pseudo != PbBefore &&
6234: ((GenericContext)ctxt)->pseudo != PbAfter)
1.340 quint 6235: /* property content is allowed only for pseudo-elements :before and
6236: :after */
1.327 vatton 6237: {
1.352 vatton 6238: end = SkipProperty (cssRule, FALSE);
1.327 vatton 6239: CSSParseError ("content is allowed only for pseudo-elements",
6240: cssRule, end);
1.352 vatton 6241: cssRule = end;
1.327 vatton 6242: }
1.352 vatton 6243: else if (i == NB_CSSSTYLEATTRIBUTE)
1.376 vatton 6244: cssRule = SkipProperty (cssRule, !ctxt->destroy);
1.327 vatton 6245: else
6246: {
6247: /* update index and skip the ":" indicator if present */
6248: p = SkipBlanksAndComments (p);
6249: if (*p == ':')
6250: {
6251: p++;
6252: p = SkipBlanksAndComments (p);
6253: /* try to parse the value associated with this property */
6254: if (CSSProperties[i].parsing_function != NULL)
6255: {
6256: valueStart = p;
6257: p = CSSProperties[i].parsing_function (element, tsch,
6258: ctxt, p, css, isHTML);
6259: if (!element && isHTML)
6260: {
6261: if (ctxt->type == HTML_EL_Input)
6262: /* it's a generic rule for the HTML element input.
6263: Generate a Thot Pres rule for each kind of
6264: input element */
6265: {
6266: ctxt->type = HTML_EL_Text_Input;
6267: p = CSSProperties[i].parsing_function (element,
6268: tsch, ctxt, valueStart, css, isHTML);
6269: ctxt->type = HTML_EL_Password_Input;
6270: p = CSSProperties[i].parsing_function (element,
6271: tsch, ctxt, valueStart, css, isHTML);
6272: ctxt->type = HTML_EL_File_Input;
6273: p = CSSProperties[i].parsing_function (element,
6274: tsch, ctxt, valueStart, css, isHTML);
6275: ctxt->type = HTML_EL_Checkbox_Input;
6276: p = CSSProperties[i].parsing_function (element,
6277: tsch, ctxt, valueStart, css, isHTML);
6278: ctxt->type = HTML_EL_Radio_Input;
6279: p = CSSProperties[i].parsing_function (element,
6280: tsch, ctxt, valueStart, css, isHTML);
6281: ctxt->type = HTML_EL_Submit_Input;
6282: p = CSSProperties[i].parsing_function (element,
6283: tsch, ctxt, valueStart, css, isHTML);
6284: ctxt->type = HTML_EL_Reset_Input;
6285: p = CSSProperties[i].parsing_function (element,
6286: tsch, ctxt, valueStart, css, isHTML);
6287: ctxt->type = HTML_EL_Button_Input;
6288: p = CSSProperties[i].parsing_function (element,
6289: tsch, ctxt, valueStart, css, isHTML);
6290: ctxt->type = HTML_EL_Input;
6291: }
6292: else if (ctxt->type == HTML_EL_ruby)
6293: /* it's a generic rule for the HTML element ruby.
6294: Generate a Thot Pres rule for each kind of
6295: ruby element. */
6296: {
6297: ctxt->type = HTML_EL_simple_ruby;
6298: p = CSSProperties[i].parsing_function (element,
6299: tsch, ctxt, valueStart, css, isHTML);
6300: ctxt->type = HTML_EL_complex_ruby;
6301: p = CSSProperties[i].parsing_function (element,
6302: tsch, ctxt, valueStart, css, isHTML);
6303: ctxt->type = HTML_EL_ruby;
6304: }
6305: }
6306: /* update index and skip the ";" separator if present */
6307: next = SkipBlanksAndComments (p);
6308: if (*next != EOS && *next != ';')
6309: CSSParseError ("Missing closing ';'", cssRule, p);
6310: cssRule = next;
6311: }
6312: }
6313: else
6314: cssRule = SkipProperty (cssRule, TRUE);
6315: }
1.360 vatton 6316: // skip important markup
6317: cssRule = SkipImportantRule (cssRule);
6318:
1.327 vatton 6319: }
1.18 cvs 6320: /* next property */
1.82 cvs 6321: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 6322: if (*cssRule == '}')
1.327 vatton 6323: {
6324: cssRule++;
6325: CSSPrintError ("Invalid character", "}");
6326: cssRule = SkipBlanksAndComments (cssRule);
6327: }
1.155 cheyroul 6328: if (*cssRule == ',' ||
1.327 vatton 6329: *cssRule == ';')
6330: {
6331: cssRule++;
6332: cssRule = SkipBlanksAndComments (cssRule);
6333: }
1.18 cvs 6334: }
1.34 cvs 6335:
6336: /* restore the display mode */
1.366 vatton 6337: if (!DoDialog && ctxt->doc && dispMode == DisplayImmediately)
1.207 vatton 6338: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 6339: }
1.1 cvs 6340:
1.111 cvs 6341: /*----------------------------------------------------------------------
1.327 vatton 6342: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
6343: This function must be called when a specific style is applied to an
6344: element.
6345: The parameter specificity is the specificity of the style, 0 if it is
6346: not really a CSS rule.
1.1 cvs 6347: ----------------------------------------------------------------------*/
1.79 cvs 6348: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.377 quint 6349: int specificity, ThotBool destroy)
1.1 cvs 6350: {
1.257 vatton 6351: DisplayMode dispMode;
1.207 vatton 6352: PresentationContext ctxt;
6353: ElementType elType;
1.413 vatton 6354: char *buff, *ptr, *end;
1.207 vatton 6355: ThotBool isHTML;
1.1 cvs 6356:
1.207 vatton 6357: /* A rule applying to BODY is really meant to address HTML */
6358: elType = TtaGetElementType (el);
1.286 quint 6359: NewLineSkipped = 0;
1.207 vatton 6360: /* store the current line for eventually reported errors */
6361: LineNumber = TtaGetElementLineNumber (el);
6362: if (destroy)
6363: /* no reported errors */
6364: ParsedDoc = 0;
6365: else if (ParsedDoc != doc)
6366: {
6367: /* update the context for reported errors */
6368: ParsedDoc = doc;
1.348 vatton 6369: Error_DocURL = DocumentURLs[doc];
1.207 vatton 6370: }
6371: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
6372: /* create the context of the Specific presentation driver */
6373: ctxt = TtaGetSpecificStyleContext (doc);
6374: if (ctxt == NULL)
6375: return;
6376: ctxt->type = elType.ElTypeNum;
6377: ctxt->cssSpecificity = specificity;
1.236 quint 6378: ctxt->cssLine = LineNumber;
1.207 vatton 6379: ctxt->destroy = destroy;
6380: /* first use of the context */
6381: ctxt->uses = 1;
1.257 vatton 6382: /* save the current display mode */
6383: dispMode = TtaGetDisplayMode (doc);
1.207 vatton 6384: /* Call the parser */
1.366 vatton 6385: DoDialog = FALSE; // not parsing for CSS dialog
1.406 quint 6386: /* if it is a property applied to a COL or a COLGROUP element in a HTML table,
6387: associate the property to the corresponding Table_head or cell elements,
6388: depending on the property. */
1.413 vatton 6389: ptr = strstr (cssRule, "background-color");
6390: if (ptr && isHTML &&
1.406 quint 6391: (elType.ElTypeNum == HTML_EL_COL || elType.ElTypeNum == HTML_EL_COLGROUP))
1.413 vatton 6392: {
6393: end = strstr (ptr, ";");
6394: if (end)
6395: {
6396: buff = TtaStrdup (ptr);
6397: end = strstr (buff, ";");
6398: *end = EOS;
6399: ColApplyCSSRule (el, (PresentationContext) ctxt, buff, NULL);
6400: TtaFreeMemory (buff);
6401: }
6402: else
6403: ColApplyCSSRule (el, (PresentationContext) ctxt, ptr, NULL);
6404: }
1.406 quint 6405: else
6406: ParseCSSRule (el, NULL, ctxt, cssRule, NULL, isHTML);
6407:
1.257 vatton 6408: /* restore the display mode if necessary */
1.417 vatton 6409: if (dispMode != NoComputedDisplay)
6410: TtaSetDisplayMode (doc, dispMode);
1.207 vatton 6411: /* check if the context can be freed */
6412: ctxt->uses -= 1;
6413: if (ctxt->uses == 0)
6414: /* no image loading */
6415: TtaFreeMemory(ctxt);
1.1 cvs 6416: }
6417:
1.366 vatton 6418:
1.343 vatton 6419: /*----------------------------------------------------------------------
6420: AddClassName adds the class name into the class list of css if it's
6421: not already there.
6422: ----------------------------------------------------------------------*/
6423: static void AddClassName (char *name, CSSInfoPtr css)
6424: {
1.344 cvs 6425: int l, index, k, length, add;
1.343 vatton 6426: char *buf;
6427: ThotBool found, previous;
6428:
6429: l = strlen (name);
6430: if (l == 0 || css == NULL)
6431: return;
6432: if (css->class_list)
6433: {
6434: buf = css->class_list;
6435: length = strlen (css->class_list);
6436: }
6437: else
6438: {
6439: if (l > 200)
6440: length = l + 1;
6441: else
6442: length = 200;
6443: buf = (char *)TtaGetMemory (length * sizeof (char));
6444: memset (buf, 0, length);
6445: css->class_list = buf;
6446: css->lg_class_list = length;
6447: length = 0;
6448: }
6449:
6450: /* compare that name with all class names already known */
6451: index = 0;
6452: found = FALSE;
6453: previous = FALSE;
6454: while (index < length && !found && !previous)
6455: {
6456: k = 0;
6457: while (k < l && buf[index + k] != EOS && buf[index + k] != SPACE)
6458: {
6459: if (name[k] == buf[index+k])
6460: k++;
6461: else
6462: {
6463: previous = (name[k] < buf[index + k]);
6464: break;
6465: }
6466: }
6467: found = (k == l);
6468: if (!previous)
6469: {
6470: index += k;
6471: while (buf[index] != EOS && buf[index] != SPACE)
6472: index++;
6473: if (buf[index] == SPACE)
6474: index++;
6475: }
6476: }
6477:
6478: if (!found)
6479: /* this class name is not known, append it */
6480: {
6481: l++; /* add a space before */
6482: if (css->lg_class_list <= length + l)
6483: {
6484: // increase the list size
6485: if (l > 200)
6486: add = l + 1;
6487: else
6488: add = 200 ;
6489: buf = (char *)TtaRealloc (buf, css->lg_class_list + (add * sizeof (char)));
6490: if (buf == NULL)
6491: return;
6492: else
6493: {
6494: css->class_list = buf;
6495: memset (&buf[css->lg_class_list], 0, add);
6496: css->lg_class_list += add;
6497: }
6498: }
6499:
6500: if (previous)
6501: {
6502: // move the tail of the current list
6503: for (k = length; k >= index; k--)
6504: buf[k+l] = buf[k];
6505: /* add this new class name at the current position */
6506: strcpy (&buf[index], name);
6507: buf[index + l - 1] = SPACE;
6508: }
6509: else
6510: {
6511: /* add this new class name at the end */
6512: if (index != 0)
6513: buf[index++] = SPACE;
6514: strcpy (&buf[index], name);
6515: }
6516: }
6517: }
6518:
1.68 cvs 6519:
1.1 cvs 6520: /*----------------------------------------------------------------------
1.207 vatton 6521: ParseGenericSelector: Create a generic context for a given selector
6522: string.
6523: If the selector is made of multiple comma, it parses them one at a time
6524: and return the end of the selector string to be handled or NULL.
1.231 vatton 6525: The parameter ctxt gives the current style context which will be passed
6526: to Thotlib.
6527: The parameter css points to the current CSS context.
6528: The parameter link points to the link element.
6529: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 6530: ----------------------------------------------------------------------*/
1.207 vatton 6531: static char *ParseGenericSelector (char *selector, char *cssRule,
1.327 vatton 6532: GenericContext ctxt, Document doc,
6533: CSSInfoPtr css, Element link, char *url)
1.79 cvs 6534: {
6535: ElementType elType;
6536: PSchema tsch;
1.119 vatton 6537: AttributeType attrType;
1.398 vatton 6538: char *deb, *cur, *sel, *next, *limit, c;
1.317 vatton 6539: char *schemaName, *mappedName, *saveURL;
1.79 cvs 6540: char *names[MAX_ANCESTORS];
1.355 quint 6541: ThotBool pseudoFirstChild[MAX_ANCESTORS];
1.340 quint 6542: ElemRel rel[MAX_ANCESTORS];
6543: char *attrnames[MAX_ANCESTORS];
6544: int attrnums[MAX_ANCESTORS];
6545: int attrlevels[MAX_ANCESTORS];
1.79 cvs 6546: char *attrvals[MAX_ANCESTORS];
1.133 vatton 6547: AttrMatch attrmatch[MAX_ANCESTORS];
1.340 quint 6548: int nbnames, nbattrs;
6549: int i, j;
1.256 vatton 6550: int att, kind;
1.118 vatton 6551: int specificity, xmlType;
1.217 vatton 6552: int skippedNL;
1.404 vatton 6553: ThotBool isHTML, noname, warn;
1.347 quint 6554: ThotBool level, quoted, doubleColon;
1.340 quint 6555: #define ATTR_ID 1
6556: #define ATTR_CLASS 2
6557: #define ATTR_PSEUDO 3
1.1 cvs 6558:
1.404 vatton 6559: // check if Amaya should report CSS warnings
6560: TtaGetEnvBoolean ("CSS_WARN", &warn);
1.207 vatton 6561: sel = ctxt->sel;
1.82 cvs 6562: sel[0] = EOS;
1.398 vatton 6563: // get the limit of the string
6564: limit = &sel[MAX_ANCESTORS * 50 -1];
6565: *limit = EOS;
1.117 vatton 6566: specificity = 0;
1.1 cvs 6567: for (i = 0; i < MAX_ANCESTORS; i++)
6568: {
1.25 cvs 6569: names[i] = NULL;
1.355 quint 6570: pseudoFirstChild[i] = FALSE;
1.340 quint 6571: rel[i] = RelAncestor;
6572: attrnames[i] = NULL;
6573: attrnums[i] = 0;
6574: attrlevels[i] = 0;
1.25 cvs 6575: attrvals[i] = NULL;
1.133 vatton 6576: attrmatch[i] = Txtmatch;
1.25 cvs 6577: ctxt->name[i] = 0;
1.355 quint 6578: ctxt->firstChild[i] = FALSE;
1.25 cvs 6579: ctxt->attrType[i] = 0;
1.129 vatton 6580: ctxt->attrLevel[i] = 0;
1.25 cvs 6581: ctxt->attrText[i] = NULL;
1.178 quint 6582: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 6583: }
1.25 cvs 6584: ctxt->box = 0;
1.312 quint 6585: ctxt->var = 0;
1.306 quint 6586: ctxt->pseudo = PbNone;
1.25 cvs 6587: ctxt->type = 0;
1.366 vatton 6588: DoDialog = FALSE; // not arsing for CSS dialog
1.114 quint 6589: /* the specificity of the rule depends on the selector */
6590: ctxt->cssSpecificity = 0;
1.231 vatton 6591: /* localisation of the CSS rule */
6592: ctxt->cssLine = LineNumber + NewLineSkipped;
6593: ctxt->cssURL = url;
1.240 quint 6594:
1.286 quint 6595: skippedNL = NewLineSkipped;
1.82 cvs 6596: selector = SkipBlanksAndComments (selector);
1.286 quint 6597: NewLineSkipped = skippedNL;
1.27 cvs 6598: cur = &sel[0];
1.340 quint 6599: nbnames = 0;
6600: nbattrs = 0;
1.1 cvs 6601: while (1)
6602: {
1.85 cvs 6603: /* point to the following word in sel[] */
1.27 cvs 6604: deb = cur;
1.25 cvs 6605: /* copy an item of the selector into sel[] */
1.1 cvs 6606: /* put one word in the sel buffer */
1.82 cvs 6607: while (*selector != EOS && *selector != ',' &&
6608: *selector != '.' && *selector != ':' &&
1.118 vatton 6609: *selector != '#' && *selector != '[' &&
1.250 vatton 6610: *selector != '>' && *selector != '+' &&
1.398 vatton 6611: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6612: *cur++ = *selector++;
1.82 cvs 6613: *cur++ = EOS; /* close the first string in sel[] */
1.380 vatton 6614: noname = TRUE;
1.82 cvs 6615: if (deb[0] != EOS)
1.340 quint 6616: /* the selector starts with an element name */
1.327 vatton 6617: {
6618: if (deb[0] <= 64 && deb[0] != '*')
6619: {
6620: CSSPrintError ("Invalid element", deb);
1.380 vatton 6621: names[0] = NULL; /* no element name */
6622: DoApply = FALSE;
1.327 vatton 6623: }
6624: else
6625: {
1.380 vatton 6626: noname = FALSE;
1.327 vatton 6627: names[0] = deb;
6628: if (!strcmp (names[0], "html"))
6629: /* give a greater priority to the backgoud color of html */
6630: specificity += 3;
6631: else
6632: /* selector "*" has specificity zero */
6633: if (strcmp (names[0], "*"))
6634: specificity += 1;
6635: }
6636: }
1.25 cvs 6637: else
1.340 quint 6638: names[0] = NULL; /* no element name */
1.226 quint 6639:
1.340 quint 6640: rel[0] = RelVoid;
1.27 cvs 6641: /* now names[0] points to the beginning of the parsed item
1.340 quint 6642: and cur to the next string to be parsed */
1.129 vatton 6643: while (*selector == '.' || *selector == ':' ||
1.327 vatton 6644: *selector == '#' || *selector == '[')
6645: {
6646: /* point to the following word in sel[] */
6647: deb = cur;
6648: if (*selector == '.')
1.340 quint 6649: /* class */
1.327 vatton 6650: {
6651: selector++;
1.340 quint 6652: while (*selector != '.' && *selector != ':' &&
6653: *selector != '#' && *selector != '[' &&
6654: *selector != EOS && *selector != ',' &&
6655: *selector != '+' && *selector != '>' &&
1.398 vatton 6656: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6657: {
6658: if (*selector == '\\')
6659: {
6660: selector++;
6661: if (*selector != EOS)
6662: *cur++ = *selector++;
6663: }
6664: else
6665: *cur++ = *selector++;
6666: }
6667: /* close the word */
6668: *cur++ = EOS;
1.340 quint 6669: /* point to the class in sel[] if it's a valid name */
1.327 vatton 6670: if (deb[0] <= 64)
6671: {
6672: CSSPrintError ("Invalid class", deb);
6673: DoApply = FALSE;
6674: }
6675: else
6676: {
1.340 quint 6677: /* simulate selector [class ~= "xxx"] */
6678: nbattrs++;
6679: if (nbattrs == MAX_ANCESTORS)
6680: /* abort parsing */
6681: {
6682: CSSPrintError ("Selector too long", deb);
6683: return (selector);
6684: }
6685: for (i = nbattrs; i > 0; i--)
6686: {
6687: attrnames[i] = attrnames[i - 1];
6688: attrnums[i] = attrnums[i - 1];
6689: attrlevels[i] = attrlevels[i - 1];
6690: attrvals[i] = attrvals[i - 1];
6691: attrmatch[i] = attrmatch[i - 1];
6692: }
6693: attrnames[0] = NULL;
6694: attrnums[0] = ATTR_CLASS;
6695: attrlevels[0] = 0;
6696: attrmatch[0] = Txtword;
6697: attrvals[0] = deb;
1.327 vatton 6698: specificity += 10;
1.343 vatton 6699: }
1.327 vatton 6700: }
6701: else if (*selector == ':')
1.340 quint 6702: /* pseudo-class or pseudo-element */
1.327 vatton 6703: {
6704: selector++;
1.347 quint 6705: doubleColon = FALSE;
6706: if (*selector == ':')
6707: /* it's a double "::". Probably CSS3 syntax */
6708: {
6709: selector++;
6710: doubleColon = TRUE;
6711: }
1.340 quint 6712: while (*selector != '.' && *selector != ':' &&
6713: *selector != '#' && *selector != '[' &&
6714: *selector != EOS && *selector != ',' &&
6715: *selector != '+' && *selector != '>' &&
1.398 vatton 6716: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6717: *cur++ = *selector++;
6718: /* close the word */
6719: *cur++ = EOS;
1.340 quint 6720: /* point to the pseudo-class or pseudo-element in sel[] if it's
6721: a valid name */
1.355 quint 6722: if (!strcmp (deb, "first-child"))
6723: /* first-child pseudo-class */
1.327 vatton 6724: {
1.355 quint 6725: pseudoFirstChild[0] = TRUE;
6726: specificity += 10;
1.327 vatton 6727: }
1.355 quint 6728: else if (!strcmp (deb, "link") || !strcmp (deb, "visited"))
6729: /* link or visited pseudo-classes */
1.327 vatton 6730: {
1.355 quint 6731: nbattrs++;
6732: if (nbattrs == MAX_ANCESTORS)
6733: /* abort parsing */
1.347 quint 6734: {
1.355 quint 6735: CSSPrintError ("Selector too long", deb);
6736: return (selector);
1.347 quint 6737: }
1.355 quint 6738: for (i = nbattrs; i > 0; i--)
1.347 quint 6739: {
1.355 quint 6740: attrnames[i] = attrnames[i - 1];
6741: attrnums[i] = attrnums[i - 1];
6742: attrlevels[i] = attrlevels[i - 1];
6743: attrvals[i] = attrvals[i - 1];
6744: attrmatch[i] = attrmatch[i - 1];
1.347 quint 6745: }
1.355 quint 6746: attrnames[0] = NULL;
6747: attrnums[0] = ATTR_PSEUDO;
6748: attrlevels[0] = 0;
6749: attrmatch[0] = Txtmatch;
6750: attrvals[0] = deb;
6751: specificity += 10;
6752: }
6753: else if (!strcmp (deb, "hover") || !strcmp (deb, "active") ||
6754: !strcmp (deb, "focus"))
6755: /* hover, active, focus pseudo-classes */
6756: {
1.403 vatton 6757: attrnames[0] = NULL;
6758: attrnums[0] = ATTR_PSEUDO;
6759: attrlevels[0] = 0;
6760: attrmatch[0] = Txtmatch;
6761: attrvals[0] = deb;
1.355 quint 6762: specificity += 10;
6763: /* not supported */
6764: DoApply = FALSE;
6765: }
6766: else if (!strncmp (deb, "lang", 4))
6767: /* it's the lang pseudo-class */
6768: {
6769: if (deb[4] != '(' || deb[strlen(deb)-1] != ')')
6770: /* at least one parenthesis is missing. Error */
1.327 vatton 6771: {
1.355 quint 6772: CSSPrintError ("Invalid :lang pseudo-class", deb);
6773: DoApply = FALSE;
1.327 vatton 6774: }
6775: else
1.355 quint 6776: /* simulate selector [lang|="xxx"] */
1.340 quint 6777: {
6778: nbattrs++;
6779: if (nbattrs == MAX_ANCESTORS)
6780: /* abort parsing */
6781: {
6782: CSSPrintError ("Selector too long", deb);
6783: return (selector);
6784: }
1.355 quint 6785: deb[strlen(deb)-1] = EOS;
6786: deb[4] = EOS;
1.340 quint 6787: for (i = nbattrs; i > 0; i--)
6788: {
6789: attrnames[i] = attrnames[i - 1];
6790: attrnums[i] = attrnums[i - 1];
6791: attrlevels[i] = attrlevels[i - 1];
6792: attrvals[i] = attrvals[i - 1];
6793: attrmatch[i] = attrmatch[i - 1];
6794: }
1.355 quint 6795: attrnames[0] = deb;
6796: attrnums[0] = 0;
1.340 quint 6797: attrlevels[0] = 0;
1.355 quint 6798: attrmatch[0] = Txtsubstring;
6799: attrvals[0] = &deb[5];
6800: specificity += 10;
1.340 quint 6801: }
1.327 vatton 6802: }
1.355 quint 6803: else if (!strcmp (deb, "first-line") ||
6804: !strcmp (deb, "first-letter"))
6805: /* pseudo-elements first-line or first-letter */
6806: {
1.404 vatton 6807: if (doubleColon && warn)
1.355 quint 6808: CSSPrintError ("Warning: \"::\" is CSS3 syntax", NULL);
6809: specificity += 1;
6810: /* not supported */
6811: DoApply = FALSE;
6812: }
6813: else if (!strncmp (deb, "before", 6))
6814: /* pseudo-element before */
6815: {
1.404 vatton 6816: if (doubleColon && warn)
1.355 quint 6817: CSSPrintError ("Warning: \"::before\" is CSS3 syntax",
6818: NULL);
6819: ctxt->pseudo = PbBefore;
6820: specificity += 1;
6821: }
6822: else if (!strncmp (deb, "after", 5))
6823: /* pseudo-element after */
6824: {
1.404 vatton 6825: if (doubleColon && warn)
1.355 quint 6826: CSSPrintError ("Warning: \"::after\" is CSS3 syntax",
6827: NULL);
6828: ctxt->pseudo = PbAfter;
6829: specificity += 1;
6830: }
1.404 vatton 6831: else if (!strncmp (deb, "target", 6))
6832: {
6833: if (warn)
6834: CSSPrintError ("Warning: \":target\" is CSS3 syntax",
6835: NULL);
6836: specificity += 1;
6837: DoApply = FALSE;
6838: }
6839: else
1.355 quint 6840: {
6841: CSSPrintError ("Invalid pseudo-element", deb);
6842: DoApply = FALSE;
6843: }
6844: if (names[0] && !strcmp (names[0], "*"))
6845: names[0] = NULL;
1.327 vatton 6846: }
6847: else if (*selector == '#')
1.340 quint 6848: /* unique identifier */
1.327 vatton 6849: {
6850: selector++;
1.340 quint 6851: while (*selector != '.' && *selector != ':' &&
6852: *selector != '#' && *selector != '[' &&
6853: *selector != '+' && *selector != '>' &&
6854: *selector != EOS && *selector != ',' &&
1.398 vatton 6855: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6856: *cur++ = *selector++;
6857: /* close the word */
6858: *cur++ = EOS;
6859: /* point to the attribute in sel[] if it's valid name */
6860: if (deb[0] <= 64)
6861: {
6862: CSSPrintError ("Invalid id", deb);
6863: DoApply = FALSE;
6864: }
6865: else
6866: {
1.340 quint 6867: nbattrs++;
6868: if (nbattrs == MAX_ANCESTORS)
6869: /* abort parsing */
6870: {
6871: CSSPrintError ("Selector too long", deb);
6872: return (selector);
6873: }
6874: for (i = nbattrs; i > 0; i--)
6875: {
6876: attrnames[i] = attrnames[i - 1];
6877: attrnums[i] = attrnums[i - 1];
6878: attrlevels[i] = attrlevels[i - 1];
6879: attrvals[i] = attrvals[i - 1];
6880: attrmatch[i] = attrmatch[i - 1];
6881: }
6882: attrnames[0] = NULL;
6883: attrnums[0] = ATTR_ID;
6884: attrlevels[0] = 0;
6885: attrmatch[0] = Txtmatch;
6886: attrvals[0] = deb;
6887: specificity += 100;
6888: if (names[0] && !strcmp (names[0], "*"))
6889: names[0] = NULL;
1.327 vatton 6890: }
6891: }
6892: else if (*selector == '[')
6893: {
6894: selector++;
1.341 quint 6895: selector = SkipBlanksAndComments (selector);
1.327 vatton 6896: while (*selector != EOS && *selector != ']' &&
6897: *selector != '=' && *selector != '~' &&
1.341 quint 6898: *selector != '|' && *selector != '^' &&
1.396 vatton 6899: *selector != '$' && *selector != '*' &&
1.398 vatton 6900: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6901: *cur++ = *selector++;
1.341 quint 6902: /* close the word (attribute name) */
1.327 vatton 6903: *cur++ = EOS;
6904: /* point to the attribute in sel[] if it's valid name */
6905: if (deb[0] <= 64)
6906: {
6907: CSSPrintError ("Invalid attribute", deb);
6908: DoApply = FALSE;
6909: }
6910: else
6911: {
1.340 quint 6912: nbattrs++;
6913: if (nbattrs == MAX_ANCESTORS)
6914: /* abort parsing */
6915: {
6916: CSSPrintError ("Selector too long", deb);
6917: return (selector);
6918: }
6919: for (i = nbattrs; i > 0; i--)
6920: {
6921: attrnames[i] = attrnames[i - 1];
6922: attrnums[i] = attrnums[i - 1];
6923: attrlevels[i] = attrlevels[i - 1];
6924: attrvals[i] = attrvals[i - 1];
6925: attrmatch[i] = attrmatch[i - 1];
6926: }
6927: attrnames[0] = deb;
6928: attrnums[0] = 0;
6929: attrlevels[0] = 0;
1.378 quint 6930: attrvals[0] = NULL;
6931: attrmatch[0] = Txtmatch;
1.327 vatton 6932: specificity += 10;
1.340 quint 6933: /* check matching */
1.341 quint 6934: selector = SkipBlanksAndComments (selector);
1.340 quint 6935: if (*selector == '~')
6936: {
6937: attrmatch[0] = Txtword;
6938: selector++;
6939: }
1.396 vatton 6940: else if (*selector == '|' || *selector == '$' || *selector == '*')
1.340 quint 6941: {
1.404 vatton 6942: if (*selector == '$' && warn)
1.396 vatton 6943: CSSPrintError ("Warning: \"$=\" is CSS3 syntax", NULL);
1.404 vatton 6944: if (*selector == '*' && warn)
1.396 vatton 6945: CSSPrintError ("Warning: \"*=\" is CSS3 syntax", NULL);
1.340 quint 6946: attrmatch[0] = Txtsubstring;
6947: selector++;
6948: }
1.341 quint 6949: else if (*selector == '^')
6950: {
6951: attrmatch[0] = Txtsubstring;
6952: selector++;
6953: }
1.340 quint 6954: else
6955: attrmatch[0] = Txtmatch;
1.327 vatton 6956: }
6957: if (*selector == '=')
6958: {
6959: /* look for a value "xxxx" */
6960: selector++;
1.341 quint 6961: selector = SkipBlanksAndComments (selector);
1.327 vatton 6962: if (*selector != '"')
6963: quoted = FALSE;
6964: else
6965: {
6966: quoted = TRUE;
6967: /* we are now parsing the attribute value */
6968: selector++;
6969: }
6970: deb = cur;
1.398 vatton 6971: while ((quoted && cur < limit &&
1.327 vatton 6972: (*selector != '"' ||
6973: (*selector == '"' && selector[-1] == '\\'))) ||
6974: (!quoted && *selector != ']'))
6975: {
6976: if (*selector == EOS)
6977: {
6978: CSSPrintError ("Invalid attribute value", deb);
6979: DoApply = FALSE;
6980: }
6981: else
6982: {
6983: if (attrmatch[0] == Txtword && TtaIsBlank (selector))
6984: {
6985: CSSPrintError ("No space allowed here: ", selector);
6986: DoApply = FALSE;
6987: }
6988: *cur++ = *selector;
6989: }
6990: selector++;
6991: }
6992: /* there is a value */
6993: if (quoted && *selector == '"')
6994: {
6995: selector++;
6996: quoted = FALSE;
6997: }
1.341 quint 6998: selector = SkipBlanksAndComments (selector);
1.327 vatton 6999: if (*selector != ']')
7000: {
7001: CSSPrintError ("Invalid attribute value", deb);
7002: DoApply = FALSE;
7003: }
7004: else
7005: {
7006: *cur++ = EOS;
7007: attrvals[0] = deb;
7008: selector++;
7009: }
7010: }
7011: /* end of the attribute */
7012: else if (*selector != ']')
7013: {
7014: selector[1] = EOS;
7015: CSSPrintError ("Invalid attribute", selector);
7016: selector += 2;
7017: DoApply = FALSE;
7018: }
7019: else
7020: {
7021: selector++;
7022: if (names[0] && !strcmp (names[0], "*"))
7023: names[0] = NULL;
7024: }
7025: }
7026: else
7027: {
7028: /* not supported selector */
1.340 quint 7029: while (*selector != '.' && *selector != ':' &&
7030: *selector != '#' && *selector != '[' &&
7031: *selector != EOS && *selector != ',' &&
7032: *selector != '+' && *selector != '>' &&
1.398 vatton 7033: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 7034: *cur++ = *selector++;
7035: /* close the word */
7036: *cur++ = EOS;
7037: CSSPrintError ("Selector not supported:", deb);
7038: DoApply = FALSE;
7039: }
7040: }
1.1 cvs 7041:
1.286 quint 7042: skippedNL = NewLineSkipped;
1.82 cvs 7043: selector = SkipBlanksAndComments (selector);
1.286 quint 7044: NewLineSkipped = skippedNL;
7045:
1.380 vatton 7046: if (noname && !pseudoFirstChild[0] && attrnums[0] == 0 && attrnames[0] == NULL)
7047: {
7048: *cur++ = EOS;
7049: CSSPrintError ("Invalid Selector", deb);
7050: DoApply = FALSE;
7051: }
1.25 cvs 7052: /* is it a multi-level selector? */
1.82 cvs 7053: if (*selector == EOS)
1.327 vatton 7054: /* end of the selector */
7055: break;
1.82 cvs 7056: else if (*selector == ',')
1.327 vatton 7057: {
7058: /* end of the current selector */
7059: selector++;
7060: skippedNL = NewLineSkipped;
7061: next = SkipBlanksAndComments (selector);
7062: NewLineSkipped = skippedNL;
7063: if (*next == EOS)
7064: /* nothing after the comma. Invalid selector */
7065: {
1.380 vatton 7066: CSSPrintError ("Syntax error:", selector);
7067: selector = NULL;
1.327 vatton 7068: }
7069: break;
7070: }
1.25 cvs 7071: else
1.327 vatton 7072: {
7073: if (*selector == '>')
7074: {
1.340 quint 7075: /* handle parent */
1.327 vatton 7076: selector++;
7077: skippedNL = NewLineSkipped;
7078: selector = SkipBlanksAndComments (selector);
7079: NewLineSkipped = skippedNL;
1.340 quint 7080: rel[0] = RelParent;
1.327 vatton 7081: }
7082: else if (*selector == '+')
7083: {
1.340 quint 7084: /* handle immediate sibling */
1.327 vatton 7085: selector++;
7086: skippedNL = NewLineSkipped;
7087: selector = SkipBlanksAndComments (selector);
7088: NewLineSkipped = skippedNL;
7089: rel[0] = RelPrevious;
7090: }
1.340 quint 7091: else
7092: rel[0] = RelAncestor;
7093: nbnames++; /* a new level in ancestor tables */
7094: if (nbnames == MAX_ANCESTORS)
7095: /* abort parsing */
7096: {
7097: CSSPrintError ("Selector too long", deb);
7098: return (selector);
7099: }
7100: /* shift the list to make room for the next part of the selector */
7101: for (i = nbnames; i > 0; i--)
1.327 vatton 7102: {
7103: names[i] = names[i - 1];
1.355 quint 7104: pseudoFirstChild[i] = pseudoFirstChild[i - 1];
1.327 vatton 7105: rel[i] = rel[i - 1];
7106: }
1.340 quint 7107: /* increase the level of all attributes */
7108: for (i = 0; i < nbattrs; i++)
7109: attrlevels[i]++;
1.327 vatton 7110: }
1.1 cvs 7111: }
7112:
1.343 vatton 7113: /* Now update the list of classes defined by the CSS */
7114: for (i = 0; i < nbattrs; i++)
7115: if (attrvals[i] && attrnums[i] == ATTR_CLASS)
7116: AddClassName (attrvals[i], css);
7117:
1.1 cvs 7118: /* Now set up the context block */
1.25 cvs 7119: i = 0;
7120: j = 0;
1.91 cvs 7121: /* default schema name */
1.119 vatton 7122: ctxt->schema = NULL;
1.340 quint 7123: ctxt->nbElem = nbnames;
1.122 vatton 7124: elType.ElSSchema = NULL;
1.355 quint 7125: elType.ElTypeNum = 0;
1.122 vatton 7126: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 7127: if (!strcmp (schemaName, "HTML"))
7128: xmlType = XHTML_TYPE;
7129: else if (!strcmp (schemaName, "MathML"))
7130: xmlType = MATH_TYPE;
7131: else if (!strcmp (schemaName, "SVG"))
7132: xmlType = SVG_TYPE;
7133: else if (!strcmp (schemaName, "XLink"))
7134: xmlType = XLINK_TYPE;
7135: else if (!strcmp (schemaName, "Annot"))
7136: xmlType = ANNOT_TYPE;
7137: else
7138: xmlType = XML_TYPE;
1.340 quint 7139: while (i <= nbnames)
1.25 cvs 7140: {
1.340 quint 7141: ctxt->rel[i] = rel[i];
1.355 quint 7142: ctxt->firstChild[i] = pseudoFirstChild[i];
7143: if (!names[i] && i > 0)
1.340 quint 7144: ctxt->name[i] = HTML_EL_ANY_TYPE;
7145: else
7146: /* store element information */
1.327 vatton 7147: {
7148: /* get the element type of this name in the current document */
7149: if (xmlType == XML_TYPE)
7150: /* it's a generic XML document. Check the main document schema */
7151: {
7152: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7153: elType.ElTypeNum = 0;
7154: if (names[i])
7155: TtaGetXmlElementType (names[i], &elType, &mappedName, doc);
1.327 vatton 7156: if (!elType.ElTypeNum)
7157: {
1.355 quint 7158: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 7159: elType.ElTypeNum = HTML_EL_ANY_TYPE;
7160: else
7161: elType.ElSSchema = NULL;
7162: }
7163: }
7164: else
7165: {
1.355 quint 7166: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 7167: {
7168: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7169: elType.ElTypeNum = HTML_EL_ANY_TYPE;
7170: }
7171: else
7172: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c,
7173: &level, doc);
7174: }
7175: if (i == 0)
1.340 quint 7176: /* rightmost part of the selector */
1.327 vatton 7177: {
7178: if (elType.ElSSchema == NULL)
7179: {
1.340 quint 7180: /* element name not found. Search in all loaded schemas */
1.355 quint 7181: if (names[i])
7182: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.327 vatton 7183: if (elType.ElSSchema)
7184: {
7185: /* the element type concerns an imported nature */
7186: schemaName = TtaGetSSchemaName(elType.ElSSchema);
7187: if (!strcmp (schemaName, "HTML"))
7188: {
7189: if (xmlType == XHTML_TYPE &&
7190: DocumentMeta[doc] && DocumentMeta[doc]->xmlformat)
7191: /* the selector was found but the case is not correct */
7192: elType.ElSSchema = NULL;
7193: else
7194: xmlType = XHTML_TYPE;
7195: }
7196: else if (!strcmp (schemaName, "MathML"))
7197: xmlType = MATH_TYPE;
7198: else if (!strcmp (schemaName, "SVG"))
7199: xmlType = SVG_TYPE;
7200: else if (!strcmp (schemaName, "XLink"))
7201: xmlType = XLINK_TYPE;
7202: else if (!strcmp (schemaName, "Annot"))
7203: xmlType = ANNOT_TYPE;
7204: else
7205: xmlType = XML_TYPE;
7206: }
1.118 vatton 7207: #ifdef XML_GENERIC
1.327 vatton 7208: else if (xmlType == XML_TYPE)
7209: {
7210: /* Creation of a new element type in the main schema */
7211: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7212: if (names[i])
7213: TtaAppendXmlElement (names[i], &elType, &mappedName,
7214: doc);
1.327 vatton 7215: }
1.118 vatton 7216: #endif /* XML_GENERIC */
1.327 vatton 7217: else
7218: {
7219: if (xmlType != XHTML_TYPE)
7220: {
7221: MapXMLElementType (XHTML_TYPE, names[i], &elType,
7222: &mappedName, &c, &level, doc);
7223: if (elType.ElSSchema)
7224: elType.ElSSchema = GetXHTMLSSchema (doc);
7225: }
7226: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
7227: {
7228: MapXMLElementType (MATH_TYPE, names[i], &elType,
7229: &mappedName, &c, &level, doc);
7230: if (elType.ElSSchema)
7231: elType.ElSSchema = GetMathMLSSchema (doc);
7232: }
7233: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
7234: {
7235: MapXMLElementType (SVG_TYPE, names[i], &elType,
7236: &mappedName, &c, &level, doc);
7237: if (elType.ElSSchema)
7238: elType.ElSSchema = GetSVGSSchema (doc);
7239: }
7240: }
7241: }
7242:
7243: if (elType.ElSSchema == NULL)
7244: /* cannot apply these CSS rules */
7245: DoApply = FALSE;
7246: else
7247: {
1.340 quint 7248: /* Store the element type contained in the rightmost part of
7249: the selector */
7250: ctxt->schema = elType.ElSSchema;
1.327 vatton 7251: ctxt->type = elType.ElTypeNum;
7252: ctxt->name[0] = elType.ElTypeNum;
1.340 quint 7253: ctxt->rel[0] = RelVoid;
1.327 vatton 7254: }
7255: }
1.340 quint 7256: else
7257: /* not the rightmost part of the selector */
1.327 vatton 7258: {
1.340 quint 7259: if (elType.ElTypeNum != 0)
7260: ctxt->name[i] = elType.ElTypeNum;
7261: #ifdef XML_GENERIC
7262: else if (xmlType == XML_TYPE)
1.327 vatton 7263: {
1.340 quint 7264: TtaGetXmlElementType (names[i], &elType, NULL, doc);
7265: if (elType.ElTypeNum == 0)
1.327 vatton 7266: {
1.340 quint 7267: /* Creation of a new element type in the main schema */
7268: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7269: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.327 vatton 7270: }
1.340 quint 7271: if (elType.ElTypeNum != 0)
7272: ctxt->name[i] = elType.ElTypeNum;
1.327 vatton 7273: }
1.340 quint 7274: #endif /* XML_GENERIC */
1.327 vatton 7275: }
1.340 quint 7276: }
7277:
7278: /* store attribute information for this element */
7279: while (j < nbattrs && attrlevels[j] <= i)
7280: {
7281: if (attrnames[j] || attrnums[j])
1.327 vatton 7282: {
1.340 quint 7283: if (attrnums[j] > 0)
1.327 vatton 7284: {
1.340 quint 7285: if (attrnums[j] == ATTR_CLASS)
1.327 vatton 7286: {
1.340 quint 7287: if (xmlType == SVG_TYPE)
7288: ctxt->attrType[j] = SVG_ATTR_class;
7289: else if (xmlType == MATH_TYPE)
7290: ctxt->attrType[j] = MathML_ATTR_class;
7291: else if (xmlType == XHTML_TYPE)
7292: ctxt->attrType[j] = HTML_ATTR_Class;
1.327 vatton 7293: else
1.119 vatton 7294: #ifdef XML_GENERIC
1.340 quint 7295: ctxt->attrType[j] = XML_ATTR_class;
1.107 cvs 7296: #else /* XML_GENERIC */
1.340 quint 7297: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 7298: #endif /* XML_GENERIC */
1.340 quint 7299: }
7300: else if (attrnums[j] == ATTR_PSEUDO)
7301: {
7302: if (xmlType == SVG_TYPE)
7303: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
7304: else if (xmlType == MATH_TYPE)
7305: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
7306: else if (xmlType == XHTML_TYPE)
7307: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
7308: else
1.119 vatton 7309: #ifdef XML_GENERIC
1.340 quint 7310: ctxt->attrType[j] = XML_ATTR_PseudoClass;
1.107 cvs 7311: #else /* XML_GENERIC */
1.340 quint 7312: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 7313: #endif /* XML_GENERIC */
1.340 quint 7314: }
7315: else if (attrnums[j] == ATTR_ID)
7316: {
7317: if (xmlType == SVG_TYPE)
7318: ctxt->attrType[j] = SVG_ATTR_id;
7319: else if (xmlType == MATH_TYPE)
7320: ctxt->attrType[j] = MathML_ATTR_id;
7321: else if (xmlType == XHTML_TYPE)
7322: ctxt->attrType[j] = HTML_ATTR_ID;
7323: else
1.119 vatton 7324: #ifdef XML_GENERIC
1.340 quint 7325: ctxt->attrType[j] = XML_ATTR_xmlid;
1.107 cvs 7326: #else /* XML_GENERIC */
1.340 quint 7327: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 7328: #endif /* XML_GENERIC */
1.340 quint 7329: }
7330: attrType.AttrTypeNum = ctxt->attrType[j];
7331: attrType.AttrSSchema = ctxt->schema;
7332: }
7333: else if (attrnames[j])
7334: {
7335: if (xmlType == XML_TYPE)
7336: {
7337: if (ctxt->schema)
7338: attrType.AttrSSchema = ctxt->schema;
7339: else
7340: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7341: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7342: att = attrType.AttrTypeNum;
7343: if (ctxt->schema == NULL && att != 0)
7344: ctxt->schema = attrType.AttrSSchema;
7345: }
7346: else
7347: {
7348: MapXMLAttribute (xmlType, attrnames[j], names[i], &level,
7349: doc, &att);
7350: if (ctxt->schema == NULL && att != 0)
7351: ctxt->schema = TtaGetDocumentSSchema (doc);
7352: }
1.393 quint 7353: if (att == 0 && xmlType != XML_TYPE)
1.340 quint 7354: /* Attribute name not found: Search in the list of all
7355: schemas loaded for this document */
7356: {
7357: attrType.AttrSSchema = NULL;
7358: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7359: att = attrType.AttrTypeNum;
7360: if (att != 0)
1.393 quint 7361: {
7362: ctxt->schema = attrType.AttrSSchema;
7363: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
7364: }
1.340 quint 7365: }
7366: attrType.AttrSSchema = ctxt->schema;
7367: attrType.AttrTypeNum = att;
1.412 vatton 7368: if ((i == 0 || xmlType == XML_TYPE) && att == 0)
1.340 quint 7369: {
1.119 vatton 7370: #ifdef XML_GENERIC
1.393 quint 7371: if (xmlType == XML_TYPE)
1.340 quint 7372: {
7373: /* The attribute is not yet present in the tree */
7374: /* Create a new global attribute */
7375: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7376: TtaAppendXmlAttribute (attrnames[j], &attrType, doc);
1.393 quint 7377: att = attrType.AttrTypeNum;
1.340 quint 7378: }
7379: #endif /* XML_GENERIC */
7380: if (attrType.AttrSSchema == NULL)
7381: /* cannot apply these CSS rules */
7382: DoApply = FALSE;
7383: else if (elType.ElSSchema)
7384: ctxt->schema = elType.ElSSchema;
7385: else
7386: ctxt->schema = attrType.AttrSSchema;
7387: }
7388: if (att == 0)
7389: {
7390: CSSPrintError ("Unknown attribute", attrnames[j]);
7391: DoApply = FALSE;
7392: }
7393: else
1.345 quint 7394: {
7395: ctxt->attrType[j] = att;
7396: if (att == DummyAttribute && !strcmp (schemaName,"HTML"))
7397: /* it's the "type" attribute for an "input" element.
7398: In the tree, it is represented by the element type,
7399: not by an attribute */
7400: {
7401: ctxt->attrType[j] = 0;
7402: if (attrvals[j] && attrmatch[i] == Txtmatch)
7403: /* a value is specified for attribute type. This
7404: value provides the Thot element type */
7405: {
7406: MapXMLAttributeValue (xmlType, attrvals[j],
7407: &attrType, &kind);
7408: /* attrType contains the element type */
7409: if (i == 0)
7410: ctxt->type = kind;
7411: ctxt->name[i] = kind;
7412: }
7413: }
7414: }
1.340 quint 7415: }
7416: if (ctxt->attrType[j])
1.327 vatton 7417: {
1.340 quint 7418: /* check the attribute type */
7419: if (!strcmp (schemaName, "HTML"))
7420: xmlType = XHTML_TYPE;
7421: else if (!strcmp (schemaName, "MathML"))
7422: xmlType = MATH_TYPE;
7423: else if (!strcmp (schemaName, "SVG"))
7424: xmlType = SVG_TYPE;
7425: else if (!strcmp (schemaName, "XLink"))
7426: xmlType = XLINK_TYPE;
7427: else if (!strcmp (schemaName, "Annot"))
7428: xmlType = ANNOT_TYPE;
7429: else
7430: xmlType = XML_TYPE;
7431: kind = TtaGetAttributeKind (attrType);
7432: if (kind == 0 && attrvals[j])
7433: {
7434: /* enumerated value */
7435: MapXMLAttributeValue (xmlType, attrvals[j], &attrType,
7436: &kind);
7437: /* store the attribute value */
7438: ctxt->attrText[j] = (char *) kind;
7439: }
7440: else
7441: ctxt->attrText[j] = attrvals[j];
7442: /* update attrLevel */
7443: ctxt->attrMatch[j] = attrmatch[j];
7444: ctxt->attrLevel[j] = attrlevels[j];
7445: }
7446: j++;
1.327 vatton 7447: }
7448: }
1.340 quint 7449: /* add a new entry */
1.25 cvs 7450: i++;
1.119 vatton 7451: if (i == 1 && ctxt->schema == NULL)
1.327 vatton 7452: /* use the document schema */
7453: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 7454: }
1.340 quint 7455:
1.312 quint 7456: ctxt->important = FALSE;
1.117 vatton 7457: /* set the selector specificity */
7458: ctxt->cssSpecificity = specificity;
1.25 cvs 7459: /* Get the schema name of the main element */
1.119 vatton 7460: schemaName = TtaGetSSchemaName (ctxt->schema);
7461: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 7462: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.217 vatton 7463: skippedNL = NewLineSkipped;
1.380 vatton 7464: if (DoApply && tsch && cssRule)
1.317 vatton 7465: {
7466: if (css)
1.327 vatton 7467: {
7468: /* point the right URL for loaded images */
7469: saveURL = css->url;
7470: css->url = url;
7471: }
1.317 vatton 7472: else
1.327 vatton 7473: saveURL = NULL;
7474: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.317 vatton 7475: if (css)
1.327 vatton 7476: /* restore previous url */
7477: css->url = saveURL;
1.317 vatton 7478: }
1.116 vatton 7479: /* future CSS rules should apply */
7480: DoApply = TRUE;
1.217 vatton 7481: if (selector)
7482: NewLineSkipped = skippedNL;
1.1 cvs 7483: return (selector);
7484: }
7485:
7486: /*----------------------------------------------------------------------
1.206 vatton 7487: ParseStyleDeclaration: parse a style declaration stored in the style
7488: element of a document
7489: We expect the style string to be of the form:
7490: .pinky, .awful { color: pink; font-family: helvetica }
1.231 vatton 7491: The parameter css points to the current CSS context.
7492: The parameter link points to the link element.
7493: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 7494: ----------------------------------------------------------------------*/
1.206 vatton 7495: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
1.327 vatton 7496: CSSInfoPtr css, Element link, char *url,
7497: ThotBool destroy)
1.1 cvs 7498: {
1.79 cvs 7499: GenericContext ctxt;
7500: char *decl_end;
7501: char *sel_end;
7502: char *selector;
1.1 cvs 7503:
7504: /* separate the selectors string */
1.82 cvs 7505: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 7506: decl_end = cssRule;
1.82 cvs 7507: while (*decl_end != EOS && *decl_end != '{')
1.286 quint 7508: {
7509: if (*decl_end == EOL)
1.327 vatton 7510: NewLineSkipped++;
1.286 quint 7511: decl_end++;
7512: }
1.82 cvs 7513: if (*decl_end == EOS)
1.86 cvs 7514: {
1.168 vatton 7515: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 7516: return;
7517: }
1.1 cvs 7518: /* verify and clean the selector string */
7519: sel_end = decl_end - 1;
1.82 cvs 7520: while (*sel_end == SPACE || *sel_end == BSPACE ||
1.411 vatton 7521: *sel_end == EOL || *sel_end == __CR__)
1.1 cvs 7522: sel_end--;
7523: sel_end++;
1.82 cvs 7524: *sel_end = EOS;
1.1 cvs 7525: selector = cssRule;
7526:
7527: /* now, deal with the content ... */
7528: decl_end++;
7529: cssRule = decl_end;
1.137 vatton 7530: decl_end = &cssRule[strlen (cssRule) - 1];
1.398 vatton 7531: if (*decl_end != '{' && *decl_end != EOS)
1.137 vatton 7532: *decl_end = EOS;
1.1 cvs 7533: /*
7534: * parse the style attribute string and install the corresponding
7535: * presentation attributes on the new element
7536: */
7537: ctxt = TtaGetGenericStyleContext (doc);
7538: if (ctxt == NULL)
7539: return;
7540: ctxt->destroy = destroy;
1.207 vatton 7541: /* first use of the context */
7542: ctxt->uses = 1;
1.197 vatton 7543: while (selector && *selector != EOS)
1.363 vatton 7544: {
7545: if (ctxt->uses > 1)
7546: {
7547: /* this context is waiting for a callback */
7548: ctxt = TtaGetGenericStyleContext (doc);
7549: if (ctxt == NULL)
7550: return;
7551: ctxt->destroy = destroy;
7552: /* first use of the context */
7553: ctxt->uses = 1;
7554: }
7555: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css,
7556: link, url);
7557: }
1.207 vatton 7558: /* check if the context can be freed */
7559: ctxt->uses -= 1;
7560: if (ctxt->uses == 0)
7561: /* no image loading */
7562: TtaFreeMemory (ctxt);
1.1 cvs 7563: }
7564:
7565: /************************************************************************
7566: * *
7567: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
7568: * *
7569: ************************************************************************/
7570:
7571: /*----------------------------------------------------------------------
1.327 vatton 7572: IsImplicitClassName: return wether the Class name is an
7573: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
7574: or an HTML context name.
1.1 cvs 7575: ----------------------------------------------------------------------*/
1.248 gully 7576: int IsImplicitClassName (char *class_, Document doc)
1.1 cvs 7577: {
1.327 vatton 7578: char name[200];
7579: char *cur = name;
7580: char *first;
7581: char save;
7582: SSchema schema;
7583:
7584: /* make a local copy */
7585: strncpy (name, class_, 199);
7586: name[199] = 0;
7587:
7588: /* loop looking if each word is a GI */
7589: while (*cur != 0)
7590: {
7591: first = cur;
7592: cur = SkipWord (cur);
7593: save = *cur;
7594: *cur = 0;
7595: schema = NULL;
7596: if (MapGI (first, &schema, doc) == -1)
7597: {
7598: return (0);
7599: }
7600: *cur = save;
7601: cur = SkipBlanksAndComments (cur);
7602: }
7603: return (1);
1.1 cvs 7604: }
7605:
7606: /************************************************************************
1.114 quint 7607: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 7608: ************************************************************************/
7609:
7610: /*----------------------------------------------------------------------
1.409 vatton 7611: SetBodyAbsolutePosition:
7612: ----------------------------------------------------------------------*/
7613: void SetBodyAbsolutePosition (Document doc)
7614: {
7615: Element root, body;
7616: ElementType elType;
7617:
7618: if (DocumentTypes[doc] != docHTML)
7619: return;
7620: root = TtaGetMainRoot (doc);
7621: elType = TtaGetElementType(root);
7622: elType.ElTypeNum = HTML_EL_BODY;
7623: body = TtaSearchTypedElement (elType, SearchInTree, root);
7624: if (body)
1.410 vatton 7625: ParseHTMLSpecificStyle (body, (char *)"position:absolute", doc, 200, FALSE);
1.409 vatton 7626: }
7627:
7628: /*----------------------------------------------------------------------
1.327 vatton 7629: HTMLSetBackgroundColor:
1.1 cvs 7630: ----------------------------------------------------------------------*/
1.264 vatton 7631: void HTMLSetBackgroundColor (Document doc, Element el, int specificity,
1.327 vatton 7632: char *color)
1.1 cvs 7633: {
1.350 vatton 7634: char css_command[1000];
1.1 cvs 7635:
1.416 vatton 7636: snprintf (css_command, 1000, "background-color: %50s", color);
1.327 vatton 7637: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7638: }
7639:
7640: /*----------------------------------------------------------------------
1.327 vatton 7641: HTMLSetForegroundColor:
1.1 cvs 7642: ----------------------------------------------------------------------*/
1.264 vatton 7643: void HTMLSetForegroundColor (Document doc, Element el, int specificity,
1.327 vatton 7644: char *color)
1.1 cvs 7645: {
1.350 vatton 7646: char css_command[1000];
1.1 cvs 7647:
1.416 vatton 7648: snprintf (css_command, 1000, "color: %50s", color);
1.327 vatton 7649: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7650: }
7651:
7652: /*----------------------------------------------------------------------
1.327 vatton 7653: HTMLResetBackgroundColor:
1.1 cvs 7654: ----------------------------------------------------------------------*/
1.97 vatton 7655: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 7656: {
1.350 vatton 7657: char css_command[1000];
1.1 cvs 7658:
1.327 vatton 7659: sprintf (css_command, "background: red");
7660: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7661: }
7662:
7663: /*----------------------------------------------------------------------
1.327 vatton 7664: HTMLResetBackgroundImage:
1.1 cvs 7665: ----------------------------------------------------------------------*/
1.97 vatton 7666: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 7667: {
1.327 vatton 7668: char css_command[1000];
1.1 cvs 7669:
1.416 vatton 7670: snprintf (css_command, 1000, "background-image: url(xx); background-repeat: repeat");
1.327 vatton 7671: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7672: }
7673:
7674: /*----------------------------------------------------------------------
1.327 vatton 7675: HTMLResetForegroundColor:
1.1 cvs 7676: ----------------------------------------------------------------------*/
1.97 vatton 7677: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 7678: {
1.350 vatton 7679: char css_command[1000];
1.1 cvs 7680:
1.327 vatton 7681: /* it's not necessary to well know the current color but it must be valid */
7682: sprintf (css_command, "color: red");
7683: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7684: }
7685:
7686: /*----------------------------------------------------------------------
1.327 vatton 7687: HTMLSetAlinkColor:
1.1 cvs 7688: ----------------------------------------------------------------------*/
1.208 vatton 7689: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 7690: {
1.350 vatton 7691: char css_command[1000];
1.1 cvs 7692:
1.416 vatton 7693: snprintf (css_command, 1000, ":link { color: %50s }", color);
1.327 vatton 7694: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7695: }
7696:
7697: /*----------------------------------------------------------------------
1.327 vatton 7698: HTMLSetAactiveColor:
1.1 cvs 7699: ----------------------------------------------------------------------*/
1.208 vatton 7700: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 7701: {
1.350 vatton 7702: char css_command[1000];
1.1 cvs 7703:
1.416 vatton 7704: snprintf (css_command, 1000, ":active { color: %50s }", color);
1.327 vatton 7705: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7706: }
7707:
7708: /*----------------------------------------------------------------------
1.327 vatton 7709: HTMLSetAvisitedColor:
1.1 cvs 7710: ----------------------------------------------------------------------*/
1.208 vatton 7711: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 7712: {
1.350 vatton 7713: char css_command[1000];
1.1 cvs 7714:
1.416 vatton 7715: snprintf (css_command, 1000, ":visited { color: %50s }", color);
1.327 vatton 7716: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7717: }
7718:
7719: /*----------------------------------------------------------------------
1.327 vatton 7720: HTMLResetAlinkColor:
1.1 cvs 7721: ----------------------------------------------------------------------*/
1.208 vatton 7722: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 7723: {
1.350 vatton 7724: char css_command[1000];
1.1 cvs 7725:
1.327 vatton 7726: sprintf (css_command, ":link { color: red }");
7727: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7728: }
7729:
7730: /*----------------------------------------------------------------------
1.327 vatton 7731: HTMLResetAactiveColor:
1.1 cvs 7732: ----------------------------------------------------------------------*/
1.208 vatton 7733: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 7734: {
1.350 vatton 7735: char css_command[1000];
1.1 cvs 7736:
1.327 vatton 7737: sprintf (css_command, ":active { color: red }");
7738: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7739: }
7740:
7741: /*----------------------------------------------------------------------
1.327 vatton 7742: HTMLResetAvisitedColor:
1.1 cvs 7743: ----------------------------------------------------------------------*/
1.208 vatton 7744: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 7745: {
1.350 vatton 7746: char css_command[1000];
1.1 cvs 7747:
1.327 vatton 7748: sprintf (css_command, ":visited { color: red }");
7749: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7750: }
7751:
7752: /*----------------------------------------------------------------------
1.206 vatton 7753: ApplyCSSRules: parse a CSS Style description stored in the header of
7754: a HTML document.
1.1 cvs 7755: ----------------------------------------------------------------------*/
1.79 cvs 7756: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 7757: {
1.206 vatton 7758: CSSInfoPtr css;
7759: PInfoPtr pInfo;
1.207 vatton 7760: ThotBool loadcss;
7761:
7762: /* check if we have to load CSS */
7763: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
7764: if (!loadcss)
7765: return;
1.376 vatton 7766: LineNumber = TtaGetElementLineNumber (el);
1.206 vatton 7767: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 7768: if (css == NULL)
1.209 vatton 7769: {
7770: /* create the document css context */
7771: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
7772: pInfo = css->infos[doc];
7773: }
1.206 vatton 7774: else if (pInfo == NULL)
7775: /* create the entry into the css context */
7776: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 7777: if (pInfo->PiEnabled)
1.376 vatton 7778: ParseStyleDeclaration (el, cssRule, doc, css, el, NULL, destroy);
7779: LineNumber = -1;
1.1 cvs 7780: }
7781:
7782: /*----------------------------------------------------------------------
1.327 vatton 7783: ReadCSSRules: is the front-end function called by the document parser
7784: when detecting a <style type="text/css"> indicating it's the
7785: beginning of a CSS fragment or when reading a file .css.
1.1 cvs 7786:
1.327 vatton 7787: The CSS parser has to handle <!-- ... --> constructs used to
7788: prevent prehistoric browser from displaying the CSS as a text
7789: content. It will stop on any sequence "<x" where x is different
7790: from ! and will return x as to the caller. Theorically x should
7791: be equal to / for the </style> end of style.
7792: The parameter doc gives the document tree that contains CSS information.
7793: The parameter docRef gives the document to which CSS are to be applied.
7794: This function uses the current css context or creates it. It's able
7795: to work on the given buffer or call GetNextChar to read the parsed
7796: file.
7797: The parameter url gives the URL of the parsed style sheet.
7798: The parameter numberOfLinesRead gives the number of lines already
7799: read in the file.
7800: The parameter withUndo indicates whether the changes made in the document
7801: structure and content have to be registered in the Undo queue or not.
1.1 cvs 7802: ----------------------------------------------------------------------*/
1.133 vatton 7803: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.343 vatton 7804: int numberOfLinesRead, ThotBool withUndo, Element link)
1.1 cvs 7805: {
1.6 cvs 7806: DisplayMode dispMode;
1.206 vatton 7807: CSSInfoPtr refcss = NULL;
1.321 vatton 7808: CSSmedia css_media = CSS_ALL;
1.206 vatton 7809: PInfoPtr pInfo;
1.321 vatton 7810: char c;
1.138 vatton 7811: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 7812: int index;
1.1 cvs 7813: int CSSindex;
1.327 vatton 7814: int CSScomment;
1.1 cvs 7815: int import;
1.358 quint 7816: int openBlock;
1.93 vatton 7817: int newlines;
1.358 quint 7818: int page;
1.14 cvs 7819: ThotBool HTMLcomment;
1.342 vatton 7820: ThotBool toParse, eof, quoted, s_quoted;
1.358 quint 7821: ThotBool ignore, media, lineComment;
1.234 vatton 7822: ThotBool noRule, ignoreImport, fontface;
1.1 cvs 7823:
1.327 vatton 7824: CSScomment = MAX_CSS_LENGTH;
1.1 cvs 7825: HTMLcomment = FALSE;
7826: CSSindex = 0;
7827: toParse = FALSE;
7828: noRule = FALSE;
1.234 vatton 7829: media = FALSE;
1.88 cvs 7830: ignoreImport = FALSE;
1.342 vatton 7831: ignore = lineComment = FALSE;
1.358 quint 7832: page = 0;
1.342 vatton 7833: quoted = s_quoted = FALSE;
1.234 vatton 7834: fontface = FALSE;
1.1 cvs 7835: eof = FALSE;
1.358 quint 7836: openBlock = 0;
1.234 vatton 7837: import = MAX_CSS_LENGTH;
1.82 cvs 7838: c = SPACE;
1.1 cvs 7839: index = 0;
1.134 vatton 7840: base = NULL;
1.310 vatton 7841: /* entering the CSS parsing */
1.311 vatton 7842: Style_parsing++;
1.93 vatton 7843: /* number of new lines parsed */
7844: newlines = 0;
1.6 cvs 7845: /* avoid too many redisplay */
7846: dispMode = TtaGetDisplayMode (docRef);
7847: if (dispMode == DisplayImmediately)
7848: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 7849:
7850: /* look for the CSS context */
7851: if (css == NULL)
1.206 vatton 7852: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 7853: else
7854: pInfo = css->infos[docRef];
1.18 cvs 7855: if (css == NULL)
1.206 vatton 7856: {
7857: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
7858: pInfo = css->infos[docRef];
7859: }
7860: else if (pInfo == NULL)
7861: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 7862: /* look for the CSS descriptor that points to the extension schema */
7863: refcss = css;
1.224 vatton 7864: if (pInfo && pInfo->PiCategory == CSS_IMPORT)
1.173 cvs 7865: {
1.206 vatton 7866: while (refcss &&
1.327 vatton 7867: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
7868: refcss = refcss->NextCSS;
1.206 vatton 7869: if (refcss)
1.327 vatton 7870: pInfo = refcss->infos[docRef];
1.173 cvs 7871: }
7872:
1.343 vatton 7873: /* register parsed CSS file and the document to which CSS are to be applied */
1.395 vatton 7874: if (DocumentMeta[docRef] == NULL || DocumentMeta[docRef]->method != CE_MAKEBOOK)
7875: ParsedDoc = docRef;
7876: else
7877: ParsedDoc = 0;
1.343 vatton 7878: /* clean up the list of classes */
7879: TtaFreeMemory (refcss->class_list);
7880: refcss->class_list = NULL;
1.133 vatton 7881: if (url)
1.348 vatton 7882: Error_DocURL = url;
1.86 cvs 7883: else
7884: /* the CSS source in within the document itself */
1.348 vatton 7885: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 7886: LineNumber = numberOfLinesRead + 1;
1.93 vatton 7887: NewLineSkipped = 0;
1.217 vatton 7888: newlines = 0;
1.392 carcone 7889:
7890: /* Search for an UTF-8 BOM character (EF BB BF) */
7891: if (index == 0 && strlen(buffer) > 2 &&
7892: (unsigned char) buffer[0] == 0xEF &&
7893: (unsigned char) buffer[1] == 0xBB &&
7894: (unsigned char) buffer[2] == 0xBF)
7895: {
7896: index = 3;
7897: }
7898:
7899: /* Search for an UTF-16 Big Endian BOM character (FE FF) */
7900: if (index == 0 && strlen(buffer) > 1 &&
7901: (unsigned char) buffer[0] == 0xFE &&
7902: (unsigned char) buffer[1] == 0xFF)
7903: {
7904: index = 2;
7905: }
7906:
7907: /* Search for an UTF-16 Little Endian BOM character (FF FE) */
7908: if (index == 0 && strlen(buffer) > 1 &&
7909: (unsigned char) buffer[0] == 0xFF &&
7910: (unsigned char) buffer[1] == 0xFE)
7911: {
7912: index = 2;
7913: }
7914:
1.82 cvs 7915: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
7916: {
7917: c = buffer[index++];
7918: eof = (c == EOS);
7919: CSSbuffer[CSSindex] = c;
1.342 vatton 7920: if (!lineComment &&
7921: (CSScomment == MAX_CSS_LENGTH || c == '*' || c == '/' || c == '<' || c == EOL))
1.327 vatton 7922: {
7923: /* we're not within a comment or we're parsing * or / */
7924: switch (c)
7925: {
7926: case '@': /* perhaps an import primitive */
1.342 vatton 7927: if (!fontface && !page && !quoted && !s_quoted)
1.327 vatton 7928: import = CSSindex;
7929: break;
7930: case ';':
1.342 vatton 7931: if (!quoted && !s_quoted && !media && import != MAX_CSS_LENGTH)
1.327 vatton 7932: {
7933: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
7934: /* it's not an import */
7935: import = MAX_CSS_LENGTH;
7936: /* save the text */
7937: noRule = TRUE;
7938: }
7939: break;
7940: case '*':
1.342 vatton 7941: if (!quoted && !s_quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.327 vatton 7942: CSSbuffer[CSSindex - 1] == '/')
7943: /* start a comment */
7944: CSScomment = CSSindex - 1;
7945: break;
7946: case '/':
1.342 vatton 7947: if (!quoted && !s_quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.399 vatton 7948: CSSbuffer[CSSindex - 1] == '*' && CSSindex != CSScomment + 2)
1.327 vatton 7949: {
7950: while (CSSindex > 0 && CSSindex >= CSScomment)
7951: {
7952: if ( CSSbuffer[CSSindex] == EOL)
7953: {
7954: LineNumber ++;
7955: newlines --;
7956: }
7957: CSSindex--;
7958: }
7959: CSSindex = CSScomment - 1; /* will be incremented later */
7960: CSScomment = MAX_CSS_LENGTH;
7961: /* clean up the buffer */
7962: if (newlines && CSSindex > 0)
7963: while (CSSindex > 0 &&
7964: (CSSbuffer[CSSindex] == SPACE ||
7965: CSSbuffer[CSSindex] == BSPACE ||
7966: CSSbuffer[CSSindex] == EOL ||
7967: CSSbuffer[CSSindex] == TAB ||
7968: CSSbuffer[CSSindex] == __CR__))
7969: {
7970: if ( CSSbuffer[CSSindex] == EOL)
7971: {
7972: LineNumber ++;
7973: newlines --;
7974: }
7975: CSSindex--;
7976: }
7977: }
1.342 vatton 7978: else if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7979: CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
7980: CSSbuffer[CSSindex - 1] == '<')
7981: {
7982: /* this is the closing tag ! */
7983: CSSindex -= 2; /* remove </ from the CSS string */
7984: noRule = TRUE;
1.342 vatton 7985: }
7986: else if (!quoted && !s_quoted &&
7987: (CSSindex == 1 || (CSSindex > 1 && CSSbuffer[CSSindex - 2] == EOL)) &&
7988: CSScomment == MAX_CSS_LENGTH &&
7989: CSSbuffer[CSSindex - 1] == '/')
7990: {
7991: CSSindex--;
7992: lineComment = TRUE;
7993: }
7994:
1.327 vatton 7995: break;
7996: case '<':
1.342 vatton 7997: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7998: CSScomment == MAX_CSS_LENGTH)
7999: {
8000: /* only if we're not parsing a comment */
8001: c = buffer[index++];
8002: eof = (c == EOS);
8003: if (c == '!')
8004: {
8005: /* CSS within an HTML comment */
8006: HTMLcomment = TRUE;
8007: CSSindex++;
8008: CSSbuffer[CSSindex] = c;
8009: }
8010: else if (c == EOS)
8011: CSSindex++;
8012: }
8013: break;
8014: case '-':
1.342 vatton 8015: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 8016: CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
8017: HTMLcomment)
8018: /* CSS within an HTML comment */
8019: noRule = TRUE;
8020: break;
8021: case '>':
1.342 vatton 8022: if (!fontface && !page && !quoted && !s_quoted && HTMLcomment)
1.327 vatton 8023: noRule = TRUE;
8024: break;
8025: case ' ':
1.358 quint 8026: if (!quoted && !s_quoted && import != MAX_CSS_LENGTH && openBlock == 0)
1.327 vatton 8027: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
8028: break;
8029: case '{':
1.342 vatton 8030: if (!quoted && !s_quoted)
1.327 vatton 8031: {
1.358 quint 8032: openBlock++;
1.327 vatton 8033: if (import != MAX_CSS_LENGTH)
8034: {
1.358 quint 8035: if (openBlock == 1 && media)
1.327 vatton 8036: {
8037: /* is it the screen concerned? */
8038: CSSbuffer[CSSindex+1] = EOS;
8039: css_media = CheckMediaCSS (&CSSbuffer[import+7]);
8040: if (TtaIsPrinting ())
8041: ignore = (css_media != CSS_ALL && css_media != CSS_PRINT);
8042: else
8043: ignore = (css_media != CSS_ALL && css_media != CSS_SCREEN);
8044: noRule = TRUE;
8045: }
8046: else if (!strncasecmp (&CSSbuffer[import+1], "page", 4))
1.358 quint 8047: /* it is a @page block */
1.327 vatton 8048: {
1.358 quint 8049: page = openBlock;/*remember the level of this block*/
1.327 vatton 8050: noRule = TRUE;
8051: }
8052: else if (!strncasecmp (&CSSbuffer[import+1], "font-face", 9))
8053: {
8054: fontface = TRUE;
8055: noRule = TRUE;
8056: }
8057: }
8058: }
8059: break;
8060: case '}':
1.342 vatton 8061: if (!quoted && !s_quoted)
1.327 vatton 8062: {
1.358 quint 8063: if (page == openBlock)
8064: /* closing the @page block */
1.327 vatton 8065: {
8066: noRule = TRUE;
1.358 quint 8067: page = 0; /* close the page section */
1.327 vatton 8068: }
8069: else if (fontface)
8070: {
8071: noRule = TRUE;
8072: fontface = FALSE; /* close the fontface section */
8073: }
1.358 quint 8074: else if (openBlock == 1 && import != MAX_CSS_LENGTH)
1.327 vatton 8075: {
8076: import = MAX_CSS_LENGTH;
8077: noRule = TRUE;
8078: ignore = FALSE;
8079: media = FALSE;
8080: }
1.358 quint 8081: else if (!page)
1.327 vatton 8082: toParse = TRUE;
1.358 quint 8083: openBlock--;
1.327 vatton 8084: }
8085: break;
8086: case '"':
8087: if (quoted)
8088: {
1.342 vatton 8089: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
1.327 vatton 8090: quoted = FALSE;
8091: }
1.342 vatton 8092: else if (!s_quoted)
1.327 vatton 8093: quoted = TRUE;
8094: break;
1.342 vatton 8095: case '\'':
8096: if (s_quoted)
8097: {
8098: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
8099: s_quoted = FALSE;
8100: }
8101: else if (!quoted)
8102: s_quoted = TRUE;
8103: break;
8104: default:
1.327 vatton 8105: if (c == EOL)
8106: {
8107: newlines++;
8108: }
8109: break;
8110: }
1.82 cvs 8111: }
1.93 vatton 8112: else if (c == EOL)
1.327 vatton 8113: {
8114: LineNumber++;
1.342 vatton 8115: lineComment = FALSE;
1.411 vatton 8116: c = __CR__;
1.327 vatton 8117: }
1.234 vatton 8118:
1.411 vatton 8119: if (!lineComment && c != __CR__)
1.327 vatton 8120: CSSindex++;
1.82 cvs 8121:
8122: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
1.327 vatton 8123: /* we're still parsing a comment: remove the text comment */
8124: CSSindex = CSScomment;
1.82 cvs 8125:
8126: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
1.327 vatton 8127: {
8128: CSSbuffer[CSSindex] = EOS;
8129: /* parse a not empty string */
8130: if (CSSindex > 0)
8131: {
1.50 cvs 8132: /* apply CSS rule if it's not just a saving of text */
1.234 vatton 8133: if (!noRule && !ignore)
1.327 vatton 8134: {
8135: /* future import rules must be ignored */
8136: ignoreImport = TRUE;
8137: NewLineSkipped = 0;
8138: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
8139: pInfo->PiLink, url, FALSE);
8140: LineNumber += newlines;
8141: newlines = 0;
8142: }
1.82 cvs 8143: else if (import != MAX_CSS_LENGTH &&
1.327 vatton 8144: !strncasecmp (&CSSbuffer[import+1], "import", 6))
8145: {
8146: /* import section */
8147: cssRule = &CSSbuffer[import+7];
1.405 kia 8148: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8149: /* save the current line number */
8150: newlines += LineNumber;
8151: if (!strncasecmp (cssRule, "url", 3))
8152: {
1.50 cvs 8153: cssRule = &cssRule[3];
1.405 kia 8154: cssRule = (char*)TtaSkipBlanks (cssRule);
1.82 cvs 8155: if (*cssRule == '(')
1.327 vatton 8156: {
8157: cssRule++;
1.405 kia 8158: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8159: quoted = (*cssRule == '"' || *cssRule == '\'');
8160: if (quoted)
8161: cssRule++;
8162: base = cssRule;
8163: while (*cssRule != EOS && *cssRule != ')')
8164: cssRule++;
8165: if (quoted)
8166: {
8167: /* isolate the file name */
8168: cssRule[-1] = EOS;
8169: quoted = FALSE;
8170: }
8171: else
8172: {
8173: /* remove extra spaces */
8174: if (cssRule[-1] == SPACE)
8175: {
8176: *cssRule = SPACE;
8177: cssRule--;
8178: while (cssRule[-1] == SPACE)
8179: cssRule--;
8180: }
8181: }
8182: *cssRule = EOS;
8183: }
8184: }
8185: else if (*cssRule == '"')
8186: {
8187: /*
8188: Do we have to accept single quotes?
8189: Double quotes are accepted here.
8190: Escaped quotes are not handled. See function SkipQuotedString
8191: */
8192: cssRule++;
1.405 kia 8193: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8194: base = cssRule;
8195: while (*cssRule != EOS &&
8196: (*cssRule != '"' ||
8197: (*cssRule == '"' && cssRule[-1] == '\\')))
8198: cssRule++;
8199: /* isolate the file name */
8200: *cssRule = EOS;
8201: }
8202: /* check if a media is defined */
8203: cssRule++;
1.405 kia 8204: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8205: if (*cssRule != ';')
8206: {
8207: css_media = CheckMediaCSS (cssRule);
8208: if (TtaIsPrinting ())
8209: ignoreImport = (css_media != CSS_ALL && css_media != CSS_PRINT);
8210: else
8211: ignoreImport = (css_media != CSS_ALL && css_media != CSS_SCREEN);
8212: }
8213: if (!ignoreImport)
8214: {
8215: /* save the displayed URL when an error is reported */
1.348 vatton 8216: saveDocURL = Error_DocURL;
1.327 vatton 8217: ptr = TtaStrdup (base);
8218: /* get the CSS URI in UTF-8 */
8219: /*ptr = ReallocUTF8String (ptr, docRef);*/
8220: LoadStyleSheet (base, docRef, (Element) css, css,
8221: url, pInfo->PiMedia,
8222: pInfo->PiCategory == CSS_USER_STYLE);
8223: /* restore the displayed URL when an error is reported */
1.348 vatton 8224: Error_DocURL = saveDocURL;
1.327 vatton 8225: TtaFreeMemory (ptr);
8226: }
8227: /* restore the number of lines */
8228: LineNumber = newlines;
8229: newlines = 0;
8230: NewLineSkipped = 0;
8231: import = MAX_CSS_LENGTH;
8232: }
8233: else
8234: {
8235: LineNumber += newlines;
8236: newlines = 0;
8237: }
8238: }
8239: toParse = FALSE;
8240: noRule = FALSE;
8241: CSSindex = 0;
1.50 cvs 8242: }
1.82 cvs 8243: }
1.310 vatton 8244: /* closing the CSS parsing */
1.311 vatton 8245: Style_parsing--;
1.330 cvs 8246: if (RedisplayImages == 0 && RedisplayBGImage && Style_parsing == 0)
1.310 vatton 8247: {
1.311 vatton 8248: /* CSS parsing finishes after a BG image was loaded */
1.310 vatton 8249: RedisplayBGImage = FALSE;
1.330 cvs 8250: if (dispMode != NoComputedDisplay)
8251: {
8252: //printf ("ReadCSS Show BGimages\n");
8253: TtaSetDisplayMode (docRef, NoComputedDisplay);
8254: TtaSetDisplayMode (docRef, dispMode);
8255: }
1.310 vatton 8256: }
1.330 cvs 8257: else if (dispMode != NoComputedDisplay)
1.311 vatton 8258: /* restore the display mode */
8259: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 8260:
8261: /* Prepare the context for style attributes */
1.348 vatton 8262: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 8263: LineNumber = -1;
1.1 cvs 8264: return (c);
8265: }
Webmaster