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