Annotation of Amaya/amaya/styleparser.c, revision 1.427
1.1 cvs 1: /*
2: *
1.420 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2009
1.1 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.164 quint 7:
1.1 cvs 8: /*
1.164 quint 9: * Everything directly related to the CSS syntax should now hopefully
1.1 cvs 10: * be contained in this module.
11: *
12: * Author: I. Vatton
13: *
14: */
15:
16: /* Included headerfiles */
17: #define THOT_EXPORT extern
18: #include "amaya.h"
19: #include "css.h"
1.25 cvs 20: #include "fetchHTMLname.h"
1.100 vatton 21: #include "SVG.h"
1.107 cvs 22: #include "XML.h"
1.141 cvs 23: #include "document.h"
1.1 cvs 24:
1.302 quint 25: typedef struct _CSSImageCallbackBlock
1.1 cvs 26: {
1.207 vatton 27: Element el;
28: PSchema tsch;
29: CSSInfoPtr css;
30: PresentationContext ctxt;
1.302 quint 31: unsigned int ruleType;
1.1 cvs 32: }
1.302 quint 33: CSSImageCallbackBlock, *CSSImageCallbackPtr;
1.1 cvs 34:
35: #include "AHTURLTools_f.h"
36: #include "HTMLpresentation_f.h"
37: #include "HTMLimage_f.h"
1.406 quint 38: #include "HTMLtable_f.h"
1.1 cvs 39: #include "UIcss_f.h"
40: #include "css_f.h"
1.24 cvs 41: #include "fetchHTMLname_f.h"
1.91 cvs 42: #include "fetchXMLname_f.h"
1.1 cvs 43: #include "html2thot_f.h"
1.91 cvs 44: #include "init_f.h"
1.1 cvs 45: #include "styleparser_f.h"
1.424 quint 46: #include "SVGbuilder_f.h"
1.366 vatton 47: #include "wxdialogapi_f.h"
1.1 cvs 48:
49: #define MAX_BUFFER_LENGTH 200
50: /*
51: * A PropertyParser is a function used to parse the
52: * description substring associated to a given style attribute
1.59 cvs 53: * e.g.: "red" for a color attribute or "12pt bold helvetica"
1.1 cvs 54: * for a font attribute.
55: */
1.79 cvs 56: typedef char *(*PropertyParser) (Element element,
1.327 vatton 57: PSchema tsch,
58: PresentationContext context,
59: char *cssRule,
60: CSSInfoPtr css,
61: ThotBool isHTML);
1.1 cvs 62:
63: /* Description of the set of CSS properties supported */
64: typedef struct CSSProperty
1.327 vatton 65: {
1.405 kia 66: const char *name;
1.327 vatton 67: PropertyParser parsing_function;
68: }
1.1 cvs 69: CSSProperty;
70:
1.86 cvs 71: static int LineNumber = -1; /* The line where the error occurs */
1.93 vatton 72: static int NewLineSkipped = 0;
1.311 vatton 73: static int RedisplayImages = 0; /* number of BG images loading */
74: static int Style_parsing = 0; /* > 0 when parsing a set of CSS rules */
1.360 vatton 75: static char *ImportantPos = NULL;
1.310 vatton 76: static ThotBool RedisplayBGImage = FALSE; /* TRUE when a BG image is inserted */
1.116 vatton 77: static ThotBool DoApply = TRUE;
1.366 vatton 78: static ThotBool All_sides = FALSE; // TRUE when "boder valus must be displayed
79:
1.1 cvs 80:
81: /*----------------------------------------------------------------------
1.327 vatton 82: SkipWord:
1.1 cvs 83: ----------------------------------------------------------------------*/
1.79 cvs 84: static char *SkipWord (char *ptr)
1.1 cvs 85: {
1.402 vatton 86: while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '#' || *ptr == '%' || *ptr == '.')
1.168 vatton 87: ptr++;
1.1 cvs 88: return (ptr);
89: }
90:
91: /*----------------------------------------------------------------------
1.327 vatton 92: SkipBlanksAndComments:
1.13 cvs 93: ----------------------------------------------------------------------*/
1.82 cvs 94: char *SkipBlanksAndComments (char *ptr)
1.13 cvs 95: {
1.93 vatton 96: /* skip spaces */
1.155 cheyroul 97: while (*ptr == SPACE ||
1.327 vatton 98: *ptr == BSPACE ||
99: *ptr == EOL ||
100: *ptr == TAB ||
101: *ptr == __CR__)
1.93 vatton 102: {
103: if (*ptr == EOL)
1.327 vatton 104: /* increment the number of newline skipped */
105: NewLineSkipped++;
1.93 vatton 106: ptr++;
107: }
1.399 vatton 108: while (ptr[0] == '/' && ptr[1] == '*')
1.13 cvs 109: {
110: /* look for the end of the comment */
111: ptr = &ptr[2];
112: while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
1.327 vatton 113: ptr++;
1.13 cvs 114: if (ptr[0] != EOS)
1.327 vatton 115: ptr = &ptr[2];
1.93 vatton 116: /* skip spaces */
117: while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
1.327 vatton 118: *ptr == TAB || *ptr == __CR__)
119: {
120: if (*ptr == EOL)
121: /* increment the number of newline skipped */
122: NewLineSkipped++;
123: ptr++;
124: }
1.13 cvs 125: }
126: return (ptr);
127: }
128:
1.366 vatton 129:
130: /*----------------------------------------------------------------------
131: Number of values
132: ----------------------------------------------------------------------*/
133: static int NumberOfValues (char *ptr)
134: {
135: int n = 0;
1.402 vatton 136: while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != ',')
1.366 vatton 137: {
138: ptr = SkipBlanksAndComments (ptr);
139: n++;
140: ptr = SkipWord (ptr);
141: }
142: return n;
143: }
144:
1.49 cvs 145: /*----------------------------------------------------------------------
1.327 vatton 146: SkipQuotedString
1.1 cvs 147: ----------------------------------------------------------------------*/
1.79 cvs 148: static char *SkipQuotedString (char *ptr, char quote)
1.1 cvs 149: {
1.14 cvs 150: ThotBool stop;
1.1 cvs 151:
152: stop = FALSE;
153: while (!stop)
154: {
1.327 vatton 155: if (*ptr == quote)
156: {
157: ptr++;
158: stop = TRUE;
159: }
160: else if (*ptr == EOS)
161: stop = TRUE;
162: else if (*ptr == '\\')
163: /* escape character */
164: {
165: ptr++;
1.82 cvs 166: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
1.327 vatton 167: (*ptr >= 'a' && *ptr <= 'f'))
168: {
169: ptr++;
170: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
171: (*ptr >= 'a' && *ptr <= 'f'))
172: ptr++;
173: }
174: else
175: ptr++;
176: }
177: else
178: ptr++;
1.1 cvs 179: }
180: return (ptr);
181: }
182:
183: /*----------------------------------------------------------------------
1.327 vatton 184: CSSPrintError
185: print the error message msg on stderr.
186: When the line is 0 ask to expat the current line number
1.86 cvs 187: ----------------------------------------------------------------------*/
1.389 vatton 188: static void CSSPrintError (const char *msg, const char *value)
1.86 cvs 189: {
1.419 vatton 190: if (!IgnoreErrors && !DoDialog && !TtaIsPrinting () && ParsedDoc > 0)
1.86 cvs 191: {
192: if (!ErrFile)
1.327 vatton 193: {
194: if (OpenParsingErrors (ParsedDoc) == FALSE)
195: return;
196: }
1.86 cvs 197:
1.308 vatton 198: /* check if a CSS error file shoulb be updated too */
199: if (ParsedCSS > 0 && !CSSErrFile)
1.327 vatton 200: OpenParsingErrors (ParsedCSS);
1.308 vatton 201:
1.348 vatton 202: if (Error_DocURL)
1.327 vatton 203: {
1.348 vatton 204: fprintf (ErrFile, "\n*** Errors/warnings in %s\n", Error_DocURL);
1.327 vatton 205: /* set to NULL as long as the CSS file doesn't change */
1.348 vatton 206: Error_DocURL = NULL;
1.327 vatton 207: }
1.89 cvs 208: CSSErrorsFound = TRUE;
1.86 cvs 209: if (LineNumber < 0)
1.347 quint 210: {
211: if (value)
212: fprintf (ErrFile, " In style attribute, %s \"%s\"\n", msg, value);
213: else
214: fprintf (ErrFile, " In style attribute, %s\n", msg);
215: }
1.86 cvs 216: else
1.327 vatton 217: {
1.347 quint 218: if (value)
219: fprintf (ErrFile, "@ line %d: %s \"%s\"\n",
220: LineNumber+NewLineSkipped, msg, value);
221: else
222: fprintf (ErrFile, "@ line %d: %s\n", LineNumber+NewLineSkipped,
223: msg);
1.327 vatton 224: if (CSSErrFile)
1.347 quint 225: {
226: if (value)
227: fprintf (CSSErrFile, "@ line %d: %s \"%s\"\n",
228: LineNumber+NewLineSkipped, msg, value);
229: else
230: fprintf (CSSErrFile, "@ line %d: %s\n",
231: LineNumber+NewLineSkipped, msg);
232: }
1.327 vatton 233: }
1.86 cvs 234: }
235: }
236:
1.168 vatton 237: /*----------------------------------------------------------------------
1.327 vatton 238: CSSParseError
239: print the error message msg on stderr.
1.168 vatton 240: ----------------------------------------------------------------------*/
1.389 vatton 241: static void CSSParseError (const char *msg, const char *value, char *endvalue)
1.168 vatton 242: {
1.230 quint 243: char c = EOS;
1.168 vatton 244:
245: if (endvalue)
246: {
247: /* close the string here */
248: c = *endvalue;
249: *endvalue = EOS;
250: }
251: CSSPrintError (msg, value);
252: if (endvalue)
253: *endvalue = c;
254: }
255:
1.288 vatton 256: /*----------------------------------------------------------------------
1.342 vatton 257: SkipString move to the end of the string
258: ----------------------------------------------------------------------*/
259: static char *SkipString (char *ptr)
260: {
261: char c = *ptr;
262:
263: ptr++;
264: while (*ptr != EOS &&
265: (*ptr != c || (*ptr == c && ptr[-1] == '\\')))
266: ptr++;
267: return ptr;
268: }
269:
270: /*----------------------------------------------------------------------
1.327 vatton 271: CSSCheckEndValue
272: print an error message if another character is found
1.288 vatton 273: ----------------------------------------------------------------------*/
1.405 kia 274: static char *CSSCheckEndValue (char *cssRule, char *endvalue, const char *msg)
1.288 vatton 275: {
276: char c = EOS;
277: if (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.316 quint 278: *endvalue != ';' && *endvalue != '}' && *endvalue != EOL &&
279: *endvalue != TAB && *endvalue != __CR__)
1.288 vatton 280: {
281: while (*endvalue != EOS && *endvalue != SPACE && *endvalue != '/' &&
1.327 vatton 282: *endvalue != ';' && *endvalue != '}' && *endvalue != EOL &&
283: *endvalue != TAB && *endvalue != __CR__)
1.342 vatton 284: {
285: if (*endvalue == '"' || *endvalue == '\'')
286: endvalue = SkipString (endvalue);
287: if (*endvalue != EOS)
288: endvalue++;
289: }
1.288 vatton 290: /* close the string here */
291: c = *endvalue;
292: *endvalue = EOS;
293: CSSPrintError (msg, cssRule);
294: *endvalue = c;
295: }
296: return endvalue;
297: }
298:
1.89 cvs 299:
1.86 cvs 300: /*----------------------------------------------------------------------
1.327 vatton 301: SkipProperty skips a property and display and error message
1.86 cvs 302: ----------------------------------------------------------------------*/
1.234 vatton 303: static char *SkipProperty (char *ptr, ThotBool reportError)
1.86 cvs 304: {
305: char *deb;
306: char c;
1.404 vatton 307: ThotBool warn;
1.86 cvs 308:
1.404 vatton 309: // check if Amaya should report CSS warnings
310: TtaGetEnvBoolean ("CSS_WARN", &warn);
311: if (!warn)
312: reportError = FALSE;
1.86 cvs 313: deb = ptr;
1.301 vatton 314: while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '}')
1.133 vatton 315: {
1.342 vatton 316: if (*ptr == '"' || *ptr == '\'')
317: ptr = SkipString (ptr);
318: if (*ptr != EOS)
319: ptr++;
1.133 vatton 320: }
1.95 cvs 321: /* print the skipped property */
1.86 cvs 322: c = *ptr;
1.386 vatton 323: if (*ptr != EOS)
324: *ptr = EOS;
1.366 vatton 325: if (DoDialog)
326: DisplayStyleValue ("", deb, ptr);
327: else if (reportError && *deb != EOS &&
328: strncasecmp (deb, "azimuth", 7) &&
329: strncasecmp (deb, "border-collapse", 15) &&
330: strncasecmp (deb, "border-spacing", 14) &&
331: strncasecmp (deb, "caption-side", 12) &&
332: strncasecmp (deb, "clip", 4) &&
333: strncasecmp (deb, "counter-increment", 16) &&
334: strncasecmp (deb, "counter-reset", 13) &&
335: strncasecmp (deb, "cue-after", 9) &&
336: strncasecmp (deb, "cue-before", 10) &&
337: strncasecmp (deb, "cue", 3) &&
338: strncasecmp (deb, "cursor", 6) &&
339: strncasecmp (deb, "elevation", 9) &&
340: strncasecmp (deb, "empty-cells", 11) &&
341: strncasecmp (deb, "font-strech", 11) &&
342: strncasecmp (deb, "letter-spacing", 14) &&
343: strncasecmp (deb, "marker-offset", 12) &&
344: strncasecmp (deb, "orphans", 7) &&
345: strncasecmp (deb, "outline-color", 13) &&
346: strncasecmp (deb, "outline-style", 13) &&
347: strncasecmp (deb, "outline-width", 13) &&
348: strncasecmp (deb, "outline", 7) &&
349: strncasecmp (deb, "overflow", 8) &&
350: strncasecmp (deb, "pause-after", 11) &&
351: strncasecmp (deb, "pause-before", 12) &&
352: strncasecmp (deb, "pause", 5) &&
353: strncasecmp (deb, "quotes", 6) &&
354: strncasecmp (deb, "richness", 8) &&
355: strncasecmp (deb, "speech-rate", 11) &&
356: strncasecmp (deb, "speak-header", 12) &&
357: strncasecmp (deb, "speak-punctuation", 17) &&
358: strncasecmp (deb, "speak-numeral", 13) &&
359: strncasecmp (deb, "speak", 5) &&
360: strncasecmp (deb, "pitch-range", 11) &&
361: strncasecmp (deb, "pitch", 5) &&
362: strncasecmp (deb, "stress", 6) &&
363: strncasecmp (deb, "table-layout", 12) &&
364: strncasecmp (deb, "text-shadow", 11) &&
365: strncasecmp (deb, "voice-family", 12) &&
366: strncasecmp (deb, "volume", 6) &&
367: strncasecmp (deb, "widows", 6))
1.205 quint 368: CSSPrintError ("CSS property ignored:", deb);
1.386 vatton 369: if (c != EOS)
370: *ptr = c;
1.86 cvs 371: return (ptr);
372: }
373:
374: /*----------------------------------------------------------------------
1.327 vatton 375: SkipValue
376: skips the value and display an error message if msg is not NULL
1.1 cvs 377: ----------------------------------------------------------------------*/
1.405 kia 378: static char *SkipValue (const char *msg, char *ptr)
1.1 cvs 379: {
1.86 cvs 380: char *deb;
381: char c;
382:
383: deb = ptr;
1.387 quint 384: while (*ptr != EOS && *ptr != ';' && *ptr != '}' && *ptr != '\n')
1.133 vatton 385: {
1.342 vatton 386: if (*ptr == '"' || *ptr == '\'')
387: ptr = SkipString (ptr);
388: if (*ptr != EOS)
389: ptr++;
1.133 vatton 390: }
1.95 cvs 391: /* print the skipped property */
1.86 cvs 392: c = *ptr;
1.397 vatton 393: if (c != EOS)
394: *ptr = EOS;
1.168 vatton 395: if (msg && *deb != EOS && *deb != ',')
396: CSSPrintError (msg, deb);
1.397 vatton 397: if (c != EOS)
398: *ptr = c;
1.1 cvs 399: return (ptr);
400: }
401:
402: /*----------------------------------------------------------------------
1.327 vatton 403: ParseNumber:
404: parse a number and returns the corresponding value.
1.1 cvs 405: ----------------------------------------------------------------------*/
1.79 cvs 406: char *ParseNumber (char *cssRule, PresentationValue *pval)
1.1 cvs 407: {
408: int val = 0;
409: int minus = 0;
410: int valid = 0;
411: int f = 0;
1.14 cvs 412: ThotBool real = FALSE;
1.1 cvs 413:
1.184 vatton 414: pval->typed_data.unit = UNIT_REL;
1.1 cvs 415: pval->typed_data.real = FALSE;
1.82 cvs 416: cssRule = SkipBlanksAndComments (cssRule);
417: if (*cssRule == '-')
1.1 cvs 418: {
419: minus = 1;
420: cssRule++;
1.82 cvs 421: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 422: }
1.387 quint 423: else if (*cssRule == '+')
1.1 cvs 424: {
425: cssRule++;
1.82 cvs 426: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 427: }
428:
1.82 cvs 429: while ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 430: {
431: val *= 10;
1.82 cvs 432: val += *cssRule - '0';
1.1 cvs 433: cssRule++;
434: valid = 1;
435: }
436:
1.82 cvs 437: if (*cssRule == '.')
1.1 cvs 438: {
439: real = TRUE;
440: f = val;
441: val = 0;
442: cssRule++;
443: /* keep only 3 digits */
1.82 cvs 444: if (*cssRule >= '0' && *cssRule <= '9')
1.327 vatton 445: {
446: val = (*cssRule - '0') * 100;
447: cssRule++;
448: if (*cssRule >= '0' && *cssRule <= '9')
449: {
450: val += (*cssRule - '0') * 10;
451: cssRule++;
452: if ((*cssRule >= '0') && (*cssRule <= '9'))
453: {
454: val += *cssRule - '0';
455: cssRule++;
456: }
457: }
458:
459: while (*cssRule >= '0' && *cssRule <= '9')
460: cssRule++;
461: valid = 1;
462: }
1.1 cvs 463: }
464:
465: if (!valid)
466: {
1.184 vatton 467: pval->typed_data.unit = UNIT_INVALID;
1.1 cvs 468: pval->typed_data.value = 0;
469: }
470: else
471: {
472: pval->typed_data.real = real;
473: if (real)
1.327 vatton 474: {
475: if (minus)
476: pval->typed_data.value = -(f * 1000 + val);
477: else
478: pval->typed_data.value = f * 1000 + val;
479: }
1.1 cvs 480: else
1.327 vatton 481: {
482: if (minus)
483: pval->typed_data.value = -val;
484: else
485: pval->typed_data.value = val;
486: }
1.64 cvs 487: }
488: return (cssRule);
489: }
1.195 vatton 490:
1.155 cheyroul 491: /*----------------------------------------------------------------------
1.407 vatton 492: ParseCSSUnit a number followed by a CSS Unit and returns the corresponding
1.327 vatton 493: value and its unit.
1.64 cvs 494: ----------------------------------------------------------------------*/
1.82 cvs 495: char *ParseCSSUnit (char *cssRule, PresentationValue *pval)
1.64 cvs 496: {
1.368 vatton 497: char *p;
1.64 cvs 498: unsigned int uni;
499:
1.184 vatton 500: pval->typed_data.unit = UNIT_REL;
1.64 cvs 501: cssRule = ParseNumber (cssRule, pval);
1.184 vatton 502: if (pval->typed_data.unit == UNIT_INVALID)
1.387 quint 503: /* it does not start with a valid number */
1.327 vatton 504: cssRule = SkipWord (cssRule);
1.64 cvs 505: else
506: {
1.369 quint 507: /* is there a space after the number? */
1.368 vatton 508: p = cssRule;
1.82 cvs 509: cssRule = SkipBlanksAndComments (cssRule);
1.368 vatton 510: if (p == cssRule)
1.369 quint 511: /* no space */
1.368 vatton 512: p = NULL;
1.369 quint 513: else
514: /* a space is here. restore the pointer */
515: cssRule = p;
1.231 vatton 516: uni = 0;
517: while (CSSUnitNames[uni].sign)
1.327 vatton 518: {
519: if (!strncasecmp (CSSUnitNames[uni].sign, cssRule,
520: strlen (CSSUnitNames[uni].sign)))
1.369 quint 521: /* this is a correct unit */
1.327 vatton 522: {
523: pval->typed_data.unit = CSSUnitNames[uni].unit;
1.368 vatton 524: if (p)
1.369 quint 525: /* there was a space before the unit. Syntax error */
1.368 vatton 526: pval->typed_data.unit = UNIT_INVALID;
1.327 vatton 527: return (cssRule + strlen (CSSUnitNames[uni].sign));
528: }
529: else
530: uni++;
531: }
1.369 quint 532: /* not in the list of accepted units */
1.184 vatton 533: pval->typed_data.unit = UNIT_BOX;
1.1 cvs 534: }
535: return (cssRule);
536: }
537:
1.43 cvs 538: /*----------------------------------------------------------------------
1.327 vatton 539: ParseClampedUnit:
540: parse a CSS Unit substring and returns the corresponding value and unit.
541: [0,1]
1.239 vatton 542: ----------------------------------------------------------------------*/
543: char *ParseClampedUnit (char *cssRule, PresentationValue *pval)
544: {
1.251 vatton 545: char *p;
546:
547: p = cssRule;
1.239 vatton 548: cssRule = ParseNumber (cssRule, pval);
1.301 vatton 549: if (*cssRule != EOS && *cssRule != SPACE && *cssRule != ';' && *cssRule != '}')
1.418 quint 550: /* the value contains something after the number. Invalid */
1.239 vatton 551: {
1.251 vatton 552: cssRule++;
1.239 vatton 553: pval->typed_data.unit = UNIT_REL;
554: if (pval->typed_data.value > 100)
1.327 vatton 555: pval->typed_data.value = 1000;
1.239 vatton 556: else
1.327 vatton 557: pval->typed_data.value *= 10;
1.251 vatton 558: CSSParseError ("Invalid value", p, cssRule);
1.239 vatton 559: }
560: else
1.418 quint 561: /* it's a number. Check its value */
1.239 vatton 562: {
563: pval->typed_data.unit = UNIT_REL;
564: if (pval->typed_data.real)
1.327 vatton 565: pval->typed_data.real = FALSE;
1.239 vatton 566: else if (pval->typed_data.value > 1)
1.327 vatton 567: {
568: pval->typed_data.value = 1000;
569: CSSParseError ("Invalid value", p, cssRule);
570: }
1.251 vatton 571: else if (pval->typed_data.value < 0)
1.327 vatton 572: {
573: pval->typed_data.value = 0;
574: CSSParseError ("Invalid value", p, cssRule);
575: }
1.239 vatton 576: else
1.327 vatton 577: pval->typed_data.value *= 1000;
1.239 vatton 578: }
579: pval->data = pval->typed_data.value;
580: return (cssRule);
581: }
582:
583:
584: /*----------------------------------------------------------------------
1.327 vatton 585: ParseABorderValue
1.43 cvs 586: ----------------------------------------------------------------------*/
1.288 vatton 587: static char *ParseABorderValue (char *cssRule, PresentationValue *border)
1.43 cvs 588: {
1.288 vatton 589: char *ptr = cssRule;
1.168 vatton 590:
1.43 cvs 591: /* first parse the attribute string */
1.319 quint 592: border->typed_data.value = 0;
593: border->typed_data.unit = UNIT_INVALID;
594: border->typed_data.real = FALSE;
595: if (!strncasecmp (cssRule, "thin", 4))
596: {
597: border->typed_data.unit = UNIT_PX;
598: border->typed_data.value = 1;
599: cssRule += 4;
600: }
601: else if (!strncasecmp (cssRule, "medium", 6))
602: {
603: border->typed_data.unit = UNIT_PX;
604: border->typed_data.value = 3;
605: cssRule += 6;
606: }
607: else if (!strncasecmp (cssRule, "thick", 5))
608: {
609: border->typed_data.unit = UNIT_PX;
610: border->typed_data.value = 5;
611: cssRule += 5;
612: }
613: else if (!strncasecmp (cssRule, "inherit", 7))
614: {
615: border->typed_data.unit = VALUE_INHERIT;
616: cssRule += 7;
617: }
618: else if (isdigit (*cssRule) || *cssRule == '.')
619: {
620: cssRule = ParseCSSUnit (cssRule, border);
1.387 quint 621: if (border->typed_data.value == 0 &&
622: border->typed_data.unit != UNIT_INVALID)
1.327 vatton 623: border->typed_data.unit = UNIT_PX;
1.319 quint 624: else if (border->typed_data.unit == UNIT_INVALID ||
1.327 vatton 625: border->typed_data.unit == UNIT_BOX ||
626: border->typed_data.unit == UNIT_PERCENT)
627: {
628: border->typed_data.unit = UNIT_INVALID;
629: border->typed_data.value = 0;
630: CSSParseError ("Invalid border-width value", ptr, cssRule);
631: }
1.319 quint 632: }
633: return (cssRule);
1.43 cvs 634: }
635:
1.288 vatton 636:
637: /*----------------------------------------------------------------------
1.327 vatton 638: ParseBorderStyle
1.43 cvs 639: ----------------------------------------------------------------------*/
1.79 cvs 640: static char *ParseBorderStyle (char *cssRule, PresentationValue *border)
1.43 cvs 641: {
642: /* first parse the attribute string */
1.327 vatton 643: border->typed_data.value = 0;
644: border->typed_data.unit = UNIT_PX;
645: border->typed_data.real = FALSE;
646: if (!strncasecmp (cssRule, "none", 4))
647: {
648: border->typed_data.value = BorderStyleNone;
649: cssRule += 4;
650: }
651: else if (!strncasecmp (cssRule, "hidden", 6))
652: {
653: border->typed_data.value = BorderStyleHidden;
654: cssRule += 6;
655: }
656: else if (!strncasecmp (cssRule, "dotted", 6))
657: {
1.288 vatton 658: cssRule += 6;
1.327 vatton 659: border->typed_data.value = BorderStyleDotted;
1.288 vatton 660: }
1.327 vatton 661: else if (!strncasecmp (cssRule, "dashed", 6))
662: {
663: border->typed_data.value = BorderStyleDashed;
664: cssRule += 6;
665: }
666: else if (!strncasecmp (cssRule, "solid", 5))
667: {
668: border->typed_data.value = BorderStyleSolid;
669: cssRule += 5;
670: }
671: else if (!strncasecmp (cssRule, "double", 6))
672: {
673: border->typed_data.value = BorderStyleDouble;
674: cssRule += 6;
675: }
676: else if (!strncasecmp (cssRule, "groove", 6))
677: {
678: border->typed_data.value = BorderStyleGroove;
679: cssRule += 6;
680: }
681: else if (!strncasecmp (cssRule, "ridge", 5))
682: {
683: border->typed_data.value = BorderStyleRidge;
684: cssRule += 5;
685: }
686: else if (!strncasecmp (cssRule, "inset", 5))
687: {
688: border->typed_data.value = BorderStyleInset;
689: cssRule += 5;
690: }
691: else if (!strncasecmp (cssRule, "outset", 6))
692: {
693: border->typed_data.value = BorderStyleOutset;
694: cssRule += 6;
695: }
696: else
697: {
698: /* invalid style */
699: border->typed_data.unit = UNIT_INVALID;
700: return (cssRule);
701: }
702: return (cssRule);
1.43 cvs 703: }
704:
705: /*----------------------------------------------------------------------
1.327 vatton 706: ParseCSSColor: parse a CSS color attribute string
707: we expect the input string describing the attribute to be
708: either a color name, a 3 tuple or an hexadecimal encoding.
709: The color used will be approximed from the current color
710: table
1.43 cvs 711: ----------------------------------------------------------------------*/
1.79 cvs 712: static char *ParseCSSColor (char *cssRule, PresentationValue * val)
1.43 cvs 713: {
1.79 cvs 714: char *ptr;
1.43 cvs 715: unsigned short redval = (unsigned short) -1;
716: unsigned short greenval = 0; /* composant of each RGB */
717: unsigned short blueval = 0; /* default to red if unknown ! */
718: int best = 0; /* best color in list found */
1.404 vatton 719: ThotBool warn;
1.43 cvs 720:
1.82 cvs 721: cssRule = SkipBlanksAndComments (cssRule);
1.184 vatton 722: val->typed_data.unit = UNIT_INVALID;
1.43 cvs 723: val->typed_data.real = FALSE;
724: val->typed_data.value = 0;
1.57 cvs 725: ptr = TtaGiveRGB (cssRule, &redval, &greenval, &blueval);
1.292 vatton 726: if (!strncasecmp (cssRule, "InactiveCaptionText", 19))
727: {
1.364 vatton 728: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 729: cssRule += 19;
730: }
731: else if (!strncasecmp (cssRule, "ThreeDLightShadow", 17))
732: {
1.364 vatton 733: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 734: cssRule += 17;
735: }
736: else if (!strncasecmp (cssRule, "ThreeDDarkShadow", 16))
737: {
1.364 vatton 738: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 739: cssRule += 16;
740: }
741: else if (!strncasecmp (cssRule, "ButtonHighlight", 15) ||
1.327 vatton 742: !strncasecmp (cssRule, "InactiveCaption", 15) ||
743: !strncasecmp (cssRule, "ThreeDHighlight", 15))
1.292 vatton 744: {
1.364 vatton 745: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 746: cssRule += 15;
747: }
748: else if (!strncasecmp (cssRule, "InactiveBorder", 14) ||
1.327 vatton 749: !strncasecmp (cssRule, "InfoBackground", 14))
1.292 vatton 750: {
1.364 vatton 751: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 752: cssRule += 14;
753: }
754: else if (!strncasecmp (cssRule, "ActiveCaption", 13) ||
1.327 vatton 755: !strncasecmp (cssRule, "HighlightText", 13))
1.292 vatton 756: {
1.364 vatton 757: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 758: cssRule += 13;
759: }
760: else if (!strncasecmp (cssRule, "ActiveBorder", 12) ||
1.327 vatton 761: !strncasecmp (cssRule, "AppWorkspace", 12) ||
762: !strncasecmp (cssRule, "ButtonShadow", 12) ||
763: !strncasecmp (cssRule, "ThreeDShadow", 12))
1.292 vatton 764: {
1.364 vatton 765: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 766: cssRule += 12;
767: }
768: else if (!strncasecmp (cssRule, "CaptionText", 11) ||
1.327 vatton 769: !strncasecmp (cssRule, "WindowFrame", 11))
1.292 vatton 770: {
1.364 vatton 771: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 772: cssRule += 11;
773: }
774: else if (!strncasecmp (cssRule, "Background", 10) ||
1.327 vatton 775: !strncasecmp (cssRule, "ButtonFace", 10) ||
776: !strncasecmp (cssRule, "ButtonText", 10) ||
777: !strncasecmp (cssRule, "ThreeDFace", 10) ||
778: !strncasecmp (cssRule, "WindowText", 10))
1.292 vatton 779: {
1.364 vatton 780: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 781: cssRule += 10;
782: }
783: else if (!strncasecmp (cssRule, "Highlight", 9) ||
1.327 vatton 784: !strncasecmp (cssRule, "Scrollbar", 9))
1.292 vatton 785: {
1.364 vatton 786: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 787: cssRule += 9;
788: }
789: else if (!strncasecmp (cssRule, "GrayText", 8) ||
1.327 vatton 790: !strncasecmp (cssRule, "InfoText", 8) ||
791: !strncasecmp (cssRule, "MenuText", 8))
1.292 vatton 792: {
1.364 vatton 793: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 794: cssRule += 8;
795: }
796: else if (!strncasecmp (cssRule, "Window", 6))
797: {
1.364 vatton 798: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 799: cssRule += 6;
800: }
801: else if (!strncasecmp (cssRule, "Menu", 5))
802: {
1.364 vatton 803: val->typed_data.unit = VALUE_INHERIT;
1.292 vatton 804: cssRule += 5;
805: }
1.293 quint 806: else if (!strncasecmp (cssRule, "inherit", 7))
807: {
808: val->typed_data.unit = VALUE_INHERIT;
809: cssRule += 7;
810: }
1.404 vatton 811: else if (!strncasecmp (cssRule, "hsl", 3))
812: {
813: val->typed_data.unit = VALUE_INHERIT;
814: // check if Amaya should report CSS warnings
815: TtaGetEnvBoolean ("CSS_WARN", &warn);
816: if (warn)
817: cssRule = SkipValue ("Warning: CSS3 value not supported", cssRule);
818: else
819: cssRule = SkipValue (NULL, cssRule);
820: }
821: else if (!strncasecmp (cssRule, "rgba", 4))
822: {
823: val->typed_data.unit = VALUE_INHERIT;
824: // check if Amaya should report CSS warnings
825: TtaGetEnvBoolean ("CSS_WARN", &warn);
826: if (warn)
827: cssRule = SkipValue ("Warning: CSS3 value not supported", cssRule);
828: else
829: cssRule = SkipValue (NULL, cssRule);
830: }
1.57 cvs 831: if (ptr == cssRule)
1.43 cvs 832: {
1.404 vatton 833: cssRule = SkipValue ("Invalid color value", cssRule);
1.43 cvs 834: val->typed_data.value = 0;
1.184 vatton 835: val->typed_data.unit = UNIT_INVALID;
1.43 cvs 836: }
1.293 quint 837: else if (val->typed_data.unit != VALUE_INHERIT)
1.43 cvs 838: {
839: best = TtaGetThotColor (redval, greenval, blueval);
840: val->typed_data.value = best;
1.184 vatton 841: val->typed_data.unit = UNIT_REL;
1.57 cvs 842: cssRule = ptr;
1.43 cvs 843: }
844: val->typed_data.real = FALSE;
1.262 vatton 845: cssRule = SkipBlanksAndComments (cssRule);
1.65 cvs 846: return (cssRule);
1.43 cvs 847: }
1.1 cvs 848:
849: /*----------------------------------------------------------------------
1.231 vatton 850: CheckImportantRule updates the field important of the context and
851: the line number.
1.117 vatton 852: ----------------------------------------------------------------------*/
1.360 vatton 853: static void CheckImportantRule (char *cssRule, PresentationContext context)
1.117 vatton 854: {
1.276 vatton 855: PresentationContextBlock dummyctxt;
856:
857: if (context == NULL)
858: /* no context provided */
859: context = &dummyctxt;
860:
1.117 vatton 861: cssRule = SkipBlanksAndComments (cssRule);
1.360 vatton 862: while (*cssRule != EOS && *cssRule != '!' && *cssRule != ';')
863: cssRule++;
1.120 vatton 864: if (*cssRule != '!')
865: context->important = FALSE;
866: else
1.117 vatton 867: {
1.120 vatton 868: cssRule++;
1.360 vatton 869: ImportantPos = cssRule;
1.120 vatton 870: cssRule = SkipBlanksAndComments (cssRule);
871: if (!strncasecmp (cssRule, "important", 9))
1.327 vatton 872: {
1.360 vatton 873: ImportantPos[-1] = EOS;
1.327 vatton 874: context->important = TRUE;
875: }
1.120 vatton 876: else
1.360 vatton 877: {
878: ImportantPos = NULL;
879: context->important = FALSE;
880: }
881: }
882: }
883:
884: /*----------------------------------------------------------------------
885: SkipImportantRule skips important markup
886: ----------------------------------------------------------------------*/
887: static char *SkipImportantRule (char *cssRule)
888: {
889: if (ImportantPos)
890: {
891: ImportantPos[-1] = '!';
1.361 vatton 892: cssRule = ImportantPos;
893: cssRule = SkipBlanksAndComments (cssRule);
894: cssRule += 9;
1.360 vatton 895: ImportantPos = NULL;
1.117 vatton 896: }
1.360 vatton 897: cssRule = SkipBlanksAndComments (cssRule);
1.117 vatton 898: return (cssRule);
899: }
900:
901: /*----------------------------------------------------------------------
1.327 vatton 902: ParseCSSBorderTopWidth: parse a CSS BorderTopWidth
903: attribute string.
1.1 cvs 904: ----------------------------------------------------------------------*/
1.79 cvs 905: static char *ParseCSSBorderTopWidth (Element element, PSchema tsch,
1.327 vatton 906: PresentationContext context,
907: char *cssRule, CSSInfoPtr css,
908: ThotBool isHTML)
1.1 cvs 909: {
1.41 cvs 910: PresentationValue border;
1.366 vatton 911: char *start_value = cssRule;
1.41 cvs 912:
1.82 cvs 913: cssRule = SkipBlanksAndComments (cssRule);
1.288 vatton 914: cssRule = ParseABorderValue (cssRule, &border);
1.366 vatton 915: if (border.typed_data.unit != UNIT_INVALID)
916: {
917: if (DoDialog)
918: {
919: if (All_sides)
920: DisplayStyleValue ("border-width", start_value, cssRule);
921: else
922: DisplayStyleValue ("border-top-width", start_value, cssRule);
923: }
924: else if (DoApply)
925: TtaSetStylePresentation (PRBorderTopWidth, element, tsch, context, border);
926: }
1.1 cvs 927: return (cssRule);
928: }
929:
930: /*----------------------------------------------------------------------
1.327 vatton 931: ParseCSSBorderBottomWidth: parse a CSS BorderBottomWidth
932: attribute string.
1.1 cvs 933: ----------------------------------------------------------------------*/
1.79 cvs 934: static char *ParseCSSBorderBottomWidth (Element element, PSchema tsch,
1.327 vatton 935: PresentationContext context,
936: char *cssRule, CSSInfoPtr css,
937: ThotBool isHTML)
1.1 cvs 938: {
1.41 cvs 939: PresentationValue border;
1.366 vatton 940: char *start_value = cssRule;
1.41 cvs 941:
1.82 cvs 942: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 943: /* first parse the attribute string */
1.288 vatton 944: cssRule = ParseABorderValue (cssRule, &border);
1.366 vatton 945: if (border.typed_data.unit != UNIT_INVALID)
946: {
947: if (DoDialog)
948: DisplayStyleValue ("border-bottom-width", start_value, cssRule);
949: else if (DoApply)
950: TtaSetStylePresentation (PRBorderBottomWidth, element, tsch, context, border);
951: }
1.1 cvs 952: return (cssRule);
953: }
954:
955: /*----------------------------------------------------------------------
1.327 vatton 956: ParseCSSBorderLeftWidth: parse a CSS BorderLeftWidth
957: attribute string.
1.1 cvs 958: ----------------------------------------------------------------------*/
1.79 cvs 959: static char *ParseCSSBorderLeftWidth (Element element, PSchema tsch,
1.327 vatton 960: PresentationContext context,
961: char *cssRule, CSSInfoPtr css,
962: ThotBool isHTML)
1.1 cvs 963: {
1.41 cvs 964: PresentationValue border;
1.366 vatton 965: char *start_value = cssRule;
1.41 cvs 966:
1.82 cvs 967: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 968: /* first parse the attribute string */
1.288 vatton 969: cssRule = ParseABorderValue (cssRule, &border);
1.366 vatton 970: if (border.typed_data.unit != UNIT_INVALID)
971: {
972: if (DoDialog)
973: DisplayStyleValue ("border-left-width", start_value, cssRule);
974: else if (DoApply)
975: TtaSetStylePresentation (PRBorderLeftWidth, element, tsch, context, border);
976: }
1.1 cvs 977: return (cssRule);
978: }
979:
980: /*----------------------------------------------------------------------
1.327 vatton 981: ParseCSSBorderRightWidth: parse a CSS BorderRightWidth
982: attribute string.
1.1 cvs 983: ----------------------------------------------------------------------*/
1.79 cvs 984: static char *ParseCSSBorderRightWidth (Element element, PSchema tsch,
1.327 vatton 985: PresentationContext context,
986: char *cssRule, CSSInfoPtr css,
987: ThotBool isHTML)
1.1 cvs 988: {
1.41 cvs 989: PresentationValue border;
1.366 vatton 990: char *start_value = cssRule;
1.41 cvs 991:
1.82 cvs 992: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 993: /* first parse the attribute string */
1.288 vatton 994: cssRule = ParseABorderValue (cssRule, &border);
1.184 vatton 995: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 996: {
997: if (DoDialog)
998: DisplayStyleValue ("border-right-width", start_value, cssRule);
999: else if (DoApply)
1000: TtaSetStylePresentation (PRBorderRightWidth, element, tsch, context, border);
1001: }
1.1 cvs 1002: return (cssRule);
1003: }
1004:
1005: /*----------------------------------------------------------------------
1.327 vatton 1006: ParseCSSBorderWidth: parse a CSS BorderWidth
1007: attribute string.
1.1 cvs 1008: ----------------------------------------------------------------------*/
1.79 cvs 1009: static char *ParseCSSBorderWidth (Element element, PSchema tsch,
1.327 vatton 1010: PresentationContext context,
1011: char *cssRule, CSSInfoPtr css,
1012: ThotBool isHTML)
1.1 cvs 1013: {
1.79 cvs 1014: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 1015: int skippedNL, n;
1.41 cvs 1016:
1.82 cvs 1017: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 1018: if (DoDialog)
1019: n = NumberOfValues (ptrT);
1020: if (DoDialog && n < 2)
1.42 cvs 1021: {
1.366 vatton 1022: // check if the border dialog must be updated
1023: All_sides = TRUE;
1024: ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1025: All_sides = FALSE;
1.42 cvs 1026: }
1027: else
1028: {
1.366 vatton 1029: /* First parse Border-Top */
1030: ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1.415 vatton 1031: if (ptrR == ptrT)
1032: {
1033: // invalid value
1034: cssRule = SkipValue ("Invalid border-width value", ptrT);
1035: return (cssRule);
1036: }
1.366 vatton 1037: ptrR = SkipBlanksAndComments (ptrR);
1038: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 1039: {
1040: skippedNL = NewLineSkipped;
1.366 vatton 1041: cssRule = ptrR;
1042: /* apply the Border-Top to all */
1043: ptrR = ParseCSSBorderRightWidth (element, tsch, context, ptrT, css, isHTML);
1044: NewLineSkipped = skippedNL;
1045: ptrR = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1046: NewLineSkipped = skippedNL;
1.366 vatton 1047: ptrR = ParseCSSBorderLeftWidth (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1048: }
1.42 cvs 1049: else
1.327 vatton 1050: {
1.366 vatton 1051: /* parse Border-Right */
1052: ptrB = ParseCSSBorderRightWidth (element, tsch, context, ptrR, css, isHTML);
1053: ptrB = SkipBlanksAndComments (ptrB);
1054: if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 1055: {
1.366 vatton 1056: skippedNL = NewLineSkipped;
1057: cssRule = ptrB;
1058: /* apply the Border-Top to Border-Bottom */
1059: ptrB = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1060: NewLineSkipped = skippedNL;
1.327 vatton 1061: /* apply the Border-Right to Border-Left */
1.366 vatton 1062: ptrB = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 1063: }
1064: else
1.366 vatton 1065: {
1066: /* parse Border-Bottom */
1067: ptrL = ParseCSSBorderBottomWidth (element, tsch, context, ptrB, css, isHTML);
1068: ptrL = SkipBlanksAndComments (ptrL);
1069: if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
1070: {
1071: cssRule = ptrL;
1072: /* apply the Border-Right to Border-Left */
1073: ptrL = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
1074: }
1075: else
1076: /* parse Border-Left */
1077: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, ptrL, css, isHTML);
1078: cssRule = SkipBlanksAndComments (cssRule);
1079: }
1.327 vatton 1080: }
1.42 cvs 1081: }
1.1 cvs 1082: return (cssRule);
1083: }
1084:
1085: /*----------------------------------------------------------------------
1.327 vatton 1086: ParseCSSBorderColorTop: parse a CSS BorderColorTop
1087: attribute string.
1.1 cvs 1088: ----------------------------------------------------------------------*/
1.79 cvs 1089: static char *ParseCSSBorderColorTop (Element element, PSchema tsch,
1.327 vatton 1090: PresentationContext context,
1091: char *cssRule, CSSInfoPtr css,
1092: ThotBool isHTML)
1.1 cvs 1093: {
1.117 vatton 1094: PresentationValue best;
1.366 vatton 1095: char *start_value = cssRule;
1.43 cvs 1096:
1.234 vatton 1097: if (!strncasecmp (cssRule, "transparent", 11))
1098: {
1099: best.typed_data.value = -2; /* -2 means transparent */
1100: best.typed_data.unit = UNIT_REL;
1101: cssRule = SkipWord (cssRule);
1102: }
1103: else
1104: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 1105: if (best.typed_data.unit != UNIT_INVALID)
1106: {
1107: if (DoDialog)
1108: {
1109: if (All_sides)
1110: DisplayStyleValue ("border-color", start_value, cssRule);
1111: else
1112: DisplayStyleValue ("border-top-color", start_value, cssRule);
1113: }
1114: else if (DoApply)
1115: /* install the new presentation */
1116: TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
1117: }
1.117 vatton 1118: return (cssRule);
1.1 cvs 1119: }
1120:
1121: /*----------------------------------------------------------------------
1.327 vatton 1122: ParseCSSBorderColorLeft: parse a CSS BorderColorLeft
1123: attribute string.
1.42 cvs 1124: ----------------------------------------------------------------------*/
1.79 cvs 1125: static char *ParseCSSBorderColorLeft (Element element, PSchema tsch,
1.327 vatton 1126: PresentationContext context,
1127: char *cssRule, CSSInfoPtr css,
1128: ThotBool isHTML)
1.42 cvs 1129: {
1.117 vatton 1130: PresentationValue best;
1.366 vatton 1131: char *start_value = cssRule;
1.117 vatton 1132:
1.234 vatton 1133: if (!strncasecmp (cssRule, "transparent", 11))
1134: {
1135: best.typed_data.value = -2; /* -2 means transparent */
1136: best.typed_data.unit = UNIT_REL;
1137: cssRule = SkipWord (cssRule);
1138: }
1139: else
1140: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 1141: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1142: {
1143: if (DoDialog)
1144: DisplayStyleValue ("border-left-color", start_value, cssRule);
1145: else if (DoApply)
1146: /* install the new presentation */
1147: TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
1148: }
1.117 vatton 1149: return (cssRule);
1.42 cvs 1150: }
1151:
1152: /*----------------------------------------------------------------------
1.327 vatton 1153: ParseCSSBorderColorBottom: parse a CSS BorderColorBottom
1154: attribute string.
1.42 cvs 1155: ----------------------------------------------------------------------*/
1.79 cvs 1156: static char *ParseCSSBorderColorBottom (Element element, PSchema tsch,
1.327 vatton 1157: PresentationContext context,
1158: char *cssRule, CSSInfoPtr css,
1159: ThotBool isHTML)
1.42 cvs 1160: {
1.117 vatton 1161: PresentationValue best;
1.366 vatton 1162: char *start_value = cssRule;
1.43 cvs 1163:
1.234 vatton 1164: if (!strncasecmp (cssRule, "transparent", 11))
1165: {
1166: best.typed_data.value = -2; /* -2 means transparent */
1167: best.typed_data.unit = UNIT_REL;
1168: cssRule = SkipWord (cssRule);
1169: }
1170: else
1171: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 1172: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1173: {
1174: if (DoDialog)
1175: DisplayStyleValue ("border-bottom-color", start_value, cssRule);
1176: else if (DoApply)
1177: /* install the new presentation */
1178: TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
1179: }
1.327 vatton 1180: return (cssRule);
1.42 cvs 1181: }
1182:
1183: /*----------------------------------------------------------------------
1.327 vatton 1184: ParseCSSBorderColorRight: parse a CSS BorderColorRight
1185: attribute string.
1.1 cvs 1186: ----------------------------------------------------------------------*/
1.79 cvs 1187: static char *ParseCSSBorderColorRight (Element element, PSchema tsch,
1.327 vatton 1188: PresentationContext context,
1189: char *cssRule, CSSInfoPtr css,
1190: ThotBool isHTML)
1.1 cvs 1191: {
1.117 vatton 1192: PresentationValue best;
1.366 vatton 1193: char *start_value = cssRule;
1.43 cvs 1194:
1.234 vatton 1195: if (!strncasecmp (cssRule, "transparent", 11))
1196: {
1197: best.typed_data.value = -2; /* -2 means transparent */
1198: best.typed_data.unit = UNIT_REL;
1199: cssRule = SkipWord (cssRule);
1200: }
1201: else
1202: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 1203: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1204: {
1205: if (DoDialog)
1206: DisplayStyleValue ("border-right-color", start_value, cssRule);
1207: else if (DoApply)
1208: TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
1209: }
1.117 vatton 1210: return (cssRule);
1.1 cvs 1211: }
1212:
1213: /*----------------------------------------------------------------------
1.327 vatton 1214: ParseCSSBorderColor: parse a CSS border-color
1215: attribute string.
1.42 cvs 1216: ----------------------------------------------------------------------*/
1.79 cvs 1217: static char *ParseCSSBorderColor (Element element, PSchema tsch,
1.327 vatton 1218: PresentationContext context,
1219: char *cssRule, CSSInfoPtr css,
1220: ThotBool isHTML)
1.42 cvs 1221: {
1.79 cvs 1222: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 1223: int skippedNL, n;
1.42 cvs 1224:
1.82 cvs 1225: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 1226: if (DoDialog)
1227: n = NumberOfValues (ptrT);
1228: if (DoDialog && n < 2)
1.42 cvs 1229: {
1.366 vatton 1230: // check if the border dialog must be updated
1231: All_sides = TRUE;
1232: ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1233: All_sides = FALSE;
1.42 cvs 1234: }
1235: else
1236: {
1.366 vatton 1237: /* First parse Border-Top */
1238: ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1239: ptrR = SkipBlanksAndComments (ptrR);
1240: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 1241: {
1242: skippedNL = NewLineSkipped;
1.366 vatton 1243: cssRule = ptrR;
1244: /* apply the Border-Top to all */
1245: ptrR = ParseCSSBorderColorRight (element, tsch, context, ptrT, css, isHTML);
1246: NewLineSkipped = skippedNL;
1247: ptrR = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1248: NewLineSkipped = skippedNL;
1.366 vatton 1249: ptrR = ParseCSSBorderColorLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1250: }
1.42 cvs 1251: else
1.327 vatton 1252: {
1.366 vatton 1253: /* parse Border-Right */
1254: ptrB = ParseCSSBorderColorRight (element, tsch, context, ptrR, css, isHTML);
1255: ptrB = SkipBlanksAndComments (ptrB);
1256: if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 1257: {
1.366 vatton 1258: skippedNL = NewLineSkipped;
1259: cssRule = ptrB;
1260: /* apply the Border-Top to Border-Bottom */
1261: ptrB = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1262: NewLineSkipped = skippedNL;
1.327 vatton 1263: /* apply the Border-Right to Border-Left */
1.366 vatton 1264: ptrB = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 1265: }
1266: else
1.366 vatton 1267: {
1268: skippedNL = NewLineSkipped;
1269: /* parse Border-Bottom */
1270: ptrL = ParseCSSBorderColorBottom (element, tsch, context, ptrB, css, isHTML);
1271: NewLineSkipped = skippedNL;
1272: ptrL = SkipBlanksAndComments (ptrL);
1273: if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
1274: {
1275: cssRule = ptrL;
1276: /* apply the Border-Right to Border-Left */
1277: ptrL = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1278: }
1279: else
1280: /* parse Border-Left */
1281: cssRule = ParseCSSBorderColorLeft (element, tsch, context, ptrL, css, isHTML);
1282: cssRule = SkipBlanksAndComments (cssRule);
1283: }
1.327 vatton 1284: }
1.42 cvs 1285: }
1286: return (cssRule);
1287: }
1288:
1289: /*----------------------------------------------------------------------
1.327 vatton 1290: ParseCSSBorderStyleTop: parse a CSS BorderStyleTop
1291: attribute string.
1.42 cvs 1292: ----------------------------------------------------------------------*/
1.79 cvs 1293: static char *ParseCSSBorderStyleTop (Element element, PSchema tsch,
1.327 vatton 1294: PresentationContext context,
1295: char *cssRule, CSSInfoPtr css,
1296: ThotBool isHTML)
1.42 cvs 1297: {
1.43 cvs 1298: PresentationValue border;
1.366 vatton 1299: char *start_value;
1.43 cvs 1300:
1.82 cvs 1301: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1302: start_value = cssRule;
1.43 cvs 1303: cssRule = ParseBorderStyle (cssRule, &border);
1.366 vatton 1304: if (border.typed_data.unit != UNIT_INVALID)
1305: {
1306: if (DoDialog)
1307: {
1308: if (All_sides)
1309: DisplayStyleValue ("border-style", start_value, cssRule);
1310: else
1311: DisplayStyleValue ("border-top-style", start_value, cssRule);
1312: }
1313: else if (DoApply)
1314: TtaSetStylePresentation (PRBorderTopStyle, element, tsch, context, border);
1315: }
1.42 cvs 1316: return (cssRule);
1317: }
1318:
1319: /*----------------------------------------------------------------------
1.327 vatton 1320: ParseCSSBorderStyleLeft: parse a CSS BorderStyleLeft
1321: attribute string.
1.42 cvs 1322: ----------------------------------------------------------------------*/
1.79 cvs 1323: static char *ParseCSSBorderStyleLeft (Element element, PSchema tsch,
1.327 vatton 1324: PresentationContext context,
1325: char *cssRule, CSSInfoPtr css,
1326: ThotBool isHTML)
1.42 cvs 1327: {
1.43 cvs 1328: PresentationValue border;
1.366 vatton 1329: char *start_value;
1.43 cvs 1330:
1.82 cvs 1331: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1332: start_value = cssRule;
1.43 cvs 1333: cssRule = ParseBorderStyle (cssRule, &border);
1.366 vatton 1334: if (border.typed_data.unit != UNIT_INVALID)
1335: {
1336: if (DoDialog)
1337: DisplayStyleValue ("border-left-style", start_value, cssRule);
1338: else if (DoApply)
1339: TtaSetStylePresentation (PRBorderLeftStyle, element, tsch, context, border);
1340: }
1.42 cvs 1341: return (cssRule);
1342: }
1343:
1344: /*----------------------------------------------------------------------
1.327 vatton 1345: ParseCSSBorderStyleBottom: parse a CSS BorderStyleBottom
1346: attribute string.
1.1 cvs 1347: ----------------------------------------------------------------------*/
1.79 cvs 1348: static char *ParseCSSBorderStyleBottom (Element element, PSchema tsch,
1.327 vatton 1349: PresentationContext context,
1350: char *cssRule, CSSInfoPtr css,
1351: ThotBool isHTML)
1.1 cvs 1352: {
1.43 cvs 1353: PresentationValue border;
1.366 vatton 1354: char *start_value;
1.43 cvs 1355:
1.82 cvs 1356: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1357: start_value = cssRule;
1.43 cvs 1358: cssRule = ParseBorderStyle (cssRule, &border);
1.366 vatton 1359: if (border.typed_data.unit != UNIT_INVALID)
1360: {
1361: if (DoDialog)
1362: DisplayStyleValue ("border-bottom-style", start_value, cssRule);
1363: else if (DoApply)
1364: TtaSetStylePresentation (PRBorderBottomStyle, element, tsch, context, border);
1365: }
1.1 cvs 1366: return (cssRule);
1367: }
1368:
1369: /*----------------------------------------------------------------------
1.327 vatton 1370: ParseCSSBorderStyleRight: parse a CSS BorderStyleRight
1371: attribute string.
1.1 cvs 1372: ----------------------------------------------------------------------*/
1.79 cvs 1373: static char *ParseCSSBorderStyleRight (Element element, PSchema tsch,
1.327 vatton 1374: PresentationContext context,
1375: char *cssRule, CSSInfoPtr css,
1376: ThotBool isHTML)
1.1 cvs 1377: {
1.43 cvs 1378: PresentationValue border;
1.366 vatton 1379: char *start_value;
1.43 cvs 1380:
1.82 cvs 1381: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1382: start_value = cssRule;
1.43 cvs 1383: cssRule = ParseBorderStyle (cssRule, &border);
1.184 vatton 1384: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.366 vatton 1385: {
1386: if (DoDialog)
1387: DisplayStyleValue ("border-right-style", start_value, cssRule);
1388: else if (DoApply)
1389: TtaSetStylePresentation (PRBorderRightStyle, element, tsch, context, border);
1390: }
1.1 cvs 1391: return (cssRule);
1392: }
1393:
1394: /*----------------------------------------------------------------------
1.349 quint 1395: ParseCSSBorderStyle: parse a CSS border-style attribute string.
1.1 cvs 1396: ----------------------------------------------------------------------*/
1.79 cvs 1397: static char *ParseCSSBorderStyle (Element element, PSchema tsch,
1.327 vatton 1398: PresentationContext context,
1399: char *cssRule, CSSInfoPtr css,
1400: ThotBool isHTML)
1.1 cvs 1401: {
1.79 cvs 1402: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 1403: int skippedNL, n;
1.42 cvs 1404:
1.82 cvs 1405: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 1406: if (DoDialog)
1407: n = NumberOfValues (ptrT);
1408: if (DoDialog && n < 2)
1.42 cvs 1409: {
1.366 vatton 1410: // check if the border dialog must be updated
1411: All_sides = TRUE;
1412: ptrR = ParseCSSBorderStyleTop(element, tsch, context, ptrT, css, isHTML);
1413: All_sides = FALSE;
1.42 cvs 1414: }
1415: else
1416: {
1.366 vatton 1417: /* First parse Border-Top */
1418: ptrR = ParseCSSBorderStyleTop (element, tsch, context, ptrT, css, isHTML);
1419: ptrR = SkipBlanksAndComments (ptrR);
1420: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 1421: {
1422: skippedNL = NewLineSkipped;
1.366 vatton 1423: cssRule = ptrR;
1424: /* apply the Border-Top to all */
1425: ptrR = ParseCSSBorderStyleRight (element, tsch, context, ptrT, css, isHTML);
1426: NewLineSkipped = skippedNL;
1427: ptrR = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1428: NewLineSkipped = skippedNL;
1.366 vatton 1429: ptrR = ParseCSSBorderStyleLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 1430: }
1.42 cvs 1431: else
1.327 vatton 1432: {
1.366 vatton 1433: /* parse Border-Right */
1434: ptrB = ParseCSSBorderStyleRight (element, tsch, context, ptrR, css, isHTML);
1435: ptrB = SkipBlanksAndComments (ptrB);
1436: if (*ptrB == ';' || *ptrR == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 1437: {
1.366 vatton 1438: skippedNL = NewLineSkipped;
1439: cssRule = ptrB;
1440: /* apply the Border-Top to Border-Bottom */
1441: ptrB = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1442: NewLineSkipped = skippedNL;
1.327 vatton 1443: /* apply the Border-Right to Border-Left */
1.366 vatton 1444: ptrB = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 1445: }
1446: else
1.366 vatton 1447: {
1448: /* parse Border-Bottom */
1449: ptrL = ParseCSSBorderStyleBottom (element, tsch, context, ptrB, css, isHTML);
1450: ptrL = SkipBlanksAndComments (ptrL);
1451: if (*ptrL == ';' || *ptrR == '}' || *ptrL == EOS || *ptrL == ',')
1452: {
1453: cssRule = ptrL;
1454: /* apply the Border-Right to Border-Left */
1455: ptrL = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1456: }
1457: else
1458: /* parse Border-Left */
1459: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, ptrL, css, isHTML);
1460: cssRule = SkipBlanksAndComments (cssRule);
1461: }
1.327 vatton 1462: }
1.42 cvs 1463: }
1464: return (cssRule);
1465: }
1466:
1467: /*----------------------------------------------------------------------
1.327 vatton 1468: ParseCSSBorderTop: parse a CSS BorderTop
1469: attribute string.
1.42 cvs 1470: ----------------------------------------------------------------------*/
1.79 cvs 1471: static char *ParseCSSBorderTop (Element element, PSchema tsch,
1.327 vatton 1472: PresentationContext context, char *cssRule,
1473: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1474: {
1.370 vatton 1475: PresentationValue best;
1476: char *ptr;
1477: ThotBool style, width, color;
1.43 cvs 1478:
1.82 cvs 1479: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1480: /* register given values */
1.337 vatton 1481: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1482: style = width = color = TRUE;
1.337 vatton 1483: else
1.370 vatton 1484: style = width = color = FALSE;
1.301 vatton 1485: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1486: {
1487: ptr = cssRule;
1488: cssRule = ParseCSSBorderStyleTop (element, tsch, context, cssRule, css, isHTML);
1489: if (ptr == cssRule)
1.327 vatton 1490: {
1491: cssRule = ParseCSSBorderTopWidth (element, tsch, context, cssRule, css, isHTML);
1492: if (ptr == cssRule)
1.370 vatton 1493: {
1494: cssRule = ParseCSSBorderColorTop (element, tsch, context, cssRule, css, isHTML);
1495: if (ptr != cssRule)
1496: color = TRUE;
1497: }
1.327 vatton 1498: else
1499: width = TRUE;
1500: if (ptr == cssRule)
1501: {
1502: /* rule not found */
1503: cssRule = SkipValue ("Invalid border value", cssRule);
1504: return (cssRule);
1505: }
1506: }
1.322 vatton 1507: else
1.327 vatton 1508: style = TRUE;
1.82 cvs 1509: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1510: }
1.322 vatton 1511:
1512: if (!width)
1.405 kia 1513: ParseCSSBorderTopWidth (element, tsch, context, (char*)"medium", css, isHTML);
1.322 vatton 1514: if (!style)
1.405 kia 1515: ParseCSSBorderStyleTop (element, tsch, context, (char*)"none", css, isHTML);
1.370 vatton 1516: if (!color && DoApply)
1517: {
1518: /* get the box color */
1519: best.typed_data.value = -1;
1520: best.typed_data.unit = UNIT_REL;
1521: best.typed_data.real = FALSE;
1522: TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
1523: }
1.42 cvs 1524: return (cssRule);
1525: }
1526:
1527: /*----------------------------------------------------------------------
1.327 vatton 1528: ParseCSSBorderLeft: parse a CSS BorderLeft
1529: attribute string.
1.42 cvs 1530: ----------------------------------------------------------------------*/
1.79 cvs 1531: static char *ParseCSSBorderLeft (Element element, PSchema tsch,
1.327 vatton 1532: PresentationContext context, char *cssRule,
1533: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1534: {
1.370 vatton 1535: PresentationValue best;
1536: char *ptr;
1537: ThotBool style, width, color;
1.43 cvs 1538:
1.82 cvs 1539: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1540: /* register given values */
1.337 vatton 1541: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1542: style = width = color = TRUE;
1.337 vatton 1543: else
1.370 vatton 1544: style = width = color = FALSE;
1.301 vatton 1545: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1546: {
1547: ptr = cssRule;
1548: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, cssRule, css, isHTML);
1549: if (ptr == cssRule)
1.327 vatton 1550: {
1551: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, cssRule, css, isHTML);
1552: if (ptr == cssRule)
1.370 vatton 1553: {
1554: cssRule = ParseCSSBorderColorLeft (element, tsch, context, cssRule, css, isHTML);
1555: if (ptr != cssRule)
1556: color = TRUE;
1557: }
1.327 vatton 1558: else
1559: width = TRUE;
1560: if (ptr == cssRule)
1561: {
1562: /* rule not found */
1563: cssRule = SkipValue ("Invalid border value", cssRule);
1564: return (cssRule);
1565: }
1566: }
1.322 vatton 1567: else
1.327 vatton 1568: style = TRUE;
1569: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1570: }
1.322 vatton 1571:
1572: if (!width)
1.405 kia 1573: ParseCSSBorderLeftWidth (element, tsch, context, (char*)"medium", css, isHTML);
1.322 vatton 1574: if (!style)
1.405 kia 1575: ParseCSSBorderStyleLeft (element, tsch, context, (char*)"none", css, isHTML);
1.370 vatton 1576: if (!color && DoApply)
1577: {
1578: /* get the box color */
1579: best.typed_data.value = -1;
1580: best.typed_data.unit = UNIT_REL;
1581: best.typed_data.real = FALSE;
1582: TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
1583: }
1.1 cvs 1584: return (cssRule);
1585: }
1586:
1587: /*----------------------------------------------------------------------
1.327 vatton 1588: ParseCSSBorderBottom: parse a CSS BorderBottom
1589: attribute string.
1.1 cvs 1590: ----------------------------------------------------------------------*/
1.79 cvs 1591: static char *ParseCSSBorderBottom (Element element, PSchema tsch,
1.327 vatton 1592: PresentationContext context, char *cssRule,
1593: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1594: {
1.370 vatton 1595: PresentationValue best;
1596: char *ptr;
1597: ThotBool style, width, color;
1.43 cvs 1598:
1.82 cvs 1599: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1600: /* register given values */
1.337 vatton 1601: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1602: style = width = color = TRUE;
1.337 vatton 1603: else
1.370 vatton 1604: style = width = color = FALSE;
1.301 vatton 1605: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1606: {
1607: ptr = cssRule;
1608: cssRule = ParseCSSBorderStyleBottom (element, tsch, context, cssRule, css, isHTML);
1609: if (ptr == cssRule)
1.327 vatton 1610: {
1611: cssRule = ParseCSSBorderBottomWidth (element, tsch, context, cssRule, css, isHTML);
1612: if (ptr == cssRule)
1.370 vatton 1613: {
1614: cssRule = ParseCSSBorderColorBottom (element, tsch, context, cssRule, css, isHTML);
1615: if (ptr != cssRule)
1616: color = TRUE;
1617: }
1.327 vatton 1618: else
1619: width = TRUE;
1620: if (ptr == cssRule)
1621: {
1622: /* rule not found */
1623: cssRule = SkipValue ("Invalid border value", cssRule);
1624: return (cssRule);
1625: }
1626: }
1.322 vatton 1627: else
1.327 vatton 1628: style = TRUE;
1.82 cvs 1629: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1630: }
1.322 vatton 1631:
1632: if (!width)
1.405 kia 1633: ParseCSSBorderBottomWidth (element, tsch, context, (char*)"medium", css, isHTML);
1.322 vatton 1634: if (!style)
1.405 kia 1635: ParseCSSBorderStyleBottom (element, tsch, context, (char*)"none", css, isHTML);
1.370 vatton 1636: if (!color && DoApply)
1637: {
1638: /* get the box color */
1639: best.typed_data.value = -1;
1640: best.typed_data.unit = UNIT_REL;
1641: best.typed_data.real = FALSE;
1642: TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
1643: }
1.1 cvs 1644: return (cssRule);
1645: }
1646:
1647: /*----------------------------------------------------------------------
1.327 vatton 1648: ParseCSSBorderRight: parse a CSS BorderRight
1649: attribute string.
1.1 cvs 1650: ----------------------------------------------------------------------*/
1.79 cvs 1651: static char *ParseCSSBorderRight (Element element, PSchema tsch,
1.327 vatton 1652: PresentationContext context, char *cssRule,
1653: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1654: {
1.370 vatton 1655: PresentationValue best;
1656: char *ptr;
1657: ThotBool style, width, color;
1.43 cvs 1658:
1.82 cvs 1659: cssRule = SkipBlanksAndComments (cssRule);
1.322 vatton 1660: /* register given values */
1.337 vatton 1661: if (!strncmp (cssRule, "none", 4))
1.370 vatton 1662: style = width = color = TRUE;
1.337 vatton 1663: else
1.370 vatton 1664: style = width = color = FALSE;
1.301 vatton 1665: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1666: {
1667: ptr = cssRule;
1668: cssRule = ParseCSSBorderStyleRight (element, tsch, context, cssRule, css, isHTML);
1669: if (ptr == cssRule)
1.327 vatton 1670: {
1671: cssRule = ParseCSSBorderRightWidth (element, tsch, context, cssRule, css, isHTML);
1672: if (ptr == cssRule)
1.370 vatton 1673: {
1674: cssRule = ParseCSSBorderColorRight (element, tsch, context, cssRule, css, isHTML);
1675: if (ptr != cssRule)
1676: color = TRUE;
1677: }
1.327 vatton 1678: else
1679: width = TRUE;
1680: if (ptr == cssRule)
1681: {
1682: /* rule not found */
1683: cssRule = SkipValue ("Invalid border value", cssRule);
1684: return (cssRule);
1685: }
1686: }
1.322 vatton 1687: else
1.327 vatton 1688: style = TRUE;
1.82 cvs 1689: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1690: }
1.322 vatton 1691:
1692: if (!width)
1.405 kia 1693: ParseCSSBorderRightWidth (element, tsch, context, (char*)"medium", css, isHTML);
1.322 vatton 1694: if (!style)
1.405 kia 1695: ParseCSSBorderStyleRight (element, tsch, context, (char*)"none", css, isHTML);
1.370 vatton 1696: if (!color && DoApply)
1697: {
1698: /* get the box color */
1699: best.typed_data.value = -1;
1700: best.typed_data.unit = UNIT_REL;
1.374 vatton 1701: best.typed_data.real = FALSE;
1.370 vatton 1702: TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
1703: }
1.1 cvs 1704: return (cssRule);
1705: }
1706:
1707: /*----------------------------------------------------------------------
1.327 vatton 1708: ParseCSSBorder: parse a CSS border
1709: attribute string.
1.42 cvs 1710: ----------------------------------------------------------------------*/
1.79 cvs 1711: static char *ParseCSSBorder (Element element, PSchema tsch,
1.327 vatton 1712: PresentationContext context, char *cssRule,
1713: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1714: {
1.79 cvs 1715: char *ptrT, *ptrR;
1.366 vatton 1716: int skippedNL, n;
1.42 cvs 1717:
1.82 cvs 1718: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 1719: if (DoDialog)
1720: n = NumberOfValues (ptrT);
1721: if (DoDialog && n < 4)
1.42 cvs 1722: {
1.366 vatton 1723: // check if the border dialog must be updated
1724: All_sides = TRUE;
1725: ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1726: All_sides = FALSE;
1727: }
1728: else
1729: {
1730: /* First parse Border-Top */
1731: ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1732: ptrR = SkipBlanksAndComments (ptrR);
1733: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1734: {
1735: skippedNL = NewLineSkipped;
1736: cssRule = ptrR;
1737: /* apply the Border-Top to all */
1738: ptrR = ParseCSSBorderRight (element, tsch, context, ptrT, css, isHTML);
1739: NewLineSkipped = skippedNL;
1740: ptrR = ParseCSSBorderBottom (element, tsch, context, ptrT, css, isHTML);
1741: NewLineSkipped = skippedNL;
1742: ptrR = ParseCSSBorderLeft (element, tsch, context, ptrT, css, isHTML);
1743: }
1.42 cvs 1744: }
1745: return (cssRule);
1746: }
1747:
1.218 vatton 1748:
1.42 cvs 1749: /*----------------------------------------------------------------------
1.327 vatton 1750: ParseCSSFloat: parse a CSS float attribute string
1.184 vatton 1751: ----------------------------------------------------------------------*/
1752: static char *ParseCSSFloat (Element element, PSchema tsch,
1.327 vatton 1753: PresentationContext context, char *cssRule,
1754: CSSInfoPtr css, ThotBool isHTML)
1.184 vatton 1755: {
1.257 vatton 1756: DisplayMode dispMode;
1.184 vatton 1757: PresentationValue pval;
1.288 vatton 1758: char *ptr = cssRule;
1.404 vatton 1759: ThotBool warn;
1.184 vatton 1760:
1.404 vatton 1761: // check if Amaya should report CSS warnings
1762: TtaGetEnvBoolean ("CSS_WARN", &warn);
1.184 vatton 1763: pval.typed_data.value = 0;
1.187 vatton 1764: pval.typed_data.unit = UNIT_BOX;
1.192 cvs 1765: pval.typed_data.real = FALSE;
1.190 vatton 1766: if (!strncasecmp (cssRule, "inherit", 7))
1767: {
1.293 quint 1768: pval.typed_data.unit = VALUE_INHERIT;
1.288 vatton 1769: cssRule += 7;
1.190 vatton 1770: }
1.184 vatton 1771: if (!strncasecmp (cssRule, "none", 4))
1.288 vatton 1772: {
1773: pval.typed_data.value = FloatNone;
1.293 quint 1774: cssRule += 4;
1.288 vatton 1775: }
1.184 vatton 1776: else if (!strncasecmp (cssRule, "left", 4))
1.288 vatton 1777: {
1778: pval.typed_data.value = FloatLeft;
1.293 quint 1779: cssRule += 4;
1.288 vatton 1780: }
1.184 vatton 1781: else if (!strncasecmp (cssRule, "right", 5))
1.288 vatton 1782: {
1783: pval.typed_data.value = FloatRight;
1.293 quint 1784: cssRule += 5;
1.288 vatton 1785: }
1.184 vatton 1786:
1.293 quint 1787: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
1.359 quint 1788: {
1789: if (!strncasecmp (cssRule, "top", 3) ||
1790: !strncasecmp (cssRule, "bottom", 6) ||
1791: !strncasecmp (cssRule, "inside", 6) ||
1792: !strncasecmp (cssRule, "outside", 7) ||
1793: !strncasecmp (cssRule, "start", 5) ||
1794: !strncasecmp (cssRule, "end", 3))
1.404 vatton 1795: {
1796: if (warn)
1797: cssRule = SkipValue ("Warning: CSS3 value not supported", cssRule);
1798: else
1799: cssRule = SkipValue (NULL, cssRule);
1800: }
1.359 quint 1801: else
1802: cssRule = SkipValue ("Invalid float value", cssRule);
1803: }
1.184 vatton 1804: else
1805: {
1.366 vatton 1806: if (DoDialog)
1807: DisplayStyleValue ("float", ptr, cssRule);
1808: else if (DoApply)
1.327 vatton 1809: {
1810: dispMode = TtaGetDisplayMode (context->doc);
1811: if (dispMode != NoComputedDisplay)
1812: {
1813: /* force a redisplay of the whole document */
1814: TtaSetDisplayMode (context->doc, NoComputedDisplay);
1.257 vatton 1815: #ifdef AMAYA_DEBUG
1.327 vatton 1816: /*printf ("Force NoComputedDisplay doc=%d\n", context->doc);*/
1.257 vatton 1817: #endif /* AMAYA_DEBUG */
1.327 vatton 1818: }
1819: TtaSetStylePresentation (PRFloat, element, tsch, context, pval);
1820: }
1.288 vatton 1821: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid float value");
1.184 vatton 1822: }
1823: return (cssRule);
1824: }
1825:
1826: /*----------------------------------------------------------------------
1.327 vatton 1827: ParseCSSClear: parse a CSS clear rule
1.1 cvs 1828: ----------------------------------------------------------------------*/
1.79 cvs 1829: static char *ParseCSSClear (Element element, PSchema tsch,
1.327 vatton 1830: PresentationContext context, char *cssRule,
1831: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1832: {
1.184 vatton 1833: PresentationValue pval;
1.366 vatton 1834: char *start_value = cssRule;
1.184 vatton 1835:
1836: pval.typed_data.value = 0;
1.187 vatton 1837: pval.typed_data.unit = UNIT_BOX;
1.193 vatton 1838: pval.typed_data.real = FALSE;
1.190 vatton 1839: if (!strncasecmp (cssRule, "inherit", 7))
1.293 quint 1840: pval.typed_data.unit = VALUE_INHERIT;
1.184 vatton 1841: if (!strncasecmp (cssRule, "none", 4))
1842: pval.typed_data.value = ClearNone;
1843: else if (!strncasecmp (cssRule, "left", 4))
1844: pval.typed_data.value = ClearLeft;
1845: else if (!strncasecmp (cssRule, "right", 5))
1846: pval.typed_data.value = ClearRight;
1847: else if (!strncasecmp (cssRule, "both", 4))
1848: pval.typed_data.value = ClearBoth;
1849:
1.293 quint 1850: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
1.295 vatton 1851: {
1852: cssRule = SkipValue ("Invalid clear value", cssRule);
1853: cssRule = SkipValue (NULL, cssRule);
1854: }
1.184 vatton 1855: else
1856: {
1.295 vatton 1857: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 1858: if (DoDialog)
1859: DisplayStyleValue ("clear", start_value, cssRule);
1860: else if (DoApply)
1.327 vatton 1861: TtaSetStylePresentation (PRClear, element, tsch, context, pval);
1.184 vatton 1862: }
1863: return (cssRule);
1864: }
1865:
1866: /*----------------------------------------------------------------------
1.333 vatton 1867: ParseCSSVisibility: parse a CSS visibility attribute string
1868: ----------------------------------------------------------------------*/
1869: static char *ParseCSSVisibility(Element element, PSchema tsch,
1870: PresentationContext context, char *cssRule,
1871: CSSInfoPtr css, ThotBool isHTML)
1872: {
1873: PresentationValue pval;
1.366 vatton 1874: char *ptr;
1.333 vatton 1875:
1876: pval.typed_data.unit = UNIT_REL;
1877: pval.typed_data.real = FALSE;
1878: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1879: ptr = cssRule;
1.333 vatton 1880: if (!strncasecmp (cssRule, "hidden", 6))
1881: {
1882: cssRule += 6;
1883: pval.typed_data.value = VsHidden;
1884: }
1885: else if (!strncasecmp (cssRule, "visible", 7))
1886: {
1887: cssRule += 7;
1888: pval.typed_data.value = VsVisible;
1889: }
1890: else if (!strncasecmp (cssRule, "collapse", 8))
1891: {
1892: cssRule += 8;
1893: pval.typed_data.value = VsCollapse;
1894: }
1895: else if (!strncasecmp (cssRule, "inherit", 7))
1896: {
1897: cssRule += 7;
1898: pval.typed_data.value = VsInherit;
1899: }
1900: else
1901: {
1902: cssRule = SkipValue ("Invalid visibility value", cssRule);
1903: return (cssRule);
1904: }
1.366 vatton 1905: if (DoDialog)
1906: DisplayStyleValue ("visibility", ptr, cssRule);
1907: else if (DoApply)
1.333 vatton 1908: TtaSetStylePresentation (PRVis, element, tsch, context, pval);
1909: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid visibility value");
1910: return (cssRule);
1911: }
1912:
1913:
1914: /*----------------------------------------------------------------------
1.327 vatton 1915: ParseCSSDisplay: parse a CSS display attribute string
1.1 cvs 1916: ----------------------------------------------------------------------*/
1.79 cvs 1917: static char *ParseCSSDisplay (Element element, PSchema tsch,
1.327 vatton 1918: PresentationContext context, char *cssRule,
1919: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1920: {
1.184 vatton 1921: PresentationValue pval;
1.366 vatton 1922: char *ptr;
1.404 vatton 1923: ThotBool warn;
1.1 cvs 1924:
1.184 vatton 1925: pval.typed_data.unit = UNIT_REL;
1926: pval.typed_data.real = FALSE;
1927: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 1928: ptr = cssRule;
1.184 vatton 1929: if (!strncasecmp (cssRule, "none", 4))
1.288 vatton 1930: {
1931: cssRule += 4;
1932: pval.typed_data.value = DisplayNone;
1933: }
1.277 quint 1934: else if (!strncasecmp (cssRule, "block", 5))
1.288 vatton 1935: {
1936: cssRule += 5;
1937: pval.typed_data.value = Block;
1938: }
1.303 vatton 1939: else if (!strncasecmp (cssRule, "inline-block", 12))
1940: {
1941: cssRule += 12;
1942: pval.typed_data.value = InlineBlock;
1943: }
1.277 quint 1944: else if (!strncasecmp (cssRule, "inline", 6))
1.288 vatton 1945: {
1946: cssRule += 6;
1947: pval.typed_data.value = Inline;
1948: }
1.277 quint 1949: else if (!strncasecmp (cssRule, "list-item", 9))
1.288 vatton 1950: {
1951: cssRule += 9;
1952: pval.typed_data.value = ListItem;
1953: }
1.277 quint 1954: else if (!strncasecmp (cssRule, "run-in", 6))
1.288 vatton 1955: {
1956: cssRule += 6;
1957: pval.typed_data.value = RunIn;
1958: }
1.293 quint 1959: else if (!strncasecmp (cssRule, "inherit", 7))
1960: {
1961: cssRule += 7;
1962: pval.typed_data.unit = VALUE_INHERIT;
1963: }
1.277 quint 1964: else
1.184 vatton 1965: {
1.404 vatton 1966: TtaGetEnvBoolean ("CSS_WARN", &warn);
1967: if (warn &&
1968: strncasecmp (cssRule, "table-row-group", 15) &&
1.327 vatton 1969: strncasecmp (cssRule, "table-column-group", 18) &&
1970: strncasecmp (cssRule, "table-header-group", 5) &&
1971: strncasecmp (cssRule, "table-footer-group", 6) &&
1972: strncasecmp (cssRule, "table-row", 9) &&
1973: strncasecmp (cssRule, "table-column", 12) &&
1974: strncasecmp (cssRule, "table-cell", 10) &&
1975: strncasecmp (cssRule, "table-caption", 13) &&
1976: strncasecmp (cssRule, "inline-table", 12) &&
1977: strncasecmp (cssRule, "table", 5))
1978: cssRule = SkipValue ("Display value not supported", cssRule);
1.281 quint 1979: else
1.327 vatton 1980: cssRule = SkipWord (cssRule);
1.277 quint 1981: return (cssRule);
1.184 vatton 1982: }
1.277 quint 1983:
1.366 vatton 1984: if (DoDialog)
1985: DisplayStyleValue ("display", ptr, cssRule);
1986: else if (DoApply)
1.295 vatton 1987: TtaSetStylePresentation (PRDisplay, element, tsch, context, pval);
1.288 vatton 1988: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid display value");
1.1 cvs 1989: return (cssRule);
1990: }
1991:
1992: /*----------------------------------------------------------------------
1.327 vatton 1993: ParseCSSLetterSpacing: parse a CSS letter-spacing
1994: attribute string.
1.1 cvs 1995: ----------------------------------------------------------------------*/
1.79 cvs 1996: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
1.327 vatton 1997: PresentationContext context, char *cssRule,
1998: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1999: {
1.366 vatton 2000: char *start_value = cssRule;
2001:
1.168 vatton 2002: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 2003: if (DoDialog)
2004: DisplayStyleValue ("letter-spacing", start_value, cssRule);
1.1 cvs 2005: return (cssRule);
2006: }
2007:
2008: /*----------------------------------------------------------------------
1.327 vatton 2009: ParseACSSListStyleType: parse a CSS list-style-type
2010: attribute string.
1.1 cvs 2011: ----------------------------------------------------------------------*/
1.318 vatton 2012: static char *ParseACSSListStyleType (Element element, PSchema tsch,
1.327 vatton 2013: PresentationContext context, char *cssRule,
2014: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2015: {
1.281 quint 2016: PresentationValue pval;
1.366 vatton 2017: char *start_value;
1.281 quint 2018:
2019: pval.typed_data.unit = UNIT_REL;
2020: pval.typed_data.real = FALSE;
2021: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2022: start_value = cssRule;
1.281 quint 2023: if (!strncasecmp (cssRule, "disc", 4))
1.288 vatton 2024: {
2025: cssRule += 4;
2026: pval.typed_data.value = Disc;
2027: }
1.281 quint 2028: else if (!strncasecmp (cssRule, "circle", 6))
1.293 quint 2029: {
1.288 vatton 2030: cssRule += 6;
2031: pval.typed_data.value = Circle;
1.293 quint 2032: }
1.281 quint 2033: else if (!strncasecmp (cssRule, "square", 6))
1.293 quint 2034: {
1.288 vatton 2035: cssRule += 6;
1.293 quint 2036: pval.typed_data.value = Square;
2037: }
1.283 quint 2038: else if (!strncasecmp (cssRule, "decimal-leading-zero", 20))
1.293 quint 2039: {
1.288 vatton 2040: cssRule += 20;
1.293 quint 2041: pval.typed_data.value = DecimalLeadingZero;
2042: }
1.281 quint 2043: else if (!strncasecmp (cssRule, "decimal", 7))
1.293 quint 2044: {
1.288 vatton 2045: cssRule += 7;
1.293 quint 2046: pval.typed_data.value = Decimal;
2047: }
1.281 quint 2048: else if (!strncasecmp (cssRule, "lower-roman", 11))
1.293 quint 2049: {
1.288 vatton 2050: cssRule += 11;
1.293 quint 2051: pval.typed_data.value = LowerRoman;
2052: }
1.281 quint 2053: else if (!strncasecmp (cssRule, "upper-roman", 11))
1.293 quint 2054: {
1.288 vatton 2055: cssRule += 11;
1.293 quint 2056: pval.typed_data.value = UpperRoman;
2057: }
1.281 quint 2058: else if (!strncasecmp (cssRule, "lower-greek", 11))
1.293 quint 2059: {
1.288 vatton 2060: cssRule += 11;
1.293 quint 2061: pval.typed_data.value = LowerGreek;
2062: }
1.281 quint 2063: else if (!strncasecmp (cssRule, "lower-latin", 11))
1.293 quint 2064: {
1.288 vatton 2065: cssRule += 11;
1.293 quint 2066: pval.typed_data.value = LowerLatin;
2067: }
1.281 quint 2068: else if (!strncasecmp (cssRule, "lower-alpha", 11))
1.293 quint 2069: {
1.288 vatton 2070: cssRule += 11;
1.293 quint 2071: pval.typed_data.value = LowerLatin;
2072: }
1.281 quint 2073: else if (!strncasecmp (cssRule, "upper-latin", 11))
1.293 quint 2074: {
1.288 vatton 2075: cssRule += 11;
1.293 quint 2076: pval.typed_data.value = UpperLatin;
2077: }
1.281 quint 2078: else if (!strncasecmp (cssRule, "upper-alpha", 11))
1.293 quint 2079: {
1.288 vatton 2080: cssRule += 11;
1.293 quint 2081: pval.typed_data.value = UpperLatin;
2082: }
1.281 quint 2083: else if (!strncasecmp (cssRule, "armenian", 8))
1.293 quint 2084: {
1.288 vatton 2085: cssRule += 8;
1.293 quint 2086: pval.typed_data.value = Decimal;
2087: }
1.281 quint 2088: else if (!strncasecmp (cssRule, "georgian", 8))
1.293 quint 2089: {
1.288 vatton 2090: cssRule += 8;
1.293 quint 2091: pval.typed_data.value = Decimal;
2092: }
1.281 quint 2093: else if (!strncasecmp (cssRule, "none", 4))
1.293 quint 2094: {
1.288 vatton 2095: cssRule += 4;
1.293 quint 2096: pval.typed_data.value = ListStyleTypeNone;
2097: }
1.281 quint 2098: else if (!strncasecmp (cssRule, "inherit", 7))
2099: {
1.293 quint 2100: cssRule += 7;
2101: pval.typed_data.unit = VALUE_INHERIT;
1.281 quint 2102: }
2103: else
2104: {
2105: cssRule = SkipValue ("Invalid list-style-type value", cssRule);
2106: return (cssRule);
2107: }
2108:
1.366 vatton 2109: if (DoDialog)
2110: DisplayStyleValue ("list-style-type", start_value, cssRule);
2111: else if (DoApply)
1.295 vatton 2112: TtaSetStylePresentation (PRListStyleType, element, tsch, context, pval);
1.318 vatton 2113: return (cssRule);
2114: }
2115:
2116: /*----------------------------------------------------------------------
1.327 vatton 2117: ParseCSSListStyleType: parse a CSS list-style-type
2118: attribute string.
1.318 vatton 2119: ----------------------------------------------------------------------*/
2120: static char *ParseCSSListStyleType (Element element, PSchema tsch,
1.327 vatton 2121: PresentationContext context, char *cssRule,
2122: CSSInfoPtr css, ThotBool isHTML)
1.318 vatton 2123: {
2124: char *ptr = cssRule;
2125: cssRule = ParseACSSListStyleType (element, tsch, context, cssRule, css,
1.327 vatton 2126: isHTML);
1.288 vatton 2127: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-type value");
1.318 vatton 2128: return cssRule;
1.1 cvs 2129: }
2130:
2131: /*----------------------------------------------------------------------
1.281 quint 2132: ParseCSSUrl: parse an URL
1.375 vatton 2133: Parse the url content (don't start with "url")
2134: Return the next pointer in the CSS string
2135: If a correct URL is found, it's returned in url (this string must
2136: be freed)
1.281 quint 2137: ----------------------------------------------------------------------*/
2138: static char *ParseCSSUrl (char *cssRule, char **url)
2139: {
2140: char saved;
2141: char *base, *ptr;
2142:
2143: cssRule = SkipBlanksAndComments (cssRule);
2144: saved = *cssRule;
2145: if (*cssRule == '(')
2146: {
2147: cssRule++;
2148: cssRule = SkipBlanksAndComments (cssRule);
2149: /*** Escaped quotes are not handled. See function SkipQuotedString */
2150: if (*cssRule == '"')
1.327 vatton 2151: {
2152: cssRule++;
2153: base = cssRule;
2154: while (*cssRule != EOS && *cssRule != '"')
2155: cssRule++;
2156: }
1.281 quint 2157: else if (*cssRule == '\'')
1.327 vatton 2158: {
2159: cssRule++;
2160: base = cssRule;
2161: while (*cssRule != EOS && *cssRule != '\'')
2162: cssRule++;
2163: }
1.281 quint 2164: else
1.327 vatton 2165: {
2166: base = cssRule;
2167: while (*cssRule != EOS && *cssRule != ')')
2168: cssRule++;
2169: }
1.281 quint 2170: /* keep the current position */
2171: ptr = cssRule;
1.402 vatton 2172: if (saved == '(')
1.327 vatton 2173: {
2174: /* remove extra spaces */
2175: if (cssRule[-1] == SPACE)
2176: {
2177: *cssRule = SPACE;
2178: cssRule--;
2179: while (cssRule[-1] == SPACE)
2180: cssRule--;
2181: }
2182: }
1.281 quint 2183: saved = *cssRule;
2184: *cssRule = EOS;
2185: *url = TtaStrdup (base);
2186: *cssRule = saved;
2187: if (saved == '"' || saved == '\'')
1.327 vatton 2188: /* we need to skip the quote character and possible spaces */
2189: {
2190: cssRule++;
2191: cssRule = SkipBlanksAndComments (cssRule);
2192: }
1.281 quint 2193: else
1.327 vatton 2194: cssRule = ptr;
1.281 quint 2195: }
2196: cssRule++;
2197: return cssRule;
2198: }
2199:
2200: /*----------------------------------------------------------------------
1.302 quint 2201: ParseCSSImageCallback: Callback called asynchronously by
2202: FetchImage when a CSS image (background-image or list-style-image)
2203: has been fetched.
2204: ----------------------------------------------------------------------*/
2205: void ParseCSSImageCallback (Document doc, Element element, char *file,
1.327 vatton 2206: void *extra, ThotBool isnew)
1.302 quint 2207: {
2208: DisplayMode dispMode = DisplayImmediately;
2209: CSSImageCallbackPtr callblock;
2210: Element el;
2211: PSchema tsch;
1.401 vatton 2212: Document redisplaydoc;
2213: PInfoPtr pInfo = NULL;
1.302 quint 2214: CSSInfoPtr css;
2215: PresentationContext ctxt;
2216: PresentationValue image;
2217: PresentationValue value;
1.400 vatton 2218: ThotBool found;
1.302 quint 2219:
2220: callblock = (CSSImageCallbackPtr) extra;
2221: if (callblock == NULL)
2222: return;
2223:
1.400 vatton 2224: css = callblock->css;
1.302 quint 2225: el = callblock->el;
2226: tsch = callblock->tsch;
2227: ctxt = callblock->ctxt;
1.401 vatton 2228: redisplaydoc = ctxt->doc;
1.302 quint 2229: if (doc == 0 && !isnew)
2230: /* apply to the current document only */
1.401 vatton 2231: doc = redisplaydoc;
1.302 quint 2232: if (doc)
1.401 vatton 2233: redisplaydoc = doc;
1.302 quint 2234: else
2235: {
2236: /* check if the CSS still exists */
2237: css = CSSList;
2238: while (css && css != callblock->css)
1.327 vatton 2239: css = css->NextCSS;
1.302 quint 2240: if (css == NULL)
1.400 vatton 2241: // the presentation schema doesn't exist anymore
1.327 vatton 2242: tsch = NULL;
1.302 quint 2243: }
1.400 vatton 2244:
1.401 vatton 2245: if (tsch && css && ctxt && redisplaydoc)
1.400 vatton 2246: {
2247: // check if the presentation schema is still there
1.401 vatton 2248: pInfo = css->infos[redisplaydoc];
2249: if (pInfo == NULL && DocumentURLs[redisplaydoc] == NULL)
2250: {
2251: // the redisplaydoc was probably an object
2252: while (redisplaydoc > 0 && pInfo == 0)
2253: pInfo = css->infos[--redisplaydoc];
2254: if (redisplaydoc)
2255: ctxt->doc = redisplaydoc;
2256: }
2257:
1.400 vatton 2258: found = FALSE;
2259: while (!found && pInfo)
2260: {
2261: found = (pInfo->PiSchemas && tsch == pInfo->PiSchemas->PiPSchema);
2262: pInfo = pInfo->PiNext;
2263: }
2264: if (!found)
2265: tsch = NULL;
2266: }
2267:
1.302 quint 2268: if (el || tsch)
2269: {
2270: /* Ok the image was fetched */
2271: image.typed_data.unit = UNIT_REL;
2272: image.typed_data.real = FALSE;
2273: image.pointer = file;
2274: TtaSetStylePresentation (callblock->ruleType, el, tsch, ctxt, image);
2275:
2276: if (callblock->ruleType == PRBackgroundPicture)
1.327 vatton 2277: /* enforce the showbox */
2278: {
2279: value.typed_data.value = 1;
2280: value.typed_data.unit = UNIT_REL;
2281: value.typed_data.real = FALSE;
2282: TtaSetStylePresentation (PRShowBox, el, tsch, ctxt, value);
2283: }
1.302 quint 2284: /* check if the context can be freed */
2285: ctxt->uses -= 1;
2286: if (ctxt->uses == 0)
1.327 vatton 2287: /* no other image loading */
2288: TtaFreeMemory (ctxt);
1.302 quint 2289: }
2290:
2291: TtaFreeMemory (callblock);
1.330 cvs 2292: if (css)
2293: RedisplayImages--;
1.401 vatton 2294: if (redisplaydoc &&
2295: /* check if all background images are now loaded */
2296: (css == NULL || (pInfo && Style_parsing == 0 && RedisplayImages == 0)))
2297: {
2298: /* don't manage a document used by make book */
2299: if (DocumentMeta[redisplaydoc] == NULL ||
2300: DocumentMeta[redisplaydoc]->method != CE_MAKEBOOK)
1.327 vatton 2301: {
2302: /* Change the Display Mode to take into account the new
2303: presentation */
1.401 vatton 2304: dispMode = TtaGetDisplayMode (redisplaydoc);
1.313 vatton 2305: /* force the redisplay of this box */
1.401 vatton 2306: TtaSetDisplayMode (redisplaydoc, NoComputedDisplay);
2307: TtaSetDisplayMode (redisplaydoc, dispMode);
1.327 vatton 2308: }
1.330 cvs 2309: RedisplayBGImage = FALSE;
1.302 quint 2310: }
1.310 vatton 2311: else
1.328 vatton 2312: RedisplayBGImage = TRUE;
1.302 quint 2313: }
2314:
2315: /*----------------------------------------------------------------------
2316: SetCSSImage fetch the image referred by a background-image or a
2317: list-style-image property.
2318: ----------------------------------------------------------------------*/
2319: static char *SetCSSImage (Element element, PSchema tsch,
1.327 vatton 2320: PresentationContext ctxt, char *cssRule,
2321: CSSInfoPtr css, unsigned int ruleType)
1.302 quint 2322: {
2323: CSSImageCallbackPtr callblock;
2324: Element el;
1.304 cvs 2325: PresentationValue image;
1.366 vatton 2326: char *url, *ptr;
1.302 quint 2327: char *bg_image;
2328: char tempname[MAX_LENGTH];
2329: char imgname[MAX_LENGTH];
2330:
2331: if (element)
2332: el = element;
2333: else
2334: /* default element for FetchImage */
2335: el = TtaGetMainRoot (ctxt->doc);
2336: url = NULL;
1.370 vatton 2337: image.typed_data.real = FALSE;
1.302 quint 2338: cssRule = ParseCSSUrl (cssRule, &url);
1.414 vatton 2339: if (strlen (url) > MAX_LENGTH / 4)
2340: url[MAX_LENGTH / 4] = EOS;
1.366 vatton 2341: ptr = cssRule;
1.302 quint 2342: if (ctxt->destroy)
2343: {
2344: /* remove the background image PRule */
2345: image.pointer = NULL;
1.366 vatton 2346: TtaSetStylePresentation (ruleType, element, tsch, ctxt, image);
1.302 quint 2347: }
1.366 vatton 2348: else if (url)
1.302 quint 2349: {
1.366 vatton 2350: if (css && css->url)
2351: /* the image concerns a CSS file */
2352: NormalizeURL (url, 0, tempname, imgname, css->url);
2353: else
2354: /* the image concerns a style element */
2355: NormalizeURL (url, ctxt->doc, tempname, imgname, NULL);
2356: if (DoDialog)
2357: {
2358: if (ruleType == PRBackgroundPicture)
2359: DisplayStyleValue ("background-image", tempname, &tempname[MAX_LENGTH-1]);
2360: else if (ruleType == PRListStyleImage)
2361: DisplayStyleValue ("list-style-image", tempname, &tempname[MAX_LENGTH-1]);
2362: else if (ruleType == PRContentURL)
2363: DisplayStyleValue ("", ptr, cssRule);
2364: }
2365: else if (DoApply)
2366: {
2367: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
2368: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
2369: /* background images are enabled */
2370: {
2371: callblock = (CSSImageCallbackPtr) TtaGetMemory (sizeof (CSSImageCallbackBlock));
2372: if (callblock)
2373: {
2374: callblock->el = element;
2375: callblock->tsch = tsch;
2376: callblock->css = css;
2377: callblock->ctxt = ctxt;
2378: callblock->ruleType = ruleType;
2379: /* new use of the context */
2380: ctxt->uses += 1;
2381: /* check if the image url is related to an external CSS */
2382: if (css)
2383: {
2384: /* fetch and display background image of element */
2385: if (FetchImage (0, el, tempname, AMAYA_LOAD_IMAGE,
2386: ParseCSSImageCallback, callblock))
2387: RedisplayImages++;
2388: }
1.327 vatton 2389: else
1.366 vatton 2390: FetchImage (ctxt->doc, el, url, AMAYA_LOAD_IMAGE,
2391: ParseCSSImageCallback, callblock);
1.327 vatton 2392: }
2393: }
2394: }
1.366 vatton 2395: TtaFreeMemory (url);
1.302 quint 2396: }
2397: return (cssRule);
2398: }
2399:
2400: /*----------------------------------------------------------------------
1.327 vatton 2401: ParseACSSListStyleImage: parse a CSS list-style-image
2402: attribute string.
1.1 cvs 2403: ----------------------------------------------------------------------*/
1.318 vatton 2404: static char *ParseACSSListStyleImage (Element element, PSchema tsch,
1.327 vatton 2405: PresentationContext ctxt,
2406: char *cssRule, CSSInfoPtr css,
2407: ThotBool isHTML)
1.1 cvs 2408: {
1.288 vatton 2409: char *url;
1.366 vatton 2410: char *start_value;
1.293 quint 2411: PresentationValue pval;
1.281 quint 2412:
1.293 quint 2413: pval.typed_data.unit = UNIT_REL;
2414: pval.typed_data.real = FALSE;
1.281 quint 2415: url = NULL;
2416: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2417: start_value = cssRule;
1.281 quint 2418: if (!strncasecmp (cssRule, "none", 4))
2419: {
2420: cssRule += 4;
1.302 quint 2421: pval.typed_data.value = 0;
1.366 vatton 2422: if (DoDialog)
2423: DisplayStyleValue ("list-style-image", start_value, cssRule);
2424: else if (DoApply)
1.327 vatton 2425: TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
1.281 quint 2426: }
2427: else if (!strncasecmp (cssRule, "url", 3))
2428: {
2429: cssRule += 3;
1.302 quint 2430: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 2431: PRListStyleImage);
1.281 quint 2432: }
2433: else if (!strncasecmp (cssRule, "inherit", 7))
1.288 vatton 2434: {
2435: cssRule += 7;
1.293 quint 2436: pval.typed_data.unit = VALUE_INHERIT;
1.366 vatton 2437: if (DoDialog)
2438: DisplayStyleValue ("list-style-image", start_value, cssRule);
2439: else if (DoApply)
1.327 vatton 2440: TtaSetStylePresentation (PRListStyleImage, element, tsch, ctxt, pval);
2441: }
1.281 quint 2442: else
1.295 vatton 2443: cssRule = SkipValue ("Invalid list-style-image value", cssRule);
1.1 cvs 2444: return (cssRule);
2445: }
2446:
2447: /*----------------------------------------------------------------------
1.327 vatton 2448: ParseCSSListStyleImage: parse a CSS list-style-image
2449: attribute string.
1.318 vatton 2450: ----------------------------------------------------------------------*/
2451: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1.327 vatton 2452: PresentationContext ctxt,
2453: char *cssRule, CSSInfoPtr css,
2454: ThotBool isHTML)
1.318 vatton 2455: {
2456: char *ptr = cssRule;
2457: cssRule = ParseACSSListStyleImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 2458: isHTML);
1.318 vatton 2459: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-image value");
2460: return cssRule;
2461: }
2462:
2463: /*----------------------------------------------------------------------
1.327 vatton 2464: ParseACSSListStylePosition: parse a CSS list-style-position
2465: attribute string.
1.1 cvs 2466: ----------------------------------------------------------------------*/
1.318 vatton 2467: static char *ParseACSSListStylePosition (Element element, PSchema tsch,
1.327 vatton 2468: PresentationContext context,
2469: char *cssRule, CSSInfoPtr css,
2470: ThotBool isHTML)
1.1 cvs 2471: {
1.281 quint 2472: PresentationValue pval;
1.366 vatton 2473: char *start_value;
1.281 quint 2474:
2475: pval.typed_data.unit = UNIT_REL;
2476: pval.typed_data.real = FALSE;
2477: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2478: start_value = cssRule;
1.281 quint 2479: if (!strncasecmp (cssRule, "inside", 6))
1.288 vatton 2480: {
2481: pval.typed_data.value = Inside;
2482: cssRule += 6;
2483: }
1.281 quint 2484: else if (!strncasecmp (cssRule, "outside", 7))
1.288 vatton 2485: {
2486: pval.typed_data.value = Outside;
2487: cssRule += 7;
2488: }
1.293 quint 2489: else if (!strncasecmp (cssRule, "inherit", 7))
2490: {
2491: pval.typed_data.unit = VALUE_INHERIT;
2492: cssRule += 7;
2493: }
1.281 quint 2494: else
2495: {
1.293 quint 2496: cssRule = SkipValue ("Invalid list-style-position value", cssRule);
1.281 quint 2497: return (cssRule);
2498: }
1.293 quint 2499:
1.366 vatton 2500: if (DoDialog)
2501: DisplayStyleValue ("list-style-position", start_value, cssRule);
2502: else if (DoApply)
1.295 vatton 2503: TtaSetStylePresentation (PRListStylePosition, element, tsch, context, pval);
1.327 vatton 2504: return (cssRule);
1.318 vatton 2505: }
2506:
2507: /*----------------------------------------------------------------------
1.327 vatton 2508: ParseCSSListStylePosition: parse a CSS list-style-position
2509: attribute string.
1.318 vatton 2510: ----------------------------------------------------------------------*/
2511: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
1.327 vatton 2512: PresentationContext context,
2513: char *cssRule, CSSInfoPtr css,
2514: ThotBool isHTML)
1.318 vatton 2515: {
2516: char *ptr = cssRule;
2517: cssRule = ParseACSSListStylePosition (element, tsch, context, cssRule, css,
1.327 vatton 2518: isHTML);
1.288 vatton 2519: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style-position value");
1.318 vatton 2520: return cssRule;
1.1 cvs 2521: }
2522:
2523: /*----------------------------------------------------------------------
1.327 vatton 2524: ParseCSSListStyle: parse a CSS list-style value string.
1.1 cvs 2525: ----------------------------------------------------------------------*/
1.79 cvs 2526: static char *ParseCSSListStyle (Element element, PSchema tsch,
1.327 vatton 2527: PresentationContext ctxt, char *cssRule,
2528: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2529: {
1.318 vatton 2530: char *ptr = cssRule;
2531: int skippedNL;
1.281 quint 2532:
2533: cssRule = SkipBlanksAndComments (cssRule);
1.301 vatton 2534: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.281 quint 2535: {
1.316 quint 2536: skippedNL = NewLineSkipped;
1.281 quint 2537: /* perhaps a list-style-image */
2538: if (!strncasecmp (cssRule, "url", 3))
1.327 vatton 2539: cssRule = ParseACSSListStyleImage (element, tsch, ctxt, cssRule, css,
2540: isHTML);
1.281 quint 2541: /* perhaps a list-style-position */
2542: else if (!strncasecmp (cssRule, "inside", 6) ||
2543: !strncasecmp (cssRule, "outside", 7))
1.327 vatton 2544: cssRule = ParseACSSListStylePosition (element, tsch, ctxt, cssRule,
2545: css, isHTML);
1.281 quint 2546: /* perhaps a list-style-type */
2547: else if (!strncasecmp (cssRule, "disc", 4) ||
1.327 vatton 2548: !strncasecmp (cssRule, "circle", 6) ||
2549: !strncasecmp (cssRule, "square", 6) ||
2550: !strncasecmp (cssRule, "decimal", 7) ||
2551: !strncasecmp (cssRule, "decimal-leading-zero", 20) ||
2552: !strncasecmp (cssRule, "lower-roman", 11) ||
2553: !strncasecmp (cssRule, "upper-roman", 11) ||
2554: !strncasecmp (cssRule, "lower-greek", 11) ||
2555: !strncasecmp (cssRule, "lower-latin", 11) ||
2556: !strncasecmp (cssRule, "lower-alpha", 11) ||
2557: !strncasecmp (cssRule, "upper-latin", 11) ||
2558: !strncasecmp (cssRule, "upper-alpha", 11) ||
2559: !strncasecmp (cssRule, "armenian", 8) ||
2560: !strncasecmp (cssRule, "georgian", 8) ||
2561: !strncasecmp (cssRule, "none", 4) ||
2562: !strncasecmp (cssRule, "inherit", 7))
2563: cssRule = ParseACSSListStyleType (element, tsch, ctxt, cssRule, css,
2564: isHTML);
1.281 quint 2565: else
1.327 vatton 2566: {
2567: NewLineSkipped = skippedNL;
2568: /* rule not found */
2569: cssRule = SkipProperty (cssRule, FALSE);
2570: }
1.281 quint 2571: cssRule = SkipBlanksAndComments (cssRule);
2572: }
1.318 vatton 2573: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid list-style value");
1.1 cvs 2574: return (cssRule);
2575: }
2576:
2577: /*----------------------------------------------------------------------
1.327 vatton 2578: ParseCSSTextAlign: parse a CSS text-align
2579: attribute string.
1.1 cvs 2580: ----------------------------------------------------------------------*/
1.79 cvs 2581: static char *ParseCSSTextAlign (Element element, PSchema tsch,
1.327 vatton 2582: PresentationContext context, char *cssRule,
2583: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2584: {
1.366 vatton 2585: char *ptr;
1.327 vatton 2586: PresentationValue align;
2587:
2588: align.typed_data.value = 0;
2589: align.typed_data.unit = UNIT_REL;
2590: align.typed_data.real = FALSE;
2591:
2592: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2593: ptr = cssRule;
1.327 vatton 2594: if (!strncasecmp (cssRule, "left", 4))
2595: {
2596: align.typed_data.value = AdjustLeft;
2597: cssRule += 4;
2598: }
2599: else if (!strncasecmp (cssRule, "right", 5))
2600: {
2601: align.typed_data.value = AdjustRight;
2602: cssRule += 5;
2603: }
2604: else if (!strncasecmp (cssRule, "center", 6))
2605: {
2606: align.typed_data.value = Centered;
2607: cssRule += 6;
2608: }
2609: else if (!strncasecmp (cssRule, "justify", 7))
2610: {
2611: align.typed_data.value = Justify;
2612: cssRule += 7;
2613: }
2614: else
2615: {
2616: cssRule = SkipValue ("Invalid text-align value", cssRule);
2617: return (cssRule);
2618: }
1.1 cvs 2619:
1.327 vatton 2620: /*
2621: * install the new presentation.
2622: */
1.366 vatton 2623: if (align.typed_data.value)
2624: {
2625: if (DoDialog)
2626: DisplayStyleValue ("text-align", ptr, cssRule);
2627: else if (DoApply)
2628: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
2629: }
1.327 vatton 2630: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-align value");
2631: return (cssRule);
1.1 cvs 2632: }
2633:
2634: /*----------------------------------------------------------------------
1.243 quint 2635: ParseCSSTextAnchor: parse a CSS text-anchor property (SVG property)
2636: We use the Thot Adjust PRule to represent the text-anchor property
2637: for CSS 1.0, as Adjust is not used otherwise in this context.
2638: ----------------------------------------------------------------------*/
2639: static char *ParseCSSTextAnchor (Element element, PSchema tsch,
1.327 vatton 2640: PresentationContext context, char *cssRule,
2641: CSSInfoPtr css, ThotBool isHTML)
1.243 quint 2642: {
1.327 vatton 2643: PresentationValue align;
1.366 vatton 2644: char *ptr;
1.327 vatton 2645:
2646: align.typed_data.value = 0;
2647: align.typed_data.unit = UNIT_REL;
2648: align.typed_data.real = FALSE;
1.243 quint 2649:
1.327 vatton 2650: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2651: ptr = cssRule;
1.327 vatton 2652: if (!strncasecmp (cssRule, "start", 5))
2653: {
2654: align.typed_data.value = AdjustLeft;
2655: cssRule += 5;
2656: }
2657: else if (!strncasecmp (cssRule, "middle", 6))
2658: {
2659: align.typed_data.value = Centered;
2660: cssRule += 6;
2661: }
2662: else if (!strncasecmp (cssRule, "end", 3))
2663: {
2664: align.typed_data.value = AdjustRight;
2665: cssRule += 3;
2666: }
2667: else if (!strncasecmp (cssRule, "inherit", 7))
2668: {
2669: align.typed_data.unit = VALUE_INHERIT;
2670: cssRule += 7;
2671: }
2672: else
2673: {
2674: cssRule = SkipValue ("Invalid text-anchor value", cssRule);
1.295 vatton 2675: return (cssRule);
1.327 vatton 2676: }
1.243 quint 2677:
1.327 vatton 2678: /*
2679: * install the new presentation.
2680: */
1.366 vatton 2681: if (align.typed_data.value || align.typed_data.unit == VALUE_INHERIT)
2682: {
2683: if (DoDialog)
2684: DisplayStyleValue ("text-anchor", ptr, cssRule);
2685: else if (DoApply)
2686: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
2687: }
1.327 vatton 2688: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-anchor value");
2689: return (cssRule);
1.243 quint 2690: }
2691:
2692: /*----------------------------------------------------------------------
1.327 vatton 2693: ParseCSSDirection: parse a CSS direction property
1.112 quint 2694: ----------------------------------------------------------------------*/
2695: static char *ParseCSSDirection (Element element, PSchema tsch,
1.327 vatton 2696: PresentationContext context, char *cssRule,
2697: CSSInfoPtr css, ThotBool isHTML)
1.112 quint 2698: {
1.327 vatton 2699: PresentationValue direction;
1.366 vatton 2700: char *ptr;
1.327 vatton 2701:
2702: direction.typed_data.value = 0;
2703: direction.typed_data.unit = UNIT_REL;
2704: direction.typed_data.real = FALSE;
2705:
2706: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2707: ptr = cssRule;
1.327 vatton 2708: if (!strncasecmp (cssRule, "ltr", 3))
2709: {
2710: direction.typed_data.value = LeftToRight;
2711: cssRule += 3;
2712: }
2713: else if (!strncasecmp (cssRule, "rtl", 3))
2714: {
2715: direction.typed_data.value = RightToLeft;
2716: cssRule += 3;
2717: }
2718: else if (!strncasecmp (cssRule, "inherit", 7))
2719: {
2720: direction.typed_data.unit = VALUE_INHERIT;
2721: cssRule += 7;
2722: }
2723: else
2724: {
2725: cssRule = SkipValue ("Invalid direction value", cssRule);
2726: return (cssRule);
2727: }
1.112 quint 2728:
1.327 vatton 2729: /*
2730: * install the new presentation.
2731: */
1.366 vatton 2732: if (direction.typed_data.value || direction.typed_data.unit == VALUE_INHERIT)
2733: {
2734: if (DoDialog)
2735: DisplayStyleValue ("direction", ptr, cssRule);
2736: else if (DoApply)
2737: TtaSetStylePresentation (PRDirection, element, tsch, context, direction);
2738: }
1.327 vatton 2739: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid direction value");
2740: return (cssRule);
1.112 quint 2741: }
2742:
2743: /*----------------------------------------------------------------------
1.327 vatton 2744: ParseCSSUnicodeBidi: parse a CSS unicode-bidi property
1.113 quint 2745: ----------------------------------------------------------------------*/
2746: static char *ParseCSSUnicodeBidi (Element element, PSchema tsch,
1.327 vatton 2747: PresentationContext context, char *cssRule,
2748: CSSInfoPtr css, ThotBool isHTML)
1.113 quint 2749: {
1.327 vatton 2750: PresentationValue bidi;
1.366 vatton 2751: char *ptr;
1.113 quint 2752:
1.327 vatton 2753: bidi.typed_data.value = 0;
2754: bidi.typed_data.unit = UNIT_REL;
2755: bidi.typed_data.real = FALSE;
2756:
2757: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2758: ptr = cssRule;
1.327 vatton 2759: if (!strncasecmp (cssRule, "normal", 6))
2760: {
2761: bidi.typed_data.value = Normal;
2762: cssRule += 6;
2763: }
2764: else if (!strncasecmp (cssRule, "embed", 5))
2765: {
2766: bidi.typed_data.value = Embed;
2767: cssRule += 5;
2768: }
2769: else if (!strncasecmp (cssRule, "bidi-override", 13))
2770: {
2771: bidi.typed_data.value = Override;
2772: cssRule += 13;
2773: }
2774: else if (!strncasecmp (cssRule, "inherit", 7))
2775: {
2776: bidi.typed_data.unit = VALUE_INHERIT;
2777: cssRule += 7;
2778: }
2779: else
2780: {
2781: cssRule = SkipValue ("Invalid unicode-bidi value", cssRule);
1.295 vatton 2782: return (cssRule);
1.327 vatton 2783: }
1.113 quint 2784:
1.327 vatton 2785: /*
2786: * install the new presentation.
2787: */
1.366 vatton 2788: if (bidi.typed_data.value || bidi.typed_data.unit == VALUE_INHERIT)
2789: {
2790: if (DoDialog)
2791: DisplayStyleValue ("unicode-bidi", ptr, cssRule);
2792: else if (DoApply)
2793: TtaSetStylePresentation (PRUnicodeBidi, element, tsch, context, bidi);
2794: }
1.327 vatton 2795: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid unicode-bidi value");
2796: return (cssRule);
1.113 quint 2797: }
2798:
2799: /*----------------------------------------------------------------------
1.327 vatton 2800: ParseCSSTextIndent: parse a CSS text-indent
2801: attribute string.
1.1 cvs 2802: ----------------------------------------------------------------------*/
1.79 cvs 2803: static char *ParseCSSTextIndent (Element element, PSchema tsch,
1.327 vatton 2804: PresentationContext context, char *cssRule,
2805: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2806: {
1.327 vatton 2807: PresentationValue pval;
2808: char *ptr;
1.1 cvs 2809:
1.370 vatton 2810: pval.typed_data.real = FALSE;
1.327 vatton 2811: cssRule = SkipBlanksAndComments (cssRule);
2812: ptr = cssRule;
2813: cssRule = ParseCSSUnit (cssRule, &pval);
1.387 quint 2814: if (pval.typed_data.value == 0 &&
2815: pval.typed_data.unit != UNIT_INVALID)
1.327 vatton 2816: pval.typed_data.unit = UNIT_PX;
2817: else if (pval.typed_data.unit == UNIT_INVALID ||
2818: pval.typed_data.unit == UNIT_BOX)
2819: {
2820: CSSParseError ("Invalid text-indent value", ptr, cssRule);
2821: return (cssRule);
2822: }
2823: /* install the attribute */
1.366 vatton 2824: if (DoDialog)
2825: DisplayStyleValue ("text-indent", ptr, cssRule);
2826: else if (DoApply)
1.327 vatton 2827: TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
2828: return (cssRule);
1.1 cvs 2829: }
2830:
2831: /*----------------------------------------------------------------------
1.327 vatton 2832: ParseCSSTextTransform: parse a CSS text-transform
2833: attribute string.
1.1 cvs 2834: ----------------------------------------------------------------------*/
1.79 cvs 2835: static char *ParseCSSTextTransform (Element element, PSchema tsch,
1.327 vatton 2836: PresentationContext context, char *cssRule,
2837: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2838: {
1.366 vatton 2839: char *ptr;
2840:
2841: cssRule = SkipBlanksAndComments (cssRule);
2842: ptr = cssRule;
1.168 vatton 2843: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 2844: if (DoDialog)
2845: DisplayStyleValue ("text-transform", ptr, cssRule);
1.1 cvs 2846: return (cssRule);
2847: }
2848:
2849: /*----------------------------------------------------------------------
1.327 vatton 2850: ParseCSSVerticalAlign: parse a CSS vertical-align
2851: attribute string.
1.1 cvs 2852: ----------------------------------------------------------------------*/
1.79 cvs 2853: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
1.327 vatton 2854: PresentationContext context, char *cssRule,
2855: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2856: {
1.273 quint 2857: char *ptr;
2858: PresentationValue pval;
2859:
2860: pval.typed_data.unit = UNIT_REL;
2861: pval.typed_data.real = FALSE;
2862: cssRule = SkipBlanksAndComments (cssRule);
1.288 vatton 2863: ptr = cssRule;
1.273 quint 2864: if (!strncasecmp (cssRule, "baseline", 8))
2865: {
2866: pval.typed_data.value = 0;
1.288 vatton 2867: cssRule += 8;
1.273 quint 2868: }
2869: else if (!strncasecmp (cssRule, "sub", 3))
2870: {
2871: pval.typed_data.value = -3;
1.288 vatton 2872: cssRule += 3;
1.273 quint 2873: }
2874: else if (!strncasecmp (cssRule, "super", 5))
2875: {
2876: pval.typed_data.value = 4;
1.288 vatton 2877: cssRule += 5;
1.273 quint 2878: }
2879: else if (!strncasecmp (cssRule, "top", 3))
2880: {
1.275 quint 2881: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2882: pval.typed_data.value = 0;
1.288 vatton 2883: cssRule += 3;
1.273 quint 2884: }
2885: else if (!strncasecmp (cssRule, "text-top", 8))
2886: {
1.275 quint 2887: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2888: pval.typed_data.value = 0;
1.288 vatton 2889: cssRule += 8;
1.273 quint 2890: }
2891: else if (!strncasecmp (cssRule, "middle", 6))
2892: {
1.275 quint 2893: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2894: pval.typed_data.value = 0;
1.288 vatton 2895: cssRule += 6;
1.273 quint 2896: }
2897: else if (!strncasecmp (cssRule, "bottom", 6))
2898: {
1.275 quint 2899: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2900: pval.typed_data.value = 0;
1.288 vatton 2901: cssRule += 6;
1.273 quint 2902: }
2903: else if (!strncasecmp (cssRule, "text-bottom", 11))
2904: {
1.275 quint 2905: pval.typed_data.unit = UNIT_INVALID; /* Not supported yet */
1.274 vatton 2906: pval.typed_data.value = 0;
1.288 vatton 2907: cssRule += 11;
1.273 quint 2908: }
2909: else if (!strncasecmp (cssRule, "inherit", 7))
2910: {
1.293 quint 2911: pval.typed_data.unit = VALUE_INHERIT;
1.274 vatton 2912: pval.typed_data.value = 0;
1.288 vatton 2913: cssRule +=7;
1.273 quint 2914: }
2915: else
2916: {
2917: /* parse <percentage> or <length> */
2918: cssRule = ParseCSSUnit (cssRule, &pval);
2919: if (pval.typed_data.unit == UNIT_INVALID)
1.327 vatton 2920: {
2921: pval.typed_data.value = 0;
2922: CSSParseError ("Invalid vertical-align value", ptr, cssRule);
2923: return (cssRule);
2924: }
1.273 quint 2925: else if (pval.typed_data.value == 0)
1.327 vatton 2926: pval.typed_data.unit = UNIT_PX;
1.273 quint 2927: else if (pval.typed_data.unit == UNIT_BOX)
1.327 vatton 2928: pval.typed_data.unit = UNIT_EM;
1.273 quint 2929: else if (pval.typed_data.unit == UNIT_PERCENT)
1.327 vatton 2930: /* it's a percentage */
2931: {
2932: /* convert it into a relative size */
2933: pval.typed_data.unit = UNIT_REL;
2934: pval.typed_data.value /= 10;
2935: }
1.273 quint 2936: }
1.295 vatton 2937:
1.366 vatton 2938: if (pval.typed_data.unit != UNIT_INVALID)
2939: {
2940: if (DoDialog)
2941: DisplayStyleValue ("vertical-align", ptr, cssRule);
2942: else if (DoApply)
2943: TtaSetStylePresentation (PRHorizRef, element, tsch, context, pval);
2944: }
1.288 vatton 2945: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid vertical-align value");
1.1 cvs 2946: return (cssRule);
2947: }
2948:
2949: /*----------------------------------------------------------------------
1.327 vatton 2950: ParseCSSWhiteSpace: parse a CSS white-space
2951: attribute string.
1.1 cvs 2952: ----------------------------------------------------------------------*/
1.79 cvs 2953: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
1.327 vatton 2954: PresentationContext context, char *cssRule,
2955: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2956: {
1.366 vatton 2957: char *ptr;
1.288 vatton 2958:
1.327 vatton 2959: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 2960: ptr = cssRule;
1.327 vatton 2961: if (!strncasecmp (cssRule, "normal", 6))
2962: cssRule += 6;
2963: else if (!strncasecmp (cssRule, "pre", 3))
2964: cssRule += 3;
2965: else if (!strncasecmp (cssRule, "nowrap", 6))
2966: cssRule += 6;
2967: else if (!strncasecmp (cssRule, "pre-wrap", 8))
2968: cssRule += 8;
2969: else if (!strncasecmp (cssRule, "pre-line", 8))
2970: cssRule += 8;
2971: else if (!strncasecmp (cssRule, "inherit", 7))
2972: cssRule += 7;
2973: else
2974: cssRule = SkipValue ("Invalid white-space value", cssRule);
2975:
1.387 quint 2976: if (ptr != cssRule && DoDialog)
1.366 vatton 2977: DisplayStyleValue ("white-space", ptr, cssRule);
1.327 vatton 2978: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid white-space value");
2979: return (cssRule);
1.1 cvs 2980: }
2981:
2982: /*----------------------------------------------------------------------
1.327 vatton 2983: ParseCSSWordSpacing: parse a CSS word-spacing
2984: attribute string.
1.1 cvs 2985: ----------------------------------------------------------------------*/
1.79 cvs 2986: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
1.327 vatton 2987: PresentationContext context, char *cssRule,
2988: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2989: {
1.366 vatton 2990: char *ptr;
2991:
2992: cssRule = SkipBlanksAndComments (cssRule);
2993: ptr = cssRule;
1.168 vatton 2994: cssRule = SkipValue (NULL, cssRule);
1.366 vatton 2995: if (DoDialog)
2996: DisplayStyleValue ("word-spacing", ptr, cssRule);
1.1 cvs 2997: return (cssRule);
2998: }
2999:
3000: /*----------------------------------------------------------------------
1.327 vatton 3001: ParseCSSLineHeight: parse a CSS line-height property
1.25 cvs 3002: ----------------------------------------------------------------------*/
1.162 quint 3003: static char *ParseCSSLineHeight (Element element, PSchema tsch,
1.327 vatton 3004: PresentationContext context, char *cssRule,
3005: CSSInfoPtr css, ThotBool isHTML)
1.25 cvs 3006: {
1.162 quint 3007: PresentationValue pval;
1.288 vatton 3008: char *ptr;
1.162 quint 3009:
1.370 vatton 3010: pval.typed_data.real = FALSE;
1.366 vatton 3011: cssRule = SkipBlanksAndComments (cssRule);
1.162 quint 3012: ptr = cssRule;
3013: if (!strncasecmp (cssRule, "normal", 6))
3014: {
1.184 vatton 3015: pval.typed_data.unit = UNIT_REL;
1.162 quint 3016: pval.typed_data.real = TRUE;
3017: pval.typed_data.value = 1100;
1.288 vatton 3018: cssRule += 6;
1.162 quint 3019: }
3020: else if (!strncasecmp (cssRule, "inherit", 7))
3021: {
1.293 quint 3022: pval.typed_data.unit = VALUE_INHERIT;
1.354 quint 3023: cssRule += 7;
1.162 quint 3024: }
3025: else
3026: cssRule = ParseCSSUnit (cssRule, &pval);
1.25 cvs 3027:
1.184 vatton 3028: if (pval.typed_data.unit == UNIT_INVALID)
1.168 vatton 3029: CSSParseError ("Invalid line-height value", ptr, cssRule);
1.387 quint 3030: else if (DoDialog)
1.366 vatton 3031: DisplayStyleValue ("line-height", ptr, cssRule);
1.162 quint 3032: else if (DoApply)
3033: {
1.166 vatton 3034: /* install the new presentation */
1.184 vatton 3035: if (pval.typed_data.unit == UNIT_BOX)
1.327 vatton 3036: pval.typed_data.unit = UNIT_EM;
1.162 quint 3037: TtaSetStylePresentation (PRLineSpacing, element, tsch, context, pval);
3038: }
3039: return (cssRule);
1.25 cvs 3040: }
3041:
3042: /*----------------------------------------------------------------------
1.327 vatton 3043: ParseCSSFontSizeAdjust: parse a CSS fontsizeAdjust attr string
3044: we expect the input string describing the attribute to be
3045: xx-small, x-small, small, medium, large, x-large, xx-large
3046: or an absolute size, or an imcrement relative to the parent
1.1 cvs 3047: ----------------------------------------------------------------------*/
1.219 vatton 3048: static char *ParseCSSFontSizeAdjust (Element element, PSchema tsch,
1.327 vatton 3049: PresentationContext context, char *cssRule,
3050: CSSInfoPtr css, ThotBool isHTML)
1.219 vatton 3051: {
1.366 vatton 3052:
3053: cssRule = SkipBlanksAndComments (cssRule);
1.234 vatton 3054: cssRule = SkipProperty (cssRule, FALSE);
1.222 quint 3055: return (cssRule);
1.219 vatton 3056: }
3057:
3058: /*----------------------------------------------------------------------
1.327 vatton 3059: ParseACSSFontSize: parse a CSS font size attr string
3060: we expect the input string describing the attribute to be
3061: xx-small, x-small, small, medium, large, x-large, xx-large
3062: or an absolute size, or an imcrement relative to the parent.
3063: The parameter check is TRUE if the rule is just checked.
1.219 vatton 3064: ----------------------------------------------------------------------*/
1.270 vatton 3065: static char *ParseACSSFontSize (Element element, PSchema tsch,
1.327 vatton 3066: PresentationContext context, char *cssRule,
3067: CSSInfoPtr css, ThotBool isHTML, ThotBool check)
1.1 cvs 3068: {
1.327 vatton 3069: ElementType elType;
3070: PresentationValue pval;
1.369 quint 3071: char *ptr = NULL, *ptr1 = NULL, *ptr2 = NULL;
1.366 vatton 3072: char *start_value;
1.369 quint 3073: ThotBool real, error, linespace = FALSE;
1.327 vatton 3074:
1.369 quint 3075: error = FALSE;
1.327 vatton 3076: pval.typed_data.real = FALSE;
3077: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3078: start_value = cssRule;
1.327 vatton 3079: /* look for a '/' within the current cssRule */
3080: ptr1 = strchr (cssRule, ';');
3081: ptr = strchr (cssRule, '/');
3082: if (ptr && (ptr1 == NULL || ptr < ptr1))
3083: {
3084: /* keep the line spacing rule */
3085: linespace = TRUE;
3086: ptr[0] = EOS;
3087: }
3088: else
3089: ptr = NULL;
3090: ptr1 = cssRule;
1.289 vatton 3091: /* relative size */
1.327 vatton 3092: if (!strncasecmp (cssRule, "larger", 6))
3093: {
3094: pval.typed_data.unit = UNIT_PERCENT;
3095: pval.typed_data.value = 130;
3096: cssRule += 6;
3097: }
3098: else if (!strncasecmp (cssRule, "smaller", 7))
3099: {
3100: pval.typed_data.unit = UNIT_PERCENT;
3101: pval.typed_data.value = 80;
3102: cssRule += 7;
3103: }
3104: /* absolute size */
3105: else if (!strncasecmp (cssRule, "xx-small", 8))
3106: {
3107: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3108: pval.typed_data.value = 6;
1.327 vatton 3109: cssRule += 8;
3110: }
3111: else if (!strncasecmp (cssRule, "x-small", 7))
3112: {
3113: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3114: pval.typed_data.value = 8;
1.327 vatton 3115: cssRule += 7;
3116: }
3117: else if (!strncasecmp (cssRule, "small", 5))
3118: {
3119: pval.typed_data.unit = UNIT_PT;
1.336 vatton 3120: pval.typed_data.value = 10;
1.327 vatton 3121: cssRule += 5;
3122: }
3123: else if (!strncasecmp (cssRule, "medium", 6))
3124: {
3125: pval.typed_data.unit = UNIT_PT;
3126: pval.typed_data.value = 12;
3127: cssRule += 6;
3128: }
3129: else if (!strncasecmp (cssRule, "large", 5))
3130: {
3131: pval.typed_data.unit = UNIT_PT;
3132: pval.typed_data.value = 13;
3133: cssRule += 5;
3134: }
3135: else if (!strncasecmp (cssRule, "x-large", 7))
3136: {
3137: pval.typed_data.unit = UNIT_PT;
3138: pval.typed_data.value = 14;
3139: cssRule += 7;
3140: }
3141: else if (!strncasecmp (cssRule, "xx-large", 8))
3142: {
3143: pval.typed_data.unit = UNIT_PT;
3144: pval.typed_data.value = 16;
3145: cssRule += 8;
3146: }
3147: else if (!strncasecmp (cssRule, "inherit", 7))
3148: {
3149: pval.typed_data.unit = VALUE_INHERIT;
3150: pval.typed_data.value = 0;
3151: cssRule += 7;
3152: }
3153: /* length or percentage */
3154: else if (!isdigit (*cssRule) && *cssRule != '.')
3155: {
3156: if (!check)
1.360 vatton 3157: cssRule = SkipValue ("Invalid font-size value", cssRule);
1.369 quint 3158: error = TRUE;
1.327 vatton 3159: }
3160: else
3161: {
3162: cssRule = ParseCSSUnit (cssRule, &pval);
3163: if (pval.typed_data.unit == UNIT_BOX)
3164: /* no unit specified */
3165: {
3166: elType = TtaGetElementType(element);
3167: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
3168: /* we are working for an SVG element. No unit means pixels */
3169: pval.typed_data.unit = UNIT_PX;
3170: }
1.387 quint 3171: if (pval.typed_data.unit == UNIT_INVALID ||
3172: (pval.typed_data.value != 0 && pval.typed_data.unit == UNIT_BOX) ||
3173: pval.typed_data.value < 0)
1.327 vatton 3174: /* not a valid value */
1.369 quint 3175: {
3176: if (!check)
3177: {
3178: ptr2 = SkipWord (cssRule);
3179: CSSParseError ("Invalid font-size value", ptr1, ptr2);
3180: }
3181: error = TRUE;
3182: }
1.327 vatton 3183: else if (pval.typed_data.unit == UNIT_REL && pval.typed_data.value > 0)
3184: /* CSS relative sizes have to be higher than Thot ones */
3185: pval.typed_data.value += 1;
3186: else
3187: {
3188: real = pval.typed_data.real;
3189: if (pval.typed_data.unit == UNIT_EM)
3190: {
3191: if (real)
3192: {
3193: pval.typed_data.value /= 10;
3194: pval.typed_data.real = FALSE;
3195: real = FALSE;
3196: }
3197: else
3198: pval.typed_data.value *= 100;
3199: pval.typed_data.unit = UNIT_PERCENT;
3200: }
3201: else if (pval.typed_data.unit == UNIT_XHEIGHT)
3202: {
3203: /* a font size expressed in ex is converted into a percentage.
3204: For example, "3ex" is converted into "180%", supposing
3205: that 1ex is approximately 0.6 times the height of the
3206: current font */
3207: if (real)
3208: {
3209: pval.typed_data.value *= 6;
3210: pval.typed_data.value /= 100;
3211: pval.typed_data.real = FALSE;
3212: real = FALSE;
3213: }
3214: else
3215: pval.typed_data.value *= 60;
3216: pval.typed_data.unit = UNIT_PERCENT;
3217: }
3218: }
3219: }
3220:
3221: /* install the presentation style */
1.369 quint 3222: if (!check && !error)
1.366 vatton 3223: {
3224: if (DoDialog)
3225: DisplayStyleValue ("font-size", start_value, cssRule);
3226: else if (DoApply)
3227: TtaSetStylePresentation (PRSize, element, tsch, context, pval);
3228: }
1.327 vatton 3229: if (!check && ptr)
3230: cssRule = ParseCSSLineHeight (element, tsch, context, &ptr[1], css, isHTML);
3231: if (linespace)
3232: *ptr = '/';
3233:
3234: return (cssRule);
3235: }
3236:
3237: /*----------------------------------------------------------------------
3238: ParseCSSFontSize: parse a CSS font size attr string
3239: we expect the input string describing the attribute to be
3240: xx-small, x-small, small, medium, large, x-large, xx-large
3241: or an absolute size, or an imcrement relative to the parent
1.270 vatton 3242: ----------------------------------------------------------------------*/
3243: static char *ParseCSSFontSize (Element element, PSchema tsch,
1.327 vatton 3244: PresentationContext context, char *cssRule,
3245: CSSInfoPtr css, ThotBool isHTML)
1.270 vatton 3246: {
1.299 vatton 3247: char *ptr = cssRule;
1.295 vatton 3248: cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.299 vatton 3249: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid font-size value");
1.295 vatton 3250: return cssRule;
1.270 vatton 3251: }
3252:
3253: /*----------------------------------------------------------------------
1.327 vatton 3254: ParseACSSFontFamily: parse a CSS font family string
3255: we expect the input string describing the attribute to be
3256: a common generic font style name
1.1 cvs 3257: ----------------------------------------------------------------------*/
1.268 vatton 3258: static char *ParseACSSFontFamily (Element element, PSchema tsch,
1.327 vatton 3259: PresentationContext context, char *cssRule,
3260: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3261: {
3262: PresentationValue font;
1.252 vatton 3263: char quoteChar, *p;
1.1 cvs 3264:
3265: font.typed_data.value = 0;
1.184 vatton 3266: font.typed_data.unit = UNIT_REL;
1.1 cvs 3267: font.typed_data.real = FALSE;
1.82 cvs 3268: cssRule = SkipBlanksAndComments (cssRule);
3269: if (*cssRule == '"' || *cssRule == '\'')
1.327 vatton 3270: {
3271: quoteChar = *cssRule;
3272: cssRule++;
3273: }
1.1 cvs 3274: else
1.327 vatton 3275: quoteChar = EOS;
1.1 cvs 3276:
1.293 quint 3277: if (!strncasecmp (cssRule, "inherit", 7) && quoteChar == EOS)
3278: {
3279: font.typed_data.unit = VALUE_INHERIT;
3280: cssRule += 7;
3281: }
3282: else if (!strncasecmp (cssRule, "times", 5) &&
1.327 vatton 3283: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 3284: {
1.184 vatton 3285: font.typed_data.value = FontTimes;
1.86 cvs 3286: cssRule += 5;
3287: }
1.92 cvs 3288: else if (!strncasecmp (cssRule, "serif", 5) &&
1.327 vatton 3289: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 3290: {
1.184 vatton 3291: font.typed_data.value = FontTimes;
1.86 cvs 3292: cssRule += 5;
1.92 cvs 3293: if (quoteChar != EOS)
1.327 vatton 3294: cssRule++;
1.86 cvs 3295: }
1.92 cvs 3296: else if (!strncasecmp (cssRule, "helvetica", 9) &&
1.327 vatton 3297: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 3298: {
1.327 vatton 3299: font.typed_data.value = FontHelvetica;
1.86 cvs 3300: cssRule += 9;
1.92 cvs 3301: if (quoteChar != EOS)
1.327 vatton 3302: cssRule++;
1.86 cvs 3303: }
1.92 cvs 3304: else if (!strncasecmp (cssRule, "verdana", 7) &&
1.327 vatton 3305: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 3306: {
1.184 vatton 3307: font.typed_data.value = FontHelvetica;
1.86 cvs 3308: cssRule += 7;
1.92 cvs 3309: if (quoteChar != EOS)
1.327 vatton 3310: cssRule++;
1.86 cvs 3311: }
1.92 cvs 3312: else if (!strncasecmp (cssRule, "sans-serif", 10) &&
1.327 vatton 3313: (quoteChar == EOS || quoteChar == cssRule[10]))
1.86 cvs 3314: {
1.184 vatton 3315: font.typed_data.value = FontHelvetica;
1.86 cvs 3316: cssRule += 10;
1.92 cvs 3317: if (quoteChar != EOS)
1.327 vatton 3318: cssRule++;
1.86 cvs 3319: }
1.268 vatton 3320: else if (!strncasecmp (cssRule, "courier new", 11) &&
1.327 vatton 3321: (quoteChar == EOS || quoteChar == cssRule[11]))
1.268 vatton 3322: {
3323: font.typed_data.value = FontCourier;
3324: cssRule += 11;
3325: if (quoteChar != EOS)
1.327 vatton 3326: cssRule++;
1.268 vatton 3327: }
1.92 cvs 3328: else if (!strncasecmp (cssRule, "courier", 7) &&
1.327 vatton 3329: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 3330: {
1.184 vatton 3331: font.typed_data.value = FontCourier;
1.86 cvs 3332: cssRule += 7;
1.92 cvs 3333: if (quoteChar != EOS)
1.327 vatton 3334: cssRule++;
1.86 cvs 3335: }
1.92 cvs 3336: else if (!strncasecmp (cssRule, "monospace", 9) &&
1.327 vatton 3337: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 3338: {
1.184 vatton 3339: font.typed_data.value = FontCourier;
1.86 cvs 3340: cssRule += 9;
1.92 cvs 3341: if (quoteChar != EOS)
1.327 vatton 3342: cssRule++;
1.86 cvs 3343: }
1.1 cvs 3344: else
3345: /* unknown font name. Skip it */
3346: {
1.252 vatton 3347: p = cssRule;
1.92 cvs 3348: if (quoteChar != EOS)
1.327 vatton 3349: cssRule = SkipQuotedString (cssRule, quoteChar);
1.86 cvs 3350: else
1.383 quint 3351: /* unquoted font name. The name may contain spaces */
3352: {
3353: cssRule = SkipWord (cssRule);
3354: while (*cssRule == SPACE || *cssRule == BSPACE || *cssRule == EOL ||
3355: *cssRule == TAB || *cssRule == __CR__)
3356: {
3357: cssRule = SkipBlanksAndComments (cssRule);
3358: if (*cssRule != ',' && *cssRule != ';' && *cssRule != '}' &&
3359: *cssRule != EOS)
3360: cssRule = SkipWord (cssRule);
3361: }
3362: }
1.252 vatton 3363: while (p == cssRule &&
1.327 vatton 3364: *cssRule != ',' && *cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
3365: {
3366: cssRule++;
3367: p = cssRule;
3368: cssRule = SkipWord (cssRule);
3369: }
1.82 cvs 3370: cssRule = SkipBlanksAndComments (cssRule);
3371: if (*cssRule == ',')
1.327 vatton 3372: {
3373: /* recursive call to ParseCSSFontFamily */
3374: cssRule++;
3375: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3376: return (cssRule);
3377: }
1.1 cvs 3378: }
3379:
1.239 vatton 3380: /* skip other values */
3381: cssRule = SkipBlanksAndComments (cssRule);
3382: while (*cssRule == ',')
3383: {
3384: cssRule++;
3385: cssRule = SkipValue (NULL, cssRule);
3386: cssRule = SkipBlanksAndComments (cssRule);
3387: }
3388:
1.366 vatton 3389: if (font.typed_data.value != 0 || font.typed_data.unit == VALUE_INHERIT)
3390: {
3391: if (!DoDialog && DoApply)
3392: /* install the new presentation */
3393: TtaSetStylePresentation (PRFont, element, tsch, context, font);
3394: }
1.1 cvs 3395: return (cssRule);
3396: }
3397:
3398: /*----------------------------------------------------------------------
1.327 vatton 3399: ParseCSSFontFamily: parse a CSS font family string
3400: we expect the input string describing the attribute to be
3401: a common generic font style name
1.268 vatton 3402: ----------------------------------------------------------------------*/
3403: static char *ParseCSSFontFamily (Element element, PSchema tsch,
1.327 vatton 3404: PresentationContext context, char *cssRule,
3405: CSSInfoPtr css, ThotBool isHTML)
1.268 vatton 3406: {
1.366 vatton 3407: char *start_value;
3408:
3409: cssRule = SkipBlanksAndComments (cssRule);
3410: start_value = cssRule;
1.268 vatton 3411: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3412: /* skip extra values */
1.301 vatton 3413: while (cssRule && *cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.268 vatton 3414: cssRule++;
1.366 vatton 3415: if (DoDialog)
3416: DisplayStyleValue ("font-family", start_value, cssRule);
1.268 vatton 3417: return (cssRule);
3418: }
3419:
3420: /*----------------------------------------------------------------------
1.327 vatton 3421: ParseACSSFontWeight: parse a CSS font weight string
3422: we expect the input string describing the attribute to be
3423: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 3424: ----------------------------------------------------------------------*/
1.263 vatton 3425: static char *ParseACSSFontWeight (Element element, PSchema tsch,
1.327 vatton 3426: PresentationContext context, char *cssRule,
3427: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3428: {
1.327 vatton 3429: PresentationValue weight;
1.366 vatton 3430: char *ptr;
1.1 cvs 3431:
1.327 vatton 3432: weight.typed_data.value = 0;
3433: weight.typed_data.unit = UNIT_REL;
3434: weight.typed_data.real = FALSE;
3435: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3436: ptr = cssRule;
1.351 quint 3437: if (isdigit (*cssRule) && *cssRule != '0' &&
3438: cssRule[1] == '0' && cssRule[2] == '0' &&
3439: (cssRule[3] == EOS || cssRule[3] == SPACE || cssRule[3] == '/' ||
3440: cssRule[3] == ';' || cssRule[3] == '}' || cssRule[3] == EOL ||
3441: cssRule[3] == TAB || cssRule[3] == __CR__))
1.327 vatton 3442: {
1.351 quint 3443: if (!strncasecmp (cssRule, "100", 3))
3444: {
1.379 quint 3445: weight.typed_data.value = -4;
1.351 quint 3446: cssRule = SkipWord (cssRule);
3447: }
3448: else if (!strncasecmp (cssRule, "200", 3))
3449: {
1.379 quint 3450: weight.typed_data.value = -3;
1.351 quint 3451: cssRule = SkipWord (cssRule);
3452: }
3453: else if (!strncasecmp (cssRule, "300", 3))
3454: {
1.379 quint 3455: weight.typed_data.value = -2;
1.351 quint 3456: cssRule = SkipWord (cssRule);
3457: }
3458: else if (!strncasecmp (cssRule, "400", 3))
3459: {
1.379 quint 3460: weight.typed_data.value = -1;
1.351 quint 3461: cssRule = SkipWord (cssRule);
3462: }
3463: else if (!strncasecmp (cssRule, "500", 3))
3464: {
1.379 quint 3465: weight.typed_data.value = 0;
1.351 quint 3466: cssRule = SkipWord (cssRule);
3467: }
3468: else if (!strncasecmp (cssRule, "600", 3))
3469: {
1.379 quint 3470: weight.typed_data.value = +1;
1.351 quint 3471: cssRule = SkipWord (cssRule);
3472: }
3473: else if (!strncasecmp (cssRule, "700", 3))
3474: {
1.379 quint 3475: weight.typed_data.value = +2;
1.351 quint 3476: cssRule = SkipWord (cssRule);
3477: }
3478: else if (!strncasecmp (cssRule, "800", 3))
3479: {
1.379 quint 3480: weight.typed_data.value = +3;
1.351 quint 3481: cssRule = SkipWord (cssRule);
3482: }
3483: else if (!strncasecmp (cssRule, "900", 3))
3484: {
1.379 quint 3485: weight.typed_data.value = +4;
1.351 quint 3486: cssRule = SkipWord (cssRule);
3487: }
1.327 vatton 3488: }
1.351 quint 3489: else if (!strncasecmp (cssRule, "normal", 6))
1.327 vatton 3490: {
3491: weight.typed_data.value = 0;
3492: cssRule = SkipWord (cssRule);
3493: }
1.351 quint 3494: else if (!strncasecmp (cssRule, "bold", 4))
1.327 vatton 3495: {
3496: weight.typed_data.value = +3;
3497: cssRule = SkipWord (cssRule);
3498: }
3499: else if (!strncasecmp (cssRule, "inherit", 7))
3500: {
3501: weight.typed_data.unit = VALUE_INHERIT;
3502: cssRule += 7;
3503: }
1.379 quint 3504: else if (!strncasecmp (cssRule, "bolder", 6))
1.327 vatton 3505: {
1.379 quint 3506: weight.typed_data.value = +2;
3507: cssRule = SkipWord (cssRule);
3508: }
3509:
3510: else if (!strncasecmp (cssRule, "lighter", 7))
3511: {
3512: weight.typed_data.value = -1;
1.327 vatton 3513: cssRule = SkipWord (cssRule);
3514: }
3515: else
3516: return (cssRule);
3517:
3518: /*
3519: * Here we have to reduce since only two font weight values are supported
3520: * by the Thot presentation API.
3521: */
3522: if (weight.typed_data.unit != VALUE_INHERIT)
3523: {
3524: if (weight.typed_data.value > 0)
3525: weight.typed_data.value = WeightBold;
3526: else
3527: weight.typed_data.value = WeightNormal;
3528: }
3529:
3530: /* install the new presentation */
1.366 vatton 3531: if (cssRule != ptr && DoDialog)
3532: DisplayStyleValue ("font-weight", ptr, cssRule);
3533: else if (DoApply)
1.327 vatton 3534: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
3535: return (cssRule);
3536: }
3537:
3538: /*----------------------------------------------------------------------
3539: ParseCSSFontWeight: parse a CSS font weight string
3540: we expect the input string describing the attribute to be
3541: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.263 vatton 3542: ----------------------------------------------------------------------*/
3543: static char *ParseCSSFontWeight (Element element, PSchema tsch,
1.327 vatton 3544: PresentationContext context, char *cssRule,
3545: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3546: {
3547: char *ptr;
3548:
1.366 vatton 3549: cssRule = SkipBlanksAndComments (cssRule);
1.263 vatton 3550: ptr = cssRule;
3551: cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3552: if (ptr == cssRule)
3553: cssRule = SkipValue ("Invalid font-weight value", cssRule);
3554: return (cssRule);
3555: }
3556:
3557: /*----------------------------------------------------------------------
1.327 vatton 3558: ParseACSSFontVariant: parse a CSS font variant string
3559: we expect the input string describing the attribute to be
3560: normal or small-caps
1.1 cvs 3561: ----------------------------------------------------------------------*/
1.263 vatton 3562: static char *ParseACSSFontVariant (Element element, PSchema tsch,
1.327 vatton 3563: PresentationContext context, char *cssRule,
3564: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3565: {
1.327 vatton 3566: PresentationValue style;
1.366 vatton 3567: char *ptr;
1.1 cvs 3568:
1.327 vatton 3569: style.typed_data.value = 0;
3570: style.typed_data.unit = UNIT_REL;
3571: style.typed_data.real = FALSE;
3572: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3573: ptr = cssRule;
1.327 vatton 3574: if (!strncasecmp (cssRule, "small-caps", 10))
3575: {
1.381 quint 3576: style.typed_data.value = VariantSmallCaps;
1.327 vatton 3577: cssRule = SkipWord (cssRule);
3578: }
3579: else if (!strncasecmp (cssRule, "normal", 6))
3580: {
1.381 quint 3581: style.typed_data.value = VariantNormal;
1.327 vatton 3582: cssRule = SkipWord (cssRule);
3583: }
3584: else if (!strncasecmp (cssRule, "inherit", 7))
3585: {
1.381 quint 3586: style.typed_data.unit = VALUE_INHERIT;
1.327 vatton 3587: cssRule = SkipWord (cssRule);
3588: }
1.381 quint 3589: else
3590: /* invalid font-variant */
3591: return (cssRule);
3592:
3593: if (style.typed_data.value != 0 || style.typed_data.unit == VALUE_INHERIT)
3594: {
3595: if (DoDialog)
3596: DisplayStyleValue ("font-variant", ptr, cssRule);
3597: else if (DoApply)
3598: TtaSetStylePresentation (PRVariant, element, tsch, context, style);
3599: }
1.295 vatton 3600: return (cssRule);
1.263 vatton 3601: }
1.1 cvs 3602:
1.263 vatton 3603: /*----------------------------------------------------------------------
1.327 vatton 3604: ParseCSSFontVariant: parse a CSS font variant string
3605: we expect the input string describing the attribute to be
3606: normal or small-caps
1.263 vatton 3607: ----------------------------------------------------------------------*/
3608: static char *ParseCSSFontVariant (Element element, PSchema tsch,
1.327 vatton 3609: PresentationContext context, char *cssRule,
3610: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3611: {
3612: char *ptr;
3613:
3614: ptr = cssRule;
3615: cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3616: if (ptr == cssRule)
3617: cssRule = SkipValue ("Invalid font-variant value", cssRule);
3618: return (cssRule);
1.1 cvs 3619: }
3620:
3621:
3622: /*----------------------------------------------------------------------
1.327 vatton 3623: ParseACSSFontStyle: parse a CSS font style string
3624: we expect the input string describing the attribute to be
3625: normal, italic, oblique or inherit
1.1 cvs 3626: ----------------------------------------------------------------------*/
1.263 vatton 3627: static char *ParseACSSFontStyle (Element element, PSchema tsch,
1.327 vatton 3628: PresentationContext context, char *cssRule,
3629: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3630: {
1.327 vatton 3631: PresentationValue style;
3632: PresentationValue size;
1.366 vatton 3633: PresentationValue previous_size;
3634: char *ptr;
1.1 cvs 3635:
1.327 vatton 3636: style.typed_data.value = 0;
3637: style.typed_data.unit = UNIT_REL;
3638: style.typed_data.real = FALSE;
3639: size.typed_data.value = 0;
3640: size.typed_data.unit = UNIT_REL;
3641: size.typed_data.real = FALSE;
3642: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3643: ptr = cssRule;
1.327 vatton 3644: if (!strncasecmp (cssRule, "italic", 6))
3645: {
3646: style.typed_data.value = StyleItalics;
3647: cssRule = SkipWord (cssRule);
3648: }
3649: else if (!strncasecmp (cssRule, "oblique", 7))
3650: {
3651: style.typed_data.value = StyleOblique;
3652: cssRule = SkipWord (cssRule);
3653: }
3654: else if (!strncasecmp (cssRule, "normal", 6))
3655: {
3656: style.typed_data.value = StyleRoman;
3657: cssRule = SkipWord (cssRule);
3658: }
3659: else if (!strncasecmp (cssRule, "inherit", 7))
3660: {
3661: style.typed_data.unit = VALUE_INHERIT;
3662: cssRule = SkipWord (cssRule);
3663: }
3664: else
3665: /* invalid font style */
3666: return (cssRule);
3667:
3668: /*
3669: * install the new presentation.
3670: */
1.366 vatton 3671: if (style.typed_data.value != 0 || style.typed_data.unit == VALUE_INHERIT)
1.327 vatton 3672: {
1.366 vatton 3673: if (DoDialog)
3674: DisplayStyleValue ("font-style", ptr, cssRule);
3675: else if (DoApply)
3676: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.327 vatton 3677: }
1.366 vatton 3678: if (size.typed_data.value != 0)
1.327 vatton 3679: {
1.366 vatton 3680: if (DoDialog)
3681: DisplayStyleValue ("font-style", ptr, cssRule);
3682: else if (DoApply)
1.327 vatton 3683: {
1.366 vatton 3684: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
3685: {
3686: /* !!!!!!!!!!!!!!!!!!!!!!!! Unit + relative !!!!!!!!!!!!!!!! */
3687: size.typed_data.value += previous_size.typed_data.value;
3688: TtaSetStylePresentation (PRSize, element, tsch, context, size);
3689: }
3690: else
3691: {
3692: size.typed_data.value = 10;
3693: TtaSetStylePresentation (PRSize, element, tsch, context, size);
3694: }
1.327 vatton 3695: }
3696: }
3697: return (cssRule);
3698: }
3699:
3700: /*----------------------------------------------------------------------
3701: ParseCSSFontStyle: parse a CSS font style string
3702: we expect the input string describing the attribute to be
3703: italic, oblique or normal
1.263 vatton 3704: ----------------------------------------------------------------------*/
3705: static char *ParseCSSFontStyle (Element element, PSchema tsch,
1.327 vatton 3706: PresentationContext context, char *cssRule,
3707: CSSInfoPtr css, ThotBool isHTML)
1.263 vatton 3708: {
3709: char *ptr;
3710:
3711: ptr = cssRule;
3712: cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3713: if (ptr == cssRule)
3714: cssRule = SkipValue ("Invalid font-style value", cssRule);
3715: return (cssRule);
3716: }
3717:
3718: /*----------------------------------------------------------------------
1.59 cvs 3719: ParseCSSFont: parse a CSS font attribute string
3720: we expect the input string describing the attribute to be
3721: !!!!!!
1.1 cvs 3722: ----------------------------------------------------------------------*/
1.79 cvs 3723: static char *ParseCSSFont (Element element, PSchema tsch,
1.327 vatton 3724: PresentationContext context, char *cssRule,
3725: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3726: {
1.270 vatton 3727: char *ptr, *p;
1.366 vatton 3728: char *start_value;
1.93 vatton 3729: int skippedNL;
1.272 vatton 3730: ThotBool variant = FALSE, style = FALSE, weight = FALSE, found;
1.1 cvs 3731:
1.82 cvs 3732: cssRule = SkipBlanksAndComments (cssRule);
3733: if (!strncasecmp (cssRule, "caption", 7))
1.263 vatton 3734: cssRule += 7;
1.82 cvs 3735: else if (!strncasecmp (cssRule, "icon", 4))
1.263 vatton 3736: cssRule += 4;
1.82 cvs 3737: else if (!strncasecmp (cssRule, "menu", 4))
1.263 vatton 3738: cssRule += 4;
1.82 cvs 3739: else if (!strncasecmp (cssRule, "message-box", 11))
1.263 vatton 3740: cssRule += 11;
1.82 cvs 3741: else if (!strncasecmp (cssRule, "small-caption", 13))
1.263 vatton 3742: cssRule += 13;
1.82 cvs 3743: else if (!strncasecmp (cssRule, "status-bar", 10))
1.263 vatton 3744: cssRule += 10;
3745: else if (!strncasecmp (cssRule, "inherit", 7))
1.293 quint 3746: {
3747: ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3748: ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3749: ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3750: ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.366 vatton 3751: cssRule = SkipBlanksAndComments (cssRule);
3752: start_value = cssRule;
1.293 quint 3753: ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3754: cssRule += 7;
1.366 vatton 3755: if (DoDialog)
3756: DisplayStyleValue ("font-family", start_value, cssRule);
1.293 quint 3757: }
1.1 cvs 3758: else
1.43 cvs 3759: {
1.270 vatton 3760: ptr = NULL;
3761: p = cssRule;
1.301 vatton 3762: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && p == cssRule)
1.327 vatton 3763: {
3764: found = FALSE;
3765: /* style, variant, weight can appear in any order */
3766: ptr = cssRule;
3767: skippedNL = NewLineSkipped;
3768: cssRule = ParseACSSFontStyle (element, tsch, context, cssRule, css, isHTML);
3769: if (ptr != cssRule)
3770: {
3771: skippedNL = NewLineSkipped;
3772: found = TRUE;
3773: style = TRUE;
3774: }
3775: else
3776: NewLineSkipped = skippedNL;
3777: ptr = cssRule;
3778: cssRule = ParseACSSFontVariant (element, tsch, context, cssRule, css, isHTML);
3779: if (ptr != cssRule)
3780: {
3781: skippedNL = NewLineSkipped;
3782: found = TRUE;
3783: variant = TRUE;
3784: }
3785: else
3786: NewLineSkipped = skippedNL;
3787: ptr = cssRule;
3788: cssRule = ParseACSSFontWeight (element, tsch, context, cssRule, css, isHTML);
3789: if (ptr != cssRule)
3790: {
3791: skippedNL = NewLineSkipped;
3792: found = TRUE;
3793: weight = TRUE;
3794: }
3795: else
3796: NewLineSkipped = skippedNL;
3797: cssRule = SkipBlanksAndComments (cssRule);
3798: p = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, TRUE);
3799: NewLineSkipped = skippedNL;
3800: if (!found)
3801: /* break the loop when the current value was not parsed */
3802: p = cssRule + 1;
3803: }
1.263 vatton 3804: ptr = cssRule;
1.270 vatton 3805: /* set default variant, style, weight */
3806: if (!variant)
1.405 kia 3807: ParseACSSFontVariant (element, tsch, context, (char*)"normal", css, isHTML);
1.270 vatton 3808: if (!style)
1.405 kia 3809: ParseACSSFontStyle (element, tsch, context, (char*)"normal", css, isHTML);
1.270 vatton 3810: if (!weight)
1.405 kia 3811: ParseACSSFontWeight (element, tsch, context, (char*)"normal", css, isHTML);
1.270 vatton 3812: /* now parse the font size and the font family */
1.301 vatton 3813: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.327 vatton 3814: cssRule = ParseACSSFontSize (element, tsch, context, cssRule, css, isHTML, FALSE);
1.301 vatton 3815: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.366 vatton 3816: {
3817: cssRule = SkipBlanksAndComments (cssRule);
3818: start_value = cssRule;
3819: cssRule = ParseACSSFontFamily (element, tsch, context, cssRule, css, isHTML);
3820: if (DoDialog)
3821: DisplayStyleValue ("font-family", start_value, cssRule);
3822: }
1.263 vatton 3823: if (ptr == cssRule)
1.360 vatton 3824: cssRule = SkipValue ("Invalid font value", cssRule);
1.43 cvs 3825: }
1.263 vatton 3826: cssRule = SkipBlanksAndComments (cssRule);
1.301 vatton 3827: if (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS)
1.360 vatton 3828: cssRule = SkipValue ("Invalid font value", cssRule);
1.43 cvs 3829: return (cssRule);
1.1 cvs 3830: }
3831:
3832: /*----------------------------------------------------------------------
1.356 quint 3833: ParseCSSTextDecoration: parse a CSS text-decoration value.
3834: We expect the input string to be none, inherit or a combination of
3835: underline, overline, line-through, and blink.
1.1 cvs 3836: ----------------------------------------------------------------------*/
1.79 cvs 3837: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
1.327 vatton 3838: PresentationContext context, char *cssRule,
3839: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3840: {
1.327 vatton 3841: PresentationValue decor;
1.366 vatton 3842: char *ptr;
1.356 quint 3843: ThotBool ok;
1.327 vatton 3844:
3845: decor.typed_data.value = 0;
3846: decor.typed_data.unit = UNIT_REL;
3847: decor.typed_data.real = FALSE;
3848: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 3849: ptr = cssRule;
1.356 quint 3850: ok = TRUE;
1.327 vatton 3851: if (!strncasecmp (cssRule, "none", 4))
3852: {
3853: decor.typed_data.value = NoUnderline;
3854: cssRule += 4;
3855: }
3856: else if (!strncasecmp (cssRule, "inherit", 7))
3857: {
3858: decor.typed_data.unit = VALUE_INHERIT;
3859: cssRule += 7;
3860: }
3861: else
3862: {
1.356 quint 3863: do
3864: {
3865: if (!strncasecmp (cssRule, "underline", 9))
3866: {
3867: decor.typed_data.value = Underline;
3868: cssRule += 9;
3869: }
3870: else if (!strncasecmp (cssRule, "overline", 8))
3871: {
3872: decor.typed_data.value = Overline;
3873: cssRule += 8;
3874: }
3875: else if (!strncasecmp (cssRule, "line-through", 12))
3876: {
3877: decor.typed_data.value = CrossOut;
3878: cssRule += 12;
3879: }
3880: else if (!strncasecmp (cssRule, "blink", 5))
3881: {
3882: /* the blink text-decoration attribute is not supported */
3883: cssRule += 5;
3884: }
3885: else
3886: ok = FALSE;
3887: if (ok)
3888: {
3889: cssRule = SkipBlanksAndComments (cssRule);
3890: }
3891: }
3892: while (ok && (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS));
3893: }
3894: if (!ok)
3895: {
1.327 vatton 3896: cssRule = SkipValue ("Invalid text-decoration value", cssRule);
3897: return (cssRule);
3898: }
1.1 cvs 3899:
1.327 vatton 3900: /*
3901: * install the new presentation.
3902: */
1.366 vatton 3903: if (decor.typed_data.value || decor.typed_data.unit == VALUE_INHERIT)
3904: {
3905: if (DoDialog)
3906: DisplayStyleValue ("text-decoration", ptr, cssRule);
3907: else if (DoApply)
3908: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
3909: }
1.327 vatton 3910: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid text-decoration value");
3911: return (cssRule);
1.1 cvs 3912: }
3913:
3914: /*----------------------------------------------------------------------
1.327 vatton 3915: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 3916: ----------------------------------------------------------------------*/
1.79 cvs 3917: static char *ParseCSSHeight (Element element, PSchema tsch,
1.327 vatton 3918: PresentationContext context, char *cssRule,
3919: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 3920: {
1.117 vatton 3921: PresentationValue val;
1.168 vatton 3922: char *ptr;
1.93 vatton 3923:
1.370 vatton 3924: val.typed_data.real = FALSE;
1.117 vatton 3925: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 3926: ptr = cssRule;
1.117 vatton 3927: /* first parse the attribute string */
1.164 quint 3928: if (!strncasecmp (cssRule, "auto", 4))
3929: {
1.184 vatton 3930: val.typed_data.unit = VALUE_AUTO;
1.164 quint 3931: val.typed_data.value = 0;
1.288 vatton 3932: cssRule += 4;
3933: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
1.164 quint 3934: }
1.117 vatton 3935: else
1.168 vatton 3936: cssRule = ParseCSSUnit (cssRule, &val);
1.295 vatton 3937:
1.387 quint 3938: if (val.typed_data.unit == UNIT_INVALID ||
3939: (val.typed_data.value != 0 &&
1.184 vatton 3940: val.typed_data.unit == UNIT_BOX))
1.387 quint 3941: CSSParseError ("height value", ptr, cssRule);
3942: else if (DoDialog)
1.366 vatton 3943: DisplayStyleValue ("height", ptr, cssRule);
3944: else if (DoApply)
1.295 vatton 3945: /* install the new presentation */
3946: TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.117 vatton 3947: return (cssRule);
1.1 cvs 3948: }
3949:
3950: /*----------------------------------------------------------------------
1.382 vatton 3951: ParseCSSMaxHeight: parse a CSS height attribute
3952: ----------------------------------------------------------------------*/
3953: static char *ParseCSSMaxHeight (Element element, PSchema tsch,
3954: PresentationContext context, char *cssRule,
3955: CSSInfoPtr css, ThotBool isHTML)
3956: {
3957: PresentationValue val;
3958: char *ptr;
3959:
3960: val.typed_data.real = FALSE;
3961: cssRule = SkipBlanksAndComments (cssRule);
3962: ptr = cssRule;
3963: /* first parse the attribute string */
3964: if (!strncasecmp (cssRule, "auto", 4))
3965: {
3966: val.typed_data.unit = VALUE_AUTO;
3967: val.typed_data.value = 0;
3968: cssRule += 4;
3969: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
3970: }
3971: else
3972: cssRule = ParseCSSUnit (cssRule, &val);
3973:
1.387 quint 3974: if (val.typed_data.unit == UNIT_INVALID ||
3975: (val.typed_data.value != 0 &&
1.382 vatton 3976: val.typed_data.unit == UNIT_BOX))
1.387 quint 3977: CSSParseError ("height value", ptr, cssRule);
3978: else if (DoDialog)
1.382 vatton 3979: DisplayStyleValue ("max-height", ptr, cssRule);
1.390 vatton 3980: /*else if (DoApply)
3981: install the new presentation
3982: TtaSetStylePresentation (PRHeight, element, tsch, context, val)*/;
1.382 vatton 3983: return (cssRule);
3984: }
3985:
3986: /*----------------------------------------------------------------------
3987: ParseCSSMinHeight: parse a CSS height attribute
3988: ----------------------------------------------------------------------*/
3989: static char *ParseCSSMinHeight (Element element, PSchema tsch,
3990: PresentationContext context, char *cssRule,
3991: CSSInfoPtr css, ThotBool isHTML)
3992: {
3993: PresentationValue val;
3994: char *ptr;
3995:
3996: val.typed_data.real = FALSE;
3997: cssRule = SkipBlanksAndComments (cssRule);
3998: ptr = cssRule;
3999: /* first parse the attribute string */
4000: if (!strncasecmp (cssRule, "auto", 4))
4001: {
4002: val.typed_data.unit = VALUE_AUTO;
4003: val.typed_data.value = 0;
4004: cssRule += 4;
4005: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid height value");
4006: }
4007: else
4008: cssRule = ParseCSSUnit (cssRule, &val);
4009:
1.387 quint 4010: if (val.typed_data.unit == UNIT_INVALID ||
4011: (val.typed_data.value != 0 &&
1.382 vatton 4012: val.typed_data.unit == UNIT_BOX))
1.387 quint 4013: CSSParseError ("height value", ptr, cssRule);
4014: else if (DoDialog)
1.382 vatton 4015: DisplayStyleValue ("min-height", ptr, cssRule);
1.390 vatton 4016: /*else if (DoApply)*/
1.382 vatton 4017: /* install the new presentation */
1.384 vatton 4018: /*TtaSetStylePresentation (PRHeight, element, tsch, context, val)*/;
1.382 vatton 4019: return (cssRule);
4020: }
4021:
4022: /*----------------------------------------------------------------------
1.327 vatton 4023: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 4024: ----------------------------------------------------------------------*/
1.79 cvs 4025: static char *ParseCSSWidth (Element element, PSchema tsch,
1.327 vatton 4026: PresentationContext context,
4027: char *cssRule, CSSInfoPtr css,
4028: ThotBool isHTML)
1.1 cvs 4029: {
1.117 vatton 4030: PresentationValue val;
1.168 vatton 4031: char *ptr;
1.93 vatton 4032:
1.370 vatton 4033: val.typed_data.real = FALSE;
1.117 vatton 4034: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4035: ptr = cssRule;
1.117 vatton 4036: /* first parse the attribute string */
1.164 quint 4037: if (!strncasecmp (cssRule, "auto", 4))
4038: {
1.184 vatton 4039: val.typed_data.unit = VALUE_AUTO;
1.164 quint 4040: val.typed_data.value = 0;
1.288 vatton 4041: cssRule += 4;
4042: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
1.164 quint 4043: }
1.117 vatton 4044: else
1.327 vatton 4045: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4046: if (val.typed_data.unit == UNIT_INVALID ||
4047: (val.typed_data.value != 0 &&
1.184 vatton 4048: val.typed_data.unit == UNIT_BOX))
1.387 quint 4049: CSSParseError ("Invalid width value", ptr, cssRule);
4050: else if (DoDialog)
1.366 vatton 4051: DisplayStyleValue ("width", ptr, cssRule);
4052: else if (DoApply)
1.295 vatton 4053: /* install the new presentation */
4054: TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.117 vatton 4055: return (cssRule);
1.1 cvs 4056: }
4057:
4058: /*----------------------------------------------------------------------
1.382 vatton 4059: ParseCSSMaxWidth: parse a CSS width attribute
4060: ----------------------------------------------------------------------*/
4061: static char *ParseCSSMaxWidth (Element element, PSchema tsch,
4062: PresentationContext context,
4063: char *cssRule, CSSInfoPtr css,
4064: ThotBool isHTML)
4065: {
4066: PresentationValue val;
4067: char *ptr;
4068:
4069: val.typed_data.real = FALSE;
4070: cssRule = SkipBlanksAndComments (cssRule);
4071: ptr = cssRule;
4072: /* first parse the attribute string */
4073: if (!strncasecmp (cssRule, "auto", 4))
4074: {
4075: val.typed_data.unit = VALUE_AUTO;
4076: val.typed_data.value = 0;
4077: cssRule += 4;
4078: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
4079: }
4080: else
4081: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4082: if (val.typed_data.unit == UNIT_INVALID ||
4083: (val.typed_data.value != 0 &&
1.382 vatton 4084: val.typed_data.unit == UNIT_BOX))
4085: CSSParseError ("Invalid width value", ptr, cssRule);
1.387 quint 4086: else if (DoDialog)
1.382 vatton 4087: DisplayStyleValue ("max-width", ptr, cssRule);
1.408 vatton 4088: /*else if (DoApply)*/
1.382 vatton 4089: /* install the new presentation */
1.384 vatton 4090: /*TtaSetStylePresentation (PRWidth, element, tsch, context, val)*/;
1.382 vatton 4091: return (cssRule);
4092: }
4093:
4094: /*----------------------------------------------------------------------
4095: ParseCSSMinWidth: parse a CSS width attribute
4096: ----------------------------------------------------------------------*/
4097: static char *ParseCSSMinWidth (Element element, PSchema tsch,
4098: PresentationContext context,
4099: char *cssRule, CSSInfoPtr css,
4100: ThotBool isHTML)
4101: {
4102: PresentationValue val;
4103: char *ptr;
4104:
4105: val.typed_data.real = FALSE;
4106: cssRule = SkipBlanksAndComments (cssRule);
4107: ptr = cssRule;
4108: /* first parse the attribute string */
4109: if (!strncasecmp (cssRule, "auto", 4))
4110: {
4111: val.typed_data.unit = VALUE_AUTO;
4112: val.typed_data.value = 0;
4113: cssRule += 4;
4114: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid width value");
4115: }
4116: else
4117: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 4118: if (val.typed_data.unit == UNIT_INVALID ||
4119: (val.typed_data.value != 0 &&
1.382 vatton 4120: val.typed_data.unit == UNIT_BOX))
1.387 quint 4121: CSSParseError ("Invalid width value", ptr, cssRule);
4122: else if (DoDialog)
1.382 vatton 4123: DisplayStyleValue ("min-width", ptr, cssRule);
1.408 vatton 4124: /*else if (DoApply)*/
1.382 vatton 4125: /* install the new presentation */
1.384 vatton 4126: /*TtaSetStylePresentation (PRWidth, element, tsch, context, val)*/;
1.382 vatton 4127: return (cssRule);
4128: }
4129:
4130: /*----------------------------------------------------------------------
1.391 vatton 4131: GetEmMarginValue returns the em value
4132: ----------------------------------------------------------------------*/
4133: int GetEmValue (char *data, Element el, Document doc)
4134: {
4135: PresentationValue val;
4136: char *ptr;
4137: int value;
4138:
4139: val.typed_data.real = FALSE;
4140: ptr = SkipBlanksAndComments (data);
4141: if (!strncasecmp (data, "auto", 4))
4142: value = TtaGetPixelValue (0, VALUE_AUTO, el, doc);
4143: else
4144: {
4145: ptr = ParseCSSUnit (data, &val);
4146: value = TtaGetPixelValue (val.typed_data.value, val.typed_data.unit,
4147: el, doc);
4148: }
4149: return TtaGetLogicalValue (value, UNIT_EM, el, doc);
4150: }
4151:
4152: /*----------------------------------------------------------------------
1.327 vatton 4153: ParseACSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 4154: ----------------------------------------------------------------------*/
1.296 vatton 4155: static char *ParseACSSMarginTop (Element element, PSchema tsch,
1.327 vatton 4156: PresentationContext context,
4157: char *cssRule, CSSInfoPtr css,
4158: ThotBool isHTML)
1.1 cvs 4159: {
4160: PresentationValue margin;
1.168 vatton 4161: char *ptr;
1.1 cvs 4162:
1.370 vatton 4163: margin.typed_data.real = FALSE;
1.82 cvs 4164: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4165: ptr = cssRule;
1.1 cvs 4166: /* first parse the attribute string */
1.164 quint 4167: if (!strncasecmp (cssRule, "auto", 4))
4168: {
1.184 vatton 4169: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4170: margin.typed_data.value = 0;
1.288 vatton 4171: cssRule += 4;
1.164 quint 4172: }
1.404 vatton 4173: else if (!strncasecmp (cssRule, "inherit", 7))
4174: {
4175: margin.typed_data.unit = VALUE_AUTO;
4176: margin.typed_data.value = 0;
4177: cssRule += 7;
4178: }
1.164 quint 4179: else
1.168 vatton 4180: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4181:
1.387 quint 4182: if (margin.typed_data.unit == UNIT_INVALID ||
4183: (margin.typed_data.value != 0 &&
1.184 vatton 4184: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4185: CSSParseError ("Invalid margin-top value", ptr, cssRule);
1.366 vatton 4186: else if (DoDialog)
4187: {
4188: if (All_sides)
4189: DisplayStyleValue ("margin", ptr, cssRule);
4190: else
4191: DisplayStyleValue ("margin-top", ptr, cssRule);
4192: }
1.168 vatton 4193: else if (DoApply)
1.295 vatton 4194: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
1.1 cvs 4195: return (cssRule);
4196: }
4197:
4198: /*----------------------------------------------------------------------
1.327 vatton 4199: ParseCSSMarginTop: parse a CSS margin-top attribute
1.296 vatton 4200: ----------------------------------------------------------------------*/
4201: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.327 vatton 4202: PresentationContext context,
4203: char *cssRule, CSSInfoPtr css,
4204: ThotBool isHTML)
1.296 vatton 4205: {
4206: char *ptr = cssRule;
4207:
4208: cssRule = ParseACSSMarginTop (element, tsch, context, ptr, css, isHTML);
4209: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-top value");
4210: return (cssRule);
4211: }
4212:
4213: /*----------------------------------------------------------------------
4214: ParseACSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 4215: ----------------------------------------------------------------------*/
1.296 vatton 4216: static char *ParseACSSMarginBottom (Element element, PSchema tsch,
1.327 vatton 4217: PresentationContext context,
4218: char *cssRule, CSSInfoPtr css,
4219: ThotBool isHTML)
1.1 cvs 4220: {
4221: PresentationValue margin;
1.168 vatton 4222: char *ptr;
1.1 cvs 4223:
1.370 vatton 4224: margin.typed_data.real = FALSE;
1.82 cvs 4225: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4226: ptr = cssRule;
1.1 cvs 4227: /* first parse the attribute string */
1.164 quint 4228: if (!strncasecmp (cssRule, "auto", 4))
4229: {
1.184 vatton 4230: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4231: margin.typed_data.value = 0;
1.288 vatton 4232: cssRule += 4;
1.164 quint 4233: }
1.404 vatton 4234: else if (!strncasecmp (cssRule, "inherit", 7))
4235: {
4236: margin.typed_data.unit = VALUE_AUTO;
4237: margin.typed_data.value = 0;
4238: cssRule += 7;
4239: }
1.164 quint 4240: else
1.168 vatton 4241: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4242:
1.387 quint 4243: if (margin.typed_data.unit == UNIT_INVALID ||
4244: (margin.typed_data.value != 0 &&
1.184 vatton 4245: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4246: CSSParseError ("Invalid margin-bottom value", ptr, cssRule);
1.366 vatton 4247: else if (DoDialog)
4248: DisplayStyleValue ("margin-bottom", ptr, cssRule);
1.168 vatton 4249: else if (DoApply)
1.295 vatton 4250: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
1.1 cvs 4251: return (cssRule);
4252: }
4253:
4254: /*----------------------------------------------------------------------
1.296 vatton 4255: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
4256: ----------------------------------------------------------------------*/
4257: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.327 vatton 4258: PresentationContext context,
4259: char *cssRule, CSSInfoPtr css,
4260: ThotBool isHTML)
1.296 vatton 4261: {
4262: char *ptr = cssRule;
4263:
4264: cssRule = ParseACSSMarginBottom (element, tsch, context, ptr, css, isHTML);
4265: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-bottom value");
4266: return (cssRule);
4267: }
4268:
4269: /*----------------------------------------------------------------------
4270: ParseACSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 4271: ----------------------------------------------------------------------*/
1.296 vatton 4272: static char *ParseACSSMarginLeft (Element element, PSchema tsch,
1.327 vatton 4273: PresentationContext context,
4274: char *cssRule, CSSInfoPtr css,
4275: ThotBool isHTML)
1.1 cvs 4276: {
4277: PresentationValue margin;
1.168 vatton 4278: char *ptr;
1.1 cvs 4279:
1.370 vatton 4280: margin.typed_data.real = FALSE;
1.82 cvs 4281: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4282: ptr = cssRule;
1.1 cvs 4283: /* first parse the attribute string */
1.164 quint 4284: if (!strncasecmp (cssRule, "auto", 4))
4285: {
1.184 vatton 4286: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4287: margin.typed_data.value = 0;
1.288 vatton 4288: cssRule += 4;
1.164 quint 4289: }
4290: else
1.168 vatton 4291: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4292:
1.387 quint 4293: if (margin.typed_data.unit == UNIT_INVALID ||
4294: (margin.typed_data.value != 0 &&
1.184 vatton 4295: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4296: CSSParseError ("Invalid margin-left value", ptr, cssRule);
1.366 vatton 4297: else if (DoDialog)
4298: DisplayStyleValue ("margin-left", ptr, cssRule);
1.295 vatton 4299: else if (DoApply && margin.typed_data.unit != UNIT_INVALID && DoApply)
1.327 vatton 4300: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
1.1 cvs 4301: return (cssRule);
4302: }
4303:
4304: /*----------------------------------------------------------------------
1.296 vatton 4305: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
4306: ----------------------------------------------------------------------*/
4307: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.327 vatton 4308: PresentationContext context,
4309: char *cssRule, CSSInfoPtr css,
4310: ThotBool isHTML)
1.296 vatton 4311: {
4312: char *ptr = cssRule;
4313:
4314: cssRule = ParseACSSMarginLeft (element, tsch, context, ptr, css, isHTML);
4315: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-left value");
4316: return (cssRule);
4317: }
4318:
4319:
4320: /*----------------------------------------------------------------------
4321: ParseACSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 4322: ----------------------------------------------------------------------*/
1.296 vatton 4323: static char *ParseACSSMarginRight (Element element, PSchema tsch,
1.327 vatton 4324: PresentationContext context,
4325: char *cssRule, CSSInfoPtr css,
4326: ThotBool isHTML)
1.1 cvs 4327: {
4328: PresentationValue margin;
1.168 vatton 4329: char *ptr;
1.1 cvs 4330:
1.370 vatton 4331: margin.typed_data.real = FALSE;
1.82 cvs 4332: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4333: ptr = cssRule;
1.1 cvs 4334: /* first parse the attribute string */
1.164 quint 4335: if (!strncasecmp (cssRule, "auto", 4))
4336: {
1.184 vatton 4337: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 4338: margin.typed_data.value = 0;
1.288 vatton 4339: cssRule += 4;
1.164 quint 4340: }
1.404 vatton 4341: else if (!strncasecmp (cssRule, "inherit", 7))
4342: {
4343: margin.typed_data.unit = VALUE_AUTO;
4344: margin.typed_data.value = 0;
4345: cssRule += 7;
4346: }
1.164 quint 4347: else
1.168 vatton 4348: cssRule = ParseCSSUnit (cssRule, &margin);
1.295 vatton 4349:
1.387 quint 4350: if (margin.typed_data.unit == UNIT_INVALID ||
4351: (margin.typed_data.value != 0 &&
1.184 vatton 4352: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 4353: CSSParseError ("Invalid margin-right value", ptr, cssRule);
1.366 vatton 4354: else if (DoDialog)
4355: DisplayStyleValue ("margin-right", ptr, cssRule);
1.168 vatton 4356: else if (DoApply)
1.295 vatton 4357: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
1.1 cvs 4358: return (cssRule);
4359: }
4360:
4361: /*----------------------------------------------------------------------
1.296 vatton 4362: ParseCSSMarginRight: parse a CSS margin-right attribute string
4363: ----------------------------------------------------------------------*/
4364: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.327 vatton 4365: PresentationContext context,
4366: char *cssRule, CSSInfoPtr css,
4367: ThotBool isHTML)
1.296 vatton 4368: {
4369: char *ptr = cssRule;
4370:
1.297 vatton 4371: cssRule = ParseACSSMarginRight (element, tsch, context, ptr, css, isHTML);
1.296 vatton 4372: cssRule = CSSCheckEndValue (ptr, cssRule, "Invalid margin-right value");
4373: return (cssRule);
4374: }
4375:
4376: /*----------------------------------------------------------------------
1.59 cvs 4377: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 4378: ----------------------------------------------------------------------*/
1.79 cvs 4379: static char *ParseCSSMargin (Element element, PSchema tsch,
1.327 vatton 4380: PresentationContext context,
4381: char *cssRule, CSSInfoPtr css,
4382: ThotBool isHTML)
1.1 cvs 4383: {
1.79 cvs 4384: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 4385: int skippedNL, n;
1.1 cvs 4386:
1.82 cvs 4387: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 4388: if (DoDialog)
4389: n = NumberOfValues (ptrT);
4390: if (DoDialog && n < 2)
1.1 cvs 4391: {
1.366 vatton 4392: // check if the margin dialog must be updated
4393: All_sides = TRUE;
4394: ptrR = ParseACSSMarginTop (element, tsch, context, ptrT, css, isHTML);
4395: All_sides = FALSE;
1.1 cvs 4396: }
4397: else
4398: {
1.366 vatton 4399: /* First parse Margin-Top */
4400: ptrR = ParseACSSMarginTop (element, tsch, context, ptrT, css, isHTML);
4401: ptrR = SkipBlanksAndComments (ptrR);
4402: if (*ptrR == ';' || *ptrR == '}' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 4403: {
4404: skippedNL = NewLineSkipped;
1.366 vatton 4405: cssRule = ptrR;
4406: /* apply the Margin-Top to all */
4407: ptrR = ParseACSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4408: NewLineSkipped = skippedNL;
1.366 vatton 4409: ptrR = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
4410: NewLineSkipped = skippedNL;
4411: ptrR = ParseACSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4412: }
1.1 cvs 4413: else
1.327 vatton 4414: {
1.366 vatton 4415: /* parse Margin-Right */
4416: ptrB = ParseACSSMarginRight (element, tsch, context, ptrR, css, isHTML);
4417: ptrB = SkipBlanksAndComments (ptrB);
4418: if (*ptrB == ';' || *ptrB == '}' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 4419: {
1.366 vatton 4420: skippedNL = NewLineSkipped;
4421: cssRule = ptrB;
4422: /* apply the Margin-Top to Margin-Bottom */
4423: ptrB = ParseACSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
4424: NewLineSkipped = skippedNL;
1.327 vatton 4425: /* apply the Margin-Right to Margin-Left */
1.366 vatton 4426: ptrB = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 4427: }
4428: else
1.366 vatton 4429: {
4430: /* parse Margin-Bottom */
4431: ptrL = ParseACSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
4432: ptrL = SkipBlanksAndComments (ptrL);
4433: if (*ptrL == ';' || *ptrL == '}' || *ptrL == EOS || *ptrL == ',')
4434: {
4435: cssRule = ptrL;
4436: /* apply the Margin-Right to Margin-Left */
4437: ptrL = ParseACSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
4438: }
4439: else
4440: /* parse Margin-Left */
4441: cssRule = ParseACSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
4442: cssRule = SkipBlanksAndComments (cssRule);
4443: }
1.327 vatton 4444: }
1.1 cvs 4445: }
4446: return (cssRule);
4447: }
4448:
4449: /*----------------------------------------------------------------------
1.418 quint 4450: ParseCSSOpacity: parse a CSS opacity property
4451: ----------------------------------------------------------------------*/
4452: static char *ParseCSSOpacity (Element element, PSchema tsch,
4453: PresentationContext context, char *cssRule,
4454: CSSInfoPtr css, ThotBool isHTML)
4455: {
4456: PresentationValue opacity;
4457:
4458: opacity.typed_data.unit = UNIT_INVALID;
4459: opacity.typed_data.real = FALSE;
4460: if (!strncasecmp (cssRule, "inherit", 7))
4461: {
4462: opacity.typed_data.unit = VALUE_INHERIT;
4463: cssRule += 7;
4464: }
4465: else
4466: cssRule = ParseClampedUnit (cssRule, &opacity);
4467: if (DoApply)
4468: /* install the new presentation. */
4469: TtaSetStylePresentation (PROpacity, element, tsch, context, opacity);
4470: return (cssRule);
4471: }
4472:
4473: /*----------------------------------------------------------------------
1.327 vatton 4474: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 4475: ----------------------------------------------------------------------*/
1.79 cvs 4476: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.327 vatton 4477: PresentationContext context,
4478: char *cssRule, CSSInfoPtr css,
4479: ThotBool isHTML)
1.1 cvs 4480: {
1.43 cvs 4481: PresentationValue padding;
1.168 vatton 4482: char *ptr;
1.370 vatton 4483:
4484: padding.typed_data.real = FALSE;
1.82 cvs 4485: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4486: ptr = cssRule;
1.43 cvs 4487: /* first parse the attribute string */
4488: cssRule = ParseCSSUnit (cssRule, &padding);
1.295 vatton 4489:
1.387 quint 4490: if (padding.typed_data.unit == UNIT_INVALID ||
4491: (padding.typed_data.value != 0 &&
1.184 vatton 4492: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4493: CSSParseError ("Invalid padding-top value", ptr, cssRule);
1.366 vatton 4494: else if (DoDialog)
4495: {
4496: if (All_sides)
4497: DisplayStyleValue ("padding", ptr, cssRule);
4498: else
4499: DisplayStyleValue ("padding-top", ptr, cssRule);
4500: }
1.168 vatton 4501: else if (DoApply)
1.295 vatton 4502: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
1.1 cvs 4503: return (cssRule);
4504: }
4505:
4506: /*----------------------------------------------------------------------
1.59 cvs 4507: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 4508: ----------------------------------------------------------------------*/
1.79 cvs 4509: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.327 vatton 4510: PresentationContext context,
4511: char *cssRule, CSSInfoPtr css,
4512: ThotBool isHTML)
1.1 cvs 4513: {
1.43 cvs 4514: PresentationValue padding;
1.168 vatton 4515: char *ptr;
1.43 cvs 4516:
1.370 vatton 4517: padding.typed_data.real = FALSE;
1.82 cvs 4518: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4519: ptr = cssRule;
1.43 cvs 4520: /* first parse the attribute string */
4521: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4522: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4523: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4524:
1.387 quint 4525: if (padding.typed_data.unit == UNIT_INVALID ||
4526: (padding.typed_data.value != 0 &&
1.184 vatton 4527: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4528: CSSParseError ("Invalid padding-bottom value", ptr, cssRule);
1.366 vatton 4529: else if (DoDialog)
4530: DisplayStyleValue ("padding-bottom", ptr, cssRule);
1.168 vatton 4531: else if (DoApply)
1.295 vatton 4532: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
1.1 cvs 4533: return (cssRule);
4534: }
4535:
4536: /*----------------------------------------------------------------------
1.59 cvs 4537: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 4538: ----------------------------------------------------------------------*/
1.79 cvs 4539: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.327 vatton 4540: PresentationContext context,
4541: char *cssRule, CSSInfoPtr css,
4542: ThotBool isHTML)
1.1 cvs 4543: {
1.43 cvs 4544: PresentationValue padding;
1.168 vatton 4545: char *ptr;
1.43 cvs 4546:
1.370 vatton 4547: padding.typed_data.real = FALSE;
1.82 cvs 4548: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4549: ptr = cssRule;
1.43 cvs 4550: /* first parse the attribute string */
4551: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4552: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4553: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4554:
1.387 quint 4555: if (padding.typed_data.unit == UNIT_INVALID ||
4556: (padding.typed_data.value != 0 &&
1.184 vatton 4557: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 4558: {
1.169 vatton 4559: CSSParseError ("Invalid padding-left value", ptr, cssRule);
1.168 vatton 4560: padding.typed_data.value = 0;
4561: }
1.366 vatton 4562: else if (DoDialog)
4563: DisplayStyleValue ("padding-left", ptr, cssRule);
1.168 vatton 4564: else if (DoApply)
1.295 vatton 4565: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.1 cvs 4566: return (cssRule);
4567: }
4568:
4569: /*----------------------------------------------------------------------
1.59 cvs 4570: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 4571: ----------------------------------------------------------------------*/
1.79 cvs 4572: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.327 vatton 4573: PresentationContext context,
4574: char *cssRule, CSSInfoPtr css,
4575: ThotBool isHTML)
1.1 cvs 4576: {
1.43 cvs 4577: PresentationValue padding;
1.168 vatton 4578: char *ptr;
1.43 cvs 4579:
1.370 vatton 4580: padding.typed_data.real = FALSE;
1.82 cvs 4581: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 4582: ptr = cssRule;
1.43 cvs 4583: /* first parse the attribute string */
4584: cssRule = ParseCSSUnit (cssRule, &padding);
1.387 quint 4585: if (padding.typed_data.value == 0 && padding.typed_data.unit != UNIT_INVALID)
1.184 vatton 4586: padding.typed_data.unit = UNIT_EM;
1.295 vatton 4587:
1.387 quint 4588: if (padding.typed_data.unit == UNIT_INVALID ||
4589: (padding.typed_data.value != 0 &&
1.184 vatton 4590: padding.typed_data.unit == UNIT_BOX))
1.387 quint 4591: CSSParseError ("Invalid padding-right value", ptr, cssRule);
1.366 vatton 4592: else if (DoDialog)
4593: DisplayStyleValue ("padding-right", ptr, cssRule);
1.168 vatton 4594: else if (DoApply)
1.295 vatton 4595: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.1 cvs 4596: return (cssRule);
4597: }
4598:
4599: /*----------------------------------------------------------------------
1.327 vatton 4600: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 4601: ----------------------------------------------------------------------*/
1.79 cvs 4602: static char *ParseCSSPadding (Element element, PSchema tsch,
1.327 vatton 4603: PresentationContext context,
4604: char *cssRule, CSSInfoPtr css,
4605: ThotBool isHTML)
1.1 cvs 4606: {
1.79 cvs 4607: char *ptrT, *ptrR, *ptrB, *ptrL;
1.366 vatton 4608: int skippedNL, n;
1.43 cvs 4609:
1.82 cvs 4610: ptrT = SkipBlanksAndComments (cssRule);
1.366 vatton 4611: if (DoDialog)
4612: n = NumberOfValues (ptrT);
4613: if (DoDialog && n < 2)
1.43 cvs 4614: {
1.366 vatton 4615: // check if the padding dialog must be updated
4616: All_sides = TRUE;
4617: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
4618: All_sides = FALSE;
1.43 cvs 4619: }
4620: else
4621: {
1.366 vatton 4622: /* First parse Padding-Top */
4623: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
4624: ptrR = SkipBlanksAndComments (ptrR);
4625: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.327 vatton 4626: {
4627: skippedNL = NewLineSkipped;
1.366 vatton 4628: cssRule = ptrR;
4629: /* apply the Padding-Top to all */
4630: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4631: NewLineSkipped = skippedNL;
1.366 vatton 4632: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
4633: NewLineSkipped = skippedNL;
4634: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
1.327 vatton 4635: }
1.43 cvs 4636: else
1.327 vatton 4637: {
1.366 vatton 4638: /* parse Padding-Right */
4639: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
4640: ptrB = SkipBlanksAndComments (ptrB);
4641: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.327 vatton 4642: {
1.366 vatton 4643: skippedNL = NewLineSkipped;
4644: cssRule = ptrB;
4645: /* apply the Padding-Top to Padding-Bottom */
4646: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
4647: NewLineSkipped = skippedNL;
1.327 vatton 4648: /* apply the Padding-Right to Padding-Left */
1.366 vatton 4649: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
1.327 vatton 4650: }
4651: else
1.366 vatton 4652: {
4653: /* parse Padding-Bottom */
4654: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
4655: ptrL = SkipBlanksAndComments (ptrL);
4656: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
4657: {
4658: cssRule = ptrL;
4659: /* apply the Padding-Right to Padding-Left */
4660: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
4661: }
4662: else
4663: /* parse Padding-Left */
4664: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
4665: cssRule = SkipBlanksAndComments (cssRule);
4666: }
1.327 vatton 4667: }
1.43 cvs 4668: }
1.1 cvs 4669: return (cssRule);
4670: }
4671:
4672: /*----------------------------------------------------------------------
1.327 vatton 4673: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 4674: ----------------------------------------------------------------------*/
1.79 cvs 4675: static char *ParseCSSForeground (Element element, PSchema tsch,
1.327 vatton 4676: PresentationContext context,
4677: char *cssRule,
4678: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 4679: {
1.425 quint 4680: ElementType elType;
1.117 vatton 4681: PresentationValue best;
1.262 vatton 4682: char *p;
1.1 cvs 4683:
1.370 vatton 4684: best.typed_data.real = FALSE;
1.366 vatton 4685: cssRule = SkipBlanksAndComments (cssRule);
1.262 vatton 4686: p = cssRule;
1.117 vatton 4687: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4688: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4689: {
4690: if (*cssRule != EOS && *cssRule !=';')
4691: {
4692: cssRule = SkipProperty (cssRule, FALSE);
1.366 vatton 4693: CSSParseError ("Invalid color value", p, cssRule);
1.327 vatton 4694: }
1.366 vatton 4695: else if (DoDialog)
4696: DisplayStyleValue ("color", p, cssRule);
4697: else if (DoApply)
1.327 vatton 4698: /* install the new presentation */
1.425 quint 4699: {
4700: elType = TtaGetElementType(element);
4701: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
4702: /* we are working for an SVG element */
4703: TtaSetStylePresentation (PRColor, element, tsch, context, best);
4704: else
4705: TtaSetStylePresentation (PRForeground, element, tsch, context,best);
4706: }
1.327 vatton 4707: }
4708: return (cssRule);
1.1 cvs 4709: }
4710:
4711: /*----------------------------------------------------------------------
1.59 cvs 4712: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 4713: ----------------------------------------------------------------------*/
1.79 cvs 4714: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.327 vatton 4715: PresentationContext context,
4716: char *cssRule,
4717: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 4718: {
4719: PresentationValue best;
1.366 vatton 4720: char *ptr;
1.1 cvs 4721:
1.370 vatton 4722: best.typed_data.real = FALSE;
1.366 vatton 4723: cssRule = SkipBlanksAndComments (cssRule);
4724: ptr = cssRule;
1.184 vatton 4725: best.typed_data.unit = UNIT_INVALID;
1.1 cvs 4726: best.typed_data.real = FALSE;
1.198 vatton 4727: if (!strncasecmp (cssRule, "transparent", 11))
1.1 cvs 4728: {
1.184 vatton 4729: best.typed_data.value = PATTERN_NONE;
4730: best.typed_data.unit = UNIT_REL;
1.295 vatton 4731: cssRule = SkipWord (cssRule);
1.116 vatton 4732: if (DoApply)
1.327 vatton 4733: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4734: }
1.1 cvs 4735: else
4736: {
4737: cssRule = ParseCSSColor (cssRule, &best);
1.366 vatton 4738: if (best.typed_data.unit != UNIT_INVALID)
1.327 vatton 4739: {
1.366 vatton 4740: if (DoDialog)
4741: DisplayStyleValue ("background-color", ptr, cssRule);
4742: else if (DoApply)
4743: {
4744: /* install the new presentation. */
4745: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
4746: /* thot specificity: need to set fill pattern for background color */
4747: best.typed_data.value = PATTERN_BACKGROUND;
4748: best.typed_data.unit = UNIT_REL;
4749: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
4750: best.typed_data.value = 1;
4751: best.typed_data.unit = UNIT_REL;
4752: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
4753: }
1.327 vatton 4754: }
1.1 cvs 4755: }
4756: return (cssRule);
4757: }
4758:
1.63 cvs 4759: /*----------------------------------------------------------------------
1.65 cvs 4760: ParseSVGStroke: parse a SVG stroke property
4761: ----------------------------------------------------------------------*/
1.79 cvs 4762: static char *ParseSVGStroke (Element element, PSchema tsch,
1.327 vatton 4763: PresentationContext context, char *cssRule,
4764: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 4765: {
4766: PresentationValue best;
1.245 quint 4767: char *url;
1.65 cvs 4768:
1.184 vatton 4769: best.typed_data.unit = UNIT_INVALID;
1.65 cvs 4770: best.typed_data.real = FALSE;
1.82 cvs 4771: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 4772: {
4773: best.typed_data.value = -2; /* -2 means transparent */
1.184 vatton 4774: best.typed_data.unit = UNIT_REL;
1.65 cvs 4775: cssRule = SkipWord (cssRule);
4776: }
1.425 quint 4777: else if (!strncasecmp (cssRule, "inherit", 7))
1.245 quint 4778: {
1.293 quint 4779: best.typed_data.unit = VALUE_INHERIT;
4780: cssRule = SkipWord (cssRule);
1.245 quint 4781: }
1.425 quint 4782: else if (!strncasecmp (cssRule, "currentColor", 12))
4783: {
4784: best.typed_data.unit = VALUE_CURRENT;
4785: cssRule = SkipWord (cssRule);
4786: }
1.245 quint 4787: else if (!strncasecmp (cssRule, "url", 3))
4788: {
4789: cssRule += 3;
4790: cssRule = ParseCSSUrl (cssRule, &url);
4791: /* **** do something with the url ***** */;
4792: TtaFreeMemory (url);
4793: /* **** caution: another color value may follow the uri (in case
1.327 vatton 4794: the uri could ne be dereferenced) *** */
1.245 quint 4795: }
1.65 cvs 4796: else
1.293 quint 4797: cssRule = ParseCSSColor (cssRule, &best);
4798:
4799: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.295 vatton 4800: /* install the new presentation */
4801: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.65 cvs 4802: return (cssRule);
4803: }
4804:
4805: /*----------------------------------------------------------------------
1.63 cvs 4806: ParseSVGFill: parse a SVG fill property
4807: ----------------------------------------------------------------------*/
1.79 cvs 4808: static char *ParseSVGFill (Element element, PSchema tsch,
1.327 vatton 4809: PresentationContext context, char *cssRule,
4810: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 4811: {
4812: PresentationValue best;
1.245 quint 4813: char *url;
1.63 cvs 4814:
1.426 quint 4815: url = NULL;
1.184 vatton 4816: best.typed_data.unit = UNIT_INVALID;
1.63 cvs 4817: best.typed_data.real = FALSE;
1.82 cvs 4818: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 4819: {
1.184 vatton 4820: best.typed_data.value = PATTERN_NONE;
4821: best.typed_data.unit = UNIT_REL;
1.116 vatton 4822: if (DoApply)
1.327 vatton 4823: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 4824: cssRule = SkipWord (cssRule);
1.294 vatton 4825: return (cssRule);
1.63 cvs 4826: }
1.425 quint 4827: else if (!strncasecmp (cssRule, "inherit", 7))
1.245 quint 4828: {
1.293 quint 4829: best.typed_data.unit = VALUE_INHERIT;
4830: cssRule = SkipWord (cssRule);
1.245 quint 4831: }
1.425 quint 4832: else if (!strncasecmp (cssRule, "currentColor", 12))
4833: {
4834: best.typed_data.unit = VALUE_CURRENT;
4835: cssRule = SkipWord (cssRule);
4836: }
1.245 quint 4837: else if (!strncasecmp (cssRule, "url", 3))
4838: {
4839: cssRule += 3;
4840: cssRule = ParseCSSUrl (cssRule, &url);
1.426 quint 4841: best.typed_data.unit = VALUE_URL;
4842: best.pointer = url;
4843: /* @@@@ caution: another color value may follow the uri (in case
4844: the uri could not be dereferenced) @@@@ */
1.245 quint 4845: }
1.63 cvs 4846: else
1.327 vatton 4847: cssRule = ParseCSSColor (cssRule, &best);
1.293 quint 4848:
4849: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.63 cvs 4850: {
1.293 quint 4851: /* install the new presentation. */
4852: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.426 quint 4853: if (url)
4854: TtaFreeMemory (url);
1.293 quint 4855: /* thot specificity: need to set fill pattern for background color */
4856: best.typed_data.value = PATTERN_BACKGROUND;
4857: best.typed_data.unit = UNIT_REL;
4858: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.63 cvs 4859: }
4860: return (cssRule);
4861: }
1.161 quint 4862:
1.155 cheyroul 4863: /*----------------------------------------------------------------------
1.424 quint 4864: ParseSVGStopColor: parse a SVG stop-color property
4865: ----------------------------------------------------------------------*/
4866: static char *ParseSVGStopColor (Element element, PSchema tsch,
4867: PresentationContext context, char *cssRule,
4868: CSSInfoPtr css, ThotBool isHTML)
4869: {
1.425 quint 4870: PresentationValue best;
4871:
4872: best.typed_data.unit = UNIT_INVALID;
4873: best.typed_data.real = FALSE;
4874: if (!strncasecmp (cssRule, "inherit", 7))
4875: {
4876: best.typed_data.unit = VALUE_INHERIT;
4877: cssRule = SkipWord (cssRule);
4878: }
4879: else if (!strncasecmp (cssRule, "currentColor", 12))
4880: {
4881: best.typed_data.unit = VALUE_CURRENT;
4882: cssRule = SkipWord (cssRule);
4883: }
4884: else
4885: cssRule = ParseCSSColor (cssRule, &best);
4886:
4887: if (best.typed_data.unit != UNIT_INVALID && DoApply)
4888: /* install the new presentation */
4889: TtaSetStylePresentation (PRStopColor, element, tsch, context, best);
4890: return (cssRule);
4891: }
4892:
4893: /*----------------------------------------------------------------------
1.427 ! quint 4894: ParseCSSColor: parse a CSS color attribute string
! 4895: we expect the input string describing the attribute to be
! 4896: either a color name, a 3 tuple or an hexadecimal encoding.
! 4897: The color used will be approximed from the current color
! 4898: table
! 4899: ----------------------------------------------------------------------*/
! 4900: static char *ParseSVGMarkerValue (char *cssRule, PresentationValue *val, char *url)
! 4901: {
! 4902: url = NULL;
! 4903: val->typed_data.unit = UNIT_INVALID;
! 4904: val->typed_data.real = FALSE;
! 4905: if (!strncasecmp (cssRule, "none", 4))
! 4906: {
! 4907: val->typed_data.unit = UNIT_REL;
! 4908: val->typed_data.value = 0;
! 4909: cssRule += 4;
! 4910: }
! 4911: else if (!strncasecmp (cssRule, "inherit", 7))
! 4912: {
! 4913: val->typed_data.unit = VALUE_INHERIT;
! 4914: cssRule += 7;
! 4915: }
! 4916: else if (!strncasecmp (cssRule, "url", 3))
! 4917: {
! 4918: cssRule += 3;
! 4919: cssRule = ParseCSSUrl (cssRule, &url);
! 4920: val->typed_data.unit = VALUE_URL;
! 4921: val->pointer = url;
! 4922: }
! 4923: return cssRule;
! 4924: }
! 4925:
! 4926: /*----------------------------------------------------------------------
! 4927: ParseSVGMarker: parse a SVG marker property
! 4928: ----------------------------------------------------------------------*/
! 4929: static char *ParseSVGMarker (Element element, PSchema tsch,
! 4930: PresentationContext context, char *cssRule,
! 4931: CSSInfoPtr css, ThotBool isHTML)
! 4932: {
! 4933: PresentationValue marker;
! 4934: char *url;
! 4935:
! 4936: url = NULL;
! 4937: cssRule = ParseSVGMarkerValue (cssRule, &marker, url);
! 4938: if (marker.typed_data.unit != UNIT_INVALID && DoApply)
! 4939: /* install the new presentation. */
! 4940: TtaSetStylePresentation (PRMarker, element, tsch, context, marker);
! 4941: if (url)
! 4942: TtaFreeMemory (url);
! 4943: return (cssRule);
! 4944: }
! 4945:
! 4946: /*----------------------------------------------------------------------
! 4947: ParseSVGMarkerEnd: parse a SVG marker-end property
! 4948: ----------------------------------------------------------------------*/
! 4949: static char *ParseSVGMarkerEnd (Element element, PSchema tsch,
! 4950: PresentationContext context, char *cssRule,
! 4951: CSSInfoPtr css, ThotBool isHTML)
! 4952: {
! 4953: PresentationValue marker;
! 4954: char *url;
! 4955:
! 4956: url = NULL;
! 4957: cssRule = ParseSVGMarkerValue (cssRule, &marker, url);
! 4958: if (marker.typed_data.unit != UNIT_INVALID && DoApply)
! 4959: /* install the new presentation. */
! 4960: TtaSetStylePresentation (PRMarkerEnd, element, tsch, context, marker);
! 4961: if (url)
! 4962: TtaFreeMemory (url);
! 4963: return (cssRule);
! 4964: }
! 4965:
! 4966: /*----------------------------------------------------------------------
! 4967: ParseSVGMarkerMid: parse a SVG marker-mid property
! 4968: ----------------------------------------------------------------------*/
! 4969: static char *ParseSVGMarkerMid (Element element, PSchema tsch,
! 4970: PresentationContext context, char *cssRule,
! 4971: CSSInfoPtr css, ThotBool isHTML)
! 4972: {
! 4973: PresentationValue marker;
! 4974: char *url;
! 4975:
! 4976: url = NULL;
! 4977: cssRule = ParseSVGMarkerValue (cssRule, &marker, url);
! 4978: if (marker.typed_data.unit != UNIT_INVALID && DoApply)
! 4979: /* install the new presentation. */
! 4980: TtaSetStylePresentation (PRMarkerMid, element, tsch, context, marker);
! 4981: if (url)
! 4982: TtaFreeMemory (url);
! 4983: return (cssRule);
! 4984: }
! 4985:
! 4986: /*----------------------------------------------------------------------
! 4987: ParseSVGMarkerStart: parse a SVG marker-start property
! 4988: ----------------------------------------------------------------------*/
! 4989: static char *ParseSVGMarkerStart (Element element, PSchema tsch,
! 4990: PresentationContext context, char *cssRule,
! 4991: CSSInfoPtr css, ThotBool isHTML)
! 4992: {
! 4993: PresentationValue marker;
! 4994: char *url;
! 4995:
! 4996: url = NULL;
! 4997: cssRule = ParseSVGMarkerValue (cssRule, &marker, url);
! 4998: if (marker.typed_data.unit != UNIT_INVALID && DoApply)
! 4999: /* install the new presentation. */
! 5000: TtaSetStylePresentation (PRMarkerStart, element, tsch, context, marker);
! 5001: if (url)
! 5002: TtaFreeMemory (url);
! 5003: return (cssRule);
! 5004: }
! 5005:
! 5006: /*----------------------------------------------------------------------
1.425 quint 5007: ParseSVGStopOpacity: parse a SVG opacity property
5008: ----------------------------------------------------------------------*/
5009: static char *ParseSVGStopOpacity (Element element, PSchema tsch,
5010: PresentationContext context, char *cssRule,
5011: CSSInfoPtr css, ThotBool isHTML)
5012: {
5013: PresentationValue opacity;
5014:
5015: opacity.typed_data.unit = UNIT_INVALID;
5016: opacity.typed_data.real = FALSE;
5017: if (!strncasecmp (cssRule, "inherit", 7))
5018: {
5019: opacity.typed_data.unit = VALUE_INHERIT;
5020: cssRule += 7;
5021: }
5022: else
5023: cssRule = ParseClampedUnit (cssRule, &opacity);
5024: if (opacity.typed_data.unit != UNIT_INVALID && DoApply)
5025: /* install the new presentation. */
5026: TtaSetStylePresentation (PRStopOpacity, element, tsch, context, opacity);
1.424 quint 5027: return (cssRule);
5028: }
5029:
5030: /*----------------------------------------------------------------------
1.346 quint 5031: ParseSVGOpacity: parse a SVG opacity property
1.155 cheyroul 5032: ----------------------------------------------------------------------*/
5033: static char *ParseSVGOpacity (Element element, PSchema tsch,
1.327 vatton 5034: PresentationContext context, char *cssRule,
5035: CSSInfoPtr css, ThotBool isHTML)
1.155 cheyroul 5036: {
1.425 quint 5037: PresentationValue opacity;
1.63 cvs 5038:
1.425 quint 5039: opacity.typed_data.unit = UNIT_INVALID;
5040: opacity.typed_data.real = FALSE;
5041: if (!strncasecmp (cssRule, "inherit", 7))
5042: {
5043: opacity.typed_data.unit = VALUE_INHERIT;
5044: cssRule += 7;
5045: }
5046: else
5047: cssRule = ParseClampedUnit (cssRule, &opacity);
5048: if (opacity.typed_data.unit != UNIT_INVALID && DoApply)
1.295 vatton 5049: /* install the new presentation. */
1.425 quint 5050: TtaSetStylePresentation (PROpacity, element, tsch, context, opacity);
1.155 cheyroul 5051: return (cssRule);
5052: }
1.346 quint 5053:
1.170 cheyroul 5054: /*----------------------------------------------------------------------
1.346 quint 5055: ParseSVGStrokeOpacity: parse a SVG stroke-opacity property
1.170 cheyroul 5056: ----------------------------------------------------------------------*/
5057: static char *ParseSVGStrokeOpacity (Element element, PSchema tsch,
1.327 vatton 5058: PresentationContext context, char *cssRule,
5059: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 5060: {
1.425 quint 5061: PresentationValue opacity;
1.161 quint 5062:
1.425 quint 5063: opacity.typed_data.unit = UNIT_INVALID;
5064: opacity.typed_data.real = FALSE;
5065: if (!strncasecmp (cssRule, "inherit", 7))
5066: {
5067: opacity.typed_data.unit = VALUE_INHERIT;
5068: cssRule += 7;
5069: }
5070: else
5071: cssRule = ParseClampedUnit (cssRule, &opacity);
5072: if (opacity.typed_data.unit != UNIT_INVALID && DoApply)
1.295 vatton 5073: /* install the new presentation. */
1.425 quint 5074: TtaSetStylePresentation (PRStrokeOpacity, element, tsch, context, opacity);
1.170 cheyroul 5075: return (cssRule);
5076: }
1.346 quint 5077:
1.170 cheyroul 5078: /*----------------------------------------------------------------------
1.420 vatton 5079: ParseSVGFillOpacity: parse a SVG fill-opacityl property
1.170 cheyroul 5080: ----------------------------------------------------------------------*/
5081: static char *ParseSVGFillOpacity (Element element, PSchema tsch,
1.327 vatton 5082: PresentationContext context, char *cssRule,
5083: CSSInfoPtr css, ThotBool isHTML)
1.170 cheyroul 5084: {
1.425 quint 5085: PresentationValue opacity;
1.170 cheyroul 5086:
1.425 quint 5087: opacity.typed_data.unit = UNIT_INVALID;
5088: opacity.typed_data.real = FALSE;
5089: if (!strncasecmp (cssRule, "inherit", 7))
5090: {
5091: opacity.typed_data.unit = VALUE_INHERIT;
5092: cssRule += 7;
5093: }
5094: else
5095: cssRule = ParseClampedUnit (cssRule, &opacity);
5096: if (opacity.typed_data.unit != UNIT_INVALID && DoApply)
1.295 vatton 5097: /* install the new presentation. */
1.425 quint 5098: TtaSetStylePresentation (PRFillOpacity, element, tsch, context, opacity);
1.170 cheyroul 5099: return (cssRule);
5100: }
1.207 vatton 5101:
1.1 cvs 5102: /*----------------------------------------------------------------------
1.420 vatton 5103: ParseSVGFillRule: parse a SVG fill-rule property
5104: ----------------------------------------------------------------------*/
5105: static char *ParseSVGFillRule (Element element, PSchema tsch,
5106: PresentationContext context, char *cssRule,
5107: CSSInfoPtr css, ThotBool isHTML)
5108: {
5109: PresentationValue best;
5110:
5111: best.typed_data.unit = UNIT_INVALID;
5112: best.typed_data.real = FALSE;
5113: if (!strncasecmp (cssRule, "inherit", 7))
5114: {
5115: best.typed_data.unit = VALUE_INHERIT;
5116: best.typed_data.value = 0;
5117: cssRule = SkipWord (cssRule);
5118: }
5119: else if (!strncasecmp (cssRule, "nonzero", 7))
5120: {
5121: best.typed_data.unit = VALUE_AUTO;
1.421 quint 5122: best.typed_data.value = NonZero;
1.420 vatton 5123: cssRule = SkipWord (cssRule);
5124: }
5125: else if (!strncasecmp (cssRule, "evenodd", 7))
5126: {
5127: best.typed_data.unit = VALUE_AUTO;
1.421 quint 5128: best.typed_data.value = EvenOdd;
1.420 vatton 5129: cssRule = SkipWord (cssRule);
5130: }
5131:
5132: if (DoApply)
5133: /* install the new presentation. */
5134: TtaSetStylePresentation (PRFillRule, element, tsch, context, best);
5135: return (cssRule);
5136: }
5137:
5138: /*----------------------------------------------------------------------
1.327 vatton 5139: GetCSSBackgroundURL searches a CSS BackgroundImage url within
5140: the cssRule.
5141: Returns NULL or a new allocated url string.
1.217 vatton 5142: ----------------------------------------------------------------------*/
5143: char *GetCSSBackgroundURL (char *cssRule)
5144: {
5145: char *b, *url;
5146:
5147: url = NULL;
5148: b = strstr (cssRule, "url");
5149: if (b)
1.290 gully 5150: b = ParseCSSUrl (b, &url);
1.217 vatton 5151: return (url);
5152: }
5153:
5154: /*----------------------------------------------------------------------
1.327 vatton 5155: ParseCSSContent: parse the value of property "content"
1.217 vatton 5156: ----------------------------------------------------------------------*/
5157: static char *ParseCSSContent (Element element, PSchema tsch,
1.327 vatton 5158: PresentationContext ctxt, char *cssRule,
5159: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5160: {
1.312 quint 5161: PresentationValue value;
1.353 quint 5162: char *last, *start, quoteChar, savedChar;
5163: int length, val;
1.366 vatton 5164: char *buffer, *p;
5165: char *start_value;
1.312 quint 5166: ThotBool repeat;
5167:
5168: value.typed_data.unit = UNIT_REL;
5169: value.typed_data.real = FALSE;
5170: value.typed_data.value = 0;
1.366 vatton 5171: if (!DoDialog && DoApply)
1.347 quint 5172: TtaSetStylePresentation (PRContent, element, tsch, ctxt, value);
1.217 vatton 5173: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5174: start_value = cssRule;
1.312 quint 5175: repeat = TRUE;
5176: while (repeat)
5177: {
1.366 vatton 5178: p = cssRule;
1.312 quint 5179: if (!strncasecmp (cssRule, "normal", 6))
1.327 vatton 5180: /* The pseudo-element is not generated */
5181: {
5182: /* @@@@@@ */
5183: cssRule += 6;
5184: repeat = FALSE;
5185: }
1.331 quint 5186: else if (!strncasecmp (cssRule, "none", 4))
5187: /* The pseudo-element is not generated */
5188: {
5189: /* @@@@@@ */
5190: cssRule += 4;
5191: repeat = FALSE;
5192: }
1.312 quint 5193: else if (*cssRule == '"' || *cssRule == '\'')
1.327 vatton 5194: /* It's a string */
5195: {
5196: quoteChar = *cssRule;
1.353 quint 5197: /* how long is the string? */
5198: last = cssRule;
5199: last = SkipString (last);
5200: length = last - cssRule;
5201: /* get a buffer to store the string */
1.366 vatton 5202: buffer = (char *)TtaGetMemory (length);
1.353 quint 5203: p = buffer; /* beginning of the string */
1.327 vatton 5204: cssRule++;
5205: while (*cssRule != EOS && *cssRule != quoteChar)
1.353 quint 5206: {
5207: if (*cssRule == '\\')
5208: {
5209: cssRule++; /* skip the backslash */
5210: if ((*cssRule >= '0' && *cssRule <= '9') ||
5211: (*cssRule >= 'A' && *cssRule <= 'F') ||
5212: (*cssRule >= 'a' && *cssRule <= 'f'))
5213: {
5214: start = cssRule; /* first hex digit after the backslash*/
5215: cssRule++;
5216: while ((*cssRule >= '0' && *cssRule <= '9') ||
5217: (*cssRule >= 'A' && *cssRule <= 'F') ||
5218: (*cssRule >= 'a' && *cssRule <= 'f'))
5219: cssRule++;
5220: savedChar = *cssRule;
5221: *cssRule = EOS;
5222: sscanf (start, "%x", &val);
1.366 vatton 5223: TtaWCToMBstring ((wchar_t) val, (unsigned char **) &p);
1.353 quint 5224: *cssRule = savedChar;
5225: }
5226: else
5227: {
5228: *p = *cssRule;
5229: p++; cssRule++;
5230: }
5231: }
5232: else
5233: {
5234: *p = *cssRule;
5235: p++; cssRule++;
5236: }
5237: }
5238: *p = EOS;
1.366 vatton 5239: if (DoDialog)
5240: {
5241: DisplayStyleValue ("", start_value, p);
5242: start_value = p;
5243: }
5244: else if (*cssRule != quoteChar)
1.327 vatton 5245: cssRule = SkipProperty (cssRule, FALSE);
5246: else
5247: {
5248: *cssRule = EOS;
5249: value.typed_data.unit = UNIT_REL;
5250: value.typed_data.real = FALSE;
1.353 quint 5251: value.pointer = buffer;
1.347 quint 5252: if (DoApply)
5253: TtaSetStylePresentation (PRContentString, element, tsch, ctxt,
5254: value);
1.327 vatton 5255: *cssRule = quoteChar;
5256: cssRule++;
5257: }
1.353 quint 5258: TtaFreeMemory (buffer);
1.327 vatton 5259: }
1.312 quint 5260: else if (!strncasecmp (cssRule, "url", 3))
1.327 vatton 5261: {
5262: cssRule += 3;
1.347 quint 5263: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
5264: PRContentURL);
1.366 vatton 5265: if (DoDialog)
5266: {
5267: DisplayStyleValue ("", start_value, p);
5268: start_value = p;
5269: }
1.327 vatton 5270: }
1.312 quint 5271: else if (!strncasecmp (cssRule, "counter", 7))
1.327 vatton 5272: {
5273: cssRule += 7;
5274: /* @@@@@@ */
1.366 vatton 5275: if (DoDialog)
5276: {
5277: DisplayStyleValue ("", start_value, p);
5278: start_value = p;
5279: }
5280: else
5281: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5282: }
1.312 quint 5283: else if (!strncasecmp (cssRule, "counters", 8))
1.327 vatton 5284: {
5285: cssRule += 8;
5286: /* @@@@@@ */
1.366 vatton 5287: if (DoDialog)
5288: {
5289: DisplayStyleValue ("", start_value, p);
5290: start_value = p;
5291: }
5292: else
5293: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5294: }
1.312 quint 5295: else if (!strncasecmp (cssRule, "attr", 4))
1.327 vatton 5296: {
1.347 quint 5297: value.pointer = NULL;
1.327 vatton 5298: cssRule += 4;
1.347 quint 5299: cssRule = SkipBlanksAndComments (cssRule);
5300: if (*cssRule == '(')
5301: {
5302: cssRule++;
5303: cssRule = SkipBlanksAndComments (cssRule);
5304: start = cssRule;
5305: while (*cssRule != EOS && *cssRule != ')')
5306: cssRule++;
5307: if (*cssRule != ')')
5308: cssRule = start;
5309: else
5310: {
5311: last = cssRule;
5312: /* remove extra spaces */
5313: if (last[-1] == SPACE)
5314: {
5315: *last = SPACE;
5316: last--;
5317: while (last[-1] == SPACE)
5318: last--;
5319: }
5320: savedChar = *last;
5321: *last = EOS;
5322: value.typed_data.unit = UNIT_REL;
5323: value.typed_data.real = FALSE;
5324: value.pointer = start;
1.366 vatton 5325: if (DoDialog)
5326: {
5327: DisplayStyleValue ("", start_value, p);
5328: start_value = p;
5329: }
5330: else if (DoApply)
1.347 quint 5331: TtaSetStylePresentation (PRContentAttr, element, tsch,
5332: ctxt, value);
5333: *last = savedChar;
5334: }
5335: }
5336: if (value.pointer == NULL)
5337: {
1.353 quint 5338: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 5339: if (DoDialog)
5340: {
5341: DisplayStyleValue ("", start_value, p);
5342: start_value = p;
5343: }
5344: else
5345: cssRule = SkipProperty (cssRule, FALSE);
1.347 quint 5346: }
5347: cssRule++;
1.327 vatton 5348: }
1.312 quint 5349: else if (!strncasecmp (cssRule, "open-quote", 10))
1.327 vatton 5350: {
5351: cssRule += 10;
5352: /* @@@@@@ */
5353: }
1.312 quint 5354: else if (!strncasecmp (cssRule, "close-quote", 11))
1.327 vatton 5355: {
5356: cssRule += 11;
5357: /* @@@@@@ */
5358: }
1.312 quint 5359: else if (!strncasecmp (cssRule, "no-open-quote", 13))
1.327 vatton 5360: {
5361: cssRule += 13;
5362: /* @@@@@@ */
5363: }
1.312 quint 5364: else if (!strncasecmp (cssRule, "no-close-quote", 14))
1.327 vatton 5365: {
5366: cssRule += 14;
5367: /* @@@@@@ */
5368: }
1.312 quint 5369: else if (!strncasecmp (cssRule, "inherit", 7))
1.327 vatton 5370: {
5371: cssRule += 7;
5372: /* @@@@@@ */
5373: repeat = FALSE;
5374: }
1.312 quint 5375: else
1.327 vatton 5376: {
1.353 quint 5377: CSSParseError ("Invalid content value", (char*) p, cssRule);
1.366 vatton 5378: if (DoDialog)
5379: {
5380: DisplayStyleValue ("", start_value, p);
5381: start_value = p;
5382: }
5383: else
5384: cssRule = SkipProperty (cssRule, FALSE);
1.327 vatton 5385: }
1.312 quint 5386: cssRule = SkipBlanksAndComments (cssRule);
5387: if (repeat)
1.327 vatton 5388: if (*cssRule == ';' || *cssRule == '}' || *cssRule == EOS ||
5389: *cssRule == '!')
5390: repeat = FALSE;
1.217 vatton 5391: }
5392: return (cssRule);
5393: }
1.1 cvs 5394:
5395: /*----------------------------------------------------------------------
1.59 cvs 5396: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 5397: ----------------------------------------------------------------------*/
1.79 cvs 5398: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
1.327 vatton 5399: PresentationContext ctxt,
5400: char *cssRule, CSSInfoPtr css,
5401: ThotBool isHTML)
1.1 cvs 5402: {
1.49 cvs 5403: PresentationValue image, value;
1.357 quint 5404: char *ptr;
1.148 vatton 5405:
1.370 vatton 5406: image.typed_data.real = FALSE;
5407: value.typed_data.real = FALSE;
1.82 cvs 5408: cssRule = SkipBlanksAndComments (cssRule);
1.357 quint 5409: ptr = cssRule;
1.161 quint 5410: if (!strncasecmp (cssRule, "none", 4))
5411: {
1.260 vatton 5412: cssRule += 4;
1.366 vatton 5413: if (DoDialog)
5414: DisplayStyleValue ("background-image", ptr, cssRule);
5415: else if (DoApply)
1.327 vatton 5416: {
5417: /* no background image */
5418: image.pointer = NULL;
5419: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt,
5420: image);
5421: }
1.161 quint 5422: }
1.357 quint 5423: else if (!strncasecmp (cssRule, "inherit", 7))
5424: {
5425: value.typed_data.unit = VALUE_INHERIT;
5426: cssRule += 7;
1.366 vatton 5427: if (DoDialog)
5428: DisplayStyleValue ("background-image", ptr, cssRule);
1.357 quint 5429: }
1.161 quint 5430: else if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 5431: {
5432: cssRule += 3;
1.302 quint 5433: cssRule = SetCSSImage (element, tsch, ctxt, cssRule, css,
1.327 vatton 5434: PRBackgroundPicture);
1.207 vatton 5435: if (ctxt->destroy)
1.327 vatton 5436: if (TtaGetStylePresentation (PRFillPattern, element, tsch, ctxt,
5437: &value) < 0)
5438: {
5439: /* there is no FillPattern rule -> remove ShowBox rule */
5440: value.typed_data.value = 1;
5441: value.typed_data.unit = UNIT_REL;
5442: value.typed_data.real = FALSE;
5443: TtaSetStylePresentation (PRShowBox, element, tsch, ctxt, value);
5444: }
1.18 cvs 5445: }
1.357 quint 5446: else
5447: {
5448: cssRule = SkipWord (cssRule);
5449: CSSParseError ("Invalid background-image value", ptr, cssRule);
5450: cssRule = SkipProperty (cssRule, FALSE);
5451: }
1.18 cvs 5452: return (cssRule);
5453: }
5454:
5455: /*----------------------------------------------------------------------
1.295 vatton 5456: ParseACSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 5457: ----------------------------------------------------------------------*/
1.295 vatton 5458: static char *ParseACSSBackgroundRepeat (Element element, PSchema tsch,
1.327 vatton 5459: PresentationContext ctxt,
5460: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5461: {
5462: PresentationValue repeat;
1.366 vatton 5463: char *start_value;
1.18 cvs 5464:
1.366 vatton 5465: cssRule = SkipBlanksAndComments (cssRule);
5466: start_value = cssRule;
1.184 vatton 5467: repeat.typed_data.value = REALSIZE;
1.191 vatton 5468: repeat.typed_data.unit = UNIT_BOX;
1.18 cvs 5469: repeat.typed_data.real = FALSE;
1.82 cvs 5470: cssRule = SkipBlanksAndComments (cssRule);
5471: if (!strncasecmp (cssRule, "no-repeat", 9))
1.184 vatton 5472: repeat.typed_data.value = REALSIZE;
1.82 cvs 5473: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.265 vatton 5474: repeat.typed_data.value = YREPEAT;
1.82 cvs 5475: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.265 vatton 5476: repeat.typed_data.value = XREPEAT;
1.82 cvs 5477: else if (!strncasecmp (cssRule, "repeat", 6))
1.184 vatton 5478: repeat.typed_data.value = REPEAT;
1.18 cvs 5479: else
5480: return (cssRule);
5481:
1.295 vatton 5482: cssRule = SkipWord (cssRule);
5483: /* check if it's an important rule */
1.366 vatton 5484: if (DoDialog)
5485: DisplayStyleValue ("background-repeat", start_value, cssRule);
5486: else if (DoApply)
1.295 vatton 5487: /* install the new presentation */
1.362 quint 5488: TtaSetStylePresentation (PRBackgroundRepeat, element, tsch, ctxt, repeat);
1.295 vatton 5489: return (cssRule);
5490: }
5491:
5492: /*----------------------------------------------------------------------
5493: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
5494: ----------------------------------------------------------------------*/
5495: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.315 gully 5496: PresentationContext ctxt,
5497: char *cssRule, CSSInfoPtr css,
5498: ThotBool isHTML)
1.295 vatton 5499: {
1.388 carcone 5500:
5501: char *ptr;
5502:
5503: ptr = cssRule;
1.295 vatton 5504: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
1.315 gully 5505: cssRule, css, isHTML);
1.388 carcone 5506:
5507: if (ptr == cssRule)
1.117 vatton 5508: {
1.295 vatton 5509: cssRule = SkipValue ("Invalid background-repeat value", cssRule);
1.117 vatton 5510: /* check if it's an important rule */
5511: }
1.295 vatton 5512: return cssRule;
1.18 cvs 5513: }
5514:
5515: /*----------------------------------------------------------------------
1.327 vatton 5516: ParseACSSBackgroundAttachment: parse a CSS BackgroundAttachment
5517: attribute string.
1.18 cvs 5518: ----------------------------------------------------------------------*/
1.295 vatton 5519: static char *ParseACSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5520: PresentationContext ctxt,
5521: char *cssRule, CSSInfoPtr css,
5522: ThotBool isHTML)
1.18 cvs 5523: {
1.366 vatton 5524: char *start_value;
5525:
1.163 quint 5526: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5527: start_value = cssRule;
1.163 quint 5528: if (!strncasecmp (cssRule, "scroll", 6))
1.199 vatton 5529: {
5530: cssRule = SkipWord (cssRule);
5531: }
1.163 quint 5532: else if (!strncasecmp (cssRule, "fixed", 5))
1.199 vatton 5533: {
5534: cssRule = SkipWord (cssRule);
5535: }
1.362 quint 5536: else if (!strncasecmp (cssRule, "inherit", 7))
5537: {
5538: cssRule = SkipWord (cssRule);
5539: }
1.366 vatton 5540: if (start_value != cssRule && DoDialog)
5541: DisplayStyleValue ("background-attachment", start_value, cssRule);
1.163 quint 5542: return (cssRule);
1.1 cvs 5543: }
5544:
5545: /*----------------------------------------------------------------------
1.327 vatton 5546: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
5547: attribute string.
1.295 vatton 5548: ----------------------------------------------------------------------*/
5549: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
1.327 vatton 5550: PresentationContext ctxt,
5551: char *cssRule, CSSInfoPtr css,
5552: ThotBool isHTML)
1.295 vatton 5553: {
5554: char *ptr;
5555:
5556: ptr = cssRule;
5557: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.327 vatton 5558: cssRule, css, isHTML);
1.295 vatton 5559: if (ptr == cssRule)
1.366 vatton 5560: cssRule = SkipValue ("Invalid background-attachment value", cssRule);
1.295 vatton 5561: return cssRule;
5562: }
5563:
5564: /*----------------------------------------------------------------------
1.327 vatton 5565: ParseACSSBackgroundPosition: parse a CSS BackgroundPosition
5566: attribute string.
1.1 cvs 5567: ----------------------------------------------------------------------*/
1.279 vatton 5568: static char *ParseACSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5569: PresentationContext ctxt,
5570: char *cssRule, CSSInfoPtr css,
1.362 quint 5571: ThotBool isHTML, ThotBool *across)
1.1 cvs 5572: {
1.362 quint 5573: PresentationValue val;
5574: char *ptr;
1.1 cvs 5575:
1.163 quint 5576: cssRule = SkipBlanksAndComments (cssRule);
1.362 quint 5577: ptr = cssRule;
5578: val.typed_data.value = 0;
5579: val.typed_data.real = FALSE;
5580: val.typed_data.unit = UNIT_INVALID;
1.163 quint 5581: if (!strncasecmp (cssRule, "left", 4))
1.362 quint 5582: {
5583: val.typed_data.value = 0;
5584: val.typed_data.unit = UNIT_PERCENT;
5585: cssRule += 4;
5586: *across = TRUE;
5587: }
1.163 quint 5588: else if (!strncasecmp (cssRule, "right", 5))
1.362 quint 5589: {
5590: val.typed_data.value = 100;
5591: val.typed_data.unit = UNIT_PERCENT;
5592: cssRule += 5;
5593: *across = TRUE;
5594: }
1.163 quint 5595: else if (!strncasecmp (cssRule, "center", 6))
1.362 quint 5596: {
5597: val.typed_data.value = 50;
5598: val.typed_data.unit = UNIT_PERCENT;
5599: cssRule += 6;
5600: }
1.163 quint 5601: else if (!strncasecmp (cssRule, "top", 3))
1.362 quint 5602: {
5603: val.typed_data.value = 0;
5604: val.typed_data.unit = UNIT_PERCENT;
5605: cssRule += 3;
5606: *across = FALSE;
5607: }
1.163 quint 5608: else if (!strncasecmp (cssRule, "bottom", 6))
1.191 vatton 5609: {
1.362 quint 5610: val.typed_data.value = 100;
5611: val.typed_data.unit = UNIT_PERCENT;
5612: cssRule += 6;
5613: *across = FALSE;
5614: }
5615: else if (!strncasecmp (cssRule, "inherit", 7))
5616: {
5617: val.typed_data.unit = VALUE_INHERIT;
5618: cssRule += 7;
1.191 vatton 5619: }
1.163 quint 5620: else
1.362 quint 5621: /* <length> or <percentage> */
5622: {
5623: cssRule = ParseCSSUnit (cssRule, &val);
5624: if (val.typed_data.unit == UNIT_BOX && val.typed_data.value == 0)
5625: /* 0 with no unit. Accept */
5626: val.typed_data.unit = UNIT_PERCENT;
5627: }
1.163 quint 5628:
1.366 vatton 5629: if (val.typed_data.unit != UNIT_INVALID && val.typed_data.unit != UNIT_BOX)
1.362 quint 5630: {
1.366 vatton 5631: if (DoDialog)
5632: {
5633: if (val.typed_data.unit == VALUE_INHERIT)
5634: {
5635: DisplayStyleValue ("background-positionH", ptr, cssRule);
5636: DisplayStyleValue ("background-positionV", ptr, cssRule);
5637: }
5638: else if (*across)
5639: DisplayStyleValue ("background-positionH", ptr, cssRule);
5640: else
5641: DisplayStyleValue ("background-positionV", ptr, cssRule);
5642: }
5643: else if (DoApply)
1.362 quint 5644: /* install the new presentation */
5645: {
5646: if (val.typed_data.unit == VALUE_INHERIT)
5647: /* "inherit" applies to both dimensions */
5648: {
5649: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5650: ctxt, val);
5651: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5652: ctxt, val);
5653: }
5654: else if (*across)
5655: TtaSetStylePresentation (PRBackgroundHorizPos, element, tsch,
5656: ctxt, val);
5657: else
5658: TtaSetStylePresentation (PRBackgroundVertPos, element, tsch,
5659: ctxt, val);
5660: }
5661: }
1.279 vatton 5662: return (cssRule);
5663: }
1.218 vatton 5664:
1.279 vatton 5665: /*----------------------------------------------------------------------
1.327 vatton 5666: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
5667: attribute string.
1.279 vatton 5668: ----------------------------------------------------------------------*/
5669: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
1.327 vatton 5670: PresentationContext ctxt,
5671: char *cssRule, CSSInfoPtr css,
5672: ThotBool isHTML)
1.279 vatton 5673: {
1.295 vatton 5674: char *ptr;
1.362 quint 5675: ThotBool across;
1.295 vatton 5676:
5677: ptr = cssRule;
1.362 quint 5678: across = TRUE;
5679: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule, css,
5680: isHTML, &across);
1.295 vatton 5681: if (ptr == cssRule)
1.360 vatton 5682: cssRule = SkipValue ("Invalid background-position value", cssRule);
1.362 quint 5683: else
1.298 vatton 5684: {
1.362 quint 5685: cssRule = SkipBlanksAndComments (cssRule);
5686: if (*cssRule != ';' && *cssRule != '!' && *cssRule != EOS)
5687: {
5688: /* possible second value */
5689: ptr = cssRule;
5690: across = !across;
5691: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5692: css, isHTML, &across);
5693: if (ptr == cssRule)
5694: cssRule = SkipValue ("Invalid background-position value", cssRule);
5695: }
1.298 vatton 5696: }
1.163 quint 5697: return (cssRule);
1.18 cvs 5698: }
5699:
5700: /*----------------------------------------------------------------------
1.327 vatton 5701: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 5702: ----------------------------------------------------------------------*/
1.79 cvs 5703: static char *ParseCSSBackground (Element element, PSchema tsch,
1.327 vatton 5704: PresentationContext ctxt, char *cssRule,
5705: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 5706: {
1.323 vatton 5707: char *ptr;
5708: int skippedNL;
1.362 quint 5709: ThotBool img, repeat, position, attach, color, across;
1.18 cvs 5710:
1.82 cvs 5711: cssRule = SkipBlanksAndComments (cssRule);
1.323 vatton 5712: img = repeat = position = attach = color = FALSE;
1.362 quint 5713: across = TRUE;
1.301 vatton 5714: while (*cssRule != ';' && *cssRule != '}' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 5715: {
1.71 cvs 5716: /* perhaps a Background Image */
1.198 vatton 5717: if (!strncasecmp (cssRule, "url", 3) || !strncasecmp (cssRule, "none", 4))
1.327 vatton 5718: {
1.334 vatton 5719: if (!strncasecmp (cssRule, "none", 4))
1.423 vatton 5720: {
5721: repeat = TRUE;
5722: ParseCSSBackgroundColor (element, tsch, ctxt, "transparent",
5723: css, isHTML);
5724: }
1.327 vatton 5725: cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
5726: css, isHTML);
5727: img = TRUE;
5728: }
1.18 cvs 5729: /* perhaps a Background Attachment */
1.82 cvs 5730: else if (!strncasecmp (cssRule, "scroll", 6) ||
5731: !strncasecmp (cssRule, "fixed", 5))
1.327 vatton 5732: {
5733: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
5734: cssRule, css, isHTML);
1.328 vatton 5735: attach = repeat = TRUE;
1.327 vatton 5736: }
1.18 cvs 5737: /* perhaps a Background Repeat */
1.82 cvs 5738: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
5739: !strncasecmp (cssRule, "repeat-y", 8) ||
5740: !strncasecmp (cssRule, "repeat-x", 8) ||
5741: !strncasecmp (cssRule, "repeat", 6))
1.327 vatton 5742: {
5743: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
5744: cssRule, css, isHTML);
5745: repeat = TRUE;
5746: }
1.18 cvs 5747: /* perhaps a Background Position */
1.82 cvs 5748: else if (!strncasecmp (cssRule, "left", 4) ||
5749: !strncasecmp (cssRule, "right", 5) ||
5750: !strncasecmp (cssRule, "center", 6) ||
5751: !strncasecmp (cssRule, "top", 3) ||
5752: !strncasecmp (cssRule, "bottom", 6) ||
1.279 vatton 5753: isdigit (*cssRule) || *cssRule == '.' || *cssRule == '-')
1.327 vatton 5754: {
1.362 quint 5755: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5756: css, isHTML, &across);
5757: across = !across;
1.328 vatton 5758: position = repeat = TRUE;
1.327 vatton 5759: }
1.18 cvs 5760: /* perhaps a Background Color */
1.323 vatton 5761: else if (!color)
1.327 vatton 5762: {
5763: skippedNL = NewLineSkipped;
5764: /* check if the rule has been found */
5765: ptr = cssRule;
5766: cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
5767: cssRule, css, isHTML);
5768: if (ptr == cssRule)
5769: {
5770: NewLineSkipped = skippedNL;
5771: /* rule not found */
5772: cssRule = SkipProperty (cssRule, FALSE);
5773: }
5774: else
5775: color = TRUE;
5776: }
1.328 vatton 5777: else
1.327 vatton 5778: cssRule = SkipProperty (cssRule, FALSE);
1.328 vatton 5779:
1.82 cvs 5780: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 5781: }
1.328 vatton 5782:
5783: if (color && !img)
1.405 kia 5784: ParseCSSBackgroundImage (element, tsch, ctxt, (char*)
5785: "none", css, isHTML);
1.328 vatton 5786:
5787: if (img && !repeat)
5788: ParseACSSBackgroundRepeat (element, tsch, ctxt,
1.405 kia 5789: (char*)"repeat", css, isHTML);
1.328 vatton 5790: if (img && !position)
5791: ParseACSSBackgroundPosition (element, tsch, ctxt,
1.405 kia 5792: (char*)"0% 0%", css, isHTML, &across);
1.328 vatton 5793: if (img && !attach)
5794: ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.405 kia 5795: (char*)"scroll", css, isHTML);
1.327 vatton 5796: return (cssRule);
1.18 cvs 5797: }
5798:
1.59 cvs 5799: /*----------------------------------------------------------------------
1.327 vatton 5800: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 5801: ----------------------------------------------------------------------*/
1.79 cvs 5802: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.327 vatton 5803: PresentationContext ctxt, char *cssRule,
5804: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 5805: {
5806: PresentationValue page;
1.366 vatton 5807: char *start_value;
1.59 cvs 5808:
1.184 vatton 5809: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5810: page.typed_data.real = FALSE;
1.82 cvs 5811: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5812: start_value = cssRule;
1.82 cvs 5813: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5814: page.typed_data.value = PageAuto;
1.82 cvs 5815: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5816: {
1.184 vatton 5817: page.typed_data.unit = UNIT_REL;
5818: page.typed_data.value = PageAlways;
1.59 cvs 5819: }
1.82 cvs 5820: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5821: {
1.184 vatton 5822: page.typed_data.unit = UNIT_REL;
5823: page.typed_data.value = PageAvoid;
1.59 cvs 5824: }
1.82 cvs 5825: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5826: {
1.184 vatton 5827: page.typed_data.unit = UNIT_REL;
5828: page.typed_data.value = PageLeft;
1.59 cvs 5829: }
1.82 cvs 5830: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5831: {
1.184 vatton 5832: page.typed_data.unit = UNIT_REL;
5833: page.typed_data.value = PageRight;
1.59 cvs 5834: }
1.82 cvs 5835: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5836: {
1.293 quint 5837: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5838: page.typed_data.value = PageInherit;
1.59 cvs 5839: }
5840: cssRule = SkipWord (cssRule);
5841: /* install the new presentation */
1.366 vatton 5842: if ((page.typed_data.unit == UNIT_REL && page.typed_data.value == PageAlways)
5843: || page.typed_data.unit == VALUE_INHERIT)
5844: {
5845: if (DoDialog)
5846: DisplayStyleValue ("page-break-before", start_value, cssRule);
5847: else if (DoApply)
5848: TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
5849: }
1.59 cvs 5850: return (cssRule);
5851: }
5852:
5853: /*----------------------------------------------------------------------
1.327 vatton 5854: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 5855: ----------------------------------------------------------------------*/
1.79 cvs 5856: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.327 vatton 5857: PresentationContext ctxt,
5858: char *cssRule, CSSInfoPtr css,
5859: ThotBool isHTML)
1.59 cvs 5860: {
5861: PresentationValue page;
1.366 vatton 5862: char *start_value;
1.59 cvs 5863:
1.184 vatton 5864: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5865: page.typed_data.real = FALSE;
1.82 cvs 5866: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5867: start_value = cssRule;
1.82 cvs 5868: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5869: page.typed_data.value = PageAuto;
1.82 cvs 5870: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5871: {
1.184 vatton 5872: page.typed_data.unit = UNIT_REL;
5873: page.typed_data.value = PageAlways;
1.59 cvs 5874: }
1.82 cvs 5875: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5876: {
1.184 vatton 5877: page.typed_data.unit = UNIT_REL;
5878: page.typed_data.value = PageAvoid;
1.59 cvs 5879: }
1.82 cvs 5880: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5881: {
1.184 vatton 5882: page.typed_data.unit = UNIT_REL;
5883: page.typed_data.value = PageLeft;
1.59 cvs 5884: }
1.82 cvs 5885: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5886: {
1.184 vatton 5887: page.typed_data.unit = UNIT_REL;
5888: page.typed_data.value = PageRight;
1.59 cvs 5889: }
1.82 cvs 5890: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5891: {
1.293 quint 5892: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5893: page.typed_data.value = PageInherit;
1.59 cvs 5894: }
5895: cssRule = SkipWord (cssRule);
5896: /* install the new presentation */
1.366 vatton 5897: if (page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT)
5898: {
5899: if (DoDialog)
5900: DisplayStyleValue ("page-break-after", start_value, cssRule);
1.367 cvs 5901: //else if (DoApply)
5902: // TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page);
1.366 vatton 5903: }
1.59 cvs 5904: return (cssRule);
5905: }
5906:
5907: /*----------------------------------------------------------------------
1.327 vatton 5908: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 5909: ----------------------------------------------------------------------*/
1.79 cvs 5910: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.327 vatton 5911: PresentationContext ctxt,
5912: char *cssRule, CSSInfoPtr css,
5913: ThotBool isHTML)
1.59 cvs 5914: {
5915: PresentationValue page;
1.366 vatton 5916: char *start_value;
1.59 cvs 5917:
1.184 vatton 5918: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5919: page.typed_data.real = FALSE;
1.82 cvs 5920: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5921: start_value = cssRule;
1.82 cvs 5922: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 5923: {
1.184 vatton 5924: /*page.typed_data.unit = UNIT_REL;*/
5925: page.typed_data.value = PageAuto;
1.59 cvs 5926: }
1.82 cvs 5927: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5928: {
1.184 vatton 5929: page.typed_data.unit = UNIT_REL;
5930: page.typed_data.value = PageAvoid;
1.59 cvs 5931: }
1.82 cvs 5932: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5933: {
1.293 quint 5934: /* page.typed_data.unit = VALUE_INHERIT; */
1.184 vatton 5935: page.typed_data.value = PageInherit;
1.59 cvs 5936: }
5937: cssRule = SkipWord (cssRule);
5938: /* install the new presentation */
1.366 vatton 5939: if ((page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT) &&
5940: page.typed_data.value == PageAvoid)
5941: {
5942: if (DoDialog)
5943: DisplayStyleValue ("page-break-inside", start_value, cssRule);
1.367 cvs 5944: //else if (DoApply)
5945: //TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);
1.366 vatton 5946: }
1.59 cvs 5947: return (cssRule);
5948: }
1.18 cvs 5949:
1.60 cvs 5950: /*----------------------------------------------------------------------
1.327 vatton 5951: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 5952: ----------------------------------------------------------------------*/
1.79 cvs 5953: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.327 vatton 5954: PresentationContext ctxt, char *cssRule,
5955: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 5956: {
5957: PresentationValue width;
5958:
1.82 cvs 5959: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 5960: width.typed_data.value = 0;
1.184 vatton 5961: width.typed_data.unit = UNIT_INVALID;
1.60 cvs 5962: width.typed_data.real = FALSE;
1.110 vatton 5963: if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 5964: {
1.327 vatton 5965: cssRule = ParseCSSUnit (cssRule, &width);
5966: if (width.typed_data.unit == UNIT_BOX)
5967: width.typed_data.unit = UNIT_PX;
1.166 vatton 5968: }
1.295 vatton 5969: else
5970: cssRule = SkipValue ("Invalid stroke-width value", cssRule);
5971:
1.184 vatton 5972: if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 5973: {
1.207 vatton 5974: TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117 vatton 5975: width.typed_data.value = 1;
1.184 vatton 5976: width.typed_data.unit = UNIT_REL;
1.117 vatton 5977: }
1.60 cvs 5978: return (cssRule);
5979: }
5980:
1.217 vatton 5981: /*----------------------------------------------------------------------
1.327 vatton 5982: ParseCSSPosition: parse a CSS Position attribute string.
1.217 vatton 5983: ----------------------------------------------------------------------*/
5984: static char *ParseCSSPosition (Element element, PSchema tsch,
1.327 vatton 5985: PresentationContext ctxt, char *cssRule,
5986: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5987: {
1.305 quint 5988: char *ptr;
5989: PresentationValue pval;
1.217 vatton 5990:
1.305 quint 5991: pval.typed_data.value = 0;
5992: pval.typed_data.unit = UNIT_BOX;
5993: pval.typed_data.real = FALSE;
1.217 vatton 5994: cssRule = SkipBlanksAndComments (cssRule);
5995: ptr = cssRule;
5996: if (!strncasecmp (cssRule, "static", 6))
1.337 vatton 5997: {
5998: pval.typed_data.value = PositionStatic;
5999: cssRule += 6;
6000: }
6001: else if (!strncasecmp (cssRule, "relative", 8))
6002: {
6003: pval.typed_data.value = PositionRelative;
6004: cssRule += 8;
6005: }
1.217 vatton 6006: else if (!strncasecmp (cssRule, "absolute", 8))
1.337 vatton 6007: {
6008: pval.typed_data.value = PositionAbsolute;
6009: cssRule += 8;
6010: }
1.217 vatton 6011: else if (!strncasecmp (cssRule, "fixed", 5))
1.337 vatton 6012: {
6013: pval.typed_data.value = PositionFixed;
6014: cssRule += 5;
6015: }
1.217 vatton 6016: else if (!strncasecmp (cssRule, "inherit", 7))
1.337 vatton 6017: {
6018: pval.typed_data.unit = VALUE_INHERIT;
6019: cssRule += 7;
6020: }
1.305 quint 6021:
6022: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
6023: {
6024: cssRule = SkipValue ("Invalid position value", ptr);
6025: cssRule = SkipValue (NULL, cssRule);
6026: }
1.217 vatton 6027: else
1.305 quint 6028: {
1.337 vatton 6029: cssRule = SkipBlanksAndComments (cssRule);
6030: if (*cssRule != EOS && *cssRule != ';')
6031: SkipValue ("Invalid position value", ptr);
1.366 vatton 6032: else if (DoDialog)
6033: DisplayStyleValue ("position", ptr, cssRule);
1.337 vatton 6034: else if (DoApply)
1.327 vatton 6035: TtaSetStylePresentation (PRPosition, element, tsch, ctxt, pval);
1.305 quint 6036: }
1.217 vatton 6037: return (cssRule);
6038: }
6039:
6040: /*----------------------------------------------------------------------
1.327 vatton 6041: ParseCSSTop: parse a CSS Top attribute
1.217 vatton 6042: ----------------------------------------------------------------------*/
6043: static char *ParseCSSTop (Element element, PSchema tsch,
1.327 vatton 6044: PresentationContext context, char *cssRule,
6045: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 6046: {
6047: PresentationValue val;
6048: char *ptr;
6049:
1.370 vatton 6050: val.typed_data.real = FALSE;
1.217 vatton 6051: cssRule = SkipBlanksAndComments (cssRule);
6052: ptr = cssRule;
1.305 quint 6053: /* first parse the value */
6054: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 6055: {
6056: val.typed_data.unit = VALUE_AUTO;
6057: val.typed_data.value = 0;
6058: cssRule = SkipWord (cssRule);
6059: }
1.305 quint 6060: else if (!strncasecmp (cssRule, "inherit", 7))
6061: {
6062: val.typed_data.unit = VALUE_INHERIT;
6063: cssRule = SkipWord (cssRule);
6064: }
1.217 vatton 6065: else
6066: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 6067:
6068: if (val.typed_data.unit == UNIT_INVALID ||
6069: (val.typed_data.value != 0 &&
1.217 vatton 6070: val.typed_data.unit == UNIT_BOX))
6071: {
1.387 quint 6072: cssRule = SkipValue ("Invalid top value", ptr);
6073: if (val.typed_data.unit == UNIT_BOX)
6074: val.typed_data.unit = UNIT_PX;
6075: else
6076: return (cssRule);
1.217 vatton 6077: }
1.366 vatton 6078: if (DoDialog)
1.387 quint 6079: DisplayStyleValue ("top", ptr, cssRule);
1.366 vatton 6080: else if (DoApply)
1.305 quint 6081: TtaSetStylePresentation (PRTop, element, tsch, context, val);
1.217 vatton 6082: return (cssRule);
6083: }
6084:
6085: /*----------------------------------------------------------------------
1.327 vatton 6086: ParseCSSRight: parse a CSS Right attribute
1.217 vatton 6087: ----------------------------------------------------------------------*/
6088: static char *ParseCSSRight (Element element, PSchema tsch,
1.327 vatton 6089: PresentationContext context, char *cssRule,
6090: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 6091: {
6092: PresentationValue val;
6093: char *ptr;
6094:
1.370 vatton 6095: val.typed_data.real = FALSE;
1.217 vatton 6096: cssRule = SkipBlanksAndComments (cssRule);
6097: ptr = cssRule;
6098: /* first parse the attribute string */
1.305 quint 6099: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 6100: {
6101: val.typed_data.unit = VALUE_AUTO;
6102: val.typed_data.value = 0;
6103: cssRule = SkipWord (cssRule);
6104: }
1.305 quint 6105: else if (!strncasecmp (cssRule, "inherit", 7))
6106: {
6107: val.typed_data.unit = VALUE_INHERIT;
6108: cssRule = SkipWord (cssRule);
6109: }
1.217 vatton 6110: else
6111: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 6112:
6113: if (val.typed_data.unit == UNIT_INVALID ||
6114: (val.typed_data.value != 0 &&
1.217 vatton 6115: val.typed_data.unit == UNIT_BOX))
6116: {
1.387 quint 6117: cssRule = SkipValue ("Invalid right value", ptr);
6118: if (val.typed_data.unit == UNIT_BOX)
6119: val.typed_data.unit = UNIT_PX;
6120: else
6121: return (cssRule);
1.217 vatton 6122: }
1.366 vatton 6123: if (DoDialog)
6124: DisplayStyleValue ("right", ptr, cssRule);
6125: else if (DoApply)
1.305 quint 6126: TtaSetStylePresentation (PRRight, element, tsch, context, val);
1.217 vatton 6127: return (cssRule);
6128: }
6129:
6130: /*----------------------------------------------------------------------
1.327 vatton 6131: ParseCSSBottom: parse a CSS Bottom attribute
1.217 vatton 6132: ----------------------------------------------------------------------*/
6133: static char *ParseCSSBottom (Element element, PSchema tsch,
1.327 vatton 6134: PresentationContext context, char *cssRule,
6135: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 6136: {
6137: PresentationValue val;
6138: char *ptr;
6139:
1.370 vatton 6140: val.typed_data.real = FALSE;
1.217 vatton 6141: cssRule = SkipBlanksAndComments (cssRule);
6142: ptr = cssRule;
6143: /* first parse the attribute string */
1.305 quint 6144: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 6145: {
6146: val.typed_data.unit = VALUE_AUTO;
6147: val.typed_data.value = 0;
6148: cssRule = SkipWord (cssRule);
6149: }
1.305 quint 6150: else if (!strncasecmp (cssRule, "inherit", 7))
6151: {
6152: val.typed_data.unit = VALUE_INHERIT;
6153: cssRule = SkipWord (cssRule);
6154: }
1.217 vatton 6155: else
6156: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 6157:
6158: if (val.typed_data.unit == UNIT_INVALID ||
6159: (val.typed_data.value != 0 &&
1.217 vatton 6160: val.typed_data.unit == UNIT_BOX))
6161: {
1.387 quint 6162: cssRule = SkipValue ("Invalid bottom value", ptr);
6163: if (val.typed_data.unit == UNIT_BOX)
6164: val.typed_data.unit = UNIT_PX;
6165: else
6166: return (cssRule);
1.217 vatton 6167: }
1.366 vatton 6168: if (DoDialog)
6169: DisplayStyleValue ("bottom", ptr, cssRule);
6170: else if (DoApply)
1.305 quint 6171: TtaSetStylePresentation (PRBottom, element, tsch, context, val);
1.217 vatton 6172: return (cssRule);
6173: }
6174:
6175: /*----------------------------------------------------------------------
1.327 vatton 6176: ParseCSSLeft: parse a CSS Left attribute
1.217 vatton 6177: ----------------------------------------------------------------------*/
6178: static char *ParseCSSLeft (Element element, PSchema tsch,
1.327 vatton 6179: PresentationContext context, char *cssRule,
6180: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 6181: {
6182: PresentationValue val;
6183: char *ptr;
6184:
1.370 vatton 6185: val.typed_data.real = FALSE;
1.217 vatton 6186: cssRule = SkipBlanksAndComments (cssRule);
6187: ptr = cssRule;
6188: /* first parse the attribute string */
1.305 quint 6189: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 6190: {
6191: val.typed_data.unit = VALUE_AUTO;
6192: val.typed_data.value = 0;
6193: cssRule = SkipWord (cssRule);
6194: }
1.305 quint 6195: else if (!strncasecmp (cssRule, "inherit", 7))
6196: {
6197: val.typed_data.unit = VALUE_INHERIT;
6198: cssRule = SkipWord (cssRule);
6199: }
1.217 vatton 6200: else
6201: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 6202:
6203: if (val.typed_data.unit == UNIT_INVALID ||
6204: (val.typed_data.value != 0 &&
1.217 vatton 6205: val.typed_data.unit == UNIT_BOX))
6206: {
1.387 quint 6207: cssRule = SkipValue ("Invalid left value", ptr);
6208: if (val.typed_data.unit == UNIT_BOX)
6209: val.typed_data.unit = UNIT_PX;
6210: else
6211: return (cssRule);
1.217 vatton 6212: }
1.366 vatton 6213: if (DoDialog)
6214: DisplayStyleValue ("left", ptr, cssRule);
6215: else if (DoApply)
1.305 quint 6216: TtaSetStylePresentation (PRLeft, element, tsch, context, val);
1.217 vatton 6217: return (cssRule);
6218: }
6219:
6220: /*----------------------------------------------------------------------
1.327 vatton 6221: ParseCSSZIndex: parse a CSS z-index attribute
1.217 vatton 6222: ----------------------------------------------------------------------*/
6223: static char *ParseCSSZIndex (Element element, PSchema tsch,
1.327 vatton 6224: PresentationContext context, char *cssRule,
6225: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 6226: {
6227: PresentationValue val;
6228: char *ptr;
6229:
1.370 vatton 6230: val.typed_data.real = FALSE;
1.217 vatton 6231: cssRule = SkipBlanksAndComments (cssRule);
6232: ptr = cssRule;
6233: /* first parse the attribute string */
1.420 vatton 6234: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 6235: {
6236: val.typed_data.unit = VALUE_AUTO;
6237: val.typed_data.value = 0;
6238: cssRule = SkipWord (cssRule);
6239: }
1.420 vatton 6240: else if (!strncasecmp (cssRule, "inherit", 7))
6241: {
6242: val.typed_data.unit = VALUE_INHERIT;
6243: val.typed_data.value = 0;
6244: cssRule = SkipWord (cssRule);
6245: }
1.217 vatton 6246: else
6247: {
6248: cssRule = ParseCSSUnit (cssRule, &val);
6249: if (val.typed_data.unit != UNIT_BOX)
1.327 vatton 6250: {
1.387 quint 6251: cssRule = SkipValue ("Invalid z-index value", ptr);
6252: return (cssRule);
1.327 vatton 6253: }
1.420 vatton 6254: val.typed_data.value = - val.typed_data.value;
1.217 vatton 6255: }
1.366 vatton 6256: if (DoDialog)
1.420 vatton 6257: DisplayStyleValue ("z-index", ptr, cssRule);
6258: else if (DoApply)
6259: TtaSetStylePresentation (PRDepth, element, tsch, context, val);
1.217 vatton 6260: return (cssRule);
6261: }
6262:
1.340 quint 6263: /*----------------------------------------------------------------------
6264: *
6265: * FUNCTIONS STYLE DECLARATIONS
6266: *
6267: *----------------------------------------------------------------------*/
1.18 cvs 6268: /*
1.59 cvs 6269: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 6270: * e.g. "FONT-SIZE" must be placed before "FONT"
6271: */
6272: static CSSProperty CSSProperties[] =
1.327 vatton 6273: {
6274: {"background-color", ParseCSSBackgroundColor},
6275: {"background-image", ParseCSSBackgroundImage},
6276: {"background-repeat", ParseCSSBackgroundRepeat},
6277: {"background-attachment", ParseCSSBackgroundAttachment},
6278: {"background-position", ParseCSSBackgroundPosition},
6279: {"background", ParseCSSBackground},
6280: {"border-top-width", ParseCSSBorderTopWidth},
6281: {"border-right-width", ParseCSSBorderRightWidth},
6282: {"border-bottom-width", ParseCSSBorderBottomWidth},
6283: {"border-left-width", ParseCSSBorderLeftWidth},
6284: {"border-width", ParseCSSBorderWidth},
6285: {"border-top-color", ParseCSSBorderColorTop},
6286: {"border-right-color", ParseCSSBorderColorRight},
6287: {"border-bottom-color", ParseCSSBorderColorBottom},
6288: {"border-left-color", ParseCSSBorderColorLeft},
6289: {"border-color", ParseCSSBorderColor},
6290: {"border-top-style", ParseCSSBorderStyleTop},
6291: {"border-right-style", ParseCSSBorderStyleRight},
6292: {"border-bottom-style", ParseCSSBorderStyleBottom},
6293: {"border-left-style", ParseCSSBorderStyleLeft},
6294: {"border-style", ParseCSSBorderStyle},
6295: {"border-top", ParseCSSBorderTop},
6296: {"border-right", ParseCSSBorderRight},
6297: {"border-bottom", ParseCSSBorderBottom},
6298: {"border-left", ParseCSSBorderLeft},
6299: {"border", ParseCSSBorder},
6300: {"bottom", ParseCSSBottom},
6301: {"clear", ParseCSSClear},
6302: {"color", ParseCSSForeground},
6303: {"content", ParseCSSContent},
6304: {"direction", ParseCSSDirection},
6305: {"display", ParseCSSDisplay},
6306: {"float", ParseCSSFloat},
6307: {"font-family", ParseCSSFontFamily},
6308: {"font-style", ParseCSSFontStyle},
6309: {"font-variant", ParseCSSFontVariant},
6310: {"font-weight", ParseCSSFontWeight},
6311: {"font-size-adjust", ParseCSSFontSizeAdjust},
6312: {"font-size", ParseCSSFontSize},
6313: {"font", ParseCSSFont},
1.382 vatton 6314: {"max-height", ParseCSSMaxHeight},
6315: {"min-height", ParseCSSMinHeight},
1.327 vatton 6316: {"height", ParseCSSHeight},
6317: {"left", ParseCSSLeft},
6318: {"letter-spacing", ParseCSSLetterSpacing},
6319: {"line-height", ParseCSSLineHeight},
6320: {"list-style-type", ParseCSSListStyleType},
6321: {"list-style-image", ParseCSSListStyleImage},
6322: {"list-style-position", ParseCSSListStylePosition},
6323: {"list-style", ParseCSSListStyle},
6324: {"margin-bottom", ParseCSSMarginBottom},
6325: {"margin-top", ParseCSSMarginTop},
6326: {"margin-right", ParseCSSMarginRight},
6327: {"margin-left", ParseCSSMarginLeft},
6328: {"margin", ParseCSSMargin},
1.418 quint 6329: {"opacity", ParseCSSOpacity},
1.327 vatton 6330: {"padding-top", ParseCSSPaddingTop},
6331: {"padding-right", ParseCSSPaddingRight},
6332: {"padding-bottom", ParseCSSPaddingBottom},
6333: {"padding-left", ParseCSSPaddingLeft},
6334: {"padding", ParseCSSPadding},
6335: {"page-break-before", ParseCSSPageBreakBefore},
6336: {"page-break-after", ParseCSSPageBreakAfter},
6337: {"page-break-inside", ParseCSSPageBreakInside},
6338: {"position", ParseCSSPosition},
6339: {"right", ParseCSSRight},
6340: {"text-align", ParseCSSTextAlign},
6341: {"text-anchor", ParseCSSTextAnchor},
6342: {"text-indent", ParseCSSTextIndent},
6343: {"text-decoration", ParseCSSTextDecoration},
6344: {"text-transform", ParseCSSTextTransform},
6345: {"top", ParseCSSTop},
6346: {"unicode-bidi", ParseCSSUnicodeBidi},
6347: {"vertical-align", ParseCSSVerticalAlign},
6348: {"white-space", ParseCSSWhiteSpace},
1.382 vatton 6349: {"max-width", ParseCSSMaxWidth},
6350: {"min-width", ParseCSSMinWidth},
1.327 vatton 6351: {"width", ParseCSSWidth},
1.333 vatton 6352: {"visibility", ParseCSSVisibility},
1.327 vatton 6353: {"word-spacing", ParseCSSWordSpacing},
6354: {"z-index", ParseCSSZIndex},
6355:
6356: /* SVG extensions */
6357: {"fill-opacity", ParseSVGFillOpacity},
1.420 vatton 6358: {"fill-rule", ParseSVGFillRule},
1.327 vatton 6359: {"fill", ParseSVGFill},
1.427 ! quint 6360: {"marker-end", ParseSVGMarkerEnd},
! 6361: {"marker-mid", ParseSVGMarkerMid},
! 6362: {"marker-start", ParseSVGMarkerStart},
! 6363: {"marker", ParseSVGMarker},
1.327 vatton 6364: {"opacity", ParseSVGOpacity},
1.424 quint 6365: {"stop-color", ParseSVGStopColor},
1.425 quint 6366: {"stop-opacity", ParseSVGStopOpacity},
1.327 vatton 6367: {"stroke-opacity", ParseSVGStrokeOpacity},
6368: {"stroke-width", ParseSVGStrokeWidth},
6369: {"stroke", ParseSVGStroke}
6370: };
1.155 cheyroul 6371:
1.18 cvs 6372: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
6373:
6374: /*----------------------------------------------------------------------
1.327 vatton 6375: ParseCSSRule: parse a CSS Style string
6376: we expect the input string describing the style to be of the form
6377: property: value [ ; property: value ]*
6378: but tolerate incorrect or incomplete input
1.18 cvs 6379: ----------------------------------------------------------------------*/
1.366 vatton 6380: void ParseCSSRule (Element element, PSchema tsch, PresentationContext ctxt,
6381: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 6382: {
1.366 vatton 6383: DisplayMode dispMode = DisplayImmediately;
1.312 quint 6384: char *p = NULL, *next, *end;
1.214 quint 6385: char *valueStart;
1.18 cvs 6386: int lg;
1.34 cvs 6387: unsigned int i;
1.76 cvs 6388: ThotBool found;
1.18 cvs 6389:
1.34 cvs 6390: /* avoid too many redisplay */
1.366 vatton 6391: if (!DoDialog && ctxt->doc)
6392: {
6393: dispMode = TtaGetDisplayMode (ctxt->doc);
6394: if (dispMode == DisplayImmediately)
6395: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
6396: }
1.34 cvs 6397:
1.82 cvs 6398: while (*cssRule != EOS)
1.18 cvs 6399: {
1.82 cvs 6400: cssRule = SkipBlanksAndComments (cssRule);
1.371 vatton 6401: if (*cssRule == ';' || *cssRule < 0x20 ||
1.372 vatton 6402: ((unsigned char)*cssRule) == 0xA0)
1.371 vatton 6403: cssRule++;
6404: else if (*cssRule < 0x41 || *cssRule > 0x7A ||
6405: (*cssRule > 0x5A && *cssRule < 0x61))
1.352 vatton 6406: {
6407: end = SkipProperty (cssRule, FALSE);
1.385 vatton 6408: if (cssRule[0] != '-')
6409: CSSParseError ("Invalid property", cssRule, end);
1.352 vatton 6410: cssRule = end;
6411: }
1.194 vatton 6412: else if (*cssRule != EOS)
1.327 vatton 6413: {
6414: found = FALSE;
6415: /* look for the type of property */
6416: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
6417: {
6418: lg = strlen (CSSProperties[i].name);
6419: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
6420: {
6421: p = cssRule + lg;
6422: found = TRUE;
6423: i--;
6424: }
6425: }
6426:
1.360 vatton 6427: // check if it's an important rule
6428: CheckImportantRule (cssRule, ctxt);
1.327 vatton 6429: if (i < NB_CSSSTYLEATTRIBUTE &&
6430: !strcasecmp (CSSProperties[i].name, "content") &&
6431: ((GenericContext)ctxt)->pseudo != PbBefore &&
6432: ((GenericContext)ctxt)->pseudo != PbAfter)
1.340 quint 6433: /* property content is allowed only for pseudo-elements :before and
6434: :after */
1.327 vatton 6435: {
1.352 vatton 6436: end = SkipProperty (cssRule, FALSE);
1.327 vatton 6437: CSSParseError ("content is allowed only for pseudo-elements",
6438: cssRule, end);
1.352 vatton 6439: cssRule = end;
1.327 vatton 6440: }
1.352 vatton 6441: else if (i == NB_CSSSTYLEATTRIBUTE)
1.376 vatton 6442: cssRule = SkipProperty (cssRule, !ctxt->destroy);
1.327 vatton 6443: else
6444: {
6445: /* update index and skip the ":" indicator if present */
6446: p = SkipBlanksAndComments (p);
6447: if (*p == ':')
6448: {
6449: p++;
6450: p = SkipBlanksAndComments (p);
6451: /* try to parse the value associated with this property */
6452: if (CSSProperties[i].parsing_function != NULL)
6453: {
6454: valueStart = p;
6455: p = CSSProperties[i].parsing_function (element, tsch,
6456: ctxt, p, css, isHTML);
6457: if (!element && isHTML)
6458: {
6459: if (ctxt->type == HTML_EL_Input)
6460: /* it's a generic rule for the HTML element input.
6461: Generate a Thot Pres rule for each kind of
6462: input element */
6463: {
6464: ctxt->type = HTML_EL_Text_Input;
6465: p = CSSProperties[i].parsing_function (element,
6466: tsch, ctxt, valueStart, css, isHTML);
6467: ctxt->type = HTML_EL_Password_Input;
6468: p = CSSProperties[i].parsing_function (element,
6469: tsch, ctxt, valueStart, css, isHTML);
6470: ctxt->type = HTML_EL_File_Input;
6471: p = CSSProperties[i].parsing_function (element,
6472: tsch, ctxt, valueStart, css, isHTML);
6473: ctxt->type = HTML_EL_Checkbox_Input;
6474: p = CSSProperties[i].parsing_function (element,
6475: tsch, ctxt, valueStart, css, isHTML);
6476: ctxt->type = HTML_EL_Radio_Input;
6477: p = CSSProperties[i].parsing_function (element,
6478: tsch, ctxt, valueStart, css, isHTML);
6479: ctxt->type = HTML_EL_Submit_Input;
6480: p = CSSProperties[i].parsing_function (element,
6481: tsch, ctxt, valueStart, css, isHTML);
6482: ctxt->type = HTML_EL_Reset_Input;
6483: p = CSSProperties[i].parsing_function (element,
6484: tsch, ctxt, valueStart, css, isHTML);
6485: ctxt->type = HTML_EL_Button_Input;
6486: p = CSSProperties[i].parsing_function (element,
6487: tsch, ctxt, valueStart, css, isHTML);
6488: ctxt->type = HTML_EL_Input;
6489: }
6490: else if (ctxt->type == HTML_EL_ruby)
6491: /* it's a generic rule for the HTML element ruby.
6492: Generate a Thot Pres rule for each kind of
6493: ruby element. */
6494: {
6495: ctxt->type = HTML_EL_simple_ruby;
6496: p = CSSProperties[i].parsing_function (element,
6497: tsch, ctxt, valueStart, css, isHTML);
6498: ctxt->type = HTML_EL_complex_ruby;
6499: p = CSSProperties[i].parsing_function (element,
6500: tsch, ctxt, valueStart, css, isHTML);
6501: ctxt->type = HTML_EL_ruby;
6502: }
6503: }
6504: /* update index and skip the ";" separator if present */
6505: next = SkipBlanksAndComments (p);
6506: if (*next != EOS && *next != ';')
6507: CSSParseError ("Missing closing ';'", cssRule, p);
6508: cssRule = next;
6509: }
6510: }
6511: else
6512: cssRule = SkipProperty (cssRule, TRUE);
6513: }
1.360 vatton 6514: // skip important markup
6515: cssRule = SkipImportantRule (cssRule);
6516:
1.327 vatton 6517: }
1.18 cvs 6518: /* next property */
1.82 cvs 6519: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 6520: if (*cssRule == '}')
1.327 vatton 6521: {
6522: cssRule++;
6523: CSSPrintError ("Invalid character", "}");
6524: cssRule = SkipBlanksAndComments (cssRule);
6525: }
1.155 cheyroul 6526: if (*cssRule == ',' ||
1.327 vatton 6527: *cssRule == ';')
6528: {
6529: cssRule++;
6530: cssRule = SkipBlanksAndComments (cssRule);
6531: }
1.18 cvs 6532: }
1.34 cvs 6533:
6534: /* restore the display mode */
1.366 vatton 6535: if (!DoDialog && ctxt->doc && dispMode == DisplayImmediately)
1.207 vatton 6536: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 6537: }
1.1 cvs 6538:
1.111 cvs 6539: /*----------------------------------------------------------------------
1.327 vatton 6540: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
6541: This function must be called when a specific style is applied to an
6542: element.
6543: The parameter specificity is the specificity of the style, 0 if it is
6544: not really a CSS rule.
1.1 cvs 6545: ----------------------------------------------------------------------*/
1.79 cvs 6546: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.377 quint 6547: int specificity, ThotBool destroy)
1.1 cvs 6548: {
1.257 vatton 6549: DisplayMode dispMode;
1.207 vatton 6550: PresentationContext ctxt;
6551: ElementType elType;
1.413 vatton 6552: char *buff, *ptr, *end;
1.207 vatton 6553: ThotBool isHTML;
1.1 cvs 6554:
1.207 vatton 6555: /* A rule applying to BODY is really meant to address HTML */
6556: elType = TtaGetElementType (el);
1.286 quint 6557: NewLineSkipped = 0;
1.207 vatton 6558: /* store the current line for eventually reported errors */
6559: LineNumber = TtaGetElementLineNumber (el);
6560: if (destroy)
6561: /* no reported errors */
6562: ParsedDoc = 0;
6563: else if (ParsedDoc != doc)
6564: {
6565: /* update the context for reported errors */
6566: ParsedDoc = doc;
1.348 vatton 6567: Error_DocURL = DocumentURLs[doc];
1.207 vatton 6568: }
6569: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
6570: /* create the context of the Specific presentation driver */
6571: ctxt = TtaGetSpecificStyleContext (doc);
6572: if (ctxt == NULL)
6573: return;
6574: ctxt->type = elType.ElTypeNum;
6575: ctxt->cssSpecificity = specificity;
1.236 quint 6576: ctxt->cssLine = LineNumber;
1.207 vatton 6577: ctxt->destroy = destroy;
6578: /* first use of the context */
6579: ctxt->uses = 1;
1.257 vatton 6580: /* save the current display mode */
6581: dispMode = TtaGetDisplayMode (doc);
1.207 vatton 6582: /* Call the parser */
1.366 vatton 6583: DoDialog = FALSE; // not parsing for CSS dialog
1.406 quint 6584: /* if it is a property applied to a COL or a COLGROUP element in a HTML table,
6585: associate the property to the corresponding Table_head or cell elements,
6586: depending on the property. */
1.413 vatton 6587: ptr = strstr (cssRule, "background-color");
6588: if (ptr && isHTML &&
1.406 quint 6589: (elType.ElTypeNum == HTML_EL_COL || elType.ElTypeNum == HTML_EL_COLGROUP))
1.413 vatton 6590: {
6591: end = strstr (ptr, ";");
6592: if (end)
6593: {
6594: buff = TtaStrdup (ptr);
6595: end = strstr (buff, ";");
6596: *end = EOS;
6597: ColApplyCSSRule (el, (PresentationContext) ctxt, buff, NULL);
6598: TtaFreeMemory (buff);
6599: }
6600: else
6601: ColApplyCSSRule (el, (PresentationContext) ctxt, ptr, NULL);
6602: }
1.406 quint 6603: else
6604: ParseCSSRule (el, NULL, ctxt, cssRule, NULL, isHTML);
6605:
1.257 vatton 6606: /* restore the display mode if necessary */
1.417 vatton 6607: if (dispMode != NoComputedDisplay)
6608: TtaSetDisplayMode (doc, dispMode);
1.207 vatton 6609: /* check if the context can be freed */
6610: ctxt->uses -= 1;
6611: if (ctxt->uses == 0)
6612: /* no image loading */
6613: TtaFreeMemory(ctxt);
1.1 cvs 6614: }
6615:
1.366 vatton 6616:
1.343 vatton 6617: /*----------------------------------------------------------------------
6618: AddClassName adds the class name into the class list of css if it's
6619: not already there.
6620: ----------------------------------------------------------------------*/
6621: static void AddClassName (char *name, CSSInfoPtr css)
6622: {
1.344 cvs 6623: int l, index, k, length, add;
1.343 vatton 6624: char *buf;
6625: ThotBool found, previous;
6626:
6627: l = strlen (name);
6628: if (l == 0 || css == NULL)
6629: return;
6630: if (css->class_list)
6631: {
6632: buf = css->class_list;
6633: length = strlen (css->class_list);
6634: }
6635: else
6636: {
6637: if (l > 200)
6638: length = l + 1;
6639: else
6640: length = 200;
6641: buf = (char *)TtaGetMemory (length * sizeof (char));
6642: memset (buf, 0, length);
6643: css->class_list = buf;
6644: css->lg_class_list = length;
6645: length = 0;
6646: }
6647:
6648: /* compare that name with all class names already known */
6649: index = 0;
6650: found = FALSE;
6651: previous = FALSE;
6652: while (index < length && !found && !previous)
6653: {
6654: k = 0;
6655: while (k < l && buf[index + k] != EOS && buf[index + k] != SPACE)
6656: {
6657: if (name[k] == buf[index+k])
6658: k++;
6659: else
6660: {
6661: previous = (name[k] < buf[index + k]);
6662: break;
6663: }
6664: }
6665: found = (k == l);
6666: if (!previous)
6667: {
6668: index += k;
6669: while (buf[index] != EOS && buf[index] != SPACE)
6670: index++;
6671: if (buf[index] == SPACE)
6672: index++;
6673: }
6674: }
6675:
6676: if (!found)
6677: /* this class name is not known, append it */
6678: {
6679: l++; /* add a space before */
6680: if (css->lg_class_list <= length + l)
6681: {
6682: // increase the list size
6683: if (l > 200)
6684: add = l + 1;
6685: else
6686: add = 200 ;
6687: buf = (char *)TtaRealloc (buf, css->lg_class_list + (add * sizeof (char)));
6688: if (buf == NULL)
6689: return;
6690: else
6691: {
6692: css->class_list = buf;
6693: memset (&buf[css->lg_class_list], 0, add);
6694: css->lg_class_list += add;
6695: }
6696: }
6697:
6698: if (previous)
6699: {
6700: // move the tail of the current list
6701: for (k = length; k >= index; k--)
6702: buf[k+l] = buf[k];
6703: /* add this new class name at the current position */
6704: strcpy (&buf[index], name);
6705: buf[index + l - 1] = SPACE;
6706: }
6707: else
6708: {
6709: /* add this new class name at the end */
6710: if (index != 0)
6711: buf[index++] = SPACE;
6712: strcpy (&buf[index], name);
6713: }
6714: }
6715: }
6716:
1.68 cvs 6717:
1.1 cvs 6718: /*----------------------------------------------------------------------
1.207 vatton 6719: ParseGenericSelector: Create a generic context for a given selector
6720: string.
6721: If the selector is made of multiple comma, it parses them one at a time
6722: and return the end of the selector string to be handled or NULL.
1.231 vatton 6723: The parameter ctxt gives the current style context which will be passed
6724: to Thotlib.
6725: The parameter css points to the current CSS context.
6726: The parameter link points to the link element.
6727: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 6728: ----------------------------------------------------------------------*/
1.207 vatton 6729: static char *ParseGenericSelector (char *selector, char *cssRule,
1.327 vatton 6730: GenericContext ctxt, Document doc,
6731: CSSInfoPtr css, Element link, char *url)
1.79 cvs 6732: {
6733: ElementType elType;
6734: PSchema tsch;
1.119 vatton 6735: AttributeType attrType;
1.398 vatton 6736: char *deb, *cur, *sel, *next, *limit, c;
1.317 vatton 6737: char *schemaName, *mappedName, *saveURL;
1.79 cvs 6738: char *names[MAX_ANCESTORS];
1.355 quint 6739: ThotBool pseudoFirstChild[MAX_ANCESTORS];
1.340 quint 6740: ElemRel rel[MAX_ANCESTORS];
6741: char *attrnames[MAX_ANCESTORS];
6742: int attrnums[MAX_ANCESTORS];
6743: int attrlevels[MAX_ANCESTORS];
1.79 cvs 6744: char *attrvals[MAX_ANCESTORS];
1.133 vatton 6745: AttrMatch attrmatch[MAX_ANCESTORS];
1.340 quint 6746: int nbnames, nbattrs;
6747: int i, j;
1.256 vatton 6748: int att, kind;
1.118 vatton 6749: int specificity, xmlType;
1.217 vatton 6750: int skippedNL;
1.404 vatton 6751: ThotBool isHTML, noname, warn;
1.347 quint 6752: ThotBool level, quoted, doubleColon;
1.340 quint 6753: #define ATTR_ID 1
6754: #define ATTR_CLASS 2
6755: #define ATTR_PSEUDO 3
1.1 cvs 6756:
1.404 vatton 6757: // check if Amaya should report CSS warnings
6758: TtaGetEnvBoolean ("CSS_WARN", &warn);
1.207 vatton 6759: sel = ctxt->sel;
1.82 cvs 6760: sel[0] = EOS;
1.398 vatton 6761: // get the limit of the string
6762: limit = &sel[MAX_ANCESTORS * 50 -1];
6763: *limit = EOS;
1.117 vatton 6764: specificity = 0;
1.1 cvs 6765: for (i = 0; i < MAX_ANCESTORS; i++)
6766: {
1.25 cvs 6767: names[i] = NULL;
1.355 quint 6768: pseudoFirstChild[i] = FALSE;
1.340 quint 6769: rel[i] = RelAncestor;
6770: attrnames[i] = NULL;
6771: attrnums[i] = 0;
6772: attrlevels[i] = 0;
1.25 cvs 6773: attrvals[i] = NULL;
1.133 vatton 6774: attrmatch[i] = Txtmatch;
1.25 cvs 6775: ctxt->name[i] = 0;
1.355 quint 6776: ctxt->firstChild[i] = FALSE;
1.25 cvs 6777: ctxt->attrType[i] = 0;
1.129 vatton 6778: ctxt->attrLevel[i] = 0;
1.25 cvs 6779: ctxt->attrText[i] = NULL;
1.178 quint 6780: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 6781: }
1.25 cvs 6782: ctxt->box = 0;
1.312 quint 6783: ctxt->var = 0;
1.306 quint 6784: ctxt->pseudo = PbNone;
1.25 cvs 6785: ctxt->type = 0;
1.366 vatton 6786: DoDialog = FALSE; // not arsing for CSS dialog
1.114 quint 6787: /* the specificity of the rule depends on the selector */
6788: ctxt->cssSpecificity = 0;
1.231 vatton 6789: /* localisation of the CSS rule */
6790: ctxt->cssLine = LineNumber + NewLineSkipped;
6791: ctxt->cssURL = url;
1.240 quint 6792:
1.286 quint 6793: skippedNL = NewLineSkipped;
1.82 cvs 6794: selector = SkipBlanksAndComments (selector);
1.286 quint 6795: NewLineSkipped = skippedNL;
1.27 cvs 6796: cur = &sel[0];
1.340 quint 6797: nbnames = 0;
6798: nbattrs = 0;
1.1 cvs 6799: while (1)
6800: {
1.85 cvs 6801: /* point to the following word in sel[] */
1.27 cvs 6802: deb = cur;
1.25 cvs 6803: /* copy an item of the selector into sel[] */
1.1 cvs 6804: /* put one word in the sel buffer */
1.82 cvs 6805: while (*selector != EOS && *selector != ',' &&
6806: *selector != '.' && *selector != ':' &&
1.118 vatton 6807: *selector != '#' && *selector != '[' &&
1.250 vatton 6808: *selector != '>' && *selector != '+' &&
1.398 vatton 6809: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6810: *cur++ = *selector++;
1.82 cvs 6811: *cur++ = EOS; /* close the first string in sel[] */
1.380 vatton 6812: noname = TRUE;
1.82 cvs 6813: if (deb[0] != EOS)
1.340 quint 6814: /* the selector starts with an element name */
1.327 vatton 6815: {
6816: if (deb[0] <= 64 && deb[0] != '*')
6817: {
6818: CSSPrintError ("Invalid element", deb);
1.380 vatton 6819: names[0] = NULL; /* no element name */
6820: DoApply = FALSE;
1.327 vatton 6821: }
6822: else
6823: {
1.380 vatton 6824: noname = FALSE;
1.327 vatton 6825: names[0] = deb;
6826: if (!strcmp (names[0], "html"))
6827: /* give a greater priority to the backgoud color of html */
6828: specificity += 3;
6829: else
6830: /* selector "*" has specificity zero */
6831: if (strcmp (names[0], "*"))
6832: specificity += 1;
6833: }
6834: }
1.25 cvs 6835: else
1.340 quint 6836: names[0] = NULL; /* no element name */
1.226 quint 6837:
1.340 quint 6838: rel[0] = RelVoid;
1.27 cvs 6839: /* now names[0] points to the beginning of the parsed item
1.340 quint 6840: and cur to the next string to be parsed */
1.129 vatton 6841: while (*selector == '.' || *selector == ':' ||
1.327 vatton 6842: *selector == '#' || *selector == '[')
6843: {
6844: /* point to the following word in sel[] */
6845: deb = cur;
6846: if (*selector == '.')
1.340 quint 6847: /* class */
1.327 vatton 6848: {
6849: selector++;
1.340 quint 6850: while (*selector != '.' && *selector != ':' &&
6851: *selector != '#' && *selector != '[' &&
6852: *selector != EOS && *selector != ',' &&
6853: *selector != '+' && *selector != '>' &&
1.398 vatton 6854: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6855: {
6856: if (*selector == '\\')
6857: {
6858: selector++;
6859: if (*selector != EOS)
6860: *cur++ = *selector++;
6861: }
6862: else
6863: *cur++ = *selector++;
6864: }
6865: /* close the word */
6866: *cur++ = EOS;
1.340 quint 6867: /* point to the class in sel[] if it's a valid name */
1.327 vatton 6868: if (deb[0] <= 64)
6869: {
6870: CSSPrintError ("Invalid class", deb);
6871: DoApply = FALSE;
6872: }
6873: else
6874: {
1.340 quint 6875: /* simulate selector [class ~= "xxx"] */
6876: nbattrs++;
6877: if (nbattrs == MAX_ANCESTORS)
6878: /* abort parsing */
6879: {
6880: CSSPrintError ("Selector too long", deb);
6881: return (selector);
6882: }
6883: for (i = nbattrs; i > 0; i--)
6884: {
6885: attrnames[i] = attrnames[i - 1];
6886: attrnums[i] = attrnums[i - 1];
6887: attrlevels[i] = attrlevels[i - 1];
6888: attrvals[i] = attrvals[i - 1];
6889: attrmatch[i] = attrmatch[i - 1];
6890: }
6891: attrnames[0] = NULL;
6892: attrnums[0] = ATTR_CLASS;
6893: attrlevels[0] = 0;
6894: attrmatch[0] = Txtword;
6895: attrvals[0] = deb;
1.327 vatton 6896: specificity += 10;
1.343 vatton 6897: }
1.327 vatton 6898: }
6899: else if (*selector == ':')
1.340 quint 6900: /* pseudo-class or pseudo-element */
1.327 vatton 6901: {
6902: selector++;
1.347 quint 6903: doubleColon = FALSE;
6904: if (*selector == ':')
6905: /* it's a double "::". Probably CSS3 syntax */
6906: {
6907: selector++;
6908: doubleColon = TRUE;
6909: }
1.340 quint 6910: while (*selector != '.' && *selector != ':' &&
6911: *selector != '#' && *selector != '[' &&
6912: *selector != EOS && *selector != ',' &&
6913: *selector != '+' && *selector != '>' &&
1.398 vatton 6914: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6915: *cur++ = *selector++;
6916: /* close the word */
6917: *cur++ = EOS;
1.340 quint 6918: /* point to the pseudo-class or pseudo-element in sel[] if it's
6919: a valid name */
1.355 quint 6920: if (!strcmp (deb, "first-child"))
6921: /* first-child pseudo-class */
1.327 vatton 6922: {
1.355 quint 6923: pseudoFirstChild[0] = TRUE;
6924: specificity += 10;
1.327 vatton 6925: }
1.355 quint 6926: else if (!strcmp (deb, "link") || !strcmp (deb, "visited"))
6927: /* link or visited pseudo-classes */
1.327 vatton 6928: {
1.355 quint 6929: nbattrs++;
6930: if (nbattrs == MAX_ANCESTORS)
6931: /* abort parsing */
1.347 quint 6932: {
1.355 quint 6933: CSSPrintError ("Selector too long", deb);
6934: return (selector);
1.347 quint 6935: }
1.355 quint 6936: for (i = nbattrs; i > 0; i--)
1.347 quint 6937: {
1.355 quint 6938: attrnames[i] = attrnames[i - 1];
6939: attrnums[i] = attrnums[i - 1];
6940: attrlevels[i] = attrlevels[i - 1];
6941: attrvals[i] = attrvals[i - 1];
6942: attrmatch[i] = attrmatch[i - 1];
1.347 quint 6943: }
1.355 quint 6944: attrnames[0] = NULL;
6945: attrnums[0] = ATTR_PSEUDO;
6946: attrlevels[0] = 0;
6947: attrmatch[0] = Txtmatch;
6948: attrvals[0] = deb;
6949: specificity += 10;
6950: }
6951: else if (!strcmp (deb, "hover") || !strcmp (deb, "active") ||
6952: !strcmp (deb, "focus"))
6953: /* hover, active, focus pseudo-classes */
6954: {
1.403 vatton 6955: attrnames[0] = NULL;
6956: attrnums[0] = ATTR_PSEUDO;
6957: attrlevels[0] = 0;
6958: attrmatch[0] = Txtmatch;
6959: attrvals[0] = deb;
1.355 quint 6960: specificity += 10;
6961: /* not supported */
6962: DoApply = FALSE;
6963: }
6964: else if (!strncmp (deb, "lang", 4))
6965: /* it's the lang pseudo-class */
6966: {
6967: if (deb[4] != '(' || deb[strlen(deb)-1] != ')')
6968: /* at least one parenthesis is missing. Error */
1.327 vatton 6969: {
1.355 quint 6970: CSSPrintError ("Invalid :lang pseudo-class", deb);
6971: DoApply = FALSE;
1.327 vatton 6972: }
6973: else
1.355 quint 6974: /* simulate selector [lang|="xxx"] */
1.340 quint 6975: {
6976: nbattrs++;
6977: if (nbattrs == MAX_ANCESTORS)
6978: /* abort parsing */
6979: {
6980: CSSPrintError ("Selector too long", deb);
6981: return (selector);
6982: }
1.355 quint 6983: deb[strlen(deb)-1] = EOS;
6984: deb[4] = EOS;
1.340 quint 6985: for (i = nbattrs; i > 0; i--)
6986: {
6987: attrnames[i] = attrnames[i - 1];
6988: attrnums[i] = attrnums[i - 1];
6989: attrlevels[i] = attrlevels[i - 1];
6990: attrvals[i] = attrvals[i - 1];
6991: attrmatch[i] = attrmatch[i - 1];
6992: }
1.355 quint 6993: attrnames[0] = deb;
6994: attrnums[0] = 0;
1.340 quint 6995: attrlevels[0] = 0;
1.355 quint 6996: attrmatch[0] = Txtsubstring;
6997: attrvals[0] = &deb[5];
6998: specificity += 10;
1.340 quint 6999: }
1.327 vatton 7000: }
1.355 quint 7001: else if (!strcmp (deb, "first-line") ||
7002: !strcmp (deb, "first-letter"))
7003: /* pseudo-elements first-line or first-letter */
7004: {
1.404 vatton 7005: if (doubleColon && warn)
1.355 quint 7006: CSSPrintError ("Warning: \"::\" is CSS3 syntax", NULL);
7007: specificity += 1;
7008: /* not supported */
7009: DoApply = FALSE;
7010: }
7011: else if (!strncmp (deb, "before", 6))
7012: /* pseudo-element before */
7013: {
1.404 vatton 7014: if (doubleColon && warn)
1.355 quint 7015: CSSPrintError ("Warning: \"::before\" is CSS3 syntax",
7016: NULL);
7017: ctxt->pseudo = PbBefore;
7018: specificity += 1;
7019: }
7020: else if (!strncmp (deb, "after", 5))
7021: /* pseudo-element after */
7022: {
1.404 vatton 7023: if (doubleColon && warn)
1.355 quint 7024: CSSPrintError ("Warning: \"::after\" is CSS3 syntax",
7025: NULL);
7026: ctxt->pseudo = PbAfter;
7027: specificity += 1;
7028: }
1.404 vatton 7029: else if (!strncmp (deb, "target", 6))
7030: {
7031: if (warn)
7032: CSSPrintError ("Warning: \":target\" is CSS3 syntax",
7033: NULL);
7034: specificity += 1;
7035: DoApply = FALSE;
7036: }
7037: else
1.355 quint 7038: {
7039: CSSPrintError ("Invalid pseudo-element", deb);
7040: DoApply = FALSE;
7041: }
7042: if (names[0] && !strcmp (names[0], "*"))
7043: names[0] = NULL;
1.327 vatton 7044: }
7045: else if (*selector == '#')
1.340 quint 7046: /* unique identifier */
1.327 vatton 7047: {
7048: selector++;
1.340 quint 7049: while (*selector != '.' && *selector != ':' &&
7050: *selector != '#' && *selector != '[' &&
7051: *selector != '+' && *selector != '>' &&
7052: *selector != EOS && *selector != ',' &&
1.398 vatton 7053: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 7054: *cur++ = *selector++;
7055: /* close the word */
7056: *cur++ = EOS;
7057: /* point to the attribute in sel[] if it's valid name */
7058: if (deb[0] <= 64)
7059: {
7060: CSSPrintError ("Invalid id", deb);
7061: DoApply = FALSE;
7062: }
7063: else
7064: {
1.340 quint 7065: nbattrs++;
7066: if (nbattrs == MAX_ANCESTORS)
7067: /* abort parsing */
7068: {
7069: CSSPrintError ("Selector too long", deb);
7070: return (selector);
7071: }
7072: for (i = nbattrs; i > 0; i--)
7073: {
7074: attrnames[i] = attrnames[i - 1];
7075: attrnums[i] = attrnums[i - 1];
7076: attrlevels[i] = attrlevels[i - 1];
7077: attrvals[i] = attrvals[i - 1];
7078: attrmatch[i] = attrmatch[i - 1];
7079: }
7080: attrnames[0] = NULL;
7081: attrnums[0] = ATTR_ID;
7082: attrlevels[0] = 0;
7083: attrmatch[0] = Txtmatch;
7084: attrvals[0] = deb;
7085: specificity += 100;
7086: if (names[0] && !strcmp (names[0], "*"))
7087: names[0] = NULL;
1.327 vatton 7088: }
7089: }
7090: else if (*selector == '[')
7091: {
7092: selector++;
1.341 quint 7093: selector = SkipBlanksAndComments (selector);
1.327 vatton 7094: while (*selector != EOS && *selector != ']' &&
7095: *selector != '=' && *selector != '~' &&
1.341 quint 7096: *selector != '|' && *selector != '^' &&
1.396 vatton 7097: *selector != '$' && *selector != '*' &&
1.398 vatton 7098: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 7099: *cur++ = *selector++;
1.341 quint 7100: /* close the word (attribute name) */
1.327 vatton 7101: *cur++ = EOS;
7102: /* point to the attribute in sel[] if it's valid name */
7103: if (deb[0] <= 64)
7104: {
7105: CSSPrintError ("Invalid attribute", deb);
7106: DoApply = FALSE;
7107: }
7108: else
7109: {
1.340 quint 7110: nbattrs++;
7111: if (nbattrs == MAX_ANCESTORS)
7112: /* abort parsing */
7113: {
7114: CSSPrintError ("Selector too long", deb);
7115: return (selector);
7116: }
7117: for (i = nbattrs; i > 0; i--)
7118: {
7119: attrnames[i] = attrnames[i - 1];
7120: attrnums[i] = attrnums[i - 1];
7121: attrlevels[i] = attrlevels[i - 1];
7122: attrvals[i] = attrvals[i - 1];
7123: attrmatch[i] = attrmatch[i - 1];
7124: }
7125: attrnames[0] = deb;
7126: attrnums[0] = 0;
7127: attrlevels[0] = 0;
1.378 quint 7128: attrvals[0] = NULL;
7129: attrmatch[0] = Txtmatch;
1.327 vatton 7130: specificity += 10;
1.340 quint 7131: /* check matching */
1.341 quint 7132: selector = SkipBlanksAndComments (selector);
1.340 quint 7133: if (*selector == '~')
7134: {
7135: attrmatch[0] = Txtword;
7136: selector++;
7137: }
1.396 vatton 7138: else if (*selector == '|' || *selector == '$' || *selector == '*')
1.340 quint 7139: {
1.404 vatton 7140: if (*selector == '$' && warn)
1.396 vatton 7141: CSSPrintError ("Warning: \"$=\" is CSS3 syntax", NULL);
1.404 vatton 7142: if (*selector == '*' && warn)
1.396 vatton 7143: CSSPrintError ("Warning: \"*=\" is CSS3 syntax", NULL);
1.340 quint 7144: attrmatch[0] = Txtsubstring;
7145: selector++;
7146: }
1.341 quint 7147: else if (*selector == '^')
7148: {
7149: attrmatch[0] = Txtsubstring;
7150: selector++;
7151: }
1.340 quint 7152: else
7153: attrmatch[0] = Txtmatch;
1.327 vatton 7154: }
7155: if (*selector == '=')
7156: {
7157: /* look for a value "xxxx" */
7158: selector++;
1.341 quint 7159: selector = SkipBlanksAndComments (selector);
1.327 vatton 7160: if (*selector != '"')
7161: quoted = FALSE;
7162: else
7163: {
7164: quoted = TRUE;
7165: /* we are now parsing the attribute value */
7166: selector++;
7167: }
7168: deb = cur;
1.398 vatton 7169: while ((quoted && cur < limit &&
1.327 vatton 7170: (*selector != '"' ||
7171: (*selector == '"' && selector[-1] == '\\'))) ||
7172: (!quoted && *selector != ']'))
7173: {
7174: if (*selector == EOS)
7175: {
7176: CSSPrintError ("Invalid attribute value", deb);
7177: DoApply = FALSE;
7178: }
7179: else
7180: {
7181: if (attrmatch[0] == Txtword && TtaIsBlank (selector))
7182: {
7183: CSSPrintError ("No space allowed here: ", selector);
7184: DoApply = FALSE;
7185: }
7186: *cur++ = *selector;
7187: }
7188: selector++;
7189: }
7190: /* there is a value */
7191: if (quoted && *selector == '"')
7192: {
7193: selector++;
7194: quoted = FALSE;
7195: }
1.341 quint 7196: selector = SkipBlanksAndComments (selector);
1.327 vatton 7197: if (*selector != ']')
7198: {
7199: CSSPrintError ("Invalid attribute value", deb);
7200: DoApply = FALSE;
7201: }
7202: else
7203: {
7204: *cur++ = EOS;
7205: attrvals[0] = deb;
7206: selector++;
7207: }
7208: }
7209: /* end of the attribute */
7210: else if (*selector != ']')
7211: {
7212: selector[1] = EOS;
7213: CSSPrintError ("Invalid attribute", selector);
7214: selector += 2;
7215: DoApply = FALSE;
7216: }
7217: else
7218: {
7219: selector++;
7220: if (names[0] && !strcmp (names[0], "*"))
7221: names[0] = NULL;
7222: }
7223: }
7224: else
7225: {
7226: /* not supported selector */
1.340 quint 7227: while (*selector != '.' && *selector != ':' &&
7228: *selector != '#' && *selector != '[' &&
7229: *selector != EOS && *selector != ',' &&
7230: *selector != '+' && *selector != '>' &&
1.398 vatton 7231: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 7232: *cur++ = *selector++;
7233: /* close the word */
7234: *cur++ = EOS;
7235: CSSPrintError ("Selector not supported:", deb);
7236: DoApply = FALSE;
7237: }
7238: }
1.1 cvs 7239:
1.286 quint 7240: skippedNL = NewLineSkipped;
1.82 cvs 7241: selector = SkipBlanksAndComments (selector);
1.286 quint 7242: NewLineSkipped = skippedNL;
7243:
1.380 vatton 7244: if (noname && !pseudoFirstChild[0] && attrnums[0] == 0 && attrnames[0] == NULL)
7245: {
7246: *cur++ = EOS;
7247: CSSPrintError ("Invalid Selector", deb);
7248: DoApply = FALSE;
7249: }
1.25 cvs 7250: /* is it a multi-level selector? */
1.82 cvs 7251: if (*selector == EOS)
1.327 vatton 7252: /* end of the selector */
7253: break;
1.82 cvs 7254: else if (*selector == ',')
1.327 vatton 7255: {
7256: /* end of the current selector */
7257: selector++;
7258: skippedNL = NewLineSkipped;
7259: next = SkipBlanksAndComments (selector);
7260: NewLineSkipped = skippedNL;
7261: if (*next == EOS)
7262: /* nothing after the comma. Invalid selector */
7263: {
1.380 vatton 7264: CSSPrintError ("Syntax error:", selector);
7265: selector = NULL;
1.327 vatton 7266: }
7267: break;
7268: }
1.25 cvs 7269: else
1.327 vatton 7270: {
7271: if (*selector == '>')
7272: {
1.340 quint 7273: /* handle parent */
1.327 vatton 7274: selector++;
7275: skippedNL = NewLineSkipped;
7276: selector = SkipBlanksAndComments (selector);
7277: NewLineSkipped = skippedNL;
1.340 quint 7278: rel[0] = RelParent;
1.327 vatton 7279: }
7280: else if (*selector == '+')
7281: {
1.340 quint 7282: /* handle immediate sibling */
1.327 vatton 7283: selector++;
7284: skippedNL = NewLineSkipped;
7285: selector = SkipBlanksAndComments (selector);
7286: NewLineSkipped = skippedNL;
7287: rel[0] = RelPrevious;
7288: }
1.340 quint 7289: else
7290: rel[0] = RelAncestor;
7291: nbnames++; /* a new level in ancestor tables */
7292: if (nbnames == MAX_ANCESTORS)
7293: /* abort parsing */
7294: {
7295: CSSPrintError ("Selector too long", deb);
7296: return (selector);
7297: }
7298: /* shift the list to make room for the next part of the selector */
7299: for (i = nbnames; i > 0; i--)
1.327 vatton 7300: {
7301: names[i] = names[i - 1];
1.355 quint 7302: pseudoFirstChild[i] = pseudoFirstChild[i - 1];
1.327 vatton 7303: rel[i] = rel[i - 1];
7304: }
1.340 quint 7305: /* increase the level of all attributes */
7306: for (i = 0; i < nbattrs; i++)
7307: attrlevels[i]++;
1.327 vatton 7308: }
1.1 cvs 7309: }
7310:
1.343 vatton 7311: /* Now update the list of classes defined by the CSS */
7312: for (i = 0; i < nbattrs; i++)
7313: if (attrvals[i] && attrnums[i] == ATTR_CLASS)
7314: AddClassName (attrvals[i], css);
7315:
1.1 cvs 7316: /* Now set up the context block */
1.25 cvs 7317: i = 0;
7318: j = 0;
1.91 cvs 7319: /* default schema name */
1.119 vatton 7320: ctxt->schema = NULL;
1.340 quint 7321: ctxt->nbElem = nbnames;
1.122 vatton 7322: elType.ElSSchema = NULL;
1.355 quint 7323: elType.ElTypeNum = 0;
1.122 vatton 7324: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 7325: if (!strcmp (schemaName, "HTML"))
7326: xmlType = XHTML_TYPE;
7327: else if (!strcmp (schemaName, "MathML"))
7328: xmlType = MATH_TYPE;
7329: else if (!strcmp (schemaName, "SVG"))
7330: xmlType = SVG_TYPE;
7331: else if (!strcmp (schemaName, "XLink"))
7332: xmlType = XLINK_TYPE;
7333: else if (!strcmp (schemaName, "Annot"))
7334: xmlType = ANNOT_TYPE;
7335: else
7336: xmlType = XML_TYPE;
1.340 quint 7337: while (i <= nbnames)
1.25 cvs 7338: {
1.340 quint 7339: ctxt->rel[i] = rel[i];
1.355 quint 7340: ctxt->firstChild[i] = pseudoFirstChild[i];
7341: if (!names[i] && i > 0)
1.340 quint 7342: ctxt->name[i] = HTML_EL_ANY_TYPE;
7343: else
7344: /* store element information */
1.327 vatton 7345: {
7346: /* get the element type of this name in the current document */
7347: if (xmlType == XML_TYPE)
7348: /* it's a generic XML document. Check the main document schema */
7349: {
7350: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7351: elType.ElTypeNum = 0;
7352: if (names[i])
7353: TtaGetXmlElementType (names[i], &elType, &mappedName, doc);
1.327 vatton 7354: if (!elType.ElTypeNum)
7355: {
1.355 quint 7356: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 7357: elType.ElTypeNum = HTML_EL_ANY_TYPE;
7358: else
7359: elType.ElSSchema = NULL;
7360: }
7361: }
7362: else
7363: {
1.355 quint 7364: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 7365: {
7366: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7367: elType.ElTypeNum = HTML_EL_ANY_TYPE;
7368: }
7369: else
7370: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c,
7371: &level, doc);
7372: }
7373: if (i == 0)
1.340 quint 7374: /* rightmost part of the selector */
1.327 vatton 7375: {
7376: if (elType.ElSSchema == NULL)
7377: {
1.340 quint 7378: /* element name not found. Search in all loaded schemas */
1.355 quint 7379: if (names[i])
7380: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.327 vatton 7381: if (elType.ElSSchema)
7382: {
7383: /* the element type concerns an imported nature */
7384: schemaName = TtaGetSSchemaName(elType.ElSSchema);
7385: if (!strcmp (schemaName, "HTML"))
7386: {
7387: if (xmlType == XHTML_TYPE &&
7388: DocumentMeta[doc] && DocumentMeta[doc]->xmlformat)
7389: /* the selector was found but the case is not correct */
7390: elType.ElSSchema = NULL;
7391: else
7392: xmlType = XHTML_TYPE;
7393: }
7394: else if (!strcmp (schemaName, "MathML"))
7395: xmlType = MATH_TYPE;
7396: else if (!strcmp (schemaName, "SVG"))
7397: xmlType = SVG_TYPE;
7398: else if (!strcmp (schemaName, "XLink"))
7399: xmlType = XLINK_TYPE;
7400: else if (!strcmp (schemaName, "Annot"))
7401: xmlType = ANNOT_TYPE;
7402: else
7403: xmlType = XML_TYPE;
7404: }
1.118 vatton 7405: #ifdef XML_GENERIC
1.327 vatton 7406: else if (xmlType == XML_TYPE)
7407: {
7408: /* Creation of a new element type in the main schema */
7409: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7410: if (names[i])
7411: TtaAppendXmlElement (names[i], &elType, &mappedName,
7412: doc);
1.327 vatton 7413: }
1.118 vatton 7414: #endif /* XML_GENERIC */
1.327 vatton 7415: else
7416: {
7417: if (xmlType != XHTML_TYPE)
7418: {
7419: MapXMLElementType (XHTML_TYPE, names[i], &elType,
7420: &mappedName, &c, &level, doc);
7421: if (elType.ElSSchema)
7422: elType.ElSSchema = GetXHTMLSSchema (doc);
7423: }
7424: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
7425: {
7426: MapXMLElementType (MATH_TYPE, names[i], &elType,
7427: &mappedName, &c, &level, doc);
7428: if (elType.ElSSchema)
7429: elType.ElSSchema = GetMathMLSSchema (doc);
7430: }
7431: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
7432: {
7433: MapXMLElementType (SVG_TYPE, names[i], &elType,
7434: &mappedName, &c, &level, doc);
7435: if (elType.ElSSchema)
7436: elType.ElSSchema = GetSVGSSchema (doc);
7437: }
7438: }
7439: }
7440:
7441: if (elType.ElSSchema == NULL)
7442: /* cannot apply these CSS rules */
7443: DoApply = FALSE;
7444: else
7445: {
1.340 quint 7446: /* Store the element type contained in the rightmost part of
7447: the selector */
7448: ctxt->schema = elType.ElSSchema;
1.327 vatton 7449: ctxt->type = elType.ElTypeNum;
7450: ctxt->name[0] = elType.ElTypeNum;
1.340 quint 7451: ctxt->rel[0] = RelVoid;
1.327 vatton 7452: }
7453: }
1.340 quint 7454: else
7455: /* not the rightmost part of the selector */
1.327 vatton 7456: {
1.340 quint 7457: if (elType.ElTypeNum != 0)
7458: ctxt->name[i] = elType.ElTypeNum;
7459: #ifdef XML_GENERIC
7460: else if (xmlType == XML_TYPE)
1.327 vatton 7461: {
1.340 quint 7462: TtaGetXmlElementType (names[i], &elType, NULL, doc);
7463: if (elType.ElTypeNum == 0)
1.327 vatton 7464: {
1.340 quint 7465: /* Creation of a new element type in the main schema */
7466: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7467: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.327 vatton 7468: }
1.340 quint 7469: if (elType.ElTypeNum != 0)
7470: ctxt->name[i] = elType.ElTypeNum;
1.327 vatton 7471: }
1.340 quint 7472: #endif /* XML_GENERIC */
1.327 vatton 7473: }
1.340 quint 7474: }
7475:
7476: /* store attribute information for this element */
7477: while (j < nbattrs && attrlevels[j] <= i)
7478: {
7479: if (attrnames[j] || attrnums[j])
1.327 vatton 7480: {
1.340 quint 7481: if (attrnums[j] > 0)
1.327 vatton 7482: {
1.340 quint 7483: if (attrnums[j] == ATTR_CLASS)
1.327 vatton 7484: {
1.340 quint 7485: if (xmlType == SVG_TYPE)
7486: ctxt->attrType[j] = SVG_ATTR_class;
7487: else if (xmlType == MATH_TYPE)
7488: ctxt->attrType[j] = MathML_ATTR_class;
7489: else if (xmlType == XHTML_TYPE)
7490: ctxt->attrType[j] = HTML_ATTR_Class;
1.327 vatton 7491: else
1.119 vatton 7492: #ifdef XML_GENERIC
1.340 quint 7493: ctxt->attrType[j] = XML_ATTR_class;
1.107 cvs 7494: #else /* XML_GENERIC */
1.340 quint 7495: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 7496: #endif /* XML_GENERIC */
1.340 quint 7497: }
7498: else if (attrnums[j] == ATTR_PSEUDO)
7499: {
7500: if (xmlType == SVG_TYPE)
7501: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
7502: else if (xmlType == MATH_TYPE)
7503: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
7504: else if (xmlType == XHTML_TYPE)
7505: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
7506: else
1.119 vatton 7507: #ifdef XML_GENERIC
1.340 quint 7508: ctxt->attrType[j] = XML_ATTR_PseudoClass;
1.107 cvs 7509: #else /* XML_GENERIC */
1.340 quint 7510: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 7511: #endif /* XML_GENERIC */
1.340 quint 7512: }
7513: else if (attrnums[j] == ATTR_ID)
7514: {
7515: if (xmlType == SVG_TYPE)
7516: ctxt->attrType[j] = SVG_ATTR_id;
7517: else if (xmlType == MATH_TYPE)
7518: ctxt->attrType[j] = MathML_ATTR_id;
7519: else if (xmlType == XHTML_TYPE)
7520: ctxt->attrType[j] = HTML_ATTR_ID;
7521: else
1.119 vatton 7522: #ifdef XML_GENERIC
1.340 quint 7523: ctxt->attrType[j] = XML_ATTR_xmlid;
1.107 cvs 7524: #else /* XML_GENERIC */
1.340 quint 7525: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 7526: #endif /* XML_GENERIC */
1.340 quint 7527: }
7528: attrType.AttrTypeNum = ctxt->attrType[j];
7529: attrType.AttrSSchema = ctxt->schema;
7530: }
7531: else if (attrnames[j])
7532: {
7533: if (xmlType == XML_TYPE)
7534: {
7535: if (ctxt->schema)
7536: attrType.AttrSSchema = ctxt->schema;
7537: else
7538: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7539: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7540: att = attrType.AttrTypeNum;
7541: if (ctxt->schema == NULL && att != 0)
7542: ctxt->schema = attrType.AttrSSchema;
7543: }
7544: else
7545: {
7546: MapXMLAttribute (xmlType, attrnames[j], names[i], &level,
7547: doc, &att);
7548: if (ctxt->schema == NULL && att != 0)
7549: ctxt->schema = TtaGetDocumentSSchema (doc);
7550: }
1.393 quint 7551: if (att == 0 && xmlType != XML_TYPE)
1.340 quint 7552: /* Attribute name not found: Search in the list of all
7553: schemas loaded for this document */
7554: {
7555: attrType.AttrSSchema = NULL;
7556: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7557: att = attrType.AttrTypeNum;
7558: if (att != 0)
1.393 quint 7559: {
7560: ctxt->schema = attrType.AttrSSchema;
7561: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
7562: }
1.340 quint 7563: }
7564: attrType.AttrSSchema = ctxt->schema;
7565: attrType.AttrTypeNum = att;
1.412 vatton 7566: if ((i == 0 || xmlType == XML_TYPE) && att == 0)
1.340 quint 7567: {
1.119 vatton 7568: #ifdef XML_GENERIC
1.393 quint 7569: if (xmlType == XML_TYPE)
1.340 quint 7570: {
7571: /* The attribute is not yet present in the tree */
7572: /* Create a new global attribute */
7573: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7574: TtaAppendXmlAttribute (attrnames[j], &attrType, doc);
1.393 quint 7575: att = attrType.AttrTypeNum;
1.340 quint 7576: }
7577: #endif /* XML_GENERIC */
7578: if (attrType.AttrSSchema == NULL)
7579: /* cannot apply these CSS rules */
7580: DoApply = FALSE;
7581: else if (elType.ElSSchema)
7582: ctxt->schema = elType.ElSSchema;
7583: else
7584: ctxt->schema = attrType.AttrSSchema;
7585: }
7586: if (att == 0)
7587: {
7588: CSSPrintError ("Unknown attribute", attrnames[j]);
7589: DoApply = FALSE;
7590: }
7591: else
1.345 quint 7592: {
7593: ctxt->attrType[j] = att;
7594: if (att == DummyAttribute && !strcmp (schemaName,"HTML"))
7595: /* it's the "type" attribute for an "input" element.
7596: In the tree, it is represented by the element type,
7597: not by an attribute */
7598: {
7599: ctxt->attrType[j] = 0;
7600: if (attrvals[j] && attrmatch[i] == Txtmatch)
7601: /* a value is specified for attribute type. This
7602: value provides the Thot element type */
7603: {
7604: MapXMLAttributeValue (xmlType, attrvals[j],
7605: &attrType, &kind);
7606: /* attrType contains the element type */
7607: if (i == 0)
7608: ctxt->type = kind;
7609: ctxt->name[i] = kind;
7610: }
7611: }
7612: }
1.340 quint 7613: }
7614: if (ctxt->attrType[j])
1.327 vatton 7615: {
1.340 quint 7616: /* check the attribute type */
7617: if (!strcmp (schemaName, "HTML"))
7618: xmlType = XHTML_TYPE;
7619: else if (!strcmp (schemaName, "MathML"))
7620: xmlType = MATH_TYPE;
7621: else if (!strcmp (schemaName, "SVG"))
7622: xmlType = SVG_TYPE;
7623: else if (!strcmp (schemaName, "XLink"))
7624: xmlType = XLINK_TYPE;
7625: else if (!strcmp (schemaName, "Annot"))
7626: xmlType = ANNOT_TYPE;
7627: else
7628: xmlType = XML_TYPE;
7629: kind = TtaGetAttributeKind (attrType);
7630: if (kind == 0 && attrvals[j])
7631: {
7632: /* enumerated value */
7633: MapXMLAttributeValue (xmlType, attrvals[j], &attrType,
7634: &kind);
7635: /* store the attribute value */
7636: ctxt->attrText[j] = (char *) kind;
7637: }
7638: else
7639: ctxt->attrText[j] = attrvals[j];
7640: /* update attrLevel */
7641: ctxt->attrMatch[j] = attrmatch[j];
7642: ctxt->attrLevel[j] = attrlevels[j];
7643: }
7644: j++;
1.327 vatton 7645: }
7646: }
1.340 quint 7647: /* add a new entry */
1.25 cvs 7648: i++;
1.119 vatton 7649: if (i == 1 && ctxt->schema == NULL)
1.327 vatton 7650: /* use the document schema */
7651: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 7652: }
1.340 quint 7653:
1.312 quint 7654: ctxt->important = FALSE;
1.117 vatton 7655: /* set the selector specificity */
7656: ctxt->cssSpecificity = specificity;
1.25 cvs 7657: /* Get the schema name of the main element */
1.119 vatton 7658: schemaName = TtaGetSSchemaName (ctxt->schema);
7659: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 7660: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.217 vatton 7661: skippedNL = NewLineSkipped;
1.380 vatton 7662: if (DoApply && tsch && cssRule)
1.317 vatton 7663: {
7664: if (css)
1.327 vatton 7665: {
7666: /* point the right URL for loaded images */
7667: saveURL = css->url;
7668: css->url = url;
7669: }
1.317 vatton 7670: else
1.327 vatton 7671: saveURL = NULL;
7672: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.317 vatton 7673: if (css)
1.327 vatton 7674: /* restore previous url */
7675: css->url = saveURL;
1.317 vatton 7676: }
1.116 vatton 7677: /* future CSS rules should apply */
7678: DoApply = TRUE;
1.217 vatton 7679: if (selector)
7680: NewLineSkipped = skippedNL;
1.1 cvs 7681: return (selector);
7682: }
7683:
7684: /*----------------------------------------------------------------------
1.206 vatton 7685: ParseStyleDeclaration: parse a style declaration stored in the style
7686: element of a document
7687: We expect the style string to be of the form:
7688: .pinky, .awful { color: pink; font-family: helvetica }
1.231 vatton 7689: The parameter css points to the current CSS context.
7690: The parameter link points to the link element.
7691: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 7692: ----------------------------------------------------------------------*/
1.206 vatton 7693: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
1.327 vatton 7694: CSSInfoPtr css, Element link, char *url,
7695: ThotBool destroy)
1.1 cvs 7696: {
1.79 cvs 7697: GenericContext ctxt;
7698: char *decl_end;
7699: char *sel_end;
7700: char *selector;
1.1 cvs 7701:
7702: /* separate the selectors string */
1.82 cvs 7703: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 7704: decl_end = cssRule;
1.82 cvs 7705: while (*decl_end != EOS && *decl_end != '{')
1.286 quint 7706: {
7707: if (*decl_end == EOL)
1.327 vatton 7708: NewLineSkipped++;
1.286 quint 7709: decl_end++;
7710: }
1.82 cvs 7711: if (*decl_end == EOS)
1.86 cvs 7712: {
1.168 vatton 7713: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 7714: return;
7715: }
1.1 cvs 7716: /* verify and clean the selector string */
7717: sel_end = decl_end - 1;
1.82 cvs 7718: while (*sel_end == SPACE || *sel_end == BSPACE ||
1.411 vatton 7719: *sel_end == EOL || *sel_end == __CR__)
1.1 cvs 7720: sel_end--;
7721: sel_end++;
1.82 cvs 7722: *sel_end = EOS;
1.1 cvs 7723: selector = cssRule;
7724:
7725: /* now, deal with the content ... */
7726: decl_end++;
7727: cssRule = decl_end;
1.137 vatton 7728: decl_end = &cssRule[strlen (cssRule) - 1];
1.398 vatton 7729: if (*decl_end != '{' && *decl_end != EOS)
1.137 vatton 7730: *decl_end = EOS;
1.1 cvs 7731: /*
7732: * parse the style attribute string and install the corresponding
7733: * presentation attributes on the new element
7734: */
7735: ctxt = TtaGetGenericStyleContext (doc);
7736: if (ctxt == NULL)
7737: return;
7738: ctxt->destroy = destroy;
1.207 vatton 7739: /* first use of the context */
7740: ctxt->uses = 1;
1.197 vatton 7741: while (selector && *selector != EOS)
1.363 vatton 7742: {
7743: if (ctxt->uses > 1)
7744: {
7745: /* this context is waiting for a callback */
7746: ctxt = TtaGetGenericStyleContext (doc);
7747: if (ctxt == NULL)
7748: return;
7749: ctxt->destroy = destroy;
7750: /* first use of the context */
7751: ctxt->uses = 1;
7752: }
7753: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css,
7754: link, url);
7755: }
1.207 vatton 7756: /* check if the context can be freed */
7757: ctxt->uses -= 1;
7758: if (ctxt->uses == 0)
7759: /* no image loading */
7760: TtaFreeMemory (ctxt);
1.1 cvs 7761: }
7762:
7763: /************************************************************************
7764: * *
7765: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
7766: * *
7767: ************************************************************************/
7768:
7769: /*----------------------------------------------------------------------
1.327 vatton 7770: IsImplicitClassName: return wether the Class name is an
7771: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
7772: or an HTML context name.
1.1 cvs 7773: ----------------------------------------------------------------------*/
1.248 gully 7774: int IsImplicitClassName (char *class_, Document doc)
1.1 cvs 7775: {
1.327 vatton 7776: char name[200];
7777: char *cur = name;
7778: char *first;
7779: char save;
7780: SSchema schema;
7781:
7782: /* make a local copy */
7783: strncpy (name, class_, 199);
7784: name[199] = 0;
7785:
7786: /* loop looking if each word is a GI */
7787: while (*cur != 0)
7788: {
7789: first = cur;
7790: cur = SkipWord (cur);
7791: save = *cur;
7792: *cur = 0;
7793: schema = NULL;
7794: if (MapGI (first, &schema, doc) == -1)
7795: {
7796: return (0);
7797: }
7798: *cur = save;
7799: cur = SkipBlanksAndComments (cur);
7800: }
7801: return (1);
1.1 cvs 7802: }
7803:
7804: /************************************************************************
1.114 quint 7805: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 7806: ************************************************************************/
7807:
7808: /*----------------------------------------------------------------------
1.409 vatton 7809: SetBodyAbsolutePosition:
7810: ----------------------------------------------------------------------*/
7811: void SetBodyAbsolutePosition (Document doc)
7812: {
7813: Element root, body;
7814: ElementType elType;
7815:
7816: if (DocumentTypes[doc] != docHTML)
7817: return;
7818: root = TtaGetMainRoot (doc);
7819: elType = TtaGetElementType(root);
7820: elType.ElTypeNum = HTML_EL_BODY;
7821: body = TtaSearchTypedElement (elType, SearchInTree, root);
7822: if (body)
1.410 vatton 7823: ParseHTMLSpecificStyle (body, (char *)"position:absolute", doc, 200, FALSE);
1.409 vatton 7824: }
7825:
7826: /*----------------------------------------------------------------------
1.327 vatton 7827: HTMLSetBackgroundColor:
1.1 cvs 7828: ----------------------------------------------------------------------*/
1.264 vatton 7829: void HTMLSetBackgroundColor (Document doc, Element el, int specificity,
1.327 vatton 7830: char *color)
1.1 cvs 7831: {
1.350 vatton 7832: char css_command[1000];
1.1 cvs 7833:
1.416 vatton 7834: snprintf (css_command, 1000, "background-color: %50s", color);
1.327 vatton 7835: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7836: }
7837:
7838: /*----------------------------------------------------------------------
1.327 vatton 7839: HTMLSetForegroundColor:
1.1 cvs 7840: ----------------------------------------------------------------------*/
1.264 vatton 7841: void HTMLSetForegroundColor (Document doc, Element el, int specificity,
1.327 vatton 7842: char *color)
1.1 cvs 7843: {
1.350 vatton 7844: char css_command[1000];
1.1 cvs 7845:
1.416 vatton 7846: snprintf (css_command, 1000, "color: %50s", color);
1.327 vatton 7847: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7848: }
7849:
7850: /*----------------------------------------------------------------------
1.327 vatton 7851: HTMLResetBackgroundColor:
1.1 cvs 7852: ----------------------------------------------------------------------*/
1.97 vatton 7853: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 7854: {
1.350 vatton 7855: char css_command[1000];
1.1 cvs 7856:
1.327 vatton 7857: sprintf (css_command, "background: red");
7858: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7859: }
7860:
7861: /*----------------------------------------------------------------------
1.327 vatton 7862: HTMLResetBackgroundImage:
1.1 cvs 7863: ----------------------------------------------------------------------*/
1.97 vatton 7864: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 7865: {
1.327 vatton 7866: char css_command[1000];
1.1 cvs 7867:
1.416 vatton 7868: snprintf (css_command, 1000, "background-image: url(xx); background-repeat: repeat");
1.327 vatton 7869: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7870: }
7871:
7872: /*----------------------------------------------------------------------
1.327 vatton 7873: HTMLResetForegroundColor:
1.1 cvs 7874: ----------------------------------------------------------------------*/
1.97 vatton 7875: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 7876: {
1.350 vatton 7877: char css_command[1000];
1.1 cvs 7878:
1.327 vatton 7879: /* it's not necessary to well know the current color but it must be valid */
7880: sprintf (css_command, "color: red");
7881: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7882: }
7883:
7884: /*----------------------------------------------------------------------
1.327 vatton 7885: HTMLSetAlinkColor:
1.1 cvs 7886: ----------------------------------------------------------------------*/
1.208 vatton 7887: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 7888: {
1.350 vatton 7889: char css_command[1000];
1.1 cvs 7890:
1.416 vatton 7891: snprintf (css_command, 1000, ":link { color: %50s }", color);
1.327 vatton 7892: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7893: }
7894:
7895: /*----------------------------------------------------------------------
1.327 vatton 7896: HTMLSetAactiveColor:
1.1 cvs 7897: ----------------------------------------------------------------------*/
1.208 vatton 7898: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 7899: {
1.350 vatton 7900: char css_command[1000];
1.1 cvs 7901:
1.416 vatton 7902: snprintf (css_command, 1000, ":active { color: %50s }", color);
1.327 vatton 7903: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7904: }
7905:
7906: /*----------------------------------------------------------------------
1.327 vatton 7907: HTMLSetAvisitedColor:
1.1 cvs 7908: ----------------------------------------------------------------------*/
1.208 vatton 7909: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 7910: {
1.350 vatton 7911: char css_command[1000];
1.1 cvs 7912:
1.416 vatton 7913: snprintf (css_command, 1000, ":visited { color: %50s }", color);
1.327 vatton 7914: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7915: }
7916:
7917: /*----------------------------------------------------------------------
1.327 vatton 7918: HTMLResetAlinkColor:
1.1 cvs 7919: ----------------------------------------------------------------------*/
1.208 vatton 7920: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 7921: {
1.350 vatton 7922: char css_command[1000];
1.1 cvs 7923:
1.327 vatton 7924: sprintf (css_command, ":link { color: red }");
7925: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7926: }
7927:
7928: /*----------------------------------------------------------------------
1.327 vatton 7929: HTMLResetAactiveColor:
1.1 cvs 7930: ----------------------------------------------------------------------*/
1.208 vatton 7931: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 7932: {
1.350 vatton 7933: char css_command[1000];
1.1 cvs 7934:
1.327 vatton 7935: sprintf (css_command, ":active { color: red }");
7936: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7937: }
7938:
7939: /*----------------------------------------------------------------------
1.327 vatton 7940: HTMLResetAvisitedColor:
1.1 cvs 7941: ----------------------------------------------------------------------*/
1.208 vatton 7942: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 7943: {
1.350 vatton 7944: char css_command[1000];
1.1 cvs 7945:
1.327 vatton 7946: sprintf (css_command, ":visited { color: red }");
7947: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7948: }
7949:
7950: /*----------------------------------------------------------------------
1.206 vatton 7951: ApplyCSSRules: parse a CSS Style description stored in the header of
7952: a HTML document.
1.1 cvs 7953: ----------------------------------------------------------------------*/
1.79 cvs 7954: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 7955: {
1.206 vatton 7956: CSSInfoPtr css;
7957: PInfoPtr pInfo;
1.207 vatton 7958: ThotBool loadcss;
7959:
7960: /* check if we have to load CSS */
7961: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
7962: if (!loadcss)
7963: return;
1.376 vatton 7964: LineNumber = TtaGetElementLineNumber (el);
1.206 vatton 7965: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 7966: if (css == NULL)
1.209 vatton 7967: {
7968: /* create the document css context */
7969: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
7970: pInfo = css->infos[doc];
7971: }
1.206 vatton 7972: else if (pInfo == NULL)
7973: /* create the entry into the css context */
7974: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 7975: if (pInfo->PiEnabled)
1.376 vatton 7976: ParseStyleDeclaration (el, cssRule, doc, css, el, NULL, destroy);
7977: LineNumber = -1;
1.1 cvs 7978: }
7979:
7980: /*----------------------------------------------------------------------
1.327 vatton 7981: ReadCSSRules: is the front-end function called by the document parser
7982: when detecting a <style type="text/css"> indicating it's the
7983: beginning of a CSS fragment or when reading a file .css.
1.1 cvs 7984:
1.327 vatton 7985: The CSS parser has to handle <!-- ... --> constructs used to
7986: prevent prehistoric browser from displaying the CSS as a text
7987: content. It will stop on any sequence "<x" where x is different
7988: from ! and will return x as to the caller. Theorically x should
7989: be equal to / for the </style> end of style.
7990: The parameter doc gives the document tree that contains CSS information.
7991: The parameter docRef gives the document to which CSS are to be applied.
7992: This function uses the current css context or creates it. It's able
7993: to work on the given buffer or call GetNextChar to read the parsed
7994: file.
7995: The parameter url gives the URL of the parsed style sheet.
7996: The parameter numberOfLinesRead gives the number of lines already
7997: read in the file.
7998: The parameter withUndo indicates whether the changes made in the document
7999: structure and content have to be registered in the Undo queue or not.
1.1 cvs 8000: ----------------------------------------------------------------------*/
1.133 vatton 8001: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.343 vatton 8002: int numberOfLinesRead, ThotBool withUndo, Element link)
1.1 cvs 8003: {
1.6 cvs 8004: DisplayMode dispMode;
1.206 vatton 8005: CSSInfoPtr refcss = NULL;
1.321 vatton 8006: CSSmedia css_media = CSS_ALL;
1.206 vatton 8007: PInfoPtr pInfo;
1.321 vatton 8008: char c;
1.138 vatton 8009: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 8010: int index;
1.1 cvs 8011: int CSSindex;
1.327 vatton 8012: int CSScomment;
1.1 cvs 8013: int import;
1.358 quint 8014: int openBlock;
1.93 vatton 8015: int newlines;
1.358 quint 8016: int page;
1.14 cvs 8017: ThotBool HTMLcomment;
1.342 vatton 8018: ThotBool toParse, eof, quoted, s_quoted;
1.358 quint 8019: ThotBool ignore, media, lineComment;
1.234 vatton 8020: ThotBool noRule, ignoreImport, fontface;
1.1 cvs 8021:
1.327 vatton 8022: CSScomment = MAX_CSS_LENGTH;
1.1 cvs 8023: HTMLcomment = FALSE;
8024: CSSindex = 0;
8025: toParse = FALSE;
8026: noRule = FALSE;
1.234 vatton 8027: media = FALSE;
1.88 cvs 8028: ignoreImport = FALSE;
1.342 vatton 8029: ignore = lineComment = FALSE;
1.358 quint 8030: page = 0;
1.342 vatton 8031: quoted = s_quoted = FALSE;
1.234 vatton 8032: fontface = FALSE;
1.1 cvs 8033: eof = FALSE;
1.358 quint 8034: openBlock = 0;
1.234 vatton 8035: import = MAX_CSS_LENGTH;
1.82 cvs 8036: c = SPACE;
1.1 cvs 8037: index = 0;
1.134 vatton 8038: base = NULL;
1.310 vatton 8039: /* entering the CSS parsing */
1.311 vatton 8040: Style_parsing++;
1.93 vatton 8041: /* number of new lines parsed */
8042: newlines = 0;
1.6 cvs 8043: /* avoid too many redisplay */
8044: dispMode = TtaGetDisplayMode (docRef);
8045: if (dispMode == DisplayImmediately)
8046: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 8047:
8048: /* look for the CSS context */
8049: if (css == NULL)
1.206 vatton 8050: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 8051: else
8052: pInfo = css->infos[docRef];
1.18 cvs 8053: if (css == NULL)
1.206 vatton 8054: {
8055: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
8056: pInfo = css->infos[docRef];
8057: }
8058: else if (pInfo == NULL)
8059: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 8060: /* look for the CSS descriptor that points to the extension schema */
8061: refcss = css;
1.224 vatton 8062: if (pInfo && pInfo->PiCategory == CSS_IMPORT)
1.173 cvs 8063: {
1.206 vatton 8064: while (refcss &&
1.327 vatton 8065: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
8066: refcss = refcss->NextCSS;
1.206 vatton 8067: if (refcss)
1.327 vatton 8068: pInfo = refcss->infos[docRef];
1.173 cvs 8069: }
8070:
1.343 vatton 8071: /* register parsed CSS file and the document to which CSS are to be applied */
1.395 vatton 8072: if (DocumentMeta[docRef] == NULL || DocumentMeta[docRef]->method != CE_MAKEBOOK)
8073: ParsedDoc = docRef;
8074: else
8075: ParsedDoc = 0;
1.343 vatton 8076: /* clean up the list of classes */
8077: TtaFreeMemory (refcss->class_list);
8078: refcss->class_list = NULL;
1.133 vatton 8079: if (url)
1.348 vatton 8080: Error_DocURL = url;
1.86 cvs 8081: else
8082: /* the CSS source in within the document itself */
1.348 vatton 8083: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 8084: LineNumber = numberOfLinesRead + 1;
1.93 vatton 8085: NewLineSkipped = 0;
1.217 vatton 8086: newlines = 0;
1.392 carcone 8087:
8088: /* Search for an UTF-8 BOM character (EF BB BF) */
8089: if (index == 0 && strlen(buffer) > 2 &&
8090: (unsigned char) buffer[0] == 0xEF &&
8091: (unsigned char) buffer[1] == 0xBB &&
8092: (unsigned char) buffer[2] == 0xBF)
8093: {
8094: index = 3;
8095: }
8096:
8097: /* Search for an UTF-16 Big Endian BOM character (FE FF) */
8098: if (index == 0 && strlen(buffer) > 1 &&
8099: (unsigned char) buffer[0] == 0xFE &&
8100: (unsigned char) buffer[1] == 0xFF)
8101: {
8102: index = 2;
8103: }
8104:
8105: /* Search for an UTF-16 Little Endian BOM character (FF FE) */
8106: if (index == 0 && strlen(buffer) > 1 &&
8107: (unsigned char) buffer[0] == 0xFF &&
8108: (unsigned char) buffer[1] == 0xFE)
8109: {
8110: index = 2;
8111: }
8112:
1.82 cvs 8113: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
8114: {
8115: c = buffer[index++];
8116: eof = (c == EOS);
8117: CSSbuffer[CSSindex] = c;
1.342 vatton 8118: if (!lineComment &&
8119: (CSScomment == MAX_CSS_LENGTH || c == '*' || c == '/' || c == '<' || c == EOL))
1.327 vatton 8120: {
8121: /* we're not within a comment or we're parsing * or / */
8122: switch (c)
8123: {
8124: case '@': /* perhaps an import primitive */
1.342 vatton 8125: if (!fontface && !page && !quoted && !s_quoted)
1.327 vatton 8126: import = CSSindex;
8127: break;
8128: case ';':
1.342 vatton 8129: if (!quoted && !s_quoted && !media && import != MAX_CSS_LENGTH)
1.327 vatton 8130: {
8131: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
8132: /* it's not an import */
8133: import = MAX_CSS_LENGTH;
8134: /* save the text */
8135: noRule = TRUE;
8136: }
8137: break;
8138: case '*':
1.342 vatton 8139: if (!quoted && !s_quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.327 vatton 8140: CSSbuffer[CSSindex - 1] == '/')
8141: /* start a comment */
8142: CSScomment = CSSindex - 1;
8143: break;
8144: case '/':
1.342 vatton 8145: if (!quoted && !s_quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.399 vatton 8146: CSSbuffer[CSSindex - 1] == '*' && CSSindex != CSScomment + 2)
1.327 vatton 8147: {
8148: while (CSSindex > 0 && CSSindex >= CSScomment)
8149: {
8150: if ( CSSbuffer[CSSindex] == EOL)
8151: {
8152: LineNumber ++;
8153: newlines --;
8154: }
8155: CSSindex--;
8156: }
8157: CSSindex = CSScomment - 1; /* will be incremented later */
8158: CSScomment = MAX_CSS_LENGTH;
8159: /* clean up the buffer */
8160: if (newlines && CSSindex > 0)
8161: while (CSSindex > 0 &&
8162: (CSSbuffer[CSSindex] == SPACE ||
8163: CSSbuffer[CSSindex] == BSPACE ||
8164: CSSbuffer[CSSindex] == EOL ||
8165: CSSbuffer[CSSindex] == TAB ||
8166: CSSbuffer[CSSindex] == __CR__))
8167: {
8168: if ( CSSbuffer[CSSindex] == EOL)
8169: {
8170: LineNumber ++;
8171: newlines --;
8172: }
8173: CSSindex--;
8174: }
8175: }
1.342 vatton 8176: else if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 8177: CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
8178: CSSbuffer[CSSindex - 1] == '<')
8179: {
8180: /* this is the closing tag ! */
8181: CSSindex -= 2; /* remove </ from the CSS string */
8182: noRule = TRUE;
1.342 vatton 8183: }
8184: else if (!quoted && !s_quoted &&
8185: (CSSindex == 1 || (CSSindex > 1 && CSSbuffer[CSSindex - 2] == EOL)) &&
8186: CSScomment == MAX_CSS_LENGTH &&
8187: CSSbuffer[CSSindex - 1] == '/')
8188: {
8189: CSSindex--;
8190: lineComment = TRUE;
8191: }
8192:
1.327 vatton 8193: break;
8194: case '<':
1.342 vatton 8195: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 8196: CSScomment == MAX_CSS_LENGTH)
8197: {
8198: /* only if we're not parsing a comment */
8199: c = buffer[index++];
8200: eof = (c == EOS);
8201: if (c == '!')
8202: {
8203: /* CSS within an HTML comment */
8204: HTMLcomment = TRUE;
8205: CSSindex++;
8206: CSSbuffer[CSSindex] = c;
8207: }
8208: else if (c == EOS)
8209: CSSindex++;
8210: }
8211: break;
8212: case '-':
1.342 vatton 8213: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 8214: CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
8215: HTMLcomment)
8216: /* CSS within an HTML comment */
8217: noRule = TRUE;
8218: break;
8219: case '>':
1.342 vatton 8220: if (!fontface && !page && !quoted && !s_quoted && HTMLcomment)
1.327 vatton 8221: noRule = TRUE;
8222: break;
8223: case ' ':
1.358 quint 8224: if (!quoted && !s_quoted && import != MAX_CSS_LENGTH && openBlock == 0)
1.327 vatton 8225: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
8226: break;
8227: case '{':
1.342 vatton 8228: if (!quoted && !s_quoted)
1.327 vatton 8229: {
1.358 quint 8230: openBlock++;
1.327 vatton 8231: if (import != MAX_CSS_LENGTH)
8232: {
1.358 quint 8233: if (openBlock == 1 && media)
1.327 vatton 8234: {
8235: /* is it the screen concerned? */
8236: CSSbuffer[CSSindex+1] = EOS;
8237: css_media = CheckMediaCSS (&CSSbuffer[import+7]);
8238: if (TtaIsPrinting ())
8239: ignore = (css_media != CSS_ALL && css_media != CSS_PRINT);
8240: else
8241: ignore = (css_media != CSS_ALL && css_media != CSS_SCREEN);
8242: noRule = TRUE;
8243: }
8244: else if (!strncasecmp (&CSSbuffer[import+1], "page", 4))
1.358 quint 8245: /* it is a @page block */
1.327 vatton 8246: {
1.358 quint 8247: page = openBlock;/*remember the level of this block*/
1.327 vatton 8248: noRule = TRUE;
8249: }
8250: else if (!strncasecmp (&CSSbuffer[import+1], "font-face", 9))
8251: {
8252: fontface = TRUE;
8253: noRule = TRUE;
8254: }
8255: }
8256: }
8257: break;
8258: case '}':
1.342 vatton 8259: if (!quoted && !s_quoted)
1.327 vatton 8260: {
1.358 quint 8261: if (page == openBlock)
8262: /* closing the @page block */
1.327 vatton 8263: {
8264: noRule = TRUE;
1.358 quint 8265: page = 0; /* close the page section */
1.327 vatton 8266: }
8267: else if (fontface)
8268: {
8269: noRule = TRUE;
8270: fontface = FALSE; /* close the fontface section */
8271: }
1.358 quint 8272: else if (openBlock == 1 && import != MAX_CSS_LENGTH)
1.327 vatton 8273: {
8274: import = MAX_CSS_LENGTH;
8275: noRule = TRUE;
8276: ignore = FALSE;
8277: media = FALSE;
8278: }
1.358 quint 8279: else if (!page)
1.327 vatton 8280: toParse = TRUE;
1.358 quint 8281: openBlock--;
1.327 vatton 8282: }
8283: break;
8284: case '"':
8285: if (quoted)
8286: {
1.342 vatton 8287: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
1.327 vatton 8288: quoted = FALSE;
8289: }
1.342 vatton 8290: else if (!s_quoted)
1.327 vatton 8291: quoted = TRUE;
8292: break;
1.342 vatton 8293: case '\'':
8294: if (s_quoted)
8295: {
8296: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
8297: s_quoted = FALSE;
8298: }
8299: else if (!quoted)
8300: s_quoted = TRUE;
8301: break;
8302: default:
1.327 vatton 8303: if (c == EOL)
8304: {
8305: newlines++;
8306: }
8307: break;
8308: }
1.82 cvs 8309: }
1.93 vatton 8310: else if (c == EOL)
1.327 vatton 8311: {
8312: LineNumber++;
1.342 vatton 8313: lineComment = FALSE;
1.411 vatton 8314: c = __CR__;
1.327 vatton 8315: }
1.234 vatton 8316:
1.411 vatton 8317: if (!lineComment && c != __CR__)
1.327 vatton 8318: CSSindex++;
1.82 cvs 8319:
8320: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
1.327 vatton 8321: /* we're still parsing a comment: remove the text comment */
8322: CSSindex = CSScomment;
1.82 cvs 8323:
8324: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
1.327 vatton 8325: {
8326: CSSbuffer[CSSindex] = EOS;
8327: /* parse a not empty string */
8328: if (CSSindex > 0)
8329: {
1.50 cvs 8330: /* apply CSS rule if it's not just a saving of text */
1.234 vatton 8331: if (!noRule && !ignore)
1.327 vatton 8332: {
8333: /* future import rules must be ignored */
8334: ignoreImport = TRUE;
8335: NewLineSkipped = 0;
8336: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
8337: pInfo->PiLink, url, FALSE);
8338: LineNumber += newlines;
8339: newlines = 0;
8340: }
1.82 cvs 8341: else if (import != MAX_CSS_LENGTH &&
1.327 vatton 8342: !strncasecmp (&CSSbuffer[import+1], "import", 6))
8343: {
8344: /* import section */
8345: cssRule = &CSSbuffer[import+7];
1.405 kia 8346: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8347: /* save the current line number */
8348: newlines += LineNumber;
8349: if (!strncasecmp (cssRule, "url", 3))
8350: {
1.50 cvs 8351: cssRule = &cssRule[3];
1.405 kia 8352: cssRule = (char*)TtaSkipBlanks (cssRule);
1.82 cvs 8353: if (*cssRule == '(')
1.327 vatton 8354: {
8355: cssRule++;
1.405 kia 8356: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8357: quoted = (*cssRule == '"' || *cssRule == '\'');
8358: if (quoted)
8359: cssRule++;
8360: base = cssRule;
8361: while (*cssRule != EOS && *cssRule != ')')
8362: cssRule++;
8363: if (quoted)
8364: {
8365: /* isolate the file name */
8366: cssRule[-1] = EOS;
8367: quoted = FALSE;
8368: }
8369: else
8370: {
8371: /* remove extra spaces */
8372: if (cssRule[-1] == SPACE)
8373: {
8374: *cssRule = SPACE;
8375: cssRule--;
8376: while (cssRule[-1] == SPACE)
8377: cssRule--;
8378: }
8379: }
8380: *cssRule = EOS;
8381: }
8382: }
8383: else if (*cssRule == '"')
8384: {
8385: /*
8386: Do we have to accept single quotes?
8387: Double quotes are accepted here.
8388: Escaped quotes are not handled. See function SkipQuotedString
8389: */
8390: cssRule++;
1.405 kia 8391: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8392: base = cssRule;
8393: while (*cssRule != EOS &&
8394: (*cssRule != '"' ||
8395: (*cssRule == '"' && cssRule[-1] == '\\')))
8396: cssRule++;
8397: /* isolate the file name */
8398: *cssRule = EOS;
8399: }
8400: /* check if a media is defined */
8401: cssRule++;
1.405 kia 8402: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8403: if (*cssRule != ';')
8404: {
8405: css_media = CheckMediaCSS (cssRule);
8406: if (TtaIsPrinting ())
8407: ignoreImport = (css_media != CSS_ALL && css_media != CSS_PRINT);
8408: else
8409: ignoreImport = (css_media != CSS_ALL && css_media != CSS_SCREEN);
8410: }
8411: if (!ignoreImport)
8412: {
8413: /* save the displayed URL when an error is reported */
1.348 vatton 8414: saveDocURL = Error_DocURL;
1.327 vatton 8415: ptr = TtaStrdup (base);
8416: /* get the CSS URI in UTF-8 */
8417: /*ptr = ReallocUTF8String (ptr, docRef);*/
8418: LoadStyleSheet (base, docRef, (Element) css, css,
8419: url, pInfo->PiMedia,
8420: pInfo->PiCategory == CSS_USER_STYLE);
8421: /* restore the displayed URL when an error is reported */
1.348 vatton 8422: Error_DocURL = saveDocURL;
1.327 vatton 8423: TtaFreeMemory (ptr);
8424: }
8425: /* restore the number of lines */
8426: LineNumber = newlines;
8427: newlines = 0;
8428: NewLineSkipped = 0;
8429: import = MAX_CSS_LENGTH;
8430: }
8431: else
8432: {
8433: LineNumber += newlines;
8434: newlines = 0;
8435: }
8436: }
8437: toParse = FALSE;
8438: noRule = FALSE;
8439: CSSindex = 0;
1.50 cvs 8440: }
1.82 cvs 8441: }
1.310 vatton 8442: /* closing the CSS parsing */
1.311 vatton 8443: Style_parsing--;
1.330 cvs 8444: if (RedisplayImages == 0 && RedisplayBGImage && Style_parsing == 0)
1.310 vatton 8445: {
1.311 vatton 8446: /* CSS parsing finishes after a BG image was loaded */
1.310 vatton 8447: RedisplayBGImage = FALSE;
1.330 cvs 8448: if (dispMode != NoComputedDisplay)
8449: {
8450: //printf ("ReadCSS Show BGimages\n");
8451: TtaSetDisplayMode (docRef, NoComputedDisplay);
8452: TtaSetDisplayMode (docRef, dispMode);
8453: }
1.310 vatton 8454: }
1.330 cvs 8455: else if (dispMode != NoComputedDisplay)
1.311 vatton 8456: /* restore the display mode */
8457: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 8458:
8459: /* Prepare the context for style attributes */
1.348 vatton 8460: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 8461: LineNumber = -1;
1.1 cvs 8462: return (c);
8463: }
Webmaster