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