Annotation of Amaya/amaya/styleparser.c, revision 1.422
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))
5515: repeat = TRUE;
1.327 vatton 5516: cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
5517: css, isHTML);
5518: img = TRUE;
5519: }
1.18 cvs 5520: /* perhaps a Background Attachment */
1.82 cvs 5521: else if (!strncasecmp (cssRule, "scroll", 6) ||
5522: !strncasecmp (cssRule, "fixed", 5))
1.327 vatton 5523: {
5524: cssRule = ParseACSSBackgroundAttachment (element, tsch, ctxt,
5525: cssRule, css, isHTML);
1.328 vatton 5526: attach = repeat = TRUE;
1.327 vatton 5527: }
1.18 cvs 5528: /* perhaps a Background Repeat */
1.82 cvs 5529: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
5530: !strncasecmp (cssRule, "repeat-y", 8) ||
5531: !strncasecmp (cssRule, "repeat-x", 8) ||
5532: !strncasecmp (cssRule, "repeat", 6))
1.327 vatton 5533: {
5534: cssRule = ParseACSSBackgroundRepeat (element, tsch, ctxt,
5535: cssRule, css, isHTML);
5536: repeat = TRUE;
5537: }
1.18 cvs 5538: /* perhaps a Background Position */
1.82 cvs 5539: else if (!strncasecmp (cssRule, "left", 4) ||
5540: !strncasecmp (cssRule, "right", 5) ||
5541: !strncasecmp (cssRule, "center", 6) ||
5542: !strncasecmp (cssRule, "top", 3) ||
5543: !strncasecmp (cssRule, "bottom", 6) ||
1.279 vatton 5544: isdigit (*cssRule) || *cssRule == '.' || *cssRule == '-')
1.327 vatton 5545: {
1.362 quint 5546: cssRule = ParseACSSBackgroundPosition (element, tsch, ctxt, cssRule,
5547: css, isHTML, &across);
5548: across = !across;
1.328 vatton 5549: position = repeat = TRUE;
1.327 vatton 5550: }
1.18 cvs 5551: /* perhaps a Background Color */
1.323 vatton 5552: else if (!color)
1.327 vatton 5553: {
5554: skippedNL = NewLineSkipped;
5555: /* check if the rule has been found */
5556: ptr = cssRule;
5557: cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
5558: cssRule, css, isHTML);
5559: if (ptr == cssRule)
5560: {
5561: NewLineSkipped = skippedNL;
5562: /* rule not found */
5563: cssRule = SkipProperty (cssRule, FALSE);
5564: }
5565: else
5566: color = TRUE;
5567: }
1.328 vatton 5568: else
1.327 vatton 5569: cssRule = SkipProperty (cssRule, FALSE);
1.328 vatton 5570:
1.82 cvs 5571: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 5572: }
1.328 vatton 5573:
5574: if (color && !img)
1.405 kia 5575: ParseCSSBackgroundImage (element, tsch, ctxt, (char*)
5576: "none", css, isHTML);
1.328 vatton 5577:
5578: if (img && !repeat)
5579: ParseACSSBackgroundRepeat (element, tsch, ctxt,
1.405 kia 5580: (char*)"repeat", css, isHTML);
1.328 vatton 5581: if (img && !position)
5582: ParseACSSBackgroundPosition (element, tsch, ctxt,
1.405 kia 5583: (char*)"0% 0%", css, isHTML, &across);
1.328 vatton 5584: if (img && !attach)
5585: ParseACSSBackgroundAttachment (element, tsch, ctxt,
1.405 kia 5586: (char*)"scroll", css, isHTML);
1.327 vatton 5587: return (cssRule);
1.18 cvs 5588: }
5589:
1.59 cvs 5590: /*----------------------------------------------------------------------
1.327 vatton 5591: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 5592: ----------------------------------------------------------------------*/
1.79 cvs 5593: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.327 vatton 5594: PresentationContext ctxt, char *cssRule,
5595: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 5596: {
5597: PresentationValue page;
1.366 vatton 5598: char *start_value;
1.59 cvs 5599:
1.184 vatton 5600: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5601: page.typed_data.real = FALSE;
1.82 cvs 5602: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5603: start_value = cssRule;
1.82 cvs 5604: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5605: page.typed_data.value = PageAuto;
1.82 cvs 5606: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5607: {
1.184 vatton 5608: page.typed_data.unit = UNIT_REL;
5609: page.typed_data.value = PageAlways;
1.59 cvs 5610: }
1.82 cvs 5611: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5612: {
1.184 vatton 5613: page.typed_data.unit = UNIT_REL;
5614: page.typed_data.value = PageAvoid;
1.59 cvs 5615: }
1.82 cvs 5616: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5617: {
1.184 vatton 5618: page.typed_data.unit = UNIT_REL;
5619: page.typed_data.value = PageLeft;
1.59 cvs 5620: }
1.82 cvs 5621: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5622: {
1.184 vatton 5623: page.typed_data.unit = UNIT_REL;
5624: page.typed_data.value = PageRight;
1.59 cvs 5625: }
1.82 cvs 5626: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5627: {
1.293 quint 5628: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5629: page.typed_data.value = PageInherit;
1.59 cvs 5630: }
5631: cssRule = SkipWord (cssRule);
5632: /* install the new presentation */
1.366 vatton 5633: if ((page.typed_data.unit == UNIT_REL && page.typed_data.value == PageAlways)
5634: || page.typed_data.unit == VALUE_INHERIT)
5635: {
5636: if (DoDialog)
5637: DisplayStyleValue ("page-break-before", start_value, cssRule);
5638: else if (DoApply)
5639: TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
5640: }
1.59 cvs 5641: return (cssRule);
5642: }
5643:
5644: /*----------------------------------------------------------------------
1.327 vatton 5645: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 5646: ----------------------------------------------------------------------*/
1.79 cvs 5647: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.327 vatton 5648: PresentationContext ctxt,
5649: char *cssRule, CSSInfoPtr css,
5650: ThotBool isHTML)
1.59 cvs 5651: {
5652: PresentationValue page;
1.366 vatton 5653: char *start_value;
1.59 cvs 5654:
1.184 vatton 5655: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5656: page.typed_data.real = FALSE;
1.82 cvs 5657: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5658: start_value = cssRule;
1.82 cvs 5659: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 5660: page.typed_data.value = PageAuto;
1.82 cvs 5661: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 5662: {
1.184 vatton 5663: page.typed_data.unit = UNIT_REL;
5664: page.typed_data.value = PageAlways;
1.59 cvs 5665: }
1.82 cvs 5666: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5667: {
1.184 vatton 5668: page.typed_data.unit = UNIT_REL;
5669: page.typed_data.value = PageAvoid;
1.59 cvs 5670: }
1.82 cvs 5671: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 5672: {
1.184 vatton 5673: page.typed_data.unit = UNIT_REL;
5674: page.typed_data.value = PageLeft;
1.59 cvs 5675: }
1.82 cvs 5676: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 5677: {
1.184 vatton 5678: page.typed_data.unit = UNIT_REL;
5679: page.typed_data.value = PageRight;
1.59 cvs 5680: }
1.82 cvs 5681: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5682: {
1.293 quint 5683: page.typed_data.unit = VALUE_INHERIT;
1.184 vatton 5684: page.typed_data.value = PageInherit;
1.59 cvs 5685: }
5686: cssRule = SkipWord (cssRule);
5687: /* install the new presentation */
1.366 vatton 5688: if (page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT)
5689: {
5690: if (DoDialog)
5691: DisplayStyleValue ("page-break-after", start_value, cssRule);
1.367 cvs 5692: //else if (DoApply)
5693: // TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page);
1.366 vatton 5694: }
1.59 cvs 5695: return (cssRule);
5696: }
5697:
5698: /*----------------------------------------------------------------------
1.327 vatton 5699: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 5700: ----------------------------------------------------------------------*/
1.79 cvs 5701: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.327 vatton 5702: PresentationContext ctxt,
5703: char *cssRule, CSSInfoPtr css,
5704: ThotBool isHTML)
1.59 cvs 5705: {
5706: PresentationValue page;
1.366 vatton 5707: char *start_value;
1.59 cvs 5708:
1.184 vatton 5709: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 5710: page.typed_data.real = FALSE;
1.82 cvs 5711: cssRule = SkipBlanksAndComments (cssRule);
1.366 vatton 5712: start_value = cssRule;
1.82 cvs 5713: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 5714: {
1.184 vatton 5715: /*page.typed_data.unit = UNIT_REL;*/
5716: page.typed_data.value = PageAuto;
1.59 cvs 5717: }
1.82 cvs 5718: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 5719: {
1.184 vatton 5720: page.typed_data.unit = UNIT_REL;
5721: page.typed_data.value = PageAvoid;
1.59 cvs 5722: }
1.82 cvs 5723: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 5724: {
1.293 quint 5725: /* page.typed_data.unit = VALUE_INHERIT; */
1.184 vatton 5726: page.typed_data.value = PageInherit;
1.59 cvs 5727: }
5728: cssRule = SkipWord (cssRule);
5729: /* install the new presentation */
1.366 vatton 5730: if ((page.typed_data.unit == UNIT_REL || page.typed_data.unit == VALUE_INHERIT) &&
5731: page.typed_data.value == PageAvoid)
5732: {
5733: if (DoDialog)
5734: DisplayStyleValue ("page-break-inside", start_value, cssRule);
1.367 cvs 5735: //else if (DoApply)
5736: //TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);
1.366 vatton 5737: }
1.59 cvs 5738: return (cssRule);
5739: }
1.18 cvs 5740:
1.60 cvs 5741: /*----------------------------------------------------------------------
1.327 vatton 5742: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 5743: ----------------------------------------------------------------------*/
1.79 cvs 5744: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.327 vatton 5745: PresentationContext ctxt, char *cssRule,
5746: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 5747: {
5748: PresentationValue width;
5749:
1.82 cvs 5750: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 5751: width.typed_data.value = 0;
1.184 vatton 5752: width.typed_data.unit = UNIT_INVALID;
1.60 cvs 5753: width.typed_data.real = FALSE;
1.110 vatton 5754: if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 5755: {
1.327 vatton 5756: cssRule = ParseCSSUnit (cssRule, &width);
5757: if (width.typed_data.unit == UNIT_BOX)
5758: width.typed_data.unit = UNIT_PX;
1.166 vatton 5759: }
1.295 vatton 5760: else
5761: cssRule = SkipValue ("Invalid stroke-width value", cssRule);
5762:
1.184 vatton 5763: if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 5764: {
1.207 vatton 5765: TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117 vatton 5766: width.typed_data.value = 1;
1.184 vatton 5767: width.typed_data.unit = UNIT_REL;
1.117 vatton 5768: }
1.60 cvs 5769: return (cssRule);
5770: }
5771:
1.217 vatton 5772: /*----------------------------------------------------------------------
1.327 vatton 5773: ParseCSSPosition: parse a CSS Position attribute string.
1.217 vatton 5774: ----------------------------------------------------------------------*/
5775: static char *ParseCSSPosition (Element element, PSchema tsch,
1.327 vatton 5776: PresentationContext ctxt, char *cssRule,
5777: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5778: {
1.305 quint 5779: char *ptr;
5780: PresentationValue pval;
1.217 vatton 5781:
1.305 quint 5782: pval.typed_data.value = 0;
5783: pval.typed_data.unit = UNIT_BOX;
5784: pval.typed_data.real = FALSE;
1.217 vatton 5785: cssRule = SkipBlanksAndComments (cssRule);
5786: ptr = cssRule;
5787: if (!strncasecmp (cssRule, "static", 6))
1.337 vatton 5788: {
5789: pval.typed_data.value = PositionStatic;
5790: cssRule += 6;
5791: }
5792: else if (!strncasecmp (cssRule, "relative", 8))
5793: {
5794: pval.typed_data.value = PositionRelative;
5795: cssRule += 8;
5796: }
1.217 vatton 5797: else if (!strncasecmp (cssRule, "absolute", 8))
1.337 vatton 5798: {
5799: pval.typed_data.value = PositionAbsolute;
5800: cssRule += 8;
5801: }
1.217 vatton 5802: else if (!strncasecmp (cssRule, "fixed", 5))
1.337 vatton 5803: {
5804: pval.typed_data.value = PositionFixed;
5805: cssRule += 5;
5806: }
1.217 vatton 5807: else if (!strncasecmp (cssRule, "inherit", 7))
1.337 vatton 5808: {
5809: pval.typed_data.unit = VALUE_INHERIT;
5810: cssRule += 7;
5811: }
1.305 quint 5812:
5813: if (pval.typed_data.value == 0 && pval.typed_data.unit != VALUE_INHERIT)
5814: {
5815: cssRule = SkipValue ("Invalid position value", ptr);
5816: cssRule = SkipValue (NULL, cssRule);
5817: }
1.217 vatton 5818: else
1.305 quint 5819: {
1.337 vatton 5820: cssRule = SkipBlanksAndComments (cssRule);
5821: if (*cssRule != EOS && *cssRule != ';')
5822: SkipValue ("Invalid position value", ptr);
1.366 vatton 5823: else if (DoDialog)
5824: DisplayStyleValue ("position", ptr, cssRule);
1.337 vatton 5825: else if (DoApply)
1.327 vatton 5826: TtaSetStylePresentation (PRPosition, element, tsch, ctxt, pval);
1.305 quint 5827: }
1.217 vatton 5828: return (cssRule);
5829: }
5830:
5831: /*----------------------------------------------------------------------
1.327 vatton 5832: ParseCSSTop: parse a CSS Top attribute
1.217 vatton 5833: ----------------------------------------------------------------------*/
5834: static char *ParseCSSTop (Element element, PSchema tsch,
1.327 vatton 5835: PresentationContext context, char *cssRule,
5836: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5837: {
5838: PresentationValue val;
5839: char *ptr;
5840:
1.370 vatton 5841: val.typed_data.real = FALSE;
1.217 vatton 5842: cssRule = SkipBlanksAndComments (cssRule);
5843: ptr = cssRule;
1.305 quint 5844: /* first parse the value */
5845: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5846: {
5847: val.typed_data.unit = VALUE_AUTO;
5848: val.typed_data.value = 0;
5849: cssRule = SkipWord (cssRule);
5850: }
1.305 quint 5851: else if (!strncasecmp (cssRule, "inherit", 7))
5852: {
5853: val.typed_data.unit = VALUE_INHERIT;
5854: cssRule = SkipWord (cssRule);
5855: }
1.217 vatton 5856: else
5857: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5858:
5859: if (val.typed_data.unit == UNIT_INVALID ||
5860: (val.typed_data.value != 0 &&
1.217 vatton 5861: val.typed_data.unit == UNIT_BOX))
5862: {
1.387 quint 5863: cssRule = SkipValue ("Invalid top value", ptr);
5864: if (val.typed_data.unit == UNIT_BOX)
5865: val.typed_data.unit = UNIT_PX;
5866: else
5867: return (cssRule);
1.217 vatton 5868: }
1.366 vatton 5869: if (DoDialog)
1.387 quint 5870: DisplayStyleValue ("top", ptr, cssRule);
1.366 vatton 5871: else if (DoApply)
1.305 quint 5872: TtaSetStylePresentation (PRTop, element, tsch, context, val);
1.217 vatton 5873: return (cssRule);
5874: }
5875:
5876: /*----------------------------------------------------------------------
1.327 vatton 5877: ParseCSSRight: parse a CSS Right attribute
1.217 vatton 5878: ----------------------------------------------------------------------*/
5879: static char *ParseCSSRight (Element element, PSchema tsch,
1.327 vatton 5880: PresentationContext context, char *cssRule,
5881: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5882: {
5883: PresentationValue val;
5884: char *ptr;
5885:
1.370 vatton 5886: val.typed_data.real = FALSE;
1.217 vatton 5887: cssRule = SkipBlanksAndComments (cssRule);
5888: ptr = cssRule;
5889: /* first parse the attribute string */
1.305 quint 5890: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5891: {
5892: val.typed_data.unit = VALUE_AUTO;
5893: val.typed_data.value = 0;
5894: cssRule = SkipWord (cssRule);
5895: }
1.305 quint 5896: else if (!strncasecmp (cssRule, "inherit", 7))
5897: {
5898: val.typed_data.unit = VALUE_INHERIT;
5899: cssRule = SkipWord (cssRule);
5900: }
1.217 vatton 5901: else
5902: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5903:
5904: if (val.typed_data.unit == UNIT_INVALID ||
5905: (val.typed_data.value != 0 &&
1.217 vatton 5906: val.typed_data.unit == UNIT_BOX))
5907: {
1.387 quint 5908: cssRule = SkipValue ("Invalid right value", ptr);
5909: if (val.typed_data.unit == UNIT_BOX)
5910: val.typed_data.unit = UNIT_PX;
5911: else
5912: return (cssRule);
1.217 vatton 5913: }
1.366 vatton 5914: if (DoDialog)
5915: DisplayStyleValue ("right", ptr, cssRule);
5916: else if (DoApply)
1.305 quint 5917: TtaSetStylePresentation (PRRight, element, tsch, context, val);
1.217 vatton 5918: return (cssRule);
5919: }
5920:
5921: /*----------------------------------------------------------------------
1.327 vatton 5922: ParseCSSBottom: parse a CSS Bottom attribute
1.217 vatton 5923: ----------------------------------------------------------------------*/
5924: static char *ParseCSSBottom (Element element, PSchema tsch,
1.327 vatton 5925: PresentationContext context, char *cssRule,
5926: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5927: {
5928: PresentationValue val;
5929: char *ptr;
5930:
1.370 vatton 5931: val.typed_data.real = FALSE;
1.217 vatton 5932: cssRule = SkipBlanksAndComments (cssRule);
5933: ptr = cssRule;
5934: /* first parse the attribute string */
1.305 quint 5935: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5936: {
5937: val.typed_data.unit = VALUE_AUTO;
5938: val.typed_data.value = 0;
5939: cssRule = SkipWord (cssRule);
5940: }
1.305 quint 5941: else if (!strncasecmp (cssRule, "inherit", 7))
5942: {
5943: val.typed_data.unit = VALUE_INHERIT;
5944: cssRule = SkipWord (cssRule);
5945: }
1.217 vatton 5946: else
5947: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5948:
5949: if (val.typed_data.unit == UNIT_INVALID ||
5950: (val.typed_data.value != 0 &&
1.217 vatton 5951: val.typed_data.unit == UNIT_BOX))
5952: {
1.387 quint 5953: cssRule = SkipValue ("Invalid bottom value", ptr);
5954: if (val.typed_data.unit == UNIT_BOX)
5955: val.typed_data.unit = UNIT_PX;
5956: else
5957: return (cssRule);
1.217 vatton 5958: }
1.366 vatton 5959: if (DoDialog)
5960: DisplayStyleValue ("bottom", ptr, cssRule);
5961: else if (DoApply)
1.305 quint 5962: TtaSetStylePresentation (PRBottom, element, tsch, context, val);
1.217 vatton 5963: return (cssRule);
5964: }
5965:
5966: /*----------------------------------------------------------------------
1.327 vatton 5967: ParseCSSLeft: parse a CSS Left attribute
1.217 vatton 5968: ----------------------------------------------------------------------*/
5969: static char *ParseCSSLeft (Element element, PSchema tsch,
1.327 vatton 5970: PresentationContext context, char *cssRule,
5971: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 5972: {
5973: PresentationValue val;
5974: char *ptr;
5975:
1.370 vatton 5976: val.typed_data.real = FALSE;
1.217 vatton 5977: cssRule = SkipBlanksAndComments (cssRule);
5978: ptr = cssRule;
5979: /* first parse the attribute string */
1.305 quint 5980: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 5981: {
5982: val.typed_data.unit = VALUE_AUTO;
5983: val.typed_data.value = 0;
5984: cssRule = SkipWord (cssRule);
5985: }
1.305 quint 5986: else if (!strncasecmp (cssRule, "inherit", 7))
5987: {
5988: val.typed_data.unit = VALUE_INHERIT;
5989: cssRule = SkipWord (cssRule);
5990: }
1.217 vatton 5991: else
5992: cssRule = ParseCSSUnit (cssRule, &val);
1.387 quint 5993:
5994: if (val.typed_data.unit == UNIT_INVALID ||
5995: (val.typed_data.value != 0 &&
1.217 vatton 5996: val.typed_data.unit == UNIT_BOX))
5997: {
1.387 quint 5998: cssRule = SkipValue ("Invalid left value", ptr);
5999: if (val.typed_data.unit == UNIT_BOX)
6000: val.typed_data.unit = UNIT_PX;
6001: else
6002: return (cssRule);
1.217 vatton 6003: }
1.366 vatton 6004: if (DoDialog)
6005: DisplayStyleValue ("left", ptr, cssRule);
6006: else if (DoApply)
1.305 quint 6007: TtaSetStylePresentation (PRLeft, element, tsch, context, val);
1.217 vatton 6008: return (cssRule);
6009: }
6010:
6011: /*----------------------------------------------------------------------
1.327 vatton 6012: ParseCSSZIndex: parse a CSS z-index attribute
1.217 vatton 6013: ----------------------------------------------------------------------*/
6014: static char *ParseCSSZIndex (Element element, PSchema tsch,
1.327 vatton 6015: PresentationContext context, char *cssRule,
6016: CSSInfoPtr css, ThotBool isHTML)
1.217 vatton 6017: {
6018: PresentationValue val;
6019: char *ptr;
6020:
1.370 vatton 6021: val.typed_data.real = FALSE;
1.217 vatton 6022: cssRule = SkipBlanksAndComments (cssRule);
6023: ptr = cssRule;
6024: /* first parse the attribute string */
1.420 vatton 6025: if (!strncasecmp (cssRule, "auto", 4))
1.217 vatton 6026: {
6027: val.typed_data.unit = VALUE_AUTO;
6028: val.typed_data.value = 0;
6029: cssRule = SkipWord (cssRule);
6030: }
1.420 vatton 6031: else if (!strncasecmp (cssRule, "inherit", 7))
6032: {
6033: val.typed_data.unit = VALUE_INHERIT;
6034: val.typed_data.value = 0;
6035: cssRule = SkipWord (cssRule);
6036: }
1.217 vatton 6037: else
6038: {
6039: cssRule = ParseCSSUnit (cssRule, &val);
6040: if (val.typed_data.unit != UNIT_BOX)
1.327 vatton 6041: {
1.387 quint 6042: cssRule = SkipValue ("Invalid z-index value", ptr);
6043: return (cssRule);
1.327 vatton 6044: }
1.420 vatton 6045: val.typed_data.value = - val.typed_data.value;
1.217 vatton 6046: }
1.366 vatton 6047: if (DoDialog)
1.420 vatton 6048: DisplayStyleValue ("z-index", ptr, cssRule);
6049: else if (DoApply)
6050: TtaSetStylePresentation (PRDepth, element, tsch, context, val);
1.217 vatton 6051: return (cssRule);
6052: }
6053:
1.340 quint 6054: /*----------------------------------------------------------------------
6055: *
6056: * FUNCTIONS STYLE DECLARATIONS
6057: *
6058: *----------------------------------------------------------------------*/
1.18 cvs 6059: /*
1.59 cvs 6060: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 6061: * e.g. "FONT-SIZE" must be placed before "FONT"
6062: */
6063: static CSSProperty CSSProperties[] =
1.327 vatton 6064: {
6065: {"background-color", ParseCSSBackgroundColor},
6066: {"background-image", ParseCSSBackgroundImage},
6067: {"background-repeat", ParseCSSBackgroundRepeat},
6068: {"background-attachment", ParseCSSBackgroundAttachment},
6069: {"background-position", ParseCSSBackgroundPosition},
6070: {"background", ParseCSSBackground},
6071: {"border-top-width", ParseCSSBorderTopWidth},
6072: {"border-right-width", ParseCSSBorderRightWidth},
6073: {"border-bottom-width", ParseCSSBorderBottomWidth},
6074: {"border-left-width", ParseCSSBorderLeftWidth},
6075: {"border-width", ParseCSSBorderWidth},
6076: {"border-top-color", ParseCSSBorderColorTop},
6077: {"border-right-color", ParseCSSBorderColorRight},
6078: {"border-bottom-color", ParseCSSBorderColorBottom},
6079: {"border-left-color", ParseCSSBorderColorLeft},
6080: {"border-color", ParseCSSBorderColor},
6081: {"border-top-style", ParseCSSBorderStyleTop},
6082: {"border-right-style", ParseCSSBorderStyleRight},
6083: {"border-bottom-style", ParseCSSBorderStyleBottom},
6084: {"border-left-style", ParseCSSBorderStyleLeft},
6085: {"border-style", ParseCSSBorderStyle},
6086: {"border-top", ParseCSSBorderTop},
6087: {"border-right", ParseCSSBorderRight},
6088: {"border-bottom", ParseCSSBorderBottom},
6089: {"border-left", ParseCSSBorderLeft},
6090: {"border", ParseCSSBorder},
6091: {"bottom", ParseCSSBottom},
6092: {"clear", ParseCSSClear},
6093: {"color", ParseCSSForeground},
6094: {"content", ParseCSSContent},
6095: {"direction", ParseCSSDirection},
6096: {"display", ParseCSSDisplay},
6097: {"float", ParseCSSFloat},
6098: {"font-family", ParseCSSFontFamily},
6099: {"font-style", ParseCSSFontStyle},
6100: {"font-variant", ParseCSSFontVariant},
6101: {"font-weight", ParseCSSFontWeight},
6102: {"font-size-adjust", ParseCSSFontSizeAdjust},
6103: {"font-size", ParseCSSFontSize},
6104: {"font", ParseCSSFont},
1.382 vatton 6105: {"max-height", ParseCSSMaxHeight},
6106: {"min-height", ParseCSSMinHeight},
1.327 vatton 6107: {"height", ParseCSSHeight},
6108: {"left", ParseCSSLeft},
6109: {"letter-spacing", ParseCSSLetterSpacing},
6110: {"line-height", ParseCSSLineHeight},
6111: {"list-style-type", ParseCSSListStyleType},
6112: {"list-style-image", ParseCSSListStyleImage},
6113: {"list-style-position", ParseCSSListStylePosition},
6114: {"list-style", ParseCSSListStyle},
6115: {"margin-bottom", ParseCSSMarginBottom},
6116: {"margin-top", ParseCSSMarginTop},
6117: {"margin-right", ParseCSSMarginRight},
6118: {"margin-left", ParseCSSMarginLeft},
6119: {"margin", ParseCSSMargin},
1.418 quint 6120: {"opacity", ParseCSSOpacity},
1.327 vatton 6121: {"padding-top", ParseCSSPaddingTop},
6122: {"padding-right", ParseCSSPaddingRight},
6123: {"padding-bottom", ParseCSSPaddingBottom},
6124: {"padding-left", ParseCSSPaddingLeft},
6125: {"padding", ParseCSSPadding},
6126: {"page-break-before", ParseCSSPageBreakBefore},
6127: {"page-break-after", ParseCSSPageBreakAfter},
6128: {"page-break-inside", ParseCSSPageBreakInside},
6129: {"position", ParseCSSPosition},
6130: {"right", ParseCSSRight},
6131: {"text-align", ParseCSSTextAlign},
6132: {"text-anchor", ParseCSSTextAnchor},
6133: {"text-indent", ParseCSSTextIndent},
6134: {"text-decoration", ParseCSSTextDecoration},
6135: {"text-transform", ParseCSSTextTransform},
6136: {"top", ParseCSSTop},
6137: {"unicode-bidi", ParseCSSUnicodeBidi},
6138: {"vertical-align", ParseCSSVerticalAlign},
6139: {"white-space", ParseCSSWhiteSpace},
1.382 vatton 6140: {"max-width", ParseCSSMaxWidth},
6141: {"min-width", ParseCSSMinWidth},
1.327 vatton 6142: {"width", ParseCSSWidth},
1.333 vatton 6143: {"visibility", ParseCSSVisibility},
1.327 vatton 6144: {"word-spacing", ParseCSSWordSpacing},
6145: {"z-index", ParseCSSZIndex},
6146:
6147: /* SVG extensions */
6148: {"fill-opacity", ParseSVGFillOpacity},
1.420 vatton 6149: {"fill-rule", ParseSVGFillRule},
1.327 vatton 6150: {"fill", ParseSVGFill},
6151: {"opacity", ParseSVGOpacity},
6152: {"stroke-opacity", ParseSVGStrokeOpacity},
6153: {"stroke-width", ParseSVGStrokeWidth},
6154: {"stroke", ParseSVGStroke}
6155: };
1.155 cheyroul 6156:
1.18 cvs 6157: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
6158:
6159: /*----------------------------------------------------------------------
1.327 vatton 6160: ParseCSSRule: parse a CSS Style string
6161: we expect the input string describing the style to be of the form
6162: property: value [ ; property: value ]*
6163: but tolerate incorrect or incomplete input
1.18 cvs 6164: ----------------------------------------------------------------------*/
1.366 vatton 6165: void ParseCSSRule (Element element, PSchema tsch, PresentationContext ctxt,
6166: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 6167: {
1.366 vatton 6168: DisplayMode dispMode = DisplayImmediately;
1.312 quint 6169: char *p = NULL, *next, *end;
1.214 quint 6170: char *valueStart;
1.18 cvs 6171: int lg;
1.34 cvs 6172: unsigned int i;
1.76 cvs 6173: ThotBool found;
1.18 cvs 6174:
1.34 cvs 6175: /* avoid too many redisplay */
1.366 vatton 6176: if (!DoDialog && ctxt->doc)
6177: {
6178: dispMode = TtaGetDisplayMode (ctxt->doc);
6179: if (dispMode == DisplayImmediately)
6180: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
6181: }
1.34 cvs 6182:
1.82 cvs 6183: while (*cssRule != EOS)
1.18 cvs 6184: {
1.82 cvs 6185: cssRule = SkipBlanksAndComments (cssRule);
1.371 vatton 6186: if (*cssRule == ';' || *cssRule < 0x20 ||
1.372 vatton 6187: ((unsigned char)*cssRule) == 0xA0)
1.371 vatton 6188: cssRule++;
6189: else if (*cssRule < 0x41 || *cssRule > 0x7A ||
6190: (*cssRule > 0x5A && *cssRule < 0x61))
1.352 vatton 6191: {
6192: end = SkipProperty (cssRule, FALSE);
1.385 vatton 6193: if (cssRule[0] != '-')
6194: CSSParseError ("Invalid property", cssRule, end);
1.352 vatton 6195: cssRule = end;
6196: }
1.194 vatton 6197: else if (*cssRule != EOS)
1.327 vatton 6198: {
6199: found = FALSE;
6200: /* look for the type of property */
6201: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
6202: {
6203: lg = strlen (CSSProperties[i].name);
6204: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
6205: {
6206: p = cssRule + lg;
6207: found = TRUE;
6208: i--;
6209: }
6210: }
6211:
1.360 vatton 6212: // check if it's an important rule
6213: CheckImportantRule (cssRule, ctxt);
1.327 vatton 6214: if (i < NB_CSSSTYLEATTRIBUTE &&
6215: !strcasecmp (CSSProperties[i].name, "content") &&
6216: ((GenericContext)ctxt)->pseudo != PbBefore &&
6217: ((GenericContext)ctxt)->pseudo != PbAfter)
1.340 quint 6218: /* property content is allowed only for pseudo-elements :before and
6219: :after */
1.327 vatton 6220: {
1.352 vatton 6221: end = SkipProperty (cssRule, FALSE);
1.327 vatton 6222: CSSParseError ("content is allowed only for pseudo-elements",
6223: cssRule, end);
1.352 vatton 6224: cssRule = end;
1.327 vatton 6225: }
1.352 vatton 6226: else if (i == NB_CSSSTYLEATTRIBUTE)
1.376 vatton 6227: cssRule = SkipProperty (cssRule, !ctxt->destroy);
1.327 vatton 6228: else
6229: {
6230: /* update index and skip the ":" indicator if present */
6231: p = SkipBlanksAndComments (p);
6232: if (*p == ':')
6233: {
6234: p++;
6235: p = SkipBlanksAndComments (p);
6236: /* try to parse the value associated with this property */
6237: if (CSSProperties[i].parsing_function != NULL)
6238: {
6239: valueStart = p;
6240: p = CSSProperties[i].parsing_function (element, tsch,
6241: ctxt, p, css, isHTML);
6242: if (!element && isHTML)
6243: {
6244: if (ctxt->type == HTML_EL_Input)
6245: /* it's a generic rule for the HTML element input.
6246: Generate a Thot Pres rule for each kind of
6247: input element */
6248: {
6249: ctxt->type = HTML_EL_Text_Input;
6250: p = CSSProperties[i].parsing_function (element,
6251: tsch, ctxt, valueStart, css, isHTML);
6252: ctxt->type = HTML_EL_Password_Input;
6253: p = CSSProperties[i].parsing_function (element,
6254: tsch, ctxt, valueStart, css, isHTML);
6255: ctxt->type = HTML_EL_File_Input;
6256: p = CSSProperties[i].parsing_function (element,
6257: tsch, ctxt, valueStart, css, isHTML);
6258: ctxt->type = HTML_EL_Checkbox_Input;
6259: p = CSSProperties[i].parsing_function (element,
6260: tsch, ctxt, valueStart, css, isHTML);
6261: ctxt->type = HTML_EL_Radio_Input;
6262: p = CSSProperties[i].parsing_function (element,
6263: tsch, ctxt, valueStart, css, isHTML);
6264: ctxt->type = HTML_EL_Submit_Input;
6265: p = CSSProperties[i].parsing_function (element,
6266: tsch, ctxt, valueStart, css, isHTML);
6267: ctxt->type = HTML_EL_Reset_Input;
6268: p = CSSProperties[i].parsing_function (element,
6269: tsch, ctxt, valueStart, css, isHTML);
6270: ctxt->type = HTML_EL_Button_Input;
6271: p = CSSProperties[i].parsing_function (element,
6272: tsch, ctxt, valueStart, css, isHTML);
6273: ctxt->type = HTML_EL_Input;
6274: }
6275: else if (ctxt->type == HTML_EL_ruby)
6276: /* it's a generic rule for the HTML element ruby.
6277: Generate a Thot Pres rule for each kind of
6278: ruby element. */
6279: {
6280: ctxt->type = HTML_EL_simple_ruby;
6281: p = CSSProperties[i].parsing_function (element,
6282: tsch, ctxt, valueStart, css, isHTML);
6283: ctxt->type = HTML_EL_complex_ruby;
6284: p = CSSProperties[i].parsing_function (element,
6285: tsch, ctxt, valueStart, css, isHTML);
6286: ctxt->type = HTML_EL_ruby;
6287: }
6288: }
6289: /* update index and skip the ";" separator if present */
6290: next = SkipBlanksAndComments (p);
6291: if (*next != EOS && *next != ';')
6292: CSSParseError ("Missing closing ';'", cssRule, p);
6293: cssRule = next;
6294: }
6295: }
6296: else
6297: cssRule = SkipProperty (cssRule, TRUE);
6298: }
1.360 vatton 6299: // skip important markup
6300: cssRule = SkipImportantRule (cssRule);
6301:
1.327 vatton 6302: }
1.18 cvs 6303: /* next property */
1.82 cvs 6304: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 6305: if (*cssRule == '}')
1.327 vatton 6306: {
6307: cssRule++;
6308: CSSPrintError ("Invalid character", "}");
6309: cssRule = SkipBlanksAndComments (cssRule);
6310: }
1.155 cheyroul 6311: if (*cssRule == ',' ||
1.327 vatton 6312: *cssRule == ';')
6313: {
6314: cssRule++;
6315: cssRule = SkipBlanksAndComments (cssRule);
6316: }
1.18 cvs 6317: }
1.34 cvs 6318:
6319: /* restore the display mode */
1.366 vatton 6320: if (!DoDialog && ctxt->doc && dispMode == DisplayImmediately)
1.207 vatton 6321: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 6322: }
1.1 cvs 6323:
1.111 cvs 6324: /*----------------------------------------------------------------------
1.327 vatton 6325: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
6326: This function must be called when a specific style is applied to an
6327: element.
6328: The parameter specificity is the specificity of the style, 0 if it is
6329: not really a CSS rule.
1.1 cvs 6330: ----------------------------------------------------------------------*/
1.79 cvs 6331: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.377 quint 6332: int specificity, ThotBool destroy)
1.1 cvs 6333: {
1.257 vatton 6334: DisplayMode dispMode;
1.207 vatton 6335: PresentationContext ctxt;
6336: ElementType elType;
1.413 vatton 6337: char *buff, *ptr, *end;
1.207 vatton 6338: ThotBool isHTML;
1.1 cvs 6339:
1.207 vatton 6340: /* A rule applying to BODY is really meant to address HTML */
6341: elType = TtaGetElementType (el);
1.286 quint 6342: NewLineSkipped = 0;
1.207 vatton 6343: /* store the current line for eventually reported errors */
6344: LineNumber = TtaGetElementLineNumber (el);
6345: if (destroy)
6346: /* no reported errors */
6347: ParsedDoc = 0;
6348: else if (ParsedDoc != doc)
6349: {
6350: /* update the context for reported errors */
6351: ParsedDoc = doc;
1.348 vatton 6352: Error_DocURL = DocumentURLs[doc];
1.207 vatton 6353: }
6354: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
6355: /* create the context of the Specific presentation driver */
6356: ctxt = TtaGetSpecificStyleContext (doc);
6357: if (ctxt == NULL)
6358: return;
6359: ctxt->type = elType.ElTypeNum;
6360: ctxt->cssSpecificity = specificity;
1.236 quint 6361: ctxt->cssLine = LineNumber;
1.207 vatton 6362: ctxt->destroy = destroy;
6363: /* first use of the context */
6364: ctxt->uses = 1;
1.257 vatton 6365: /* save the current display mode */
6366: dispMode = TtaGetDisplayMode (doc);
1.207 vatton 6367: /* Call the parser */
1.366 vatton 6368: DoDialog = FALSE; // not parsing for CSS dialog
1.406 quint 6369: /* if it is a property applied to a COL or a COLGROUP element in a HTML table,
6370: associate the property to the corresponding Table_head or cell elements,
6371: depending on the property. */
1.413 vatton 6372: ptr = strstr (cssRule, "background-color");
6373: if (ptr && isHTML &&
1.406 quint 6374: (elType.ElTypeNum == HTML_EL_COL || elType.ElTypeNum == HTML_EL_COLGROUP))
1.413 vatton 6375: {
6376: end = strstr (ptr, ";");
6377: if (end)
6378: {
6379: buff = TtaStrdup (ptr);
6380: end = strstr (buff, ";");
6381: *end = EOS;
6382: ColApplyCSSRule (el, (PresentationContext) ctxt, buff, NULL);
6383: TtaFreeMemory (buff);
6384: }
6385: else
6386: ColApplyCSSRule (el, (PresentationContext) ctxt, ptr, NULL);
6387: }
1.406 quint 6388: else
6389: ParseCSSRule (el, NULL, ctxt, cssRule, NULL, isHTML);
6390:
1.257 vatton 6391: /* restore the display mode if necessary */
1.417 vatton 6392: if (dispMode != NoComputedDisplay)
6393: TtaSetDisplayMode (doc, dispMode);
1.207 vatton 6394: /* check if the context can be freed */
6395: ctxt->uses -= 1;
6396: if (ctxt->uses == 0)
6397: /* no image loading */
6398: TtaFreeMemory(ctxt);
1.1 cvs 6399: }
6400:
1.366 vatton 6401:
1.343 vatton 6402: /*----------------------------------------------------------------------
6403: AddClassName adds the class name into the class list of css if it's
6404: not already there.
6405: ----------------------------------------------------------------------*/
6406: static void AddClassName (char *name, CSSInfoPtr css)
6407: {
1.344 cvs 6408: int l, index, k, length, add;
1.343 vatton 6409: char *buf;
6410: ThotBool found, previous;
6411:
6412: l = strlen (name);
6413: if (l == 0 || css == NULL)
6414: return;
6415: if (css->class_list)
6416: {
6417: buf = css->class_list;
6418: length = strlen (css->class_list);
6419: }
6420: else
6421: {
6422: if (l > 200)
6423: length = l + 1;
6424: else
6425: length = 200;
6426: buf = (char *)TtaGetMemory (length * sizeof (char));
6427: memset (buf, 0, length);
6428: css->class_list = buf;
6429: css->lg_class_list = length;
6430: length = 0;
6431: }
6432:
6433: /* compare that name with all class names already known */
6434: index = 0;
6435: found = FALSE;
6436: previous = FALSE;
6437: while (index < length && !found && !previous)
6438: {
6439: k = 0;
6440: while (k < l && buf[index + k] != EOS && buf[index + k] != SPACE)
6441: {
6442: if (name[k] == buf[index+k])
6443: k++;
6444: else
6445: {
6446: previous = (name[k] < buf[index + k]);
6447: break;
6448: }
6449: }
6450: found = (k == l);
6451: if (!previous)
6452: {
6453: index += k;
6454: while (buf[index] != EOS && buf[index] != SPACE)
6455: index++;
6456: if (buf[index] == SPACE)
6457: index++;
6458: }
6459: }
6460:
6461: if (!found)
6462: /* this class name is not known, append it */
6463: {
6464: l++; /* add a space before */
6465: if (css->lg_class_list <= length + l)
6466: {
6467: // increase the list size
6468: if (l > 200)
6469: add = l + 1;
6470: else
6471: add = 200 ;
6472: buf = (char *)TtaRealloc (buf, css->lg_class_list + (add * sizeof (char)));
6473: if (buf == NULL)
6474: return;
6475: else
6476: {
6477: css->class_list = buf;
6478: memset (&buf[css->lg_class_list], 0, add);
6479: css->lg_class_list += add;
6480: }
6481: }
6482:
6483: if (previous)
6484: {
6485: // move the tail of the current list
6486: for (k = length; k >= index; k--)
6487: buf[k+l] = buf[k];
6488: /* add this new class name at the current position */
6489: strcpy (&buf[index], name);
6490: buf[index + l - 1] = SPACE;
6491: }
6492: else
6493: {
6494: /* add this new class name at the end */
6495: if (index != 0)
6496: buf[index++] = SPACE;
6497: strcpy (&buf[index], name);
6498: }
6499: }
6500: }
6501:
1.68 cvs 6502:
1.1 cvs 6503: /*----------------------------------------------------------------------
1.207 vatton 6504: ParseGenericSelector: Create a generic context for a given selector
6505: string.
6506: If the selector is made of multiple comma, it parses them one at a time
6507: and return the end of the selector string to be handled or NULL.
1.231 vatton 6508: The parameter ctxt gives the current style context which will be passed
6509: to Thotlib.
6510: The parameter css points to the current CSS context.
6511: The parameter link points to the link element.
6512: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 6513: ----------------------------------------------------------------------*/
1.207 vatton 6514: static char *ParseGenericSelector (char *selector, char *cssRule,
1.327 vatton 6515: GenericContext ctxt, Document doc,
6516: CSSInfoPtr css, Element link, char *url)
1.79 cvs 6517: {
6518: ElementType elType;
6519: PSchema tsch;
1.119 vatton 6520: AttributeType attrType;
1.398 vatton 6521: char *deb, *cur, *sel, *next, *limit, c;
1.317 vatton 6522: char *schemaName, *mappedName, *saveURL;
1.79 cvs 6523: char *names[MAX_ANCESTORS];
1.355 quint 6524: ThotBool pseudoFirstChild[MAX_ANCESTORS];
1.340 quint 6525: ElemRel rel[MAX_ANCESTORS];
6526: char *attrnames[MAX_ANCESTORS];
6527: int attrnums[MAX_ANCESTORS];
6528: int attrlevels[MAX_ANCESTORS];
1.79 cvs 6529: char *attrvals[MAX_ANCESTORS];
1.133 vatton 6530: AttrMatch attrmatch[MAX_ANCESTORS];
1.340 quint 6531: int nbnames, nbattrs;
6532: int i, j;
1.256 vatton 6533: int att, kind;
1.118 vatton 6534: int specificity, xmlType;
1.217 vatton 6535: int skippedNL;
1.404 vatton 6536: ThotBool isHTML, noname, warn;
1.347 quint 6537: ThotBool level, quoted, doubleColon;
1.340 quint 6538: #define ATTR_ID 1
6539: #define ATTR_CLASS 2
6540: #define ATTR_PSEUDO 3
1.1 cvs 6541:
1.404 vatton 6542: // check if Amaya should report CSS warnings
6543: TtaGetEnvBoolean ("CSS_WARN", &warn);
1.207 vatton 6544: sel = ctxt->sel;
1.82 cvs 6545: sel[0] = EOS;
1.398 vatton 6546: // get the limit of the string
6547: limit = &sel[MAX_ANCESTORS * 50 -1];
6548: *limit = EOS;
1.117 vatton 6549: specificity = 0;
1.1 cvs 6550: for (i = 0; i < MAX_ANCESTORS; i++)
6551: {
1.25 cvs 6552: names[i] = NULL;
1.355 quint 6553: pseudoFirstChild[i] = FALSE;
1.340 quint 6554: rel[i] = RelAncestor;
6555: attrnames[i] = NULL;
6556: attrnums[i] = 0;
6557: attrlevels[i] = 0;
1.25 cvs 6558: attrvals[i] = NULL;
1.133 vatton 6559: attrmatch[i] = Txtmatch;
1.25 cvs 6560: ctxt->name[i] = 0;
1.355 quint 6561: ctxt->firstChild[i] = FALSE;
1.25 cvs 6562: ctxt->attrType[i] = 0;
1.129 vatton 6563: ctxt->attrLevel[i] = 0;
1.25 cvs 6564: ctxt->attrText[i] = NULL;
1.178 quint 6565: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 6566: }
1.25 cvs 6567: ctxt->box = 0;
1.312 quint 6568: ctxt->var = 0;
1.306 quint 6569: ctxt->pseudo = PbNone;
1.25 cvs 6570: ctxt->type = 0;
1.366 vatton 6571: DoDialog = FALSE; // not arsing for CSS dialog
1.114 quint 6572: /* the specificity of the rule depends on the selector */
6573: ctxt->cssSpecificity = 0;
1.231 vatton 6574: /* localisation of the CSS rule */
6575: ctxt->cssLine = LineNumber + NewLineSkipped;
6576: ctxt->cssURL = url;
1.240 quint 6577:
1.286 quint 6578: skippedNL = NewLineSkipped;
1.82 cvs 6579: selector = SkipBlanksAndComments (selector);
1.286 quint 6580: NewLineSkipped = skippedNL;
1.27 cvs 6581: cur = &sel[0];
1.340 quint 6582: nbnames = 0;
6583: nbattrs = 0;
1.1 cvs 6584: while (1)
6585: {
1.85 cvs 6586: /* point to the following word in sel[] */
1.27 cvs 6587: deb = cur;
1.25 cvs 6588: /* copy an item of the selector into sel[] */
1.1 cvs 6589: /* put one word in the sel buffer */
1.82 cvs 6590: while (*selector != EOS && *selector != ',' &&
6591: *selector != '.' && *selector != ':' &&
1.118 vatton 6592: *selector != '#' && *selector != '[' &&
1.250 vatton 6593: *selector != '>' && *selector != '+' &&
1.398 vatton 6594: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6595: *cur++ = *selector++;
1.82 cvs 6596: *cur++ = EOS; /* close the first string in sel[] */
1.380 vatton 6597: noname = TRUE;
1.82 cvs 6598: if (deb[0] != EOS)
1.340 quint 6599: /* the selector starts with an element name */
1.327 vatton 6600: {
6601: if (deb[0] <= 64 && deb[0] != '*')
6602: {
6603: CSSPrintError ("Invalid element", deb);
1.380 vatton 6604: names[0] = NULL; /* no element name */
6605: DoApply = FALSE;
1.327 vatton 6606: }
6607: else
6608: {
1.380 vatton 6609: noname = FALSE;
1.327 vatton 6610: names[0] = deb;
6611: if (!strcmp (names[0], "html"))
6612: /* give a greater priority to the backgoud color of html */
6613: specificity += 3;
6614: else
6615: /* selector "*" has specificity zero */
6616: if (strcmp (names[0], "*"))
6617: specificity += 1;
6618: }
6619: }
1.25 cvs 6620: else
1.340 quint 6621: names[0] = NULL; /* no element name */
1.226 quint 6622:
1.340 quint 6623: rel[0] = RelVoid;
1.27 cvs 6624: /* now names[0] points to the beginning of the parsed item
1.340 quint 6625: and cur to the next string to be parsed */
1.129 vatton 6626: while (*selector == '.' || *selector == ':' ||
1.327 vatton 6627: *selector == '#' || *selector == '[')
6628: {
6629: /* point to the following word in sel[] */
6630: deb = cur;
6631: if (*selector == '.')
1.340 quint 6632: /* class */
1.327 vatton 6633: {
6634: selector++;
1.340 quint 6635: while (*selector != '.' && *selector != ':' &&
6636: *selector != '#' && *selector != '[' &&
6637: *selector != EOS && *selector != ',' &&
6638: *selector != '+' && *selector != '>' &&
1.398 vatton 6639: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6640: {
6641: if (*selector == '\\')
6642: {
6643: selector++;
6644: if (*selector != EOS)
6645: *cur++ = *selector++;
6646: }
6647: else
6648: *cur++ = *selector++;
6649: }
6650: /* close the word */
6651: *cur++ = EOS;
1.340 quint 6652: /* point to the class in sel[] if it's a valid name */
1.327 vatton 6653: if (deb[0] <= 64)
6654: {
6655: CSSPrintError ("Invalid class", deb);
6656: DoApply = FALSE;
6657: }
6658: else
6659: {
1.340 quint 6660: /* simulate selector [class ~= "xxx"] */
6661: nbattrs++;
6662: if (nbattrs == MAX_ANCESTORS)
6663: /* abort parsing */
6664: {
6665: CSSPrintError ("Selector too long", deb);
6666: return (selector);
6667: }
6668: for (i = nbattrs; i > 0; i--)
6669: {
6670: attrnames[i] = attrnames[i - 1];
6671: attrnums[i] = attrnums[i - 1];
6672: attrlevels[i] = attrlevels[i - 1];
6673: attrvals[i] = attrvals[i - 1];
6674: attrmatch[i] = attrmatch[i - 1];
6675: }
6676: attrnames[0] = NULL;
6677: attrnums[0] = ATTR_CLASS;
6678: attrlevels[0] = 0;
6679: attrmatch[0] = Txtword;
6680: attrvals[0] = deb;
1.327 vatton 6681: specificity += 10;
1.343 vatton 6682: }
1.327 vatton 6683: }
6684: else if (*selector == ':')
1.340 quint 6685: /* pseudo-class or pseudo-element */
1.327 vatton 6686: {
6687: selector++;
1.347 quint 6688: doubleColon = FALSE;
6689: if (*selector == ':')
6690: /* it's a double "::". Probably CSS3 syntax */
6691: {
6692: selector++;
6693: doubleColon = TRUE;
6694: }
1.340 quint 6695: while (*selector != '.' && *selector != ':' &&
6696: *selector != '#' && *selector != '[' &&
6697: *selector != EOS && *selector != ',' &&
6698: *selector != '+' && *selector != '>' &&
1.398 vatton 6699: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6700: *cur++ = *selector++;
6701: /* close the word */
6702: *cur++ = EOS;
1.340 quint 6703: /* point to the pseudo-class or pseudo-element in sel[] if it's
6704: a valid name */
1.355 quint 6705: if (!strcmp (deb, "first-child"))
6706: /* first-child pseudo-class */
1.327 vatton 6707: {
1.355 quint 6708: pseudoFirstChild[0] = TRUE;
6709: specificity += 10;
1.327 vatton 6710: }
1.355 quint 6711: else if (!strcmp (deb, "link") || !strcmp (deb, "visited"))
6712: /* link or visited pseudo-classes */
1.327 vatton 6713: {
1.355 quint 6714: nbattrs++;
6715: if (nbattrs == MAX_ANCESTORS)
6716: /* abort parsing */
1.347 quint 6717: {
1.355 quint 6718: CSSPrintError ("Selector too long", deb);
6719: return (selector);
1.347 quint 6720: }
1.355 quint 6721: for (i = nbattrs; i > 0; i--)
1.347 quint 6722: {
1.355 quint 6723: attrnames[i] = attrnames[i - 1];
6724: attrnums[i] = attrnums[i - 1];
6725: attrlevels[i] = attrlevels[i - 1];
6726: attrvals[i] = attrvals[i - 1];
6727: attrmatch[i] = attrmatch[i - 1];
1.347 quint 6728: }
1.355 quint 6729: attrnames[0] = NULL;
6730: attrnums[0] = ATTR_PSEUDO;
6731: attrlevels[0] = 0;
6732: attrmatch[0] = Txtmatch;
6733: attrvals[0] = deb;
6734: specificity += 10;
6735: }
6736: else if (!strcmp (deb, "hover") || !strcmp (deb, "active") ||
6737: !strcmp (deb, "focus"))
6738: /* hover, active, focus pseudo-classes */
6739: {
1.403 vatton 6740: attrnames[0] = NULL;
6741: attrnums[0] = ATTR_PSEUDO;
6742: attrlevels[0] = 0;
6743: attrmatch[0] = Txtmatch;
6744: attrvals[0] = deb;
1.355 quint 6745: specificity += 10;
6746: /* not supported */
6747: DoApply = FALSE;
6748: }
6749: else if (!strncmp (deb, "lang", 4))
6750: /* it's the lang pseudo-class */
6751: {
6752: if (deb[4] != '(' || deb[strlen(deb)-1] != ')')
6753: /* at least one parenthesis is missing. Error */
1.327 vatton 6754: {
1.355 quint 6755: CSSPrintError ("Invalid :lang pseudo-class", deb);
6756: DoApply = FALSE;
1.327 vatton 6757: }
6758: else
1.355 quint 6759: /* simulate selector [lang|="xxx"] */
1.340 quint 6760: {
6761: nbattrs++;
6762: if (nbattrs == MAX_ANCESTORS)
6763: /* abort parsing */
6764: {
6765: CSSPrintError ("Selector too long", deb);
6766: return (selector);
6767: }
1.355 quint 6768: deb[strlen(deb)-1] = EOS;
6769: deb[4] = EOS;
1.340 quint 6770: for (i = nbattrs; i > 0; i--)
6771: {
6772: attrnames[i] = attrnames[i - 1];
6773: attrnums[i] = attrnums[i - 1];
6774: attrlevels[i] = attrlevels[i - 1];
6775: attrvals[i] = attrvals[i - 1];
6776: attrmatch[i] = attrmatch[i - 1];
6777: }
1.355 quint 6778: attrnames[0] = deb;
6779: attrnums[0] = 0;
1.340 quint 6780: attrlevels[0] = 0;
1.355 quint 6781: attrmatch[0] = Txtsubstring;
6782: attrvals[0] = &deb[5];
6783: specificity += 10;
1.340 quint 6784: }
1.327 vatton 6785: }
1.355 quint 6786: else if (!strcmp (deb, "first-line") ||
6787: !strcmp (deb, "first-letter"))
6788: /* pseudo-elements first-line or first-letter */
6789: {
1.404 vatton 6790: if (doubleColon && warn)
1.355 quint 6791: CSSPrintError ("Warning: \"::\" is CSS3 syntax", NULL);
6792: specificity += 1;
6793: /* not supported */
6794: DoApply = FALSE;
6795: }
6796: else if (!strncmp (deb, "before", 6))
6797: /* pseudo-element before */
6798: {
1.404 vatton 6799: if (doubleColon && warn)
1.355 quint 6800: CSSPrintError ("Warning: \"::before\" is CSS3 syntax",
6801: NULL);
6802: ctxt->pseudo = PbBefore;
6803: specificity += 1;
6804: }
6805: else if (!strncmp (deb, "after", 5))
6806: /* pseudo-element after */
6807: {
1.404 vatton 6808: if (doubleColon && warn)
1.355 quint 6809: CSSPrintError ("Warning: \"::after\" is CSS3 syntax",
6810: NULL);
6811: ctxt->pseudo = PbAfter;
6812: specificity += 1;
6813: }
1.404 vatton 6814: else if (!strncmp (deb, "target", 6))
6815: {
6816: if (warn)
6817: CSSPrintError ("Warning: \":target\" is CSS3 syntax",
6818: NULL);
6819: specificity += 1;
6820: DoApply = FALSE;
6821: }
6822: else
1.355 quint 6823: {
6824: CSSPrintError ("Invalid pseudo-element", deb);
6825: DoApply = FALSE;
6826: }
6827: if (names[0] && !strcmp (names[0], "*"))
6828: names[0] = NULL;
1.327 vatton 6829: }
6830: else if (*selector == '#')
1.340 quint 6831: /* unique identifier */
1.327 vatton 6832: {
6833: selector++;
1.340 quint 6834: while (*selector != '.' && *selector != ':' &&
6835: *selector != '#' && *selector != '[' &&
6836: *selector != '+' && *selector != '>' &&
6837: *selector != EOS && *selector != ',' &&
1.398 vatton 6838: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6839: *cur++ = *selector++;
6840: /* close the word */
6841: *cur++ = EOS;
6842: /* point to the attribute in sel[] if it's valid name */
6843: if (deb[0] <= 64)
6844: {
6845: CSSPrintError ("Invalid id", deb);
6846: DoApply = FALSE;
6847: }
6848: else
6849: {
1.340 quint 6850: nbattrs++;
6851: if (nbattrs == MAX_ANCESTORS)
6852: /* abort parsing */
6853: {
6854: CSSPrintError ("Selector too long", deb);
6855: return (selector);
6856: }
6857: for (i = nbattrs; i > 0; i--)
6858: {
6859: attrnames[i] = attrnames[i - 1];
6860: attrnums[i] = attrnums[i - 1];
6861: attrlevels[i] = attrlevels[i - 1];
6862: attrvals[i] = attrvals[i - 1];
6863: attrmatch[i] = attrmatch[i - 1];
6864: }
6865: attrnames[0] = NULL;
6866: attrnums[0] = ATTR_ID;
6867: attrlevels[0] = 0;
6868: attrmatch[0] = Txtmatch;
6869: attrvals[0] = deb;
6870: specificity += 100;
6871: if (names[0] && !strcmp (names[0], "*"))
6872: names[0] = NULL;
1.327 vatton 6873: }
6874: }
6875: else if (*selector == '[')
6876: {
6877: selector++;
1.341 quint 6878: selector = SkipBlanksAndComments (selector);
1.327 vatton 6879: while (*selector != EOS && *selector != ']' &&
6880: *selector != '=' && *selector != '~' &&
1.341 quint 6881: *selector != '|' && *selector != '^' &&
1.396 vatton 6882: *selector != '$' && *selector != '*' &&
1.398 vatton 6883: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 6884: *cur++ = *selector++;
1.341 quint 6885: /* close the word (attribute name) */
1.327 vatton 6886: *cur++ = EOS;
6887: /* point to the attribute in sel[] if it's valid name */
6888: if (deb[0] <= 64)
6889: {
6890: CSSPrintError ("Invalid attribute", deb);
6891: DoApply = FALSE;
6892: }
6893: else
6894: {
1.340 quint 6895: nbattrs++;
6896: if (nbattrs == MAX_ANCESTORS)
6897: /* abort parsing */
6898: {
6899: CSSPrintError ("Selector too long", deb);
6900: return (selector);
6901: }
6902: for (i = nbattrs; i > 0; i--)
6903: {
6904: attrnames[i] = attrnames[i - 1];
6905: attrnums[i] = attrnums[i - 1];
6906: attrlevels[i] = attrlevels[i - 1];
6907: attrvals[i] = attrvals[i - 1];
6908: attrmatch[i] = attrmatch[i - 1];
6909: }
6910: attrnames[0] = deb;
6911: attrnums[0] = 0;
6912: attrlevels[0] = 0;
1.378 quint 6913: attrvals[0] = NULL;
6914: attrmatch[0] = Txtmatch;
1.327 vatton 6915: specificity += 10;
1.340 quint 6916: /* check matching */
1.341 quint 6917: selector = SkipBlanksAndComments (selector);
1.340 quint 6918: if (*selector == '~')
6919: {
6920: attrmatch[0] = Txtword;
6921: selector++;
6922: }
1.396 vatton 6923: else if (*selector == '|' || *selector == '$' || *selector == '*')
1.340 quint 6924: {
1.404 vatton 6925: if (*selector == '$' && warn)
1.396 vatton 6926: CSSPrintError ("Warning: \"$=\" is CSS3 syntax", NULL);
1.404 vatton 6927: if (*selector == '*' && warn)
1.396 vatton 6928: CSSPrintError ("Warning: \"*=\" is CSS3 syntax", NULL);
1.340 quint 6929: attrmatch[0] = Txtsubstring;
6930: selector++;
6931: }
1.341 quint 6932: else if (*selector == '^')
6933: {
6934: attrmatch[0] = Txtsubstring;
6935: selector++;
6936: }
1.340 quint 6937: else
6938: attrmatch[0] = Txtmatch;
1.327 vatton 6939: }
6940: if (*selector == '=')
6941: {
6942: /* look for a value "xxxx" */
6943: selector++;
1.341 quint 6944: selector = SkipBlanksAndComments (selector);
1.327 vatton 6945: if (*selector != '"')
6946: quoted = FALSE;
6947: else
6948: {
6949: quoted = TRUE;
6950: /* we are now parsing the attribute value */
6951: selector++;
6952: }
6953: deb = cur;
1.398 vatton 6954: while ((quoted && cur < limit &&
1.327 vatton 6955: (*selector != '"' ||
6956: (*selector == '"' && selector[-1] == '\\'))) ||
6957: (!quoted && *selector != ']'))
6958: {
6959: if (*selector == EOS)
6960: {
6961: CSSPrintError ("Invalid attribute value", deb);
6962: DoApply = FALSE;
6963: }
6964: else
6965: {
6966: if (attrmatch[0] == Txtword && TtaIsBlank (selector))
6967: {
6968: CSSPrintError ("No space allowed here: ", selector);
6969: DoApply = FALSE;
6970: }
6971: *cur++ = *selector;
6972: }
6973: selector++;
6974: }
6975: /* there is a value */
6976: if (quoted && *selector == '"')
6977: {
6978: selector++;
6979: quoted = FALSE;
6980: }
1.341 quint 6981: selector = SkipBlanksAndComments (selector);
1.327 vatton 6982: if (*selector != ']')
6983: {
6984: CSSPrintError ("Invalid attribute value", deb);
6985: DoApply = FALSE;
6986: }
6987: else
6988: {
6989: *cur++ = EOS;
6990: attrvals[0] = deb;
6991: selector++;
6992: }
6993: }
6994: /* end of the attribute */
6995: else if (*selector != ']')
6996: {
6997: selector[1] = EOS;
6998: CSSPrintError ("Invalid attribute", selector);
6999: selector += 2;
7000: DoApply = FALSE;
7001: }
7002: else
7003: {
7004: selector++;
7005: if (names[0] && !strcmp (names[0], "*"))
7006: names[0] = NULL;
7007: }
7008: }
7009: else
7010: {
7011: /* not supported selector */
1.340 quint 7012: while (*selector != '.' && *selector != ':' &&
7013: *selector != '#' && *selector != '[' &&
7014: *selector != EOS && *selector != ',' &&
7015: *selector != '+' && *selector != '>' &&
1.398 vatton 7016: !TtaIsBlank (selector) && cur < limit)
1.327 vatton 7017: *cur++ = *selector++;
7018: /* close the word */
7019: *cur++ = EOS;
7020: CSSPrintError ("Selector not supported:", deb);
7021: DoApply = FALSE;
7022: }
7023: }
1.1 cvs 7024:
1.286 quint 7025: skippedNL = NewLineSkipped;
1.82 cvs 7026: selector = SkipBlanksAndComments (selector);
1.286 quint 7027: NewLineSkipped = skippedNL;
7028:
1.380 vatton 7029: if (noname && !pseudoFirstChild[0] && attrnums[0] == 0 && attrnames[0] == NULL)
7030: {
7031: *cur++ = EOS;
7032: CSSPrintError ("Invalid Selector", deb);
7033: DoApply = FALSE;
7034: }
1.25 cvs 7035: /* is it a multi-level selector? */
1.82 cvs 7036: if (*selector == EOS)
1.327 vatton 7037: /* end of the selector */
7038: break;
1.82 cvs 7039: else if (*selector == ',')
1.327 vatton 7040: {
7041: /* end of the current selector */
7042: selector++;
7043: skippedNL = NewLineSkipped;
7044: next = SkipBlanksAndComments (selector);
7045: NewLineSkipped = skippedNL;
7046: if (*next == EOS)
7047: /* nothing after the comma. Invalid selector */
7048: {
1.380 vatton 7049: CSSPrintError ("Syntax error:", selector);
7050: selector = NULL;
1.327 vatton 7051: }
7052: break;
7053: }
1.25 cvs 7054: else
1.327 vatton 7055: {
7056: if (*selector == '>')
7057: {
1.340 quint 7058: /* handle parent */
1.327 vatton 7059: selector++;
7060: skippedNL = NewLineSkipped;
7061: selector = SkipBlanksAndComments (selector);
7062: NewLineSkipped = skippedNL;
1.340 quint 7063: rel[0] = RelParent;
1.327 vatton 7064: }
7065: else if (*selector == '+')
7066: {
1.340 quint 7067: /* handle immediate sibling */
1.327 vatton 7068: selector++;
7069: skippedNL = NewLineSkipped;
7070: selector = SkipBlanksAndComments (selector);
7071: NewLineSkipped = skippedNL;
7072: rel[0] = RelPrevious;
7073: }
1.340 quint 7074: else
7075: rel[0] = RelAncestor;
7076: nbnames++; /* a new level in ancestor tables */
7077: if (nbnames == MAX_ANCESTORS)
7078: /* abort parsing */
7079: {
7080: CSSPrintError ("Selector too long", deb);
7081: return (selector);
7082: }
7083: /* shift the list to make room for the next part of the selector */
7084: for (i = nbnames; i > 0; i--)
1.327 vatton 7085: {
7086: names[i] = names[i - 1];
1.355 quint 7087: pseudoFirstChild[i] = pseudoFirstChild[i - 1];
1.327 vatton 7088: rel[i] = rel[i - 1];
7089: }
1.340 quint 7090: /* increase the level of all attributes */
7091: for (i = 0; i < nbattrs; i++)
7092: attrlevels[i]++;
1.327 vatton 7093: }
1.1 cvs 7094: }
7095:
1.343 vatton 7096: /* Now update the list of classes defined by the CSS */
7097: for (i = 0; i < nbattrs; i++)
7098: if (attrvals[i] && attrnums[i] == ATTR_CLASS)
7099: AddClassName (attrvals[i], css);
7100:
1.1 cvs 7101: /* Now set up the context block */
1.25 cvs 7102: i = 0;
7103: j = 0;
1.91 cvs 7104: /* default schema name */
1.119 vatton 7105: ctxt->schema = NULL;
1.340 quint 7106: ctxt->nbElem = nbnames;
1.122 vatton 7107: elType.ElSSchema = NULL;
1.355 quint 7108: elType.ElTypeNum = 0;
1.122 vatton 7109: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 7110: if (!strcmp (schemaName, "HTML"))
7111: xmlType = XHTML_TYPE;
7112: else if (!strcmp (schemaName, "MathML"))
7113: xmlType = MATH_TYPE;
7114: else if (!strcmp (schemaName, "SVG"))
7115: xmlType = SVG_TYPE;
7116: else if (!strcmp (schemaName, "XLink"))
7117: xmlType = XLINK_TYPE;
7118: else if (!strcmp (schemaName, "Annot"))
7119: xmlType = ANNOT_TYPE;
7120: else
7121: xmlType = XML_TYPE;
1.340 quint 7122: while (i <= nbnames)
1.25 cvs 7123: {
1.340 quint 7124: ctxt->rel[i] = rel[i];
1.355 quint 7125: ctxt->firstChild[i] = pseudoFirstChild[i];
7126: if (!names[i] && i > 0)
1.340 quint 7127: ctxt->name[i] = HTML_EL_ANY_TYPE;
7128: else
7129: /* store element information */
1.327 vatton 7130: {
7131: /* get the element type of this name in the current document */
7132: if (xmlType == XML_TYPE)
7133: /* it's a generic XML document. Check the main document schema */
7134: {
7135: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7136: elType.ElTypeNum = 0;
7137: if (names[i])
7138: TtaGetXmlElementType (names[i], &elType, &mappedName, doc);
1.327 vatton 7139: if (!elType.ElTypeNum)
7140: {
1.355 quint 7141: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 7142: elType.ElTypeNum = HTML_EL_ANY_TYPE;
7143: else
7144: elType.ElSSchema = NULL;
7145: }
7146: }
7147: else
7148: {
1.355 quint 7149: if (!names[i] || !strcmp (names[i], "*"))
1.327 vatton 7150: {
7151: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7152: elType.ElTypeNum = HTML_EL_ANY_TYPE;
7153: }
7154: else
7155: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c,
7156: &level, doc);
7157: }
7158: if (i == 0)
1.340 quint 7159: /* rightmost part of the selector */
1.327 vatton 7160: {
7161: if (elType.ElSSchema == NULL)
7162: {
1.340 quint 7163: /* element name not found. Search in all loaded schemas */
1.355 quint 7164: if (names[i])
7165: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.327 vatton 7166: if (elType.ElSSchema)
7167: {
7168: /* the element type concerns an imported nature */
7169: schemaName = TtaGetSSchemaName(elType.ElSSchema);
7170: if (!strcmp (schemaName, "HTML"))
7171: {
7172: if (xmlType == XHTML_TYPE &&
7173: DocumentMeta[doc] && DocumentMeta[doc]->xmlformat)
7174: /* the selector was found but the case is not correct */
7175: elType.ElSSchema = NULL;
7176: else
7177: xmlType = XHTML_TYPE;
7178: }
7179: else if (!strcmp (schemaName, "MathML"))
7180: xmlType = MATH_TYPE;
7181: else if (!strcmp (schemaName, "SVG"))
7182: xmlType = SVG_TYPE;
7183: else if (!strcmp (schemaName, "XLink"))
7184: xmlType = XLINK_TYPE;
7185: else if (!strcmp (schemaName, "Annot"))
7186: xmlType = ANNOT_TYPE;
7187: else
7188: xmlType = XML_TYPE;
7189: }
1.118 vatton 7190: #ifdef XML_GENERIC
1.327 vatton 7191: else if (xmlType == XML_TYPE)
7192: {
7193: /* Creation of a new element type in the main schema */
7194: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.355 quint 7195: if (names[i])
7196: TtaAppendXmlElement (names[i], &elType, &mappedName,
7197: doc);
1.327 vatton 7198: }
1.118 vatton 7199: #endif /* XML_GENERIC */
1.327 vatton 7200: else
7201: {
7202: if (xmlType != XHTML_TYPE)
7203: {
7204: MapXMLElementType (XHTML_TYPE, names[i], &elType,
7205: &mappedName, &c, &level, doc);
7206: if (elType.ElSSchema)
7207: elType.ElSSchema = GetXHTMLSSchema (doc);
7208: }
7209: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
7210: {
7211: MapXMLElementType (MATH_TYPE, names[i], &elType,
7212: &mappedName, &c, &level, doc);
7213: if (elType.ElSSchema)
7214: elType.ElSSchema = GetMathMLSSchema (doc);
7215: }
7216: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
7217: {
7218: MapXMLElementType (SVG_TYPE, names[i], &elType,
7219: &mappedName, &c, &level, doc);
7220: if (elType.ElSSchema)
7221: elType.ElSSchema = GetSVGSSchema (doc);
7222: }
7223: }
7224: }
7225:
7226: if (elType.ElSSchema == NULL)
7227: /* cannot apply these CSS rules */
7228: DoApply = FALSE;
7229: else
7230: {
1.340 quint 7231: /* Store the element type contained in the rightmost part of
7232: the selector */
7233: ctxt->schema = elType.ElSSchema;
1.327 vatton 7234: ctxt->type = elType.ElTypeNum;
7235: ctxt->name[0] = elType.ElTypeNum;
1.340 quint 7236: ctxt->rel[0] = RelVoid;
1.327 vatton 7237: }
7238: }
1.340 quint 7239: else
7240: /* not the rightmost part of the selector */
1.327 vatton 7241: {
1.340 quint 7242: if (elType.ElTypeNum != 0)
7243: ctxt->name[i] = elType.ElTypeNum;
7244: #ifdef XML_GENERIC
7245: else if (xmlType == XML_TYPE)
1.327 vatton 7246: {
1.340 quint 7247: TtaGetXmlElementType (names[i], &elType, NULL, doc);
7248: if (elType.ElTypeNum == 0)
1.327 vatton 7249: {
1.340 quint 7250: /* Creation of a new element type in the main schema */
7251: elType.ElSSchema = TtaGetDocumentSSchema (doc);
7252: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.327 vatton 7253: }
1.340 quint 7254: if (elType.ElTypeNum != 0)
7255: ctxt->name[i] = elType.ElTypeNum;
1.327 vatton 7256: }
1.340 quint 7257: #endif /* XML_GENERIC */
1.327 vatton 7258: }
1.340 quint 7259: }
7260:
7261: /* store attribute information for this element */
7262: while (j < nbattrs && attrlevels[j] <= i)
7263: {
7264: if (attrnames[j] || attrnums[j])
1.327 vatton 7265: {
1.340 quint 7266: if (attrnums[j] > 0)
1.327 vatton 7267: {
1.340 quint 7268: if (attrnums[j] == ATTR_CLASS)
1.327 vatton 7269: {
1.340 quint 7270: if (xmlType == SVG_TYPE)
7271: ctxt->attrType[j] = SVG_ATTR_class;
7272: else if (xmlType == MATH_TYPE)
7273: ctxt->attrType[j] = MathML_ATTR_class;
7274: else if (xmlType == XHTML_TYPE)
7275: ctxt->attrType[j] = HTML_ATTR_Class;
1.327 vatton 7276: else
1.119 vatton 7277: #ifdef XML_GENERIC
1.340 quint 7278: ctxt->attrType[j] = XML_ATTR_class;
1.107 cvs 7279: #else /* XML_GENERIC */
1.340 quint 7280: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 7281: #endif /* XML_GENERIC */
1.340 quint 7282: }
7283: else if (attrnums[j] == ATTR_PSEUDO)
7284: {
7285: if (xmlType == SVG_TYPE)
7286: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
7287: else if (xmlType == MATH_TYPE)
7288: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
7289: else if (xmlType == XHTML_TYPE)
7290: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
7291: else
1.119 vatton 7292: #ifdef XML_GENERIC
1.340 quint 7293: ctxt->attrType[j] = XML_ATTR_PseudoClass;
1.107 cvs 7294: #else /* XML_GENERIC */
1.340 quint 7295: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 7296: #endif /* XML_GENERIC */
1.340 quint 7297: }
7298: else if (attrnums[j] == ATTR_ID)
7299: {
7300: if (xmlType == SVG_TYPE)
7301: ctxt->attrType[j] = SVG_ATTR_id;
7302: else if (xmlType == MATH_TYPE)
7303: ctxt->attrType[j] = MathML_ATTR_id;
7304: else if (xmlType == XHTML_TYPE)
7305: ctxt->attrType[j] = HTML_ATTR_ID;
7306: else
1.119 vatton 7307: #ifdef XML_GENERIC
1.340 quint 7308: ctxt->attrType[j] = XML_ATTR_xmlid;
1.107 cvs 7309: #else /* XML_GENERIC */
1.340 quint 7310: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 7311: #endif /* XML_GENERIC */
1.340 quint 7312: }
7313: attrType.AttrTypeNum = ctxt->attrType[j];
7314: attrType.AttrSSchema = ctxt->schema;
7315: }
7316: else if (attrnames[j])
7317: {
7318: if (xmlType == XML_TYPE)
7319: {
7320: if (ctxt->schema)
7321: attrType.AttrSSchema = ctxt->schema;
7322: else
7323: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7324: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7325: att = attrType.AttrTypeNum;
7326: if (ctxt->schema == NULL && att != 0)
7327: ctxt->schema = attrType.AttrSSchema;
7328: }
7329: else
7330: {
7331: MapXMLAttribute (xmlType, attrnames[j], names[i], &level,
7332: doc, &att);
7333: if (ctxt->schema == NULL && att != 0)
7334: ctxt->schema = TtaGetDocumentSSchema (doc);
7335: }
1.393 quint 7336: if (att == 0 && xmlType != XML_TYPE)
1.340 quint 7337: /* Attribute name not found: Search in the list of all
7338: schemas loaded for this document */
7339: {
7340: attrType.AttrSSchema = NULL;
7341: TtaGetXmlAttributeType (attrnames[j], &attrType, doc);
7342: att = attrType.AttrTypeNum;
7343: if (att != 0)
1.393 quint 7344: {
7345: ctxt->schema = attrType.AttrSSchema;
7346: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
7347: }
1.340 quint 7348: }
7349: attrType.AttrSSchema = ctxt->schema;
7350: attrType.AttrTypeNum = att;
1.412 vatton 7351: if ((i == 0 || xmlType == XML_TYPE) && att == 0)
1.340 quint 7352: {
1.119 vatton 7353: #ifdef XML_GENERIC
1.393 quint 7354: if (xmlType == XML_TYPE)
1.340 quint 7355: {
7356: /* The attribute is not yet present in the tree */
7357: /* Create a new global attribute */
7358: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
7359: TtaAppendXmlAttribute (attrnames[j], &attrType, doc);
1.393 quint 7360: att = attrType.AttrTypeNum;
1.340 quint 7361: }
7362: #endif /* XML_GENERIC */
7363: if (attrType.AttrSSchema == NULL)
7364: /* cannot apply these CSS rules */
7365: DoApply = FALSE;
7366: else if (elType.ElSSchema)
7367: ctxt->schema = elType.ElSSchema;
7368: else
7369: ctxt->schema = attrType.AttrSSchema;
7370: }
7371: if (att == 0)
7372: {
7373: CSSPrintError ("Unknown attribute", attrnames[j]);
7374: DoApply = FALSE;
7375: }
7376: else
1.345 quint 7377: {
7378: ctxt->attrType[j] = att;
7379: if (att == DummyAttribute && !strcmp (schemaName,"HTML"))
7380: /* it's the "type" attribute for an "input" element.
7381: In the tree, it is represented by the element type,
7382: not by an attribute */
7383: {
7384: ctxt->attrType[j] = 0;
7385: if (attrvals[j] && attrmatch[i] == Txtmatch)
7386: /* a value is specified for attribute type. This
7387: value provides the Thot element type */
7388: {
7389: MapXMLAttributeValue (xmlType, attrvals[j],
7390: &attrType, &kind);
7391: /* attrType contains the element type */
7392: if (i == 0)
7393: ctxt->type = kind;
7394: ctxt->name[i] = kind;
7395: }
7396: }
7397: }
1.340 quint 7398: }
7399: if (ctxt->attrType[j])
1.327 vatton 7400: {
1.340 quint 7401: /* check the attribute type */
7402: if (!strcmp (schemaName, "HTML"))
7403: xmlType = XHTML_TYPE;
7404: else if (!strcmp (schemaName, "MathML"))
7405: xmlType = MATH_TYPE;
7406: else if (!strcmp (schemaName, "SVG"))
7407: xmlType = SVG_TYPE;
7408: else if (!strcmp (schemaName, "XLink"))
7409: xmlType = XLINK_TYPE;
7410: else if (!strcmp (schemaName, "Annot"))
7411: xmlType = ANNOT_TYPE;
7412: else
7413: xmlType = XML_TYPE;
7414: kind = TtaGetAttributeKind (attrType);
7415: if (kind == 0 && attrvals[j])
7416: {
7417: /* enumerated value */
7418: MapXMLAttributeValue (xmlType, attrvals[j], &attrType,
7419: &kind);
7420: /* store the attribute value */
7421: ctxt->attrText[j] = (char *) kind;
7422: }
7423: else
7424: ctxt->attrText[j] = attrvals[j];
7425: /* update attrLevel */
7426: ctxt->attrMatch[j] = attrmatch[j];
7427: ctxt->attrLevel[j] = attrlevels[j];
7428: }
7429: j++;
1.327 vatton 7430: }
7431: }
1.340 quint 7432: /* add a new entry */
1.25 cvs 7433: i++;
1.119 vatton 7434: if (i == 1 && ctxt->schema == NULL)
1.327 vatton 7435: /* use the document schema */
7436: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 7437: }
1.340 quint 7438:
1.312 quint 7439: ctxt->important = FALSE;
1.117 vatton 7440: /* set the selector specificity */
7441: ctxt->cssSpecificity = specificity;
1.25 cvs 7442: /* Get the schema name of the main element */
1.119 vatton 7443: schemaName = TtaGetSSchemaName (ctxt->schema);
7444: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 7445: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.217 vatton 7446: skippedNL = NewLineSkipped;
1.380 vatton 7447: if (DoApply && tsch && cssRule)
1.317 vatton 7448: {
7449: if (css)
1.327 vatton 7450: {
7451: /* point the right URL for loaded images */
7452: saveURL = css->url;
7453: css->url = url;
7454: }
1.317 vatton 7455: else
1.327 vatton 7456: saveURL = NULL;
7457: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.317 vatton 7458: if (css)
1.327 vatton 7459: /* restore previous url */
7460: css->url = saveURL;
1.317 vatton 7461: }
1.116 vatton 7462: /* future CSS rules should apply */
7463: DoApply = TRUE;
1.217 vatton 7464: if (selector)
7465: NewLineSkipped = skippedNL;
1.1 cvs 7466: return (selector);
7467: }
7468:
7469: /*----------------------------------------------------------------------
1.206 vatton 7470: ParseStyleDeclaration: parse a style declaration stored in the style
7471: element of a document
7472: We expect the style string to be of the form:
7473: .pinky, .awful { color: pink; font-family: helvetica }
1.231 vatton 7474: The parameter css points to the current CSS context.
7475: The parameter link points to the link element.
7476: The parameter url gives the URL of the parsed style sheet.
1.1 cvs 7477: ----------------------------------------------------------------------*/
1.206 vatton 7478: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
1.327 vatton 7479: CSSInfoPtr css, Element link, char *url,
7480: ThotBool destroy)
1.1 cvs 7481: {
1.79 cvs 7482: GenericContext ctxt;
7483: char *decl_end;
7484: char *sel_end;
7485: char *selector;
1.1 cvs 7486:
7487: /* separate the selectors string */
1.82 cvs 7488: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 7489: decl_end = cssRule;
1.82 cvs 7490: while (*decl_end != EOS && *decl_end != '{')
1.286 quint 7491: {
7492: if (*decl_end == EOL)
1.327 vatton 7493: NewLineSkipped++;
1.286 quint 7494: decl_end++;
7495: }
1.82 cvs 7496: if (*decl_end == EOS)
1.86 cvs 7497: {
1.168 vatton 7498: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 7499: return;
7500: }
1.1 cvs 7501: /* verify and clean the selector string */
7502: sel_end = decl_end - 1;
1.82 cvs 7503: while (*sel_end == SPACE || *sel_end == BSPACE ||
1.411 vatton 7504: *sel_end == EOL || *sel_end == __CR__)
1.1 cvs 7505: sel_end--;
7506: sel_end++;
1.82 cvs 7507: *sel_end = EOS;
1.1 cvs 7508: selector = cssRule;
7509:
7510: /* now, deal with the content ... */
7511: decl_end++;
7512: cssRule = decl_end;
1.137 vatton 7513: decl_end = &cssRule[strlen (cssRule) - 1];
1.398 vatton 7514: if (*decl_end != '{' && *decl_end != EOS)
1.137 vatton 7515: *decl_end = EOS;
1.1 cvs 7516: /*
7517: * parse the style attribute string and install the corresponding
7518: * presentation attributes on the new element
7519: */
7520: ctxt = TtaGetGenericStyleContext (doc);
7521: if (ctxt == NULL)
7522: return;
7523: ctxt->destroy = destroy;
1.207 vatton 7524: /* first use of the context */
7525: ctxt->uses = 1;
1.197 vatton 7526: while (selector && *selector != EOS)
1.363 vatton 7527: {
7528: if (ctxt->uses > 1)
7529: {
7530: /* this context is waiting for a callback */
7531: ctxt = TtaGetGenericStyleContext (doc);
7532: if (ctxt == NULL)
7533: return;
7534: ctxt->destroy = destroy;
7535: /* first use of the context */
7536: ctxt->uses = 1;
7537: }
7538: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css,
7539: link, url);
7540: }
1.207 vatton 7541: /* check if the context can be freed */
7542: ctxt->uses -= 1;
7543: if (ctxt->uses == 0)
7544: /* no image loading */
7545: TtaFreeMemory (ctxt);
1.1 cvs 7546: }
7547:
7548: /************************************************************************
7549: * *
7550: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
7551: * *
7552: ************************************************************************/
7553:
7554: /*----------------------------------------------------------------------
1.327 vatton 7555: IsImplicitClassName: return wether the Class name is an
7556: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
7557: or an HTML context name.
1.1 cvs 7558: ----------------------------------------------------------------------*/
1.248 gully 7559: int IsImplicitClassName (char *class_, Document doc)
1.1 cvs 7560: {
1.327 vatton 7561: char name[200];
7562: char *cur = name;
7563: char *first;
7564: char save;
7565: SSchema schema;
7566:
7567: /* make a local copy */
7568: strncpy (name, class_, 199);
7569: name[199] = 0;
7570:
7571: /* loop looking if each word is a GI */
7572: while (*cur != 0)
7573: {
7574: first = cur;
7575: cur = SkipWord (cur);
7576: save = *cur;
7577: *cur = 0;
7578: schema = NULL;
7579: if (MapGI (first, &schema, doc) == -1)
7580: {
7581: return (0);
7582: }
7583: *cur = save;
7584: cur = SkipBlanksAndComments (cur);
7585: }
7586: return (1);
1.1 cvs 7587: }
7588:
7589: /************************************************************************
1.114 quint 7590: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 7591: ************************************************************************/
7592:
7593: /*----------------------------------------------------------------------
1.409 vatton 7594: SetBodyAbsolutePosition:
7595: ----------------------------------------------------------------------*/
7596: void SetBodyAbsolutePosition (Document doc)
7597: {
7598: Element root, body;
7599: ElementType elType;
7600:
7601: if (DocumentTypes[doc] != docHTML)
7602: return;
7603: root = TtaGetMainRoot (doc);
7604: elType = TtaGetElementType(root);
7605: elType.ElTypeNum = HTML_EL_BODY;
7606: body = TtaSearchTypedElement (elType, SearchInTree, root);
7607: if (body)
1.410 vatton 7608: ParseHTMLSpecificStyle (body, (char *)"position:absolute", doc, 200, FALSE);
1.409 vatton 7609: }
7610:
7611: /*----------------------------------------------------------------------
1.327 vatton 7612: HTMLSetBackgroundColor:
1.1 cvs 7613: ----------------------------------------------------------------------*/
1.264 vatton 7614: void HTMLSetBackgroundColor (Document doc, Element el, int specificity,
1.327 vatton 7615: char *color)
1.1 cvs 7616: {
1.350 vatton 7617: char css_command[1000];
1.1 cvs 7618:
1.416 vatton 7619: snprintf (css_command, 1000, "background-color: %50s", color);
1.327 vatton 7620: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7621: }
7622:
7623: /*----------------------------------------------------------------------
1.327 vatton 7624: HTMLSetForegroundColor:
1.1 cvs 7625: ----------------------------------------------------------------------*/
1.264 vatton 7626: void HTMLSetForegroundColor (Document doc, Element el, int specificity,
1.327 vatton 7627: char *color)
1.1 cvs 7628: {
1.350 vatton 7629: char css_command[1000];
1.1 cvs 7630:
1.416 vatton 7631: snprintf (css_command, 1000, "color: %50s", color);
1.327 vatton 7632: ParseHTMLSpecificStyle (el, css_command, doc, specificity, FALSE);
1.1 cvs 7633: }
7634:
7635: /*----------------------------------------------------------------------
1.327 vatton 7636: HTMLResetBackgroundColor:
1.1 cvs 7637: ----------------------------------------------------------------------*/
1.97 vatton 7638: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 7639: {
1.350 vatton 7640: char css_command[1000];
1.1 cvs 7641:
1.327 vatton 7642: sprintf (css_command, "background: red");
7643: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7644: }
7645:
7646: /*----------------------------------------------------------------------
1.327 vatton 7647: HTMLResetBackgroundImage:
1.1 cvs 7648: ----------------------------------------------------------------------*/
1.97 vatton 7649: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 7650: {
1.327 vatton 7651: char css_command[1000];
1.1 cvs 7652:
1.416 vatton 7653: snprintf (css_command, 1000, "background-image: url(xx); background-repeat: repeat");
1.327 vatton 7654: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7655: }
7656:
7657: /*----------------------------------------------------------------------
1.327 vatton 7658: HTMLResetForegroundColor:
1.1 cvs 7659: ----------------------------------------------------------------------*/
1.97 vatton 7660: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 7661: {
1.350 vatton 7662: char css_command[1000];
1.1 cvs 7663:
1.327 vatton 7664: /* it's not necessary to well know the current color but it must be valid */
7665: sprintf (css_command, "color: red");
7666: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 7667: }
7668:
7669: /*----------------------------------------------------------------------
1.327 vatton 7670: HTMLSetAlinkColor:
1.1 cvs 7671: ----------------------------------------------------------------------*/
1.208 vatton 7672: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 7673: {
1.350 vatton 7674: char css_command[1000];
1.1 cvs 7675:
1.416 vatton 7676: snprintf (css_command, 1000, ":link { color: %50s }", color);
1.327 vatton 7677: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7678: }
7679:
7680: /*----------------------------------------------------------------------
1.327 vatton 7681: HTMLSetAactiveColor:
1.1 cvs 7682: ----------------------------------------------------------------------*/
1.208 vatton 7683: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 7684: {
1.350 vatton 7685: char css_command[1000];
1.1 cvs 7686:
1.416 vatton 7687: snprintf (css_command, 1000, ":active { color: %50s }", color);
1.327 vatton 7688: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7689: }
7690:
7691: /*----------------------------------------------------------------------
1.327 vatton 7692: HTMLSetAvisitedColor:
1.1 cvs 7693: ----------------------------------------------------------------------*/
1.208 vatton 7694: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 7695: {
1.350 vatton 7696: char css_command[1000];
1.1 cvs 7697:
1.416 vatton 7698: snprintf (css_command, 1000, ":visited { color: %50s }", color);
1.327 vatton 7699: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 7700: }
7701:
7702: /*----------------------------------------------------------------------
1.327 vatton 7703: HTMLResetAlinkColor:
1.1 cvs 7704: ----------------------------------------------------------------------*/
1.208 vatton 7705: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 7706: {
1.350 vatton 7707: char css_command[1000];
1.1 cvs 7708:
1.327 vatton 7709: sprintf (css_command, ":link { color: red }");
7710: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7711: }
7712:
7713: /*----------------------------------------------------------------------
1.327 vatton 7714: HTMLResetAactiveColor:
1.1 cvs 7715: ----------------------------------------------------------------------*/
1.208 vatton 7716: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 7717: {
1.350 vatton 7718: char css_command[1000];
1.1 cvs 7719:
1.327 vatton 7720: sprintf (css_command, ":active { color: red }");
7721: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7722: }
7723:
7724: /*----------------------------------------------------------------------
1.327 vatton 7725: HTMLResetAvisitedColor:
1.1 cvs 7726: ----------------------------------------------------------------------*/
1.208 vatton 7727: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 7728: {
1.350 vatton 7729: char css_command[1000];
1.1 cvs 7730:
1.327 vatton 7731: sprintf (css_command, ":visited { color: red }");
7732: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 7733: }
7734:
7735: /*----------------------------------------------------------------------
1.206 vatton 7736: ApplyCSSRules: parse a CSS Style description stored in the header of
7737: a HTML document.
1.1 cvs 7738: ----------------------------------------------------------------------*/
1.79 cvs 7739: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 7740: {
1.206 vatton 7741: CSSInfoPtr css;
7742: PInfoPtr pInfo;
1.207 vatton 7743: ThotBool loadcss;
7744:
7745: /* check if we have to load CSS */
7746: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
7747: if (!loadcss)
7748: return;
1.376 vatton 7749: LineNumber = TtaGetElementLineNumber (el);
1.206 vatton 7750: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 7751: if (css == NULL)
1.209 vatton 7752: {
7753: /* create the document css context */
7754: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
7755: pInfo = css->infos[doc];
7756: }
1.206 vatton 7757: else if (pInfo == NULL)
7758: /* create the entry into the css context */
7759: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 7760: if (pInfo->PiEnabled)
1.376 vatton 7761: ParseStyleDeclaration (el, cssRule, doc, css, el, NULL, destroy);
7762: LineNumber = -1;
1.1 cvs 7763: }
7764:
7765: /*----------------------------------------------------------------------
1.327 vatton 7766: ReadCSSRules: is the front-end function called by the document parser
7767: when detecting a <style type="text/css"> indicating it's the
7768: beginning of a CSS fragment or when reading a file .css.
1.1 cvs 7769:
1.327 vatton 7770: The CSS parser has to handle <!-- ... --> constructs used to
7771: prevent prehistoric browser from displaying the CSS as a text
7772: content. It will stop on any sequence "<x" where x is different
7773: from ! and will return x as to the caller. Theorically x should
7774: be equal to / for the </style> end of style.
7775: The parameter doc gives the document tree that contains CSS information.
7776: The parameter docRef gives the document to which CSS are to be applied.
7777: This function uses the current css context or creates it. It's able
7778: to work on the given buffer or call GetNextChar to read the parsed
7779: file.
7780: The parameter url gives the URL of the parsed style sheet.
7781: The parameter numberOfLinesRead gives the number of lines already
7782: read in the file.
7783: The parameter withUndo indicates whether the changes made in the document
7784: structure and content have to be registered in the Undo queue or not.
1.1 cvs 7785: ----------------------------------------------------------------------*/
1.133 vatton 7786: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.343 vatton 7787: int numberOfLinesRead, ThotBool withUndo, Element link)
1.1 cvs 7788: {
1.6 cvs 7789: DisplayMode dispMode;
1.206 vatton 7790: CSSInfoPtr refcss = NULL;
1.321 vatton 7791: CSSmedia css_media = CSS_ALL;
1.206 vatton 7792: PInfoPtr pInfo;
1.321 vatton 7793: char c;
1.138 vatton 7794: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 7795: int index;
1.1 cvs 7796: int CSSindex;
1.327 vatton 7797: int CSScomment;
1.1 cvs 7798: int import;
1.358 quint 7799: int openBlock;
1.93 vatton 7800: int newlines;
1.358 quint 7801: int page;
1.14 cvs 7802: ThotBool HTMLcomment;
1.342 vatton 7803: ThotBool toParse, eof, quoted, s_quoted;
1.358 quint 7804: ThotBool ignore, media, lineComment;
1.234 vatton 7805: ThotBool noRule, ignoreImport, fontface;
1.1 cvs 7806:
1.327 vatton 7807: CSScomment = MAX_CSS_LENGTH;
1.1 cvs 7808: HTMLcomment = FALSE;
7809: CSSindex = 0;
7810: toParse = FALSE;
7811: noRule = FALSE;
1.234 vatton 7812: media = FALSE;
1.88 cvs 7813: ignoreImport = FALSE;
1.342 vatton 7814: ignore = lineComment = FALSE;
1.358 quint 7815: page = 0;
1.342 vatton 7816: quoted = s_quoted = FALSE;
1.234 vatton 7817: fontface = FALSE;
1.1 cvs 7818: eof = FALSE;
1.358 quint 7819: openBlock = 0;
1.234 vatton 7820: import = MAX_CSS_LENGTH;
1.82 cvs 7821: c = SPACE;
1.1 cvs 7822: index = 0;
1.134 vatton 7823: base = NULL;
1.310 vatton 7824: /* entering the CSS parsing */
1.311 vatton 7825: Style_parsing++;
1.93 vatton 7826: /* number of new lines parsed */
7827: newlines = 0;
1.6 cvs 7828: /* avoid too many redisplay */
7829: dispMode = TtaGetDisplayMode (docRef);
7830: if (dispMode == DisplayImmediately)
7831: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 7832:
7833: /* look for the CSS context */
7834: if (css == NULL)
1.206 vatton 7835: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 7836: else
7837: pInfo = css->infos[docRef];
1.18 cvs 7838: if (css == NULL)
1.206 vatton 7839: {
7840: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
7841: pInfo = css->infos[docRef];
7842: }
7843: else if (pInfo == NULL)
7844: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 7845: /* look for the CSS descriptor that points to the extension schema */
7846: refcss = css;
1.224 vatton 7847: if (pInfo && pInfo->PiCategory == CSS_IMPORT)
1.173 cvs 7848: {
1.206 vatton 7849: while (refcss &&
1.327 vatton 7850: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
7851: refcss = refcss->NextCSS;
1.206 vatton 7852: if (refcss)
1.327 vatton 7853: pInfo = refcss->infos[docRef];
1.173 cvs 7854: }
7855:
1.343 vatton 7856: /* register parsed CSS file and the document to which CSS are to be applied */
1.395 vatton 7857: if (DocumentMeta[docRef] == NULL || DocumentMeta[docRef]->method != CE_MAKEBOOK)
7858: ParsedDoc = docRef;
7859: else
7860: ParsedDoc = 0;
1.343 vatton 7861: /* clean up the list of classes */
7862: TtaFreeMemory (refcss->class_list);
7863: refcss->class_list = NULL;
1.133 vatton 7864: if (url)
1.348 vatton 7865: Error_DocURL = url;
1.86 cvs 7866: else
7867: /* the CSS source in within the document itself */
1.348 vatton 7868: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 7869: LineNumber = numberOfLinesRead + 1;
1.93 vatton 7870: NewLineSkipped = 0;
1.217 vatton 7871: newlines = 0;
1.392 carcone 7872:
7873: /* Search for an UTF-8 BOM character (EF BB BF) */
7874: if (index == 0 && strlen(buffer) > 2 &&
7875: (unsigned char) buffer[0] == 0xEF &&
7876: (unsigned char) buffer[1] == 0xBB &&
7877: (unsigned char) buffer[2] == 0xBF)
7878: {
7879: index = 3;
7880: }
7881:
7882: /* Search for an UTF-16 Big Endian BOM character (FE FF) */
7883: if (index == 0 && strlen(buffer) > 1 &&
7884: (unsigned char) buffer[0] == 0xFE &&
7885: (unsigned char) buffer[1] == 0xFF)
7886: {
7887: index = 2;
7888: }
7889:
7890: /* Search for an UTF-16 Little Endian BOM character (FF FE) */
7891: if (index == 0 && strlen(buffer) > 1 &&
7892: (unsigned char) buffer[0] == 0xFF &&
7893: (unsigned char) buffer[1] == 0xFE)
7894: {
7895: index = 2;
7896: }
7897:
1.82 cvs 7898: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
7899: {
7900: c = buffer[index++];
7901: eof = (c == EOS);
7902: CSSbuffer[CSSindex] = c;
1.342 vatton 7903: if (!lineComment &&
7904: (CSScomment == MAX_CSS_LENGTH || c == '*' || c == '/' || c == '<' || c == EOL))
1.327 vatton 7905: {
7906: /* we're not within a comment or we're parsing * or / */
7907: switch (c)
7908: {
7909: case '@': /* perhaps an import primitive */
1.342 vatton 7910: if (!fontface && !page && !quoted && !s_quoted)
1.327 vatton 7911: import = CSSindex;
7912: break;
7913: case ';':
1.342 vatton 7914: if (!quoted && !s_quoted && !media && import != MAX_CSS_LENGTH)
1.327 vatton 7915: {
7916: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
7917: /* it's not an import */
7918: import = MAX_CSS_LENGTH;
7919: /* save the text */
7920: noRule = TRUE;
7921: }
7922: break;
7923: case '*':
1.342 vatton 7924: if (!quoted && !s_quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.327 vatton 7925: CSSbuffer[CSSindex - 1] == '/')
7926: /* start a comment */
7927: CSScomment = CSSindex - 1;
7928: break;
7929: case '/':
1.342 vatton 7930: if (!quoted && !s_quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.399 vatton 7931: CSSbuffer[CSSindex - 1] == '*' && CSSindex != CSScomment + 2)
1.327 vatton 7932: {
7933: while (CSSindex > 0 && CSSindex >= CSScomment)
7934: {
7935: if ( CSSbuffer[CSSindex] == EOL)
7936: {
7937: LineNumber ++;
7938: newlines --;
7939: }
7940: CSSindex--;
7941: }
7942: CSSindex = CSScomment - 1; /* will be incremented later */
7943: CSScomment = MAX_CSS_LENGTH;
7944: /* clean up the buffer */
7945: if (newlines && CSSindex > 0)
7946: while (CSSindex > 0 &&
7947: (CSSbuffer[CSSindex] == SPACE ||
7948: CSSbuffer[CSSindex] == BSPACE ||
7949: CSSbuffer[CSSindex] == EOL ||
7950: CSSbuffer[CSSindex] == TAB ||
7951: CSSbuffer[CSSindex] == __CR__))
7952: {
7953: if ( CSSbuffer[CSSindex] == EOL)
7954: {
7955: LineNumber ++;
7956: newlines --;
7957: }
7958: CSSindex--;
7959: }
7960: }
1.342 vatton 7961: else if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7962: CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
7963: CSSbuffer[CSSindex - 1] == '<')
7964: {
7965: /* this is the closing tag ! */
7966: CSSindex -= 2; /* remove </ from the CSS string */
7967: noRule = TRUE;
1.342 vatton 7968: }
7969: else if (!quoted && !s_quoted &&
7970: (CSSindex == 1 || (CSSindex > 1 && CSSbuffer[CSSindex - 2] == EOL)) &&
7971: CSScomment == MAX_CSS_LENGTH &&
7972: CSSbuffer[CSSindex - 1] == '/')
7973: {
7974: CSSindex--;
7975: lineComment = TRUE;
7976: }
7977:
1.327 vatton 7978: break;
7979: case '<':
1.342 vatton 7980: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7981: CSScomment == MAX_CSS_LENGTH)
7982: {
7983: /* only if we're not parsing a comment */
7984: c = buffer[index++];
7985: eof = (c == EOS);
7986: if (c == '!')
7987: {
7988: /* CSS within an HTML comment */
7989: HTMLcomment = TRUE;
7990: CSSindex++;
7991: CSSbuffer[CSSindex] = c;
7992: }
7993: else if (c == EOS)
7994: CSSindex++;
7995: }
7996: break;
7997: case '-':
1.342 vatton 7998: if (!fontface && !page && !quoted && !s_quoted &&
1.327 vatton 7999: CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
8000: HTMLcomment)
8001: /* CSS within an HTML comment */
8002: noRule = TRUE;
8003: break;
8004: case '>':
1.342 vatton 8005: if (!fontface && !page && !quoted && !s_quoted && HTMLcomment)
1.327 vatton 8006: noRule = TRUE;
8007: break;
8008: case ' ':
1.358 quint 8009: if (!quoted && !s_quoted && import != MAX_CSS_LENGTH && openBlock == 0)
1.327 vatton 8010: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
8011: break;
8012: case '{':
1.342 vatton 8013: if (!quoted && !s_quoted)
1.327 vatton 8014: {
1.358 quint 8015: openBlock++;
1.327 vatton 8016: if (import != MAX_CSS_LENGTH)
8017: {
1.358 quint 8018: if (openBlock == 1 && media)
1.327 vatton 8019: {
8020: /* is it the screen concerned? */
8021: CSSbuffer[CSSindex+1] = EOS;
8022: css_media = CheckMediaCSS (&CSSbuffer[import+7]);
8023: if (TtaIsPrinting ())
8024: ignore = (css_media != CSS_ALL && css_media != CSS_PRINT);
8025: else
8026: ignore = (css_media != CSS_ALL && css_media != CSS_SCREEN);
8027: noRule = TRUE;
8028: }
8029: else if (!strncasecmp (&CSSbuffer[import+1], "page", 4))
1.358 quint 8030: /* it is a @page block */
1.327 vatton 8031: {
1.358 quint 8032: page = openBlock;/*remember the level of this block*/
1.327 vatton 8033: noRule = TRUE;
8034: }
8035: else if (!strncasecmp (&CSSbuffer[import+1], "font-face", 9))
8036: {
8037: fontface = TRUE;
8038: noRule = TRUE;
8039: }
8040: }
8041: }
8042: break;
8043: case '}':
1.342 vatton 8044: if (!quoted && !s_quoted)
1.327 vatton 8045: {
1.358 quint 8046: if (page == openBlock)
8047: /* closing the @page block */
1.327 vatton 8048: {
8049: noRule = TRUE;
1.358 quint 8050: page = 0; /* close the page section */
1.327 vatton 8051: }
8052: else if (fontface)
8053: {
8054: noRule = TRUE;
8055: fontface = FALSE; /* close the fontface section */
8056: }
1.358 quint 8057: else if (openBlock == 1 && import != MAX_CSS_LENGTH)
1.327 vatton 8058: {
8059: import = MAX_CSS_LENGTH;
8060: noRule = TRUE;
8061: ignore = FALSE;
8062: media = FALSE;
8063: }
1.358 quint 8064: else if (!page)
1.327 vatton 8065: toParse = TRUE;
1.358 quint 8066: openBlock--;
1.327 vatton 8067: }
8068: break;
8069: case '"':
8070: if (quoted)
8071: {
1.342 vatton 8072: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
1.327 vatton 8073: quoted = FALSE;
8074: }
1.342 vatton 8075: else if (!s_quoted)
1.327 vatton 8076: quoted = TRUE;
8077: break;
1.342 vatton 8078: case '\'':
8079: if (s_quoted)
8080: {
8081: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] != '\\')
8082: s_quoted = FALSE;
8083: }
8084: else if (!quoted)
8085: s_quoted = TRUE;
8086: break;
8087: default:
1.327 vatton 8088: if (c == EOL)
8089: {
8090: newlines++;
8091: }
8092: break;
8093: }
1.82 cvs 8094: }
1.93 vatton 8095: else if (c == EOL)
1.327 vatton 8096: {
8097: LineNumber++;
1.342 vatton 8098: lineComment = FALSE;
1.411 vatton 8099: c = __CR__;
1.327 vatton 8100: }
1.234 vatton 8101:
1.411 vatton 8102: if (!lineComment && c != __CR__)
1.327 vatton 8103: CSSindex++;
1.82 cvs 8104:
8105: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
1.327 vatton 8106: /* we're still parsing a comment: remove the text comment */
8107: CSSindex = CSScomment;
1.82 cvs 8108:
8109: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
1.327 vatton 8110: {
8111: CSSbuffer[CSSindex] = EOS;
8112: /* parse a not empty string */
8113: if (CSSindex > 0)
8114: {
1.50 cvs 8115: /* apply CSS rule if it's not just a saving of text */
1.234 vatton 8116: if (!noRule && !ignore)
1.327 vatton 8117: {
8118: /* future import rules must be ignored */
8119: ignoreImport = TRUE;
8120: NewLineSkipped = 0;
8121: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
8122: pInfo->PiLink, url, FALSE);
8123: LineNumber += newlines;
8124: newlines = 0;
8125: }
1.82 cvs 8126: else if (import != MAX_CSS_LENGTH &&
1.327 vatton 8127: !strncasecmp (&CSSbuffer[import+1], "import", 6))
8128: {
8129: /* import section */
8130: cssRule = &CSSbuffer[import+7];
1.405 kia 8131: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8132: /* save the current line number */
8133: newlines += LineNumber;
8134: if (!strncasecmp (cssRule, "url", 3))
8135: {
1.50 cvs 8136: cssRule = &cssRule[3];
1.405 kia 8137: cssRule = (char*)TtaSkipBlanks (cssRule);
1.82 cvs 8138: if (*cssRule == '(')
1.327 vatton 8139: {
8140: cssRule++;
1.405 kia 8141: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8142: quoted = (*cssRule == '"' || *cssRule == '\'');
8143: if (quoted)
8144: cssRule++;
8145: base = cssRule;
8146: while (*cssRule != EOS && *cssRule != ')')
8147: cssRule++;
8148: if (quoted)
8149: {
8150: /* isolate the file name */
8151: cssRule[-1] = EOS;
8152: quoted = FALSE;
8153: }
8154: else
8155: {
8156: /* remove extra spaces */
8157: if (cssRule[-1] == SPACE)
8158: {
8159: *cssRule = SPACE;
8160: cssRule--;
8161: while (cssRule[-1] == SPACE)
8162: cssRule--;
8163: }
8164: }
8165: *cssRule = EOS;
8166: }
8167: }
8168: else if (*cssRule == '"')
8169: {
8170: /*
8171: Do we have to accept single quotes?
8172: Double quotes are accepted here.
8173: Escaped quotes are not handled. See function SkipQuotedString
8174: */
8175: cssRule++;
1.405 kia 8176: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8177: base = cssRule;
8178: while (*cssRule != EOS &&
8179: (*cssRule != '"' ||
8180: (*cssRule == '"' && cssRule[-1] == '\\')))
8181: cssRule++;
8182: /* isolate the file name */
8183: *cssRule = EOS;
8184: }
8185: /* check if a media is defined */
8186: cssRule++;
1.405 kia 8187: cssRule = (char*)TtaSkipBlanks (cssRule);
1.327 vatton 8188: if (*cssRule != ';')
8189: {
8190: css_media = CheckMediaCSS (cssRule);
8191: if (TtaIsPrinting ())
8192: ignoreImport = (css_media != CSS_ALL && css_media != CSS_PRINT);
8193: else
8194: ignoreImport = (css_media != CSS_ALL && css_media != CSS_SCREEN);
8195: }
8196: if (!ignoreImport)
8197: {
8198: /* save the displayed URL when an error is reported */
1.348 vatton 8199: saveDocURL = Error_DocURL;
1.327 vatton 8200: ptr = TtaStrdup (base);
8201: /* get the CSS URI in UTF-8 */
8202: /*ptr = ReallocUTF8String (ptr, docRef);*/
8203: LoadStyleSheet (base, docRef, (Element) css, css,
8204: url, pInfo->PiMedia,
8205: pInfo->PiCategory == CSS_USER_STYLE);
8206: /* restore the displayed URL when an error is reported */
1.348 vatton 8207: Error_DocURL = saveDocURL;
1.327 vatton 8208: TtaFreeMemory (ptr);
8209: }
8210: /* restore the number of lines */
8211: LineNumber = newlines;
8212: newlines = 0;
8213: NewLineSkipped = 0;
8214: import = MAX_CSS_LENGTH;
8215: }
8216: else
8217: {
8218: LineNumber += newlines;
8219: newlines = 0;
8220: }
8221: }
8222: toParse = FALSE;
8223: noRule = FALSE;
8224: CSSindex = 0;
1.50 cvs 8225: }
1.82 cvs 8226: }
1.310 vatton 8227: /* closing the CSS parsing */
1.311 vatton 8228: Style_parsing--;
1.330 cvs 8229: if (RedisplayImages == 0 && RedisplayBGImage && Style_parsing == 0)
1.310 vatton 8230: {
1.311 vatton 8231: /* CSS parsing finishes after a BG image was loaded */
1.310 vatton 8232: RedisplayBGImage = FALSE;
1.330 cvs 8233: if (dispMode != NoComputedDisplay)
8234: {
8235: //printf ("ReadCSS Show BGimages\n");
8236: TtaSetDisplayMode (docRef, NoComputedDisplay);
8237: TtaSetDisplayMode (docRef, dispMode);
8238: }
1.310 vatton 8239: }
1.330 cvs 8240: else if (dispMode != NoComputedDisplay)
1.311 vatton 8241: /* restore the display mode */
8242: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 8243:
8244: /* Prepare the context for style attributes */
1.348 vatton 8245: Error_DocURL = DocumentURLs[docRef];
1.86 cvs 8246: LineNumber = -1;
1.1 cvs 8247: return (c);
8248: }
Webmaster