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