Annotation of Amaya/amaya/styleparser.c, revision 1.210
1.1 cvs 1: /*
2: *
1.165 vatton 3: * (c) COPYRIGHT INRIA and W3C, 1996-2003
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:
25: typedef struct _BackgroundImageCallbackBlock
26: {
1.207 vatton 27: Element el;
28: PSchema tsch;
29: CSSInfoPtr css;
30: PresentationContext ctxt;
1.1 cvs 31: }
32: BackgroundImageCallbackBlock, *BackgroundImageCallbackPtr;
33:
34: #include "AHTURLTools_f.h"
35: #include "HTMLpresentation_f.h"
36: #include "HTMLimage_f.h"
37: #include "UIcss_f.h"
38: #include "css_f.h"
1.24 cvs 39: #include "fetchHTMLname_f.h"
1.91 cvs 40: #include "fetchXMLname_f.h"
1.1 cvs 41: #include "html2thot_f.h"
1.91 cvs 42: #include "init_f.h"
1.1 cvs 43: #include "styleparser_f.h"
44:
45: #define MAX_BUFFER_LENGTH 200
46: /*
47: * A PropertyParser is a function used to parse the
48: * description substring associated to a given style attribute
1.59 cvs 49: * e.g.: "red" for a color attribute or "12pt bold helvetica"
1.1 cvs 50: * for a font attribute.
51: */
1.79 cvs 52: typedef char *(*PropertyParser) (Element element,
1.56 cvs 53: PSchema tsch,
54: PresentationContext context,
1.79 cvs 55: char *cssRule,
1.56 cvs 56: CSSInfoPtr css,
57: ThotBool isHTML);
1.1 cvs 58:
59: /* Description of the set of CSS properties supported */
60: typedef struct CSSProperty
61: {
1.79 cvs 62: char *name;
1.25 cvs 63: PropertyParser parsing_function;
1.1 cvs 64: }
65: CSSProperty;
66:
67: struct unit_def
68: {
1.79 cvs 69: char *sign;
1.1 cvs 70: unsigned int unit;
71: };
72:
73: static struct unit_def CSSUnitNames[] =
74: {
1.184 vatton 75: {"pt", UNIT_PT},
76: {"pc", UNIT_PC},
77: {"in", UNIT_IN},
78: {"cm", UNIT_CM},
79: {"mm", UNIT_MM},
80: {"em", UNIT_EM},
81: {"px", UNIT_PX},
82: {"ex", UNIT_XHEIGHT},
83: {"%", UNIT_PERCENT}
1.1 cvs 84: };
85:
86: #define NB_UNITS (sizeof(CSSUnitNames) / sizeof(struct unit_def))
1.86 cvs 87: static char *DocURL = NULL; /* The parsed CSS file */
88: static Document ParsedDoc; /* The document to which CSS are to be applied */
89: static int LineNumber = -1; /* The line where the error occurs */
1.93 vatton 90: static int NewLineSkipped = 0;
1.116 vatton 91: static ThotBool DoApply = TRUE;
1.1 cvs 92:
93: /*----------------------------------------------------------------------
94: SkipWord:
95: ----------------------------------------------------------------------*/
1.79 cvs 96: static char *SkipWord (char *ptr)
1.1 cvs 97: {
1.168 vatton 98: while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '#' || *ptr == '%')
99: ptr++;
1.1 cvs 100: return (ptr);
101: }
102:
103: /*----------------------------------------------------------------------
1.13 cvs 104: SkipBlanksAndComments:
105: ----------------------------------------------------------------------*/
1.82 cvs 106: char *SkipBlanksAndComments (char *ptr)
1.13 cvs 107: {
1.93 vatton 108: /* skip spaces */
1.155 cheyroul 109: while (*ptr == SPACE ||
110: *ptr == BSPACE ||
111: *ptr == EOL ||
112: *ptr == TAB ||
113: *ptr == __CR__)
1.93 vatton 114: {
115: if (*ptr == EOL)
116: /* increment the number of newline skipped */
117: NewLineSkipped++;
118: ptr++;
119: }
1.155 cheyroul 120: while (ptr[0] == '/' &&
121: ptr[1] == '*')
1.13 cvs 122: {
123: /* look for the end of the comment */
124: ptr = &ptr[2];
125: while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
126: ptr++;
127: if (ptr[0] != EOS)
128: ptr = &ptr[2];
1.93 vatton 129: /* skip spaces */
130: while (*ptr == SPACE || *ptr == BSPACE || *ptr == EOL ||
131: *ptr == TAB || *ptr == __CR__)
132: {
133: if (*ptr == EOL)
134: /* increment the number of newline skipped */
135: NewLineSkipped++;
136: ptr++;
137: }
1.13 cvs 138: }
139: return (ptr);
140: }
141:
1.49 cvs 142: /*----------------------------------------------------------------------
1.161 quint 143: SkipQuotedString
1.1 cvs 144: ----------------------------------------------------------------------*/
1.79 cvs 145: static char *SkipQuotedString (char *ptr, char quote)
1.1 cvs 146: {
1.14 cvs 147: ThotBool stop;
1.1 cvs 148:
149: stop = FALSE;
150: while (!stop)
151: {
152: if (*ptr == quote)
153: {
154: ptr++;
155: stop = TRUE;
156: }
1.82 cvs 157: else if (*ptr == EOS)
1.1 cvs 158: stop = TRUE;
1.82 cvs 159: else if (*ptr == '\\')
1.1 cvs 160: /* escape character */
161: {
162: ptr++;
1.82 cvs 163: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
164: (*ptr >= 'a' && *ptr <= 'f'))
1.1 cvs 165: {
166: ptr++;
1.82 cvs 167: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
168: (*ptr >= 'a' && *ptr <= 'f'))
1.1 cvs 169: ptr++;
170: }
171: else
172: ptr++;
173: }
174: else
175: ptr++;
176: }
177: return (ptr);
178: }
179:
180: /*----------------------------------------------------------------------
1.168 vatton 181: CSSPrintError
1.86 cvs 182: print the error message msg on stderr.
183: When the line is 0 ask to expat the current line number
184: ----------------------------------------------------------------------*/
1.168 vatton 185: static void CSSPrintError (char *msg, char *value)
1.86 cvs 186: {
187: if (!TtaIsPrinting () && ParsedDoc > 0)
188: {
189: if (!ErrFile)
190: {
1.90 cvs 191: if (OpenParsingErrors (ParsedDoc) == FALSE)
1.86 cvs 192: return;
193: }
194:
1.133 vatton 195: if (DocURL)
1.86 cvs 196: {
1.94 cvs 197: fprintf (ErrFile, "*** Errors/warnings in %s\n", DocURL);
1.86 cvs 198: /* set to NULL as long as the CSS file doesn't change */
199: DocURL = NULL;
200: }
1.89 cvs 201: CSSErrorsFound = TRUE;
1.86 cvs 202: if (LineNumber < 0)
1.205 quint 203: fprintf (ErrFile, " In style attribute, %s \"%s\"\n", msg, value);
1.86 cvs 204: else
1.162 quint 205: fprintf (ErrFile, " line %d: %s \"%s\"\n", LineNumber+NewLineSkipped,
1.93 vatton 206: msg, value);
1.86 cvs 207: }
208: }
209:
1.168 vatton 210: /*----------------------------------------------------------------------
211: CSSParseError
212: print the error message msg on stderr.
213: When the line is 0 ask to expat the current line number
214: ----------------------------------------------------------------------*/
215: static void CSSParseError (char *msg, char *value, char *endvalue)
216: {
217: char c = EOS;
218:
219: if (endvalue)
220: {
221: /* close the string here */
222: c = *endvalue;
223: *endvalue = EOS;
224: }
225: CSSPrintError (msg, value);
226: if (endvalue)
227: *endvalue = c;
228: }
229:
1.89 cvs 230:
1.86 cvs 231: /*----------------------------------------------------------------------
1.168 vatton 232: SkipProperty skips a property and display and error message
1.86 cvs 233: ----------------------------------------------------------------------*/
234: static char *SkipProperty (char *ptr)
235: {
236: char *deb;
237: char c;
238:
239: deb = ptr;
1.135 vatton 240: while (*ptr != EOS && *ptr != ';' && *ptr != '}')
1.133 vatton 241: {
1.194 vatton 242: if (*ptr == '"' && (ptr == deb || ptr[-1] != '\\'))
1.133 vatton 243: {
244: /* skip to the end of the string "..." */
245: ptr++;
1.194 vatton 246: while (*ptr != EOS &&
247: (*ptr != '"' || (*ptr == '"' && ptr[-1] == '\\')))
1.133 vatton 248: ptr++;
249: }
250: ptr++;
251: }
1.95 cvs 252: /* print the skipped property */
1.86 cvs 253: c = *ptr;
254: *ptr = EOS;
1.95 cvs 255: #ifdef CSS_WARNING
1.86 cvs 256: if (*deb != EOS)
1.205 quint 257: CSSPrintError ("CSS property ignored:", deb);
1.95 cvs 258: #endif /* CSS_WARNING */
1.86 cvs 259: *ptr = c;
260: return (ptr);
261: }
262:
263: /*----------------------------------------------------------------------
1.168 vatton 264: SkipValue
265: skips the value and display an error message if msg is not NULL
1.1 cvs 266: ----------------------------------------------------------------------*/
1.168 vatton 267: static char *SkipValue (char *msg, char *ptr)
1.1 cvs 268: {
1.86 cvs 269: char *deb;
270: char c;
271:
272: deb = ptr;
1.135 vatton 273: while (*ptr != EOS && *ptr != ';' && *ptr != '}')
1.133 vatton 274: {
275: if (*ptr == '"' && (ptr == deb || ptr[-1] != '\\'))
276: {
277: /* skip to the end of the string "..." */
278: ptr++;
1.184 vatton 279: while (*ptr != '"' || (ptr[0] == '"' && ptr[-1] == '\\'))
1.133 vatton 280: ptr++;
281: }
282: ptr++;
283: }
1.95 cvs 284: /* print the skipped property */
1.86 cvs 285: c = *ptr;
286: *ptr = EOS;
1.168 vatton 287: if (msg && *deb != EOS && *deb != ',')
288: CSSPrintError (msg, deb);
1.86 cvs 289: *ptr = c;
1.1 cvs 290: return (ptr);
291: }
292:
293: /*----------------------------------------------------------------------
1.64 cvs 294: ParseNumber:
295: parse a number and returns the corresponding value.
1.1 cvs 296: ----------------------------------------------------------------------*/
1.79 cvs 297: char *ParseNumber (char *cssRule, PresentationValue *pval)
1.1 cvs 298: {
299: int val = 0;
300: int minus = 0;
301: int valid = 0;
302: int f = 0;
1.14 cvs 303: ThotBool real = FALSE;
1.1 cvs 304:
1.184 vatton 305: pval->typed_data.unit = UNIT_REL;
1.1 cvs 306: pval->typed_data.real = FALSE;
1.82 cvs 307: cssRule = SkipBlanksAndComments (cssRule);
308: if (*cssRule == '-')
1.1 cvs 309: {
310: minus = 1;
311: cssRule++;
1.82 cvs 312: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 313: }
314:
1.82 cvs 315: if (*cssRule == '+')
1.1 cvs 316: {
317: cssRule++;
1.82 cvs 318: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 319: }
320:
1.82 cvs 321: while ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 322: {
323: val *= 10;
1.82 cvs 324: val += *cssRule - '0';
1.1 cvs 325: cssRule++;
326: valid = 1;
327: }
328:
1.82 cvs 329: if (*cssRule == '.')
1.1 cvs 330: {
331: real = TRUE;
332: f = val;
333: val = 0;
334: cssRule++;
335: /* keep only 3 digits */
1.82 cvs 336: if (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 337: {
1.82 cvs 338: val = (*cssRule - '0') * 100;
1.1 cvs 339: cssRule++;
1.82 cvs 340: if (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 341: {
1.82 cvs 342: val += (*cssRule - '0') * 10;
1.1 cvs 343: cssRule++;
1.82 cvs 344: if ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 345: {
1.82 cvs 346: val += *cssRule - '0';
1.1 cvs 347: cssRule++;
348: }
349: }
350:
1.82 cvs 351: while (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 352: cssRule++;
353: valid = 1;
354: }
355: }
356:
357: if (!valid)
358: {
1.184 vatton 359: pval->typed_data.unit = UNIT_INVALID;
1.1 cvs 360: pval->typed_data.value = 0;
361: }
362: else
363: {
364: pval->typed_data.real = real;
365: if (real)
366: {
367: if (minus)
368: pval->typed_data.value = -(f * 1000 + val);
369: else
370: pval->typed_data.value = f * 1000 + val;
371: }
372: else
373: {
374: if (minus)
375: pval->typed_data.value = -val;
376: else
377: pval->typed_data.value = val;
378: }
1.64 cvs 379: }
380: return (cssRule);
381: }
1.195 vatton 382:
1.155 cheyroul 383: /*----------------------------------------------------------------------
384: ParseClampedUnit:
385: parse a CSS Unit substring and returns the corresponding
386: value and its unit.
387: [0,1]
388: or
389: [0,100] in %
390: ----------------------------------------------------------------------*/
1.195 vatton 391: char *ParseClampedUnit (char *text, PresentationValue *pval)
1.155 cheyroul 392: {
1.170 cheyroul 393: float clamped_value;
394: int int_clamped_value;
1.155 cheyroul 395:
396: if (*(text + strlen (text) -1) == '%')
1.195 vatton 397: {
398: int_clamped_value = atoi (text);
399: if (int_clamped_value < 0 || int_clamped_value > 100)
400: int_clamped_value = 1000;
1.155 cheyroul 401: else
1.195 vatton 402: int_clamped_value = int_clamped_value * 10;
403: }
404: else
405: {
406: clamped_value = (float) atof (text);
407: if (clamped_value < 0.0 || clamped_value > 1.0)
408: int_clamped_value = 1000;
409: else
410: int_clamped_value = (int) (clamped_value * 1000.);
411: }
412: pval->typed_data.unit = UNIT_REL;
413: pval->typed_data.value = int_clamped_value;
414: pval->typed_data.real = FALSE;
415: pval->data = int_clamped_value;
1.155 cheyroul 416: return (SkipWord (text));
417: }
1.64 cvs 418:
419: /*----------------------------------------------------------------------
420: ParseCSSUnit:
421: parse a CSS Unit substring and returns the corresponding
422: value and its unit.
423: ----------------------------------------------------------------------*/
1.82 cvs 424: char *ParseCSSUnit (char *cssRule, PresentationValue *pval)
1.64 cvs 425: {
426: unsigned int uni;
427:
1.184 vatton 428: pval->typed_data.unit = UNIT_REL;
1.64 cvs 429: cssRule = ParseNumber (cssRule, pval);
1.184 vatton 430: if (pval->typed_data.unit == UNIT_INVALID)
1.64 cvs 431: cssRule = SkipWord (cssRule);
432: else
433: {
1.82 cvs 434: cssRule = SkipBlanksAndComments (cssRule);
1.64 cvs 435: for (uni = 0; uni < NB_UNITS; uni++)
436: {
1.82 cvs 437: if (!strncasecmp (CSSUnitNames[uni].sign, cssRule,
438: strlen (CSSUnitNames[uni].sign)))
1.64 cvs 439: {
440: pval->typed_data.unit = CSSUnitNames[uni].unit;
1.82 cvs 441: return (cssRule + strlen (CSSUnitNames[uni].sign));
1.64 cvs 442: }
443: }
444: /* not in the list of predefined units */
1.184 vatton 445: pval->typed_data.unit = UNIT_BOX;
1.1 cvs 446: }
447: return (cssRule);
448: }
449:
1.43 cvs 450: /*----------------------------------------------------------------------
451: ParseBorderValue
452: ----------------------------------------------------------------------*/
1.79 cvs 453: static char *ParseBorderValue (char *cssRule, PresentationValue *border)
1.43 cvs 454: {
1.168 vatton 455: char *ptr;
456:
1.43 cvs 457: /* first parse the attribute string */
458: border->typed_data.value = 0;
1.184 vatton 459: border->typed_data.unit = UNIT_INVALID;
1.43 cvs 460: border->typed_data.real = FALSE;
1.82 cvs 461: if (!strncasecmp (cssRule, "thin", 4))
1.43 cvs 462: {
1.184 vatton 463: border->typed_data.unit = UNIT_PX;
1.43 cvs 464: border->typed_data.value = 1;
465: cssRule = SkipWord (cssRule);
466: }
1.82 cvs 467: else if (!strncasecmp (cssRule, "medium", 6))
1.43 cvs 468: {
1.184 vatton 469: border->typed_data.unit = UNIT_PX;
1.43 cvs 470: border->typed_data.value = 3;
471: cssRule = SkipWord (cssRule);
472: }
1.82 cvs 473: else if (!strncasecmp (cssRule, "thick", 5))
1.43 cvs 474: {
1.184 vatton 475: border->typed_data.unit = UNIT_PX;
1.43 cvs 476: border->typed_data.value = 5;
477: cssRule = SkipWord (cssRule);
478: }
1.110 vatton 479: else if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 480: {
1.168 vatton 481: ptr = cssRule;
1.166 vatton 482: cssRule = ParseCSSUnit (cssRule, border);
1.168 vatton 483: if (border->typed_data.value == 0)
1.184 vatton 484: border->typed_data.unit = UNIT_PX;
485: else if (border->typed_data.unit == UNIT_INVALID ||
486: border->typed_data.unit == UNIT_BOX)
1.168 vatton 487: {
1.184 vatton 488: border->typed_data.unit = UNIT_INVALID;
1.168 vatton 489: border->typed_data.value = 0;
490: CSSParseError ("Invalid border-width value", ptr, cssRule);
491: }
1.166 vatton 492: }
1.43 cvs 493: return (cssRule);
494: }
495:
496: /*----------------------------------------------------------------------
497: ParseBorderStyle
498: ----------------------------------------------------------------------*/
1.79 cvs 499: static char *ParseBorderStyle (char *cssRule, PresentationValue *border)
1.43 cvs 500: {
501: /* first parse the attribute string */
502: border->typed_data.value = 0;
1.184 vatton 503: border->typed_data.unit = UNIT_PX;
1.43 cvs 504: border->typed_data.real = FALSE;
1.82 cvs 505: if (!strncasecmp (cssRule, "none", 4))
1.184 vatton 506: border->typed_data.value = BorderStyleNone;
1.82 cvs 507: else if (!strncasecmp (cssRule, "hidden", 6))
1.184 vatton 508: border->typed_data.value = BorderStyleHidden;
1.82 cvs 509: else if (!strncasecmp (cssRule, "dotted", 6))
1.184 vatton 510: border->typed_data.value = BorderStyleDotted;
1.82 cvs 511: else if (!strncasecmp (cssRule, "dashed", 6))
1.184 vatton 512: border->typed_data.value = BorderStyleDashed;
1.82 cvs 513: else if (!strncasecmp (cssRule, "solid", 5))
1.184 vatton 514: border->typed_data.value = BorderStyleSolid;
1.82 cvs 515: else if (!strncasecmp (cssRule, "double", 6))
1.184 vatton 516: border->typed_data.value = BorderStyleDouble;
1.82 cvs 517: else if (!strncasecmp (cssRule, "groove", 6))
1.184 vatton 518: border->typed_data.value = BorderStyleGroove;
1.82 cvs 519: else if (!strncasecmp (cssRule, "ridge", 5))
1.184 vatton 520: border->typed_data.value = BorderStyleRidge;
1.82 cvs 521: else if (!strncasecmp (cssRule, "inset", 5))
1.184 vatton 522: border->typed_data.value = BorderStyleInset;
1.82 cvs 523: else if (!strncasecmp (cssRule, "outset", 6))
1.184 vatton 524: border->typed_data.value = BorderStyleOutset;
1.43 cvs 525: else
1.44 cvs 526: {
527: /* invalid style */
1.184 vatton 528: border->typed_data.unit = UNIT_INVALID;
1.44 cvs 529: return (cssRule);
530: }
1.43 cvs 531: /* the value is parsed now */
532: cssRule = SkipWord (cssRule);
533: return (cssRule);
534: }
535:
536: /*----------------------------------------------------------------------
1.59 cvs 537: ParseCSSColor: parse a CSS color attribute string
1.43 cvs 538: we expect the input string describing the attribute to be
539: either a color name, a 3 tuple or an hexadecimal encoding.
540: The color used will be approximed from the current color
541: table
542: ----------------------------------------------------------------------*/
1.79 cvs 543: static char *ParseCSSColor (char *cssRule, PresentationValue * val)
1.43 cvs 544: {
1.79 cvs 545: char *ptr;
1.43 cvs 546: unsigned short redval = (unsigned short) -1;
547: unsigned short greenval = 0; /* composant of each RGB */
548: unsigned short blueval = 0; /* default to red if unknown ! */
549: int best = 0; /* best color in list found */
550:
1.82 cvs 551: cssRule = SkipBlanksAndComments (cssRule);
1.184 vatton 552: val->typed_data.unit = UNIT_INVALID;
1.43 cvs 553: val->typed_data.real = FALSE;
554: val->typed_data.value = 0;
1.57 cvs 555: ptr = TtaGiveRGB (cssRule, &redval, &greenval, &blueval);
1.135 vatton 556: if (!strncasecmp (cssRule, "inherit", 7))
557: {
558: cssRule = SkipWord (cssRule);
559: return (cssRule);
560: }
1.57 cvs 561: if (ptr == cssRule)
1.43 cvs 562: {
1.168 vatton 563: cssRule = SkipWord (cssRule);
564: CSSParseError ("Invalid color value", ptr, cssRule);
1.43 cvs 565: val->typed_data.value = 0;
1.184 vatton 566: val->typed_data.unit = UNIT_INVALID;
1.43 cvs 567: }
568: else
569: {
570: best = TtaGetThotColor (redval, greenval, blueval);
571: val->typed_data.value = best;
1.184 vatton 572: val->typed_data.unit = UNIT_REL;
1.57 cvs 573: cssRule = ptr;
1.43 cvs 574: }
575: val->typed_data.real = FALSE;
1.65 cvs 576: return (cssRule);
1.43 cvs 577: }
1.1 cvs 578:
579: /*----------------------------------------------------------------------
1.117 vatton 580: CheckImportantRule updates the field important of the context.
581: ----------------------------------------------------------------------*/
582: static char *CheckImportantRule (char *cssRule, PresentationContext context)
583: {
584: cssRule = SkipBlanksAndComments (cssRule);
1.120 vatton 585: if (*cssRule != '!')
586: context->important = FALSE;
587: else
1.117 vatton 588: {
1.120 vatton 589: cssRule++;
590: cssRule = SkipBlanksAndComments (cssRule);
591: if (!strncasecmp (cssRule, "important", 9))
592: {
593: context->important = TRUE;
594: cssRule += 9;
595: }
596: else
597: context->important = FALSE;
1.117 vatton 598: }
599: return (cssRule);
600: }
601:
602: /*----------------------------------------------------------------------
1.59 cvs 603: ParseCSSBorderTopWidth: parse a CSS BorderTopWidth
1.1 cvs 604: attribute string.
605: ----------------------------------------------------------------------*/
1.79 cvs 606: static char *ParseCSSBorderTopWidth (Element element, PSchema tsch,
607: PresentationContext context,
608: char *cssRule, CSSInfoPtr css,
609: ThotBool isHTML)
1.1 cvs 610: {
1.41 cvs 611: PresentationValue border;
612:
1.82 cvs 613: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 614: cssRule = ParseBorderValue (cssRule, &border);
1.184 vatton 615: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44 cvs 616: {
1.117 vatton 617: /* check if it's an important rule */
618: if (tsch)
619: cssRule = CheckImportantRule (cssRule, context);
1.44 cvs 620: TtaSetStylePresentation (PRBorderTopWidth, element, tsch, context, border);
621: border.typed_data.value = 1;
1.184 vatton 622: border.typed_data.unit = UNIT_REL;
1.44 cvs 623: }
1.1 cvs 624: return (cssRule);
625: }
626:
627: /*----------------------------------------------------------------------
1.59 cvs 628: ParseCSSBorderBottomWidth: parse a CSS BorderBottomWidth
1.1 cvs 629: attribute string.
630: ----------------------------------------------------------------------*/
1.79 cvs 631: static char *ParseCSSBorderBottomWidth (Element element, PSchema tsch,
632: PresentationContext context,
633: char *cssRule, CSSInfoPtr css,
634: ThotBool isHTML)
1.1 cvs 635: {
1.41 cvs 636: PresentationValue border;
637:
1.82 cvs 638: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 639: /* first parse the attribute string */
1.43 cvs 640: cssRule = ParseBorderValue (cssRule, &border);
1.184 vatton 641: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44 cvs 642: {
1.117 vatton 643: /* check if it's an important rule */
644: if (tsch)
645: cssRule = CheckImportantRule (cssRule, context);
1.44 cvs 646: TtaSetStylePresentation (PRBorderBottomWidth, element, tsch, context, border);
647: border.typed_data.value = 1;
1.184 vatton 648: border.typed_data.unit = UNIT_REL;
1.44 cvs 649: }
1.1 cvs 650: return (cssRule);
651: }
652:
653: /*----------------------------------------------------------------------
1.59 cvs 654: ParseCSSBorderLeftWidth: parse a CSS BorderLeftWidth
1.1 cvs 655: attribute string.
656: ----------------------------------------------------------------------*/
1.79 cvs 657: static char *ParseCSSBorderLeftWidth (Element element, PSchema tsch,
658: PresentationContext context,
659: char *cssRule, CSSInfoPtr css,
660: ThotBool isHTML)
1.1 cvs 661: {
1.41 cvs 662: PresentationValue border;
663:
1.82 cvs 664: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 665: /* first parse the attribute string */
1.43 cvs 666: cssRule = ParseBorderValue (cssRule, &border);
1.184 vatton 667: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44 cvs 668: {
1.117 vatton 669: /* check if it's an important rule */
670: if (tsch)
671: cssRule = CheckImportantRule (cssRule, context);
1.44 cvs 672: TtaSetStylePresentation (PRBorderLeftWidth, element, tsch, context, border);
673: border.typed_data.value = 1;
1.184 vatton 674: border.typed_data.unit = UNIT_REL;
1.44 cvs 675: }
1.1 cvs 676: return (cssRule);
677: }
678:
679: /*----------------------------------------------------------------------
1.59 cvs 680: ParseCSSBorderRightWidth: parse a CSS BorderRightWidth
1.1 cvs 681: attribute string.
682: ----------------------------------------------------------------------*/
1.79 cvs 683: static char *ParseCSSBorderRightWidth (Element element, PSchema tsch,
684: PresentationContext context,
685: char *cssRule, CSSInfoPtr css,
686: ThotBool isHTML)
1.1 cvs 687: {
1.41 cvs 688: PresentationValue border;
689:
1.82 cvs 690: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 691: /* first parse the attribute string */
1.43 cvs 692: cssRule = ParseBorderValue (cssRule, &border);
1.184 vatton 693: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.44 cvs 694: {
1.117 vatton 695: /* check if it's an important rule */
696: if (tsch)
697: cssRule = CheckImportantRule (cssRule, context);
1.44 cvs 698: TtaSetStylePresentation (PRBorderRightWidth, element, tsch, context, border);
699: border.typed_data.value = 1;
1.184 vatton 700: border.typed_data.unit = UNIT_REL;
1.44 cvs 701: }
1.1 cvs 702: return (cssRule);
703: }
704:
705: /*----------------------------------------------------------------------
1.59 cvs 706: ParseCSSBorderWidth: parse a CSS BorderWidth
1.1 cvs 707: attribute string.
708: ----------------------------------------------------------------------*/
1.79 cvs 709: static char *ParseCSSBorderWidth (Element element, PSchema tsch,
710: PresentationContext context,
711: char *cssRule, CSSInfoPtr css,
712: ThotBool isHTML)
1.1 cvs 713: {
1.79 cvs 714: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 715: int skippedNL;
1.41 cvs 716:
1.82 cvs 717: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 718: /* First parse Border-Top */
719: ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 720: ptrR = SkipBlanksAndComments (ptrR);
721: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 722: {
1.93 vatton 723: skippedNL = NewLineSkipped;
1.42 cvs 724: cssRule = ptrR;
725: /* apply the Border-Top to all */
726: ptrR = ParseCSSBorderRightWidth (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 727: NewLineSkipped = skippedNL;
1.42 cvs 728: ptrR = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 729: NewLineSkipped = skippedNL;
1.42 cvs 730: ptrR = ParseCSSBorderLeftWidth (element, tsch, context, ptrT, css, isHTML);
731: }
732: else
733: {
734: /* parse Border-Right */
735: ptrB = ParseCSSBorderRightWidth (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 736: ptrB = SkipBlanksAndComments (ptrB);
737: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 738: {
1.93 vatton 739: skippedNL = NewLineSkipped;
1.42 cvs 740: cssRule = ptrB;
741: /* apply the Border-Top to Border-Bottom */
742: ptrB = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 743: NewLineSkipped = skippedNL;
1.42 cvs 744: /* apply the Border-Right to Border-Left */
745: ptrB = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
746: }
747: else
748: {
749: /* parse Border-Bottom */
750: ptrL = ParseCSSBorderBottomWidth (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 751: ptrL = SkipBlanksAndComments (ptrL);
752: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 753: {
754: cssRule = ptrL;
755: /* apply the Border-Right to Border-Left */
756: ptrL = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
757: }
758: else
759: /* parse Border-Left */
760: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 761: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 762: }
763: }
1.1 cvs 764: return (cssRule);
765: }
766:
767: /*----------------------------------------------------------------------
1.59 cvs 768: ParseCSSBorderColorTop: parse a CSS BorderColorTop
1.1 cvs 769: attribute string.
770: ----------------------------------------------------------------------*/
1.79 cvs 771: static char *ParseCSSBorderColorTop (Element element, PSchema tsch,
772: PresentationContext context,
773: char *cssRule, CSSInfoPtr css,
774: ThotBool isHTML)
1.1 cvs 775: {
1.117 vatton 776: PresentationValue best;
1.43 cvs 777:
1.117 vatton 778: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 779: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 780: {
781: /* check if it's an important rule */
782: if (tsch)
783: cssRule = CheckImportantRule (cssRule, context);
784: /* install the new presentation */
785: TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
786: }
787: return (cssRule);
1.1 cvs 788: }
789:
790: /*----------------------------------------------------------------------
1.59 cvs 791: ParseCSSBorderColorLeft: parse a CSS BorderColorLeft
1.42 cvs 792: attribute string.
793: ----------------------------------------------------------------------*/
1.79 cvs 794: static char *ParseCSSBorderColorLeft (Element element, PSchema tsch,
795: PresentationContext context,
796: char *cssRule, CSSInfoPtr css,
797: ThotBool isHTML)
1.42 cvs 798: {
1.117 vatton 799: PresentationValue best;
800:
801: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 802: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 803: {
804: /* check if it's an important rule */
805: if (tsch)
806: cssRule = CheckImportantRule (cssRule, context);
807: /* install the new presentation */
808: TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
809: }
810: return (cssRule);
1.42 cvs 811: }
812:
813: /*----------------------------------------------------------------------
1.59 cvs 814: ParseCSSBorderColorBottom: parse a CSS BorderColorBottom
1.42 cvs 815: attribute string.
816: ----------------------------------------------------------------------*/
1.79 cvs 817: static char *ParseCSSBorderColorBottom (Element element, PSchema tsch,
818: PresentationContext context,
819: char *cssRule, CSSInfoPtr css,
820: ThotBool isHTML)
1.42 cvs 821: {
1.117 vatton 822: PresentationValue best;
1.43 cvs 823:
1.117 vatton 824: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 825: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 826: {
827: /* check if it's an important rule */
828: if (tsch)
829: cssRule = CheckImportantRule (cssRule, context);
830: /* install the new presentation */
831: TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
832: }
1.65 cvs 833: return (cssRule);
1.42 cvs 834: }
835:
836: /*----------------------------------------------------------------------
1.59 cvs 837: ParseCSSBorderColorRight: parse a CSS BorderColorRight
1.1 cvs 838: attribute string.
839: ----------------------------------------------------------------------*/
1.79 cvs 840: static char *ParseCSSBorderColorRight (Element element, PSchema tsch,
841: PresentationContext context,
842: char *cssRule, CSSInfoPtr css,
843: ThotBool isHTML)
1.1 cvs 844: {
1.117 vatton 845: PresentationValue best;
1.43 cvs 846:
1.117 vatton 847: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 848: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 849: {
850: /* check if it's an important rule */
851: if (tsch)
852: cssRule = CheckImportantRule (cssRule, context);
853: /* install the new presentation */
854: TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
855: }
856: return (cssRule);
1.1 cvs 857: }
858:
859: /*----------------------------------------------------------------------
1.59 cvs 860: ParseCSSBorderColor: parse a CSS border-color
1.42 cvs 861: attribute string.
862: ----------------------------------------------------------------------*/
1.79 cvs 863: static char *ParseCSSBorderColor (Element element, PSchema tsch,
864: PresentationContext context,
865: char *cssRule, CSSInfoPtr css,
866: ThotBool isHTML)
1.42 cvs 867: {
1.79 cvs 868: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 869: int skippedNL;
1.42 cvs 870:
1.82 cvs 871: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 872: /* First parse Border-Top */
1.43 cvs 873: ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 874: ptrR = SkipBlanksAndComments (ptrR);
875: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 876: {
1.93 vatton 877: skippedNL = NewLineSkipped;
1.42 cvs 878: cssRule = ptrR;
879: /* apply the Border-Top to all */
1.43 cvs 880: ptrR = ParseCSSBorderColorRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 881: NewLineSkipped = skippedNL;
1.43 cvs 882: ptrR = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 883: NewLineSkipped = skippedNL;
1.43 cvs 884: ptrR = ParseCSSBorderColorLeft (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 885: }
886: else
887: {
888: /* parse Border-Right */
1.43 cvs 889: ptrB = ParseCSSBorderColorRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 890: ptrB = SkipBlanksAndComments (ptrB);
891: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 892: {
1.93 vatton 893: skippedNL = NewLineSkipped;
1.42 cvs 894: cssRule = ptrB;
895: /* apply the Border-Top to Border-Bottom */
1.43 cvs 896: ptrB = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 897: NewLineSkipped = skippedNL;
1.42 cvs 898: /* apply the Border-Right to Border-Left */
1.43 cvs 899: ptrB = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 900: }
901: else
902: {
1.93 vatton 903: skippedNL = NewLineSkipped;
1.42 cvs 904: /* parse Border-Bottom */
1.43 cvs 905: ptrL = ParseCSSBorderColorBottom (element, tsch, context, ptrB, css, isHTML);
1.93 vatton 906: NewLineSkipped = skippedNL;
1.82 cvs 907: ptrL = SkipBlanksAndComments (ptrL);
908: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 909: {
910: cssRule = ptrL;
911: /* apply the Border-Right to Border-Left */
1.43 cvs 912: ptrL = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 913: }
914: else
915: /* parse Border-Left */
1.43 cvs 916: cssRule = ParseCSSBorderColorLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 917: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 918: }
919: }
920: return (cssRule);
921: }
922:
923: /*----------------------------------------------------------------------
1.59 cvs 924: ParseCSSBorderStyleTop: parse a CSS BorderStyleTop
1.42 cvs 925: attribute string.
926: ----------------------------------------------------------------------*/
1.79 cvs 927: static char *ParseCSSBorderStyleTop (Element element, PSchema tsch,
928: PresentationContext context,
929: char *cssRule, CSSInfoPtr css,
930: ThotBool isHTML)
1.42 cvs 931: {
1.43 cvs 932: PresentationValue border;
933:
1.82 cvs 934: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 935: cssRule = ParseBorderStyle (cssRule, &border);
1.184 vatton 936: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 937: {
938: /* check if it's an important rule */
939: if (tsch)
940: cssRule = CheckImportantRule (cssRule, context);
941: TtaSetStylePresentation (PRBorderTopStyle, element, tsch, context, border);
942: }
1.42 cvs 943: return (cssRule);
944: }
945:
946: /*----------------------------------------------------------------------
1.59 cvs 947: ParseCSSBorderStyleLeft: parse a CSS BorderStyleLeft
1.42 cvs 948: attribute string.
949: ----------------------------------------------------------------------*/
1.79 cvs 950: static char *ParseCSSBorderStyleLeft (Element element, PSchema tsch,
951: PresentationContext context,
952: char *cssRule, CSSInfoPtr css,
953: ThotBool isHTML)
1.42 cvs 954: {
1.43 cvs 955: PresentationValue border;
956:
1.82 cvs 957: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 958: cssRule = ParseBorderStyle (cssRule, &border);
1.184 vatton 959: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 960: {
961: /* check if it's an important rule */
962: if (tsch)
963: cssRule = CheckImportantRule (cssRule, context);
964: TtaSetStylePresentation (PRBorderLeftStyle, element, tsch, context, border);
965: }
1.42 cvs 966: return (cssRule);
967: }
968:
969: /*----------------------------------------------------------------------
1.59 cvs 970: ParseCSSBorderStyleBottom: parse a CSS BorderStyleBottom
1.1 cvs 971: attribute string.
972: ----------------------------------------------------------------------*/
1.79 cvs 973: static char *ParseCSSBorderStyleBottom (Element element, PSchema tsch,
974: PresentationContext context,
975: char *cssRule, CSSInfoPtr css,
976: ThotBool isHTML)
1.1 cvs 977: {
1.43 cvs 978: PresentationValue border;
979:
1.82 cvs 980: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 981: cssRule = ParseBorderStyle (cssRule, &border);
1.184 vatton 982: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 983: {
984: /* check if it's an important rule */
985: if (tsch)
986: cssRule = CheckImportantRule (cssRule, context);
987: TtaSetStylePresentation (PRBorderBottomStyle, element, tsch, context, border);
988: }
1.1 cvs 989: return (cssRule);
990: }
991:
992: /*----------------------------------------------------------------------
1.59 cvs 993: ParseCSSBorderStyleRight: parse a CSS BorderStyleRight
1.1 cvs 994: attribute string.
995: ----------------------------------------------------------------------*/
1.79 cvs 996: static char *ParseCSSBorderStyleRight (Element element, PSchema tsch,
997: PresentationContext context,
998: char *cssRule, CSSInfoPtr css,
999: ThotBool isHTML)
1.1 cvs 1000: {
1.43 cvs 1001: PresentationValue border;
1002:
1.82 cvs 1003: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1004: cssRule = ParseBorderStyle (cssRule, &border);
1.184 vatton 1005: if (border.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 1006: {
1007: /* check if it's an important rule */
1008: if (tsch)
1009: cssRule = CheckImportantRule (cssRule, context);
1010: TtaSetStylePresentation (PRBorderRightStyle, element, tsch, context, border);
1011: }
1.1 cvs 1012: return (cssRule);
1013: }
1014:
1015: /*----------------------------------------------------------------------
1.59 cvs 1016: ParseCSSBorderStyleStyle: parse a CSS border-style
1.1 cvs 1017: attribute string.
1018: ----------------------------------------------------------------------*/
1.79 cvs 1019: static char *ParseCSSBorderStyle (Element element, PSchema tsch,
1020: PresentationContext context,
1021: char *cssRule, CSSInfoPtr css,
1022: ThotBool isHTML)
1.1 cvs 1023: {
1.79 cvs 1024: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 1025: int skippedNL;
1.42 cvs 1026:
1.82 cvs 1027: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 1028: /* First parse Border-Top */
1.43 cvs 1029: ptrR = ParseCSSBorderStyleTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 1030: ptrR = SkipBlanksAndComments (ptrR);
1031: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 1032: {
1.93 vatton 1033: skippedNL = NewLineSkipped;
1.42 cvs 1034: cssRule = ptrR;
1035: /* apply the Border-Top to all */
1.43 cvs 1036: ptrR = ParseCSSBorderStyleRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 1037: NewLineSkipped = skippedNL;
1.43 cvs 1038: ptrR = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 1039: NewLineSkipped = skippedNL;
1.43 cvs 1040: ptrR = ParseCSSBorderStyleLeft (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 1041: }
1042: else
1043: {
1044: /* parse Border-Right */
1.43 cvs 1045: ptrB = ParseCSSBorderStyleRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 1046: ptrB = SkipBlanksAndComments (ptrB);
1047: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 1048: {
1.93 vatton 1049: skippedNL = NewLineSkipped;
1.42 cvs 1050: cssRule = ptrB;
1051: /* apply the Border-Top to Border-Bottom */
1.43 cvs 1052: ptrB = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 1053: NewLineSkipped = skippedNL;
1.42 cvs 1054: /* apply the Border-Right to Border-Left */
1.43 cvs 1055: ptrB = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 1056: }
1057: else
1058: {
1059: /* parse Border-Bottom */
1.43 cvs 1060: ptrL = ParseCSSBorderStyleBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 1061: ptrL = SkipBlanksAndComments (ptrL);
1062: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 1063: {
1064: cssRule = ptrL;
1065: /* apply the Border-Right to Border-Left */
1.43 cvs 1066: ptrL = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 1067: }
1068: else
1069: /* parse Border-Left */
1.43 cvs 1070: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 1071: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 1072: }
1073: }
1074: return (cssRule);
1075: }
1076:
1077: /*----------------------------------------------------------------------
1.59 cvs 1078: ParseCSSBorderTop: parse a CSS BorderTop
1.42 cvs 1079: attribute string.
1080: ----------------------------------------------------------------------*/
1.79 cvs 1081: static char *ParseCSSBorderTop (Element element, PSchema tsch,
1082: PresentationContext context, char *cssRule,
1083: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1084: {
1.79 cvs 1085: char *ptr;
1.43 cvs 1086:
1.82 cvs 1087: cssRule = SkipBlanksAndComments (cssRule);
1088: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1089: {
1090: ptr = cssRule;
1091: cssRule = ParseCSSBorderStyleTop (element, tsch, context, cssRule, css, isHTML);
1092: if (ptr == cssRule)
1093: cssRule = ParseCSSBorderTopWidth (element, tsch, context, cssRule, css, isHTML);
1094: if (ptr == cssRule)
1095: cssRule = ParseCSSBorderColorTop (element, tsch, context, cssRule, css, isHTML);
1096: if (ptr == cssRule)
1097: /* rule not found */
1.168 vatton 1098: cssRule = SkipValue ("Invalid border value", cssRule);
1.82 cvs 1099: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1100: }
1.42 cvs 1101: return (cssRule);
1102: }
1103:
1104: /*----------------------------------------------------------------------
1.59 cvs 1105: ParseCSSBorderLeft: parse a CSS BorderLeft
1.42 cvs 1106: attribute string.
1107: ----------------------------------------------------------------------*/
1.79 cvs 1108: static char *ParseCSSBorderLeft (Element element, PSchema tsch,
1109: PresentationContext context, char *cssRule,
1110: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1111: {
1.79 cvs 1112: char *ptr;
1.43 cvs 1113:
1.82 cvs 1114: cssRule = SkipBlanksAndComments (cssRule);
1115: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1116: {
1117: ptr = cssRule;
1118: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, cssRule, css, isHTML);
1119: if (ptr == cssRule)
1120: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, cssRule, css, isHTML);
1121: if (ptr == cssRule)
1122: cssRule = ParseCSSBorderColorLeft (element, tsch, context, cssRule, css, isHTML);
1123: if (ptr == cssRule)
1124: /* rule not found */
1.168 vatton 1125: cssRule = SkipValue ("Invalid border value", cssRule);
1.82 cvs 1126: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1127: }
1.1 cvs 1128: return (cssRule);
1129: }
1130:
1131: /*----------------------------------------------------------------------
1.59 cvs 1132: ParseCSSBorderBottom: parse a CSS BorderBottom
1.1 cvs 1133: attribute string.
1134: ----------------------------------------------------------------------*/
1.79 cvs 1135: static char *ParseCSSBorderBottom (Element element, PSchema tsch,
1136: PresentationContext context, char *cssRule,
1137: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1138: {
1.79 cvs 1139: char *ptr;
1.43 cvs 1140:
1.82 cvs 1141: cssRule = SkipBlanksAndComments (cssRule);
1142: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1143: {
1144: ptr = cssRule;
1145: cssRule = ParseCSSBorderStyleBottom (element, tsch, context, cssRule, css, isHTML);
1146: if (ptr == cssRule)
1147: cssRule = ParseCSSBorderBottomWidth (element, tsch, context, cssRule, css, isHTML);
1148: if (ptr == cssRule)
1149: cssRule = ParseCSSBorderColorBottom (element, tsch, context, cssRule, css, isHTML);
1150: if (ptr == cssRule)
1151: /* rule not found */
1.168 vatton 1152: cssRule = SkipValue ("Invalid border value", cssRule);
1.82 cvs 1153: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1154: }
1.1 cvs 1155: return (cssRule);
1156: }
1157:
1158: /*----------------------------------------------------------------------
1.59 cvs 1159: ParseCSSBorderRight: parse a CSS BorderRight
1.1 cvs 1160: attribute string.
1161: ----------------------------------------------------------------------*/
1.79 cvs 1162: static char *ParseCSSBorderRight (Element element, PSchema tsch,
1163: PresentationContext context, char *cssRule,
1164: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1165: {
1.79 cvs 1166: char *ptr;
1.43 cvs 1167:
1.82 cvs 1168: cssRule = SkipBlanksAndComments (cssRule);
1169: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1170: {
1171: ptr = cssRule;
1172: cssRule = ParseCSSBorderStyleRight (element, tsch, context, cssRule, css, isHTML);
1173: if (ptr == cssRule)
1174: cssRule = ParseCSSBorderRightWidth (element, tsch, context, cssRule, css, isHTML);
1175: if (ptr == cssRule)
1176: cssRule = ParseCSSBorderColorRight (element, tsch, context, cssRule, css, isHTML);
1177: if (ptr == cssRule)
1178: /* rule not found */
1.168 vatton 1179: cssRule = SkipValue ("Invalid border value", cssRule);
1.82 cvs 1180: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1181: }
1.1 cvs 1182: return (cssRule);
1183: }
1184:
1185: /*----------------------------------------------------------------------
1.59 cvs 1186: ParseCSSBorder: parse a CSS border
1.42 cvs 1187: attribute string.
1188: ----------------------------------------------------------------------*/
1.79 cvs 1189: static char *ParseCSSBorder (Element element, PSchema tsch,
1190: PresentationContext context, char *cssRule,
1191: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 1192: {
1.79 cvs 1193: char *ptrT, *ptrR;
1.93 vatton 1194: int skippedNL;
1.42 cvs 1195:
1.82 cvs 1196: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 1197: /* First parse Border-Top */
1198: ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 1199: ptrR = SkipBlanksAndComments (ptrR);
1200: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 1201: {
1.93 vatton 1202: skippedNL = NewLineSkipped;
1.42 cvs 1203: cssRule = ptrR;
1204: /* apply the Border-Top to all */
1205: ptrR = ParseCSSBorderRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 1206: NewLineSkipped = skippedNL;
1.42 cvs 1207: ptrR = ParseCSSBorderBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 1208: NewLineSkipped = skippedNL;
1.42 cvs 1209: ptrR = ParseCSSBorderLeft (element, tsch, context, ptrT, css, isHTML);
1210: }
1211: return (cssRule);
1212: }
1213:
1214: /*----------------------------------------------------------------------
1.184 vatton 1215: ParseCSSFloat: parse a CSS float attribute string
1216: ----------------------------------------------------------------------*/
1217: static char *ParseCSSFloat (Element element, PSchema tsch,
1218: PresentationContext context, char *cssRule,
1219: CSSInfoPtr css, ThotBool isHTML)
1220: {
1221: PresentationValue pval;
1222: char *ptr;
1223:
1224: pval.typed_data.value = 0;
1.187 vatton 1225: pval.typed_data.unit = UNIT_BOX;
1.192 cvs 1226: pval.typed_data.real = FALSE;
1.190 vatton 1227: if (!strncasecmp (cssRule, "inherit", 7))
1228: {
1229: cssRule = SkipWord (cssRule);
1230: return (cssRule);
1231: }
1.184 vatton 1232: if (!strncasecmp (cssRule, "none", 4))
1233: pval.typed_data.value = FloatNone;
1234: else if (!strncasecmp (cssRule, "left", 4))
1235: pval.typed_data.value = FloatLeft;
1236: else if (!strncasecmp (cssRule, "right", 5))
1237: pval.typed_data.value = FloatRight;
1238:
1239: ptr = cssRule;
1240: cssRule = SkipWord (cssRule);
1241: if (pval.typed_data.value == 0)
1242: CSSParseError ("Invalid float value", ptr, cssRule);
1243: else
1244: {
1245: if (DoApply)
1246: {
1247: if (tsch)
1248: cssRule = CheckImportantRule (cssRule, context);
1249: TtaSetStylePresentation (PRFloat, element, tsch, context, pval);
1250: }
1251: }
1252: cssRule = SkipValue (NULL, cssRule);
1253: return (cssRule);
1254: }
1255:
1256: /*----------------------------------------------------------------------
1257: ParseCSSClear: parse a CSS clear rule
1.1 cvs 1258: ----------------------------------------------------------------------*/
1.79 cvs 1259: static char *ParseCSSClear (Element element, PSchema tsch,
1260: PresentationContext context, char *cssRule,
1261: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1262: {
1.184 vatton 1263: PresentationValue pval;
1264: char *ptr;
1265:
1266: pval.typed_data.value = 0;
1.187 vatton 1267: pval.typed_data.unit = UNIT_BOX;
1.193 vatton 1268: pval.typed_data.real = FALSE;
1.190 vatton 1269: if (!strncasecmp (cssRule, "inherit", 7))
1270: {
1271: cssRule = SkipWord (cssRule);
1272: return (cssRule);
1273: }
1.184 vatton 1274: if (!strncasecmp (cssRule, "none", 4))
1275: pval.typed_data.value = ClearNone;
1276: else if (!strncasecmp (cssRule, "left", 4))
1277: pval.typed_data.value = ClearLeft;
1278: else if (!strncasecmp (cssRule, "right", 5))
1279: pval.typed_data.value = ClearRight;
1280: else if (!strncasecmp (cssRule, "both", 4))
1281: pval.typed_data.value = ClearBoth;
1282:
1283: ptr = cssRule;
1284: cssRule = SkipWord (cssRule);
1285: if (pval.typed_data.value == 0)
1.196 vatton 1286: CSSParseError ("Invalid clear value", ptr, cssRule);
1.184 vatton 1287: else
1288: {
1289: if (DoApply)
1290: {
1291: if (tsch)
1292: cssRule = CheckImportantRule (cssRule, context);
1293: TtaSetStylePresentation (PRClear, element, tsch, context, pval);
1294: }
1295: }
1296: cssRule = SkipValue (NULL, cssRule);
1297: return (cssRule);
1298: }
1299:
1300: /*----------------------------------------------------------------------
1301: ParseCSSContent: parse a CSS content value
1302: ----------------------------------------------------------------------*/
1303: static char *ParseCSSContent (Element element, PSchema tsch,
1304: PresentationContext context, char *cssRule,
1305: CSSInfoPtr css, ThotBool isHTML)
1306: {
1.168 vatton 1307: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1308: return (cssRule);
1309: }
1310:
1311: /*----------------------------------------------------------------------
1.59 cvs 1312: ParseCSSDisplay: parse a CSS display attribute string
1.1 cvs 1313: ----------------------------------------------------------------------*/
1.79 cvs 1314: static char *ParseCSSDisplay (Element element, PSchema tsch,
1315: PresentationContext context, char *cssRule,
1316: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1317: {
1.184 vatton 1318: PresentationValue pval;
1319: char *ptr;
1.1 cvs 1320:
1.184 vatton 1321: pval.typed_data.unit = UNIT_REL;
1322: pval.typed_data.real = FALSE;
1323: cssRule = SkipBlanksAndComments (cssRule);
1324: if (!strncasecmp (cssRule, "none", 4))
1325: {
1326: pval.typed_data.value = 0;
1327: if (DoApply)
1.117 vatton 1328: {
1329: if (tsch)
1330: cssRule = CheckImportantRule (cssRule, context);
1.116 vatton 1331: TtaSetStylePresentation (PRVisibility, element, tsch, context, pval);
1.117 vatton 1332: }
1.184 vatton 1333: cssRule = SkipWord (cssRule);
1334: }
1335: else
1336: {
1337: if (!strncasecmp (cssRule, "block", 5))
1338: pval.typed_data.value = Block;
1339: else if (!strncasecmp (cssRule, "inline", 6))
1340: pval.typed_data.value = Inline;
1341: else if (!strncasecmp (cssRule, "list-item", 9))
1342: pval.typed_data.value = ListItem;
1343: else if (!strncasecmp (cssRule, "run-in", 6))
1344: pval.typed_data.value = RunIn;
1345: else if (!strncasecmp (cssRule, "compact", 7))
1346: pval.typed_data.value = Compact;
1347: else if (!strncasecmp (cssRule, "marker", 6))
1348: pval.typed_data.value = Marker;
1349: else
1350: {
1351: if (strncasecmp (cssRule, "table-row-group", 15) &&
1352: strncasecmp (cssRule, "table-column-group", 18) &&
1353: strncasecmp (cssRule, "table-header-group", 5) &&
1354: strncasecmp (cssRule, "table-footer-group", 6) &&
1355: strncasecmp (cssRule, "table-row", 9) &&
1356: strncasecmp (cssRule, "table-column", 12) &&
1357: strncasecmp (cssRule, "table-cell", 10) &&
1358: strncasecmp (cssRule, "table-caption", 13) &&
1359: strncasecmp (cssRule, "table", 5) &&
1360: strncasecmp (cssRule, "inherit", 7))
1361: {
1362: ptr = cssRule;
1363: cssRule = SkipWord (cssRule);
1364: CSSParseError ("Invalid display value", ptr, cssRule);
1365: }
1366: return (cssRule);
1367: }
1368:
1369: if (DoApply)
1370: {
1371: if (tsch)
1372: cssRule = CheckImportantRule (cssRule, context);
1373: TtaSetStylePresentation (PRDisplay, element, tsch, context, pval);
1374: }
1375: cssRule = SkipWord (cssRule);
1376: }
1.1 cvs 1377: return (cssRule);
1378: }
1379:
1380: /*----------------------------------------------------------------------
1.59 cvs 1381: ParseCSSLetterSpacing: parse a CSS letter-spacing
1.1 cvs 1382: attribute string.
1383: ----------------------------------------------------------------------*/
1.79 cvs 1384: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
1385: PresentationContext context, char *cssRule,
1386: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1387: {
1.168 vatton 1388: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1389: return (cssRule);
1390: }
1391:
1392: /*----------------------------------------------------------------------
1.59 cvs 1393: ParseCSSListStyleType: parse a CSS list-style-type
1.1 cvs 1394: attribute string.
1395: ----------------------------------------------------------------------*/
1.79 cvs 1396: static char *ParseCSSListStyleType (Element element, PSchema tsch,
1397: PresentationContext context, char *cssRule,
1398: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1399: {
1.168 vatton 1400: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1401: return (cssRule);
1402: }
1403:
1404: /*----------------------------------------------------------------------
1.59 cvs 1405: ParseCSSListStyleImage: parse a CSS list-style-image
1.1 cvs 1406: attribute string.
1407: ----------------------------------------------------------------------*/
1.79 cvs 1408: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1409: PresentationContext context, char *cssRule,
1410: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1411: {
1.168 vatton 1412: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1413: return (cssRule);
1414: }
1415:
1416: /*----------------------------------------------------------------------
1.59 cvs 1417: ParseCSSListStylePosition: parse a CSS list-style-position
1.1 cvs 1418: attribute string.
1419: ----------------------------------------------------------------------*/
1.79 cvs 1420: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
1421: PresentationContext context,
1422: char *cssRule, CSSInfoPtr css,
1423: ThotBool isHTML)
1.1 cvs 1424: {
1.168 vatton 1425: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1426: return (cssRule);
1427: }
1428:
1429: /*----------------------------------------------------------------------
1.59 cvs 1430: ParseCSSListStyle: parse a CSS list-style
1.1 cvs 1431: attribute string.
1432: ----------------------------------------------------------------------*/
1.79 cvs 1433: static char *ParseCSSListStyle (Element element, PSchema tsch,
1434: PresentationContext context, char *cssRule,
1435: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1436: {
1.168 vatton 1437: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1438: return (cssRule);
1439: }
1440:
1441: /*----------------------------------------------------------------------
1.59 cvs 1442: ParseCSSTextAlign: parse a CSS text-align
1.1 cvs 1443: attribute string.
1444: ----------------------------------------------------------------------*/
1.79 cvs 1445: static char *ParseCSSTextAlign (Element element, PSchema tsch,
1446: PresentationContext context, char *cssRule,
1447: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1448: {
1449: PresentationValue align;
1.168 vatton 1450: char *ptr;
1.1 cvs 1451:
1452: align.typed_data.value = 0;
1.184 vatton 1453: align.typed_data.unit = UNIT_REL;
1.1 cvs 1454: align.typed_data.real = FALSE;
1455:
1.82 cvs 1456: cssRule = SkipBlanksAndComments (cssRule);
1457: if (!strncasecmp (cssRule, "left", 4))
1.1 cvs 1458: {
1459: align.typed_data.value = AdjustLeft;
1460: cssRule = SkipWord (cssRule);
1461: }
1.82 cvs 1462: else if (!strncasecmp (cssRule, "right", 5))
1.1 cvs 1463: {
1464: align.typed_data.value = AdjustRight;
1465: cssRule = SkipWord (cssRule);
1466: }
1.82 cvs 1467: else if (!strncasecmp (cssRule, "center", 6))
1.1 cvs 1468: {
1469: align.typed_data.value = Centered;
1470: cssRule = SkipWord (cssRule);
1471: }
1.82 cvs 1472: else if (!strncasecmp (cssRule, "justify", 7))
1.1 cvs 1473: {
1.81 cvs 1474: align.typed_data.value = Justify;
1.1 cvs 1475: cssRule = SkipWord (cssRule);
1476: }
1477: else
1478: {
1.168 vatton 1479: ptr = cssRule;
1480: cssRule = SkipWord (cssRule);
1481: CSSParseError ("Invalid text-align value", ptr, cssRule);
1.1 cvs 1482: return (cssRule);
1483: }
1484:
1485: /*
1486: * install the new presentation.
1487: */
1.116 vatton 1488: if (align.typed_data.value && DoApply)
1.117 vatton 1489: {
1490: if (tsch)
1491: cssRule = CheckImportantRule (cssRule, context);
1492: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
1493: }
1.1 cvs 1494: return (cssRule);
1495: }
1496:
1497: /*----------------------------------------------------------------------
1.112 quint 1498: ParseCSSDirection: parse a CSS direction property
1499: ----------------------------------------------------------------------*/
1500: static char *ParseCSSDirection (Element element, PSchema tsch,
1501: PresentationContext context, char *cssRule,
1502: CSSInfoPtr css, ThotBool isHTML)
1503: {
1504: PresentationValue direction;
1.168 vatton 1505: char *ptr;
1.112 quint 1506:
1507: direction.typed_data.value = 0;
1.184 vatton 1508: direction.typed_data.unit = UNIT_REL;
1.112 quint 1509: direction.typed_data.real = FALSE;
1510:
1511: cssRule = SkipBlanksAndComments (cssRule);
1512: if (!strncasecmp (cssRule, "ltr", 3))
1513: {
1.184 vatton 1514: direction.typed_data.value = LeftToRight;
1.112 quint 1515: cssRule = SkipWord (cssRule);
1516: }
1517: else if (!strncasecmp (cssRule, "rtl", 3))
1518: {
1.184 vatton 1519: direction.typed_data.value = RightToLeft;
1.112 quint 1520: cssRule = SkipWord (cssRule);
1521: }
1522: else if (!strncasecmp (cssRule, "inherit", 7))
1523: {
1524: /* not implemented */
1525: cssRule = SkipWord (cssRule);
1526: return (cssRule);
1527: }
1528: else
1529: {
1.168 vatton 1530: ptr = cssRule;
1531: cssRule = SkipWord (cssRule);
1532: CSSParseError ("Invalid direction value", ptr, cssRule);
1.112 quint 1533: return (cssRule);
1534: }
1535:
1536: /*
1537: * install the new presentation.
1538: */
1.116 vatton 1539: if (direction.typed_data.value && DoApply)
1.117 vatton 1540: {
1541: if (tsch)
1542: cssRule = CheckImportantRule (cssRule, context);
1543: TtaSetStylePresentation (PRDirection, element, tsch, context, direction);
1544: }
1.112 quint 1545: return (cssRule);
1546: }
1547:
1548: /*----------------------------------------------------------------------
1.113 quint 1549: ParseCSSUnicodeBidi: parse a CSS unicode-bidi property
1550: ----------------------------------------------------------------------*/
1551: static char *ParseCSSUnicodeBidi (Element element, PSchema tsch,
1552: PresentationContext context, char *cssRule,
1553: CSSInfoPtr css, ThotBool isHTML)
1554: {
1555: PresentationValue bidi;
1.168 vatton 1556: char *ptr;
1.113 quint 1557:
1558: bidi.typed_data.value = 0;
1.184 vatton 1559: bidi.typed_data.unit = UNIT_REL;
1.113 quint 1560: bidi.typed_data.real = FALSE;
1561:
1562: cssRule = SkipBlanksAndComments (cssRule);
1563: if (!strncasecmp (cssRule, "normal", 6))
1564: {
1.184 vatton 1565: bidi.typed_data.value = Normal;
1.113 quint 1566: cssRule = SkipWord (cssRule);
1567: }
1568: else if (!strncasecmp (cssRule, "embed", 5))
1569: {
1.184 vatton 1570: bidi.typed_data.value = Embed;
1.113 quint 1571: cssRule = SkipWord (cssRule);
1572: }
1573: else if (!strncasecmp (cssRule, "override", 8))
1574: {
1.184 vatton 1575: bidi.typed_data.value = Override;
1.113 quint 1576: cssRule = SkipWord (cssRule);
1577: }
1578: else if (!strncasecmp (cssRule, "inherit", 7))
1579: {
1580: /* not implemented */
1581: cssRule = SkipWord (cssRule);
1582: return (cssRule);
1583: }
1584: else
1585: {
1.168 vatton 1586: ptr = cssRule;
1587: cssRule = SkipWord (cssRule);
1588: CSSParseError ("Invalid unicode-bidi value", ptr, cssRule);
1.113 quint 1589: return (cssRule);
1590: }
1591:
1592: /*
1593: * install the new presentation.
1594: */
1.116 vatton 1595: if (bidi.typed_data.value && DoApply)
1.117 vatton 1596: {
1597: if (tsch)
1598: cssRule = CheckImportantRule (cssRule, context);
1599: TtaSetStylePresentation (PRUnicodeBidi, element, tsch, context, bidi);
1600: }
1.113 quint 1601: return (cssRule);
1602: }
1603:
1604: /*----------------------------------------------------------------------
1.168 vatton 1605: ParseCSSTextIndent: parse a CSS text-indent
1.1 cvs 1606: attribute string.
1607: ----------------------------------------------------------------------*/
1.79 cvs 1608: static char *ParseCSSTextIndent (Element element, PSchema tsch,
1609: PresentationContext context, char *cssRule,
1610: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1611: {
1612: PresentationValue pval;
1.168 vatton 1613: char *ptr;
1.1 cvs 1614:
1.82 cvs 1615: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 1616: ptr = cssRule;
1.1 cvs 1617: cssRule = ParseCSSUnit (cssRule, &pval);
1.168 vatton 1618: if (pval.typed_data.value == 0)
1.184 vatton 1619: pval.typed_data.unit = UNIT_PX;
1620: else if (pval.typed_data.unit == UNIT_INVALID ||
1621: pval.typed_data.unit == UNIT_BOX)
1.168 vatton 1622: {
1623: CSSParseError ("Invalid text-indent value", ptr, cssRule);
1624: return (cssRule);
1625: }
1.1 cvs 1626: /* install the attribute */
1.116 vatton 1627: if (DoApply)
1.117 vatton 1628: {
1629: if (tsch)
1630: cssRule = CheckImportantRule (cssRule, context);
1631: TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
1632: }
1.1 cvs 1633: return (cssRule);
1634: }
1635:
1636: /*----------------------------------------------------------------------
1.59 cvs 1637: ParseCSSTextTransform: parse a CSS text-transform
1.1 cvs 1638: attribute string.
1639: ----------------------------------------------------------------------*/
1.79 cvs 1640: static char *ParseCSSTextTransform (Element element, PSchema tsch,
1641: PresentationContext context, char *cssRule,
1642: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1643: {
1.168 vatton 1644: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1645: return (cssRule);
1646: }
1647:
1648: /*----------------------------------------------------------------------
1.59 cvs 1649: ParseCSSVerticalAlign: parse a CSS vertical-align
1.1 cvs 1650: attribute string.
1651: ----------------------------------------------------------------------*/
1.79 cvs 1652: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
1653: PresentationContext context, char *cssRule,
1654: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1655: {
1.168 vatton 1656: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1657: return (cssRule);
1658: }
1659:
1660: /*----------------------------------------------------------------------
1.59 cvs 1661: ParseCSSWhiteSpace: parse a CSS white-space
1.1 cvs 1662: attribute string.
1663: ----------------------------------------------------------------------*/
1.79 cvs 1664: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
1665: PresentationContext context, char *cssRule,
1666: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1667: {
1.82 cvs 1668: cssRule = SkipBlanksAndComments (cssRule);
1669: if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1670: cssRule = SkipWord (cssRule);
1.82 cvs 1671: else if (!strncasecmp (cssRule, "pre", 3))
1.1 cvs 1672: cssRule = SkipWord (cssRule);
1673: else
1674: return (cssRule);
1675: return (cssRule);
1676: }
1677:
1678: /*----------------------------------------------------------------------
1.59 cvs 1679: ParseCSSWordSpacing: parse a CSS word-spacing
1.1 cvs 1680: attribute string.
1681: ----------------------------------------------------------------------*/
1.79 cvs 1682: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
1683: PresentationContext context, char *cssRule,
1684: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1685: {
1.168 vatton 1686: cssRule = SkipValue (NULL, cssRule);
1.1 cvs 1687: return (cssRule);
1688: }
1689:
1690: /*----------------------------------------------------------------------
1.162 quint 1691: ParseCSSLineHeight: parse a CSS line-height property
1.25 cvs 1692: ----------------------------------------------------------------------*/
1.162 quint 1693: static char *ParseCSSLineHeight (Element element, PSchema tsch,
1.166 vatton 1694: PresentationContext context, char *cssRule,
1695: CSSInfoPtr css, ThotBool isHTML)
1.25 cvs 1696: {
1.162 quint 1697: PresentationValue pval;
1698: char *ptr;
1699:
1700: ptr = cssRule;
1701: if (!strncasecmp (cssRule, "normal", 6))
1702: {
1.184 vatton 1703: pval.typed_data.unit = UNIT_REL;
1.162 quint 1704: pval.typed_data.real = TRUE;
1705: pval.typed_data.value = 1100;
1706: cssRule = SkipWord (cssRule);
1707: }
1708: else if (!strncasecmp (cssRule, "inherit", 7))
1709: {
1710: cssRule = SkipWord (cssRule);
1711: return (cssRule);
1712: }
1713: else
1714: cssRule = ParseCSSUnit (cssRule, &pval);
1.25 cvs 1715:
1.184 vatton 1716: if (pval.typed_data.unit == UNIT_INVALID)
1.168 vatton 1717: CSSParseError ("Invalid line-height value", ptr, cssRule);
1.162 quint 1718: else if (DoApply)
1719: {
1.166 vatton 1720: /* install the new presentation */
1.184 vatton 1721: if (pval.typed_data.unit == UNIT_BOX)
1722: pval.typed_data.unit = UNIT_EM;
1.162 quint 1723: if (tsch)
1724: cssRule = CheckImportantRule (cssRule, context);
1725: TtaSetStylePresentation (PRLineSpacing, element, tsch, context, pval);
1726: }
1727: return (cssRule);
1.25 cvs 1728: }
1729:
1730: /*----------------------------------------------------------------------
1.59 cvs 1731: ParseCSSFontSize: parse a CSS font size attr string
1.1 cvs 1732: we expect the input string describing the attribute to be
1733: xx-small, x-small, small, medium, large, x-large, xx-large
1734: or an absolute size, or an imcrement relative to the parent
1735: ----------------------------------------------------------------------*/
1.79 cvs 1736: static char *ParseCSSFontSize (Element element, PSchema tsch,
1737: PresentationContext context, char *cssRule,
1738: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1739: {
1.171 quint 1740: ElementType elType;
1.1 cvs 1741: PresentationValue pval;
1.137 vatton 1742: char *ptr = NULL, *ptr1 = NULL;
1.14 cvs 1743: ThotBool real;
1.1 cvs 1744:
1745: pval.typed_data.real = FALSE;
1.82 cvs 1746: cssRule = SkipBlanksAndComments (cssRule);
1747: if (!strncasecmp (cssRule, "larger", 6))
1.1 cvs 1748: {
1.184 vatton 1749: pval.typed_data.unit = UNIT_PERCENT;
1.1 cvs 1750: pval.typed_data.value = 130;
1751: cssRule = SkipWord (cssRule);
1752: }
1.82 cvs 1753: else if (!strncasecmp (cssRule, "smaller", 7))
1.1 cvs 1754: {
1.184 vatton 1755: pval.typed_data.unit = UNIT_PERCENT;
1.1 cvs 1756: pval.typed_data.value = 80;
1757: cssRule = SkipWord (cssRule);
1758: }
1.82 cvs 1759: else if (!strncasecmp (cssRule, "xx-small", 8))
1.1 cvs 1760: {
1.184 vatton 1761: pval.typed_data.unit = UNIT_REL;
1.1 cvs 1762: pval.typed_data.value = 1;
1763: cssRule = SkipWord (cssRule);
1764: }
1.82 cvs 1765: else if (!strncasecmp (cssRule, "x-small", 7))
1.1 cvs 1766: {
1.184 vatton 1767: pval.typed_data.unit = UNIT_REL;
1.1 cvs 1768: pval.typed_data.value = 2;
1769: cssRule = SkipWord (cssRule);
1770: }
1.82 cvs 1771: else if (!strncasecmp (cssRule, "small", 5))
1.1 cvs 1772: {
1.184 vatton 1773: pval.typed_data.unit = UNIT_REL;
1.1 cvs 1774: pval.typed_data.value = 3;
1775: cssRule = SkipWord (cssRule);
1776: }
1.82 cvs 1777: else if (!strncasecmp (cssRule, "medium", 6))
1.1 cvs 1778: {
1.184 vatton 1779: pval.typed_data.unit = UNIT_REL;
1.1 cvs 1780: pval.typed_data.value = 4;
1781: cssRule = SkipWord (cssRule);
1782: }
1.82 cvs 1783: else if (!strncasecmp (cssRule, "large", 5))
1.1 cvs 1784: {
1.184 vatton 1785: pval.typed_data.unit = UNIT_REL;
1.1 cvs 1786: pval.typed_data.value = 5;
1787: cssRule = SkipWord (cssRule);
1788: }
1.82 cvs 1789: else if (!strncasecmp (cssRule, "x-large", 7))
1.1 cvs 1790: {
1.184 vatton 1791: pval.typed_data.unit = UNIT_REL;
1.1 cvs 1792: pval.typed_data.value = 6;
1793: cssRule = SkipWord (cssRule);
1794: }
1.82 cvs 1795: else if (!strncasecmp (cssRule, "xx-large", 8))
1.1 cvs 1796: {
1.184 vatton 1797: pval.typed_data.unit = UNIT_REL;
1.1 cvs 1798: pval.typed_data.value = 7;
1799: cssRule = SkipWord (cssRule);
1800: }
1.171 quint 1801: else if (!isdigit (*cssRule) && *cssRule != '.')
1802: return (cssRule);
1.1 cvs 1803: else
1804: {
1.25 cvs 1805: /* look for a '/' within the current cssRule */
1.137 vatton 1806: ptr1 = strchr (cssRule, ';');
1.82 cvs 1807: ptr = strchr (cssRule, '/');
1.137 vatton 1808: if (ptr && (ptr1 == NULL || ptr < ptr1))
1.25 cvs 1809: {
1810: /* keep the line spacing rule */
1.82 cvs 1811: ptr[0] = EOS;
1.25 cvs 1812: ptr = &ptr[1];
1813: }
1.137 vatton 1814: else
1815: ptr = NULL;
1.171 quint 1816:
1.1 cvs 1817: cssRule = ParseCSSUnit (cssRule, &pval);
1.171 quint 1818:
1.184 vatton 1819: if (pval.typed_data.unit == UNIT_BOX)
1.171 quint 1820: /* no unit specified */
1821: {
1822: elType = TtaGetElementType(element);
1823: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
1824: /* we are working for an SVG element. No unit means pixels */
1.184 vatton 1825: pval.typed_data.unit = UNIT_PX;
1.171 quint 1826: }
1.168 vatton 1827: if (pval.typed_data.value != 0 &&
1.184 vatton 1828: (pval.typed_data.unit == UNIT_INVALID ||
1829: pval.typed_data.unit == UNIT_BOX ||
1.168 vatton 1830: pval.typed_data.value < 0))
1831: /* not a valid value */
1.1 cvs 1832: return (cssRule);
1.184 vatton 1833: else if (pval.typed_data.unit == UNIT_REL && pval.typed_data.value > 0)
1.1 cvs 1834: /* CSS relative sizes have to be higher than Thot ones */
1835: pval.typed_data.value += 1;
1836: else
1837: {
1838: real = pval.typed_data.real;
1.184 vatton 1839: if (pval.typed_data.unit == UNIT_EM)
1.1 cvs 1840: {
1841: if (real)
1842: {
1843: pval.typed_data.value /= 10;
1.11 cvs 1844: pval.typed_data.real = FALSE;
1.1 cvs 1845: real = FALSE;
1846: }
1847: else
1848: pval.typed_data.value *= 100;
1.184 vatton 1849: pval.typed_data.unit = UNIT_PERCENT;
1.1 cvs 1850: }
1.184 vatton 1851: else if (pval.typed_data.unit == UNIT_XHEIGHT)
1.146 quint 1852: {
1853: /* a font size expressed in ex is converted into a percentage.
1854: For example, "3ex" is converted into "180%", supposing
1855: that 1ex is approximately 0.6 times the height of the
1856: current font */
1857: if (real)
1858: {
1859: pval.typed_data.value *= 6;
1860: pval.typed_data.value /= 100;
1861: pval.typed_data.real = FALSE;
1862: real = FALSE;
1863: }
1864: else
1865: pval.typed_data.value *= 60;
1.184 vatton 1866: pval.typed_data.unit = UNIT_PERCENT;
1.146 quint 1867: }
1.1 cvs 1868: }
1869: }
1870:
1.25 cvs 1871: /* install the presentation style */
1.116 vatton 1872: if (DoApply)
1.117 vatton 1873: {
1874: if (tsch)
1875: cssRule = CheckImportantRule (cssRule, context);
1876: TtaSetStylePresentation (PRSize, element, tsch, context, pval);
1877: }
1878: if (ptr)
1.162 quint 1879: cssRule = ParseCSSLineHeight (element, tsch, context, ptr, css, isHTML);
1.1 cvs 1880: return (cssRule);
1881: }
1882:
1883: /*----------------------------------------------------------------------
1.59 cvs 1884: ParseCSSFontFamily: parse a CSS font family string
1.1 cvs 1885: we expect the input string describing the attribute to be
1886: a common generic font style name
1887: ----------------------------------------------------------------------*/
1.79 cvs 1888: static char *ParseCSSFontFamily (Element element, PSchema tsch,
1889: PresentationContext context, char *cssRule,
1890: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1891: {
1892: PresentationValue font;
1.79 cvs 1893: char quoteChar;
1.1 cvs 1894:
1895: font.typed_data.value = 0;
1.184 vatton 1896: font.typed_data.unit = UNIT_REL;
1.1 cvs 1897: font.typed_data.real = FALSE;
1.82 cvs 1898: cssRule = SkipBlanksAndComments (cssRule);
1899: if (*cssRule == '"' || *cssRule == '\'')
1.1 cvs 1900: {
1901: quoteChar = *cssRule;
1902: cssRule++;
1903: }
1904: else
1.82 cvs 1905: quoteChar = EOS;
1.1 cvs 1906:
1.92 cvs 1907: if (!strncasecmp (cssRule, "times", 5) &&
1908: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 1909: {
1.184 vatton 1910: font.typed_data.value = FontTimes;
1.86 cvs 1911: cssRule += 5;
1912: }
1.92 cvs 1913: else if (!strncasecmp (cssRule, "serif", 5) &&
1914: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 1915: {
1.184 vatton 1916: font.typed_data.value = FontTimes;
1.86 cvs 1917: cssRule += 5;
1.92 cvs 1918: if (quoteChar != EOS)
1919: cssRule++;
1.86 cvs 1920: }
1.92 cvs 1921: else if (!strncasecmp (cssRule, "helvetica", 9) &&
1922: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 1923: {
1.184 vatton 1924: font.typed_data.value = FontHelvetica;
1.86 cvs 1925: cssRule += 9;
1.92 cvs 1926: if (quoteChar != EOS)
1927: cssRule++;
1.86 cvs 1928: }
1.92 cvs 1929: else if (!strncasecmp (cssRule, "verdana", 7) &&
1930: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 1931: {
1.184 vatton 1932: font.typed_data.value = FontHelvetica;
1.86 cvs 1933: cssRule += 7;
1.92 cvs 1934: if (quoteChar != EOS)
1935: cssRule++;
1.86 cvs 1936: }
1.92 cvs 1937: else if (!strncasecmp (cssRule, "sans-serif", 10) &&
1938: (quoteChar == EOS || quoteChar == cssRule[10]))
1.86 cvs 1939: {
1.184 vatton 1940: font.typed_data.value = FontHelvetica;
1.86 cvs 1941: cssRule += 10;
1.92 cvs 1942: if (quoteChar != EOS)
1943: cssRule++;
1.86 cvs 1944: }
1.92 cvs 1945: else if (!strncasecmp (cssRule, "courier", 7) &&
1946: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 1947: {
1.184 vatton 1948: font.typed_data.value = FontCourier;
1.86 cvs 1949: cssRule += 7;
1.92 cvs 1950: if (quoteChar != EOS)
1951: cssRule++;
1.86 cvs 1952: }
1.92 cvs 1953: else if (!strncasecmp (cssRule, "monospace", 9) &&
1954: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 1955: {
1.184 vatton 1956: font.typed_data.value = FontCourier;
1.86 cvs 1957: cssRule += 9;
1.92 cvs 1958: if (quoteChar != EOS)
1959: cssRule++;
1.86 cvs 1960: }
1.1 cvs 1961: else
1962: /* unknown font name. Skip it */
1963: {
1.92 cvs 1964: if (quoteChar != EOS)
1.54 cvs 1965: cssRule = SkipQuotedString (cssRule, quoteChar);
1.86 cvs 1966: else
1.1 cvs 1967: cssRule = SkipWord (cssRule);
1.82 cvs 1968: cssRule = SkipBlanksAndComments (cssRule);
1969: if (*cssRule == ',')
1.1 cvs 1970: {
1.86 cvs 1971: cssRule++;
1972: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1973: return (cssRule);
1.1 cvs 1974: }
1975: }
1976:
1977: if (font.typed_data.value != 0)
1978: {
1.93 vatton 1979: cssRule = SkipBlanksAndComments (cssRule);
1.133 vatton 1980: if (*cssRule == ',')
1981: {
1982: cssRule++;
1.168 vatton 1983: cssRule = SkipValue (NULL, cssRule);
1.133 vatton 1984: }
1.93 vatton 1985: /* install the new presentation */
1.116 vatton 1986: if (DoApply)
1.117 vatton 1987: {
1988: if (tsch)
1989: cssRule = CheckImportantRule (cssRule, context);
1990: TtaSetStylePresentation (PRFont, element, tsch, context, font);
1991: }
1.1 cvs 1992: }
1993: return (cssRule);
1994: }
1995:
1996: /*----------------------------------------------------------------------
1.59 cvs 1997: ParseCSSFontWeight: parse a CSS font weight string
1.1 cvs 1998: we expect the input string describing the attribute to be
1.20 cvs 1999: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 2000: ----------------------------------------------------------------------*/
1.79 cvs 2001: static char *ParseCSSFontWeight (Element element, PSchema tsch,
2002: PresentationContext context, char *cssRule,
2003: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2004: {
1.20 cvs 2005: PresentationValue weight;
1.1 cvs 2006:
2007: weight.typed_data.value = 0;
1.184 vatton 2008: weight.typed_data.unit = UNIT_REL;
1.1 cvs 2009: weight.typed_data.real = FALSE;
1.82 cvs 2010: cssRule = SkipBlanksAndComments (cssRule);
2011: if (!strncasecmp (cssRule, "100", 3) && !isalpha (cssRule[3]))
1.1 cvs 2012: {
2013: weight.typed_data.value = -3;
2014: cssRule = SkipWord (cssRule);
2015: }
1.82 cvs 2016: else if (!strncasecmp (cssRule, "200", 3) && !isalpha (cssRule[3]))
1.1 cvs 2017: {
2018: weight.typed_data.value = -2;
2019: cssRule = SkipWord (cssRule);
2020: }
1.82 cvs 2021: else if (!strncasecmp (cssRule, "300", 3) && ! isalpha(cssRule[3]))
1.1 cvs 2022: {
2023: weight.typed_data.value = -1;
2024: cssRule = SkipWord (cssRule);
2025: }
1.82 cvs 2026: else if (!strncasecmp (cssRule, "normal", 6) || (!strncasecmp (cssRule, "400", 3) && !isalpha (cssRule[3])))
1.1 cvs 2027: {
2028: weight.typed_data.value = 0;
2029: cssRule = SkipWord (cssRule);
2030: }
1.82 cvs 2031: else if (!strncasecmp (cssRule, "500", 3) && !isalpha (cssRule[3]))
1.1 cvs 2032: {
2033: weight.typed_data.value = +1;
2034: cssRule = SkipWord (cssRule);
2035: }
1.82 cvs 2036: else if (!strncasecmp (cssRule, "600", 3) && !isalpha (cssRule[3]))
1.1 cvs 2037: {
2038: weight.typed_data.value = +2;
2039: cssRule = SkipWord (cssRule);
2040: }
1.82 cvs 2041: else if (!strncasecmp (cssRule, "bold", 4) || (!strncasecmp (cssRule, "700", 3) && !isalpha (cssRule[3])))
1.1 cvs 2042: {
2043: weight.typed_data.value = +3;
2044: cssRule = SkipWord (cssRule);
2045: }
1.82 cvs 2046: else if (!strncasecmp (cssRule, "800", 3) && !isalpha (cssRule[3]))
1.1 cvs 2047: {
2048: weight.typed_data.value = +4;
2049: cssRule = SkipWord (cssRule);
2050: }
1.82 cvs 2051: else if (!strncasecmp (cssRule, "900", 3) && !isalpha (cssRule[3]))
1.1 cvs 2052: {
2053: weight.typed_data.value = +5;
2054: cssRule = SkipWord (cssRule);
2055: }
1.82 cvs 2056: else if (!strncasecmp (cssRule, "inherit", 7) || !strncasecmp (cssRule, "bolder", 6) || !strncasecmp (cssRule, "lighter", 7))
1.1 cvs 2057: {
2058: /* not implemented */
2059: cssRule = SkipWord (cssRule);
2060: return (cssRule);
2061: }
2062: else
2063: return (cssRule);
2064:
2065: /*
1.20 cvs 2066: * Here we have to reduce since only two font weight values are supported
1.1 cvs 2067: * by the Thot presentation API.
2068: */
1.20 cvs 2069: if (weight.typed_data.value > 0)
1.184 vatton 2070: weight.typed_data.value = WeightBold;
1.20 cvs 2071: else
1.184 vatton 2072: weight.typed_data.value = WeightNormal;
1.1 cvs 2073:
2074: /* install the new presentation */
1.116 vatton 2075: if (DoApply)
1.117 vatton 2076: {
2077: if (tsch)
2078: cssRule = CheckImportantRule (cssRule, context);
2079: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
2080: }
1.1 cvs 2081: return (cssRule);
2082: }
2083:
2084: /*----------------------------------------------------------------------
1.59 cvs 2085: ParseCSSFontVariant: parse a CSS font variant string
1.1 cvs 2086: we expect the input string describing the attribute to be
2087: normal or small-caps
2088: ----------------------------------------------------------------------*/
1.79 cvs 2089: static char *ParseCSSFontVariant (Element element, PSchema tsch,
2090: PresentationContext context, char *cssRule,
2091: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2092: {
2093: PresentationValue style;
2094:
2095: style.typed_data.value = 0;
1.184 vatton 2096: style.typed_data.unit = UNIT_REL;
1.1 cvs 2097: style.typed_data.real = FALSE;
1.82 cvs 2098: cssRule = SkipBlanksAndComments (cssRule);
2099: if (!strncasecmp (cssRule, "small-caps", 10))
1.1 cvs 2100: {
2101: /* Not supported yet */
2102: cssRule = SkipWord (cssRule);
2103: }
1.82 cvs 2104: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 2105: {
2106: /* Not supported yet */
2107: cssRule = SkipWord (cssRule);
2108: }
1.82 cvs 2109: else if (!strncasecmp (cssRule, "inherit", 7))
1.1 cvs 2110: {
2111: /* Not supported yet */
2112: cssRule = SkipWord (cssRule);
2113: }
2114: else
2115: return (cssRule);
2116:
2117: return (cssRule);
2118: }
2119:
2120:
2121: /*----------------------------------------------------------------------
1.59 cvs 2122: ParseCSSFontStyle: parse a CSS font style string
1.1 cvs 2123: we expect the input string describing the attribute to be
2124: italic, oblique or normal
2125: ----------------------------------------------------------------------*/
1.79 cvs 2126: static char *ParseCSSFontStyle (Element element, PSchema tsch,
2127: PresentationContext context, char *cssRule,
2128: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2129: {
2130: PresentationValue style;
2131: PresentationValue size;
2132:
2133: style.typed_data.value = 0;
1.184 vatton 2134: style.typed_data.unit = UNIT_REL;
1.1 cvs 2135: style.typed_data.real = FALSE;
2136: size.typed_data.value = 0;
1.184 vatton 2137: size.typed_data.unit = UNIT_REL;
1.1 cvs 2138: size.typed_data.real = FALSE;
1.82 cvs 2139: cssRule = SkipBlanksAndComments (cssRule);
2140: if (!strncasecmp (cssRule, "italic", 6))
1.1 cvs 2141: {
1.184 vatton 2142: style.typed_data.value = StyleItalics;
1.1 cvs 2143: cssRule = SkipWord (cssRule);
2144: }
1.82 cvs 2145: else if (!strncasecmp (cssRule, "oblique", 7))
1.1 cvs 2146: {
1.184 vatton 2147: style.typed_data.value = StyleOblique;
1.1 cvs 2148: cssRule = SkipWord (cssRule);
2149: }
1.82 cvs 2150: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 2151: {
1.184 vatton 2152: style.typed_data.value = StyleRoman;
1.1 cvs 2153: cssRule = SkipWord (cssRule);
2154: }
1.108 cvs 2155: else if (!strncasecmp (cssRule, "inherit", 7))
2156: {
2157: /* not implemented */
2158: cssRule = SkipWord (cssRule);
2159: return (cssRule);
2160: }
1.1 cvs 2161: else
2162: {
2163: /* invalid font style */
1.108 cvs 2164: return (cssRule);
1.1 cvs 2165: }
2166:
2167: /*
2168: * install the new presentation.
2169: */
1.116 vatton 2170: if (style.typed_data.value != 0 && DoApply)
1.117 vatton 2171: {
2172: if (tsch)
2173: cssRule = CheckImportantRule (cssRule, context);
1.20 cvs 2174: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.117 vatton 2175: }
1.116 vatton 2176: if (size.typed_data.value != 0 && DoApply)
1.1 cvs 2177: {
2178: PresentationValue previous_size;
2179:
2180: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
2181: {
2182: /* !!!!!!!!!!!!!!!!!!!!!!!! Unite + relatif !!!!!!!!!!!!!!!! */
2183: size.typed_data.value += previous_size.typed_data.value;
2184: TtaSetStylePresentation (PRSize, element, tsch, context, size);
2185: }
2186: else
2187: {
2188: size.typed_data.value = 10;
2189: TtaSetStylePresentation (PRSize, element, tsch, context, size);
2190: }
2191: }
2192: return (cssRule);
2193: }
2194:
2195: /*----------------------------------------------------------------------
1.59 cvs 2196: ParseCSSFont: parse a CSS font attribute string
2197: we expect the input string describing the attribute to be
2198: !!!!!!
1.1 cvs 2199: ----------------------------------------------------------------------*/
1.79 cvs 2200: static char *ParseCSSFont (Element element, PSchema tsch,
2201: PresentationContext context, char *cssRule,
2202: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2203: {
1.79 cvs 2204: char *ptr;
1.93 vatton 2205: int skippedNL;
1.1 cvs 2206:
1.82 cvs 2207: cssRule = SkipBlanksAndComments (cssRule);
2208: if (!strncasecmp (cssRule, "caption", 7))
1.1 cvs 2209: ;
1.82 cvs 2210: else if (!strncasecmp (cssRule, "icon", 4))
1.1 cvs 2211: ;
1.82 cvs 2212: else if (!strncasecmp (cssRule, "menu", 4))
1.1 cvs 2213: ;
1.82 cvs 2214: else if (!strncasecmp (cssRule, "message-box", 11))
1.1 cvs 2215: ;
1.82 cvs 2216: else if (!strncasecmp (cssRule, "small-caption", 13))
1.1 cvs 2217: ;
1.82 cvs 2218: else if (!strncasecmp (cssRule, "status-bar", 10))
1.1 cvs 2219: ;
2220: else
1.43 cvs 2221: {
1.133 vatton 2222: while (*cssRule != ';' && *cssRule != EOS)
1.43 cvs 2223: {
1.72 cvs 2224: ptr = cssRule;
1.93 vatton 2225: skippedNL = NewLineSkipped;
1.72 cvs 2226: cssRule = ParseCSSFontStyle (element, tsch, context, cssRule, css, isHTML);
2227: if (ptr == cssRule)
1.93 vatton 2228: {
2229: NewLineSkipped = skippedNL;
2230: cssRule = ParseCSSFontVariant (element, tsch, context, cssRule, css, isHTML);
2231: }
1.72 cvs 2232: if (ptr == cssRule)
1.93 vatton 2233: {
2234: NewLineSkipped = skippedNL;
2235: cssRule = ParseCSSFontWeight (element, tsch, context, cssRule, css, isHTML);
2236: }
1.72 cvs 2237: if (ptr == cssRule)
1.93 vatton 2238: {
2239: NewLineSkipped = skippedNL;
2240: cssRule = ParseCSSFontSize (element, tsch, context, cssRule, css, isHTML);
2241: }
1.72 cvs 2242: if (ptr == cssRule)
1.93 vatton 2243: {
2244: NewLineSkipped = skippedNL;
2245: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
2246: }
1.99 vatton 2247: if (ptr == cssRule)
1.168 vatton 2248: cssRule = SkipValue ("Invalid font value", cssRule);
1.82 cvs 2249: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2250: }
2251: }
2252: return (cssRule);
1.1 cvs 2253: }
2254:
2255: /*----------------------------------------------------------------------
1.59 cvs 2256: ParseCSSTextDecoration: parse a CSS text decor string
2257: we expect the input string describing the attribute to be
1.109 cvs 2258: underline, overline, line-through, blink or none.
1.1 cvs 2259: ----------------------------------------------------------------------*/
1.79 cvs 2260: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
2261: PresentationContext context, char *cssRule,
2262: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2263: {
2264: PresentationValue decor;
1.168 vatton 2265: char *ptr;
1.1 cvs 2266:
2267: decor.typed_data.value = 0;
1.184 vatton 2268: decor.typed_data.unit = UNIT_REL;
1.1 cvs 2269: decor.typed_data.real = FALSE;
1.82 cvs 2270: cssRule = SkipBlanksAndComments (cssRule);
1.142 quint 2271: if (!strncasecmp (cssRule, "none", strlen ("none")))
2272: {
2273: decor.typed_data.value = NoUnderline;
2274: cssRule = SkipWord (cssRule);
2275: }
2276: else if (!strncasecmp (cssRule, "underline", strlen ("underline")))
1.1 cvs 2277: {
2278: decor.typed_data.value = Underline;
2279: cssRule = SkipWord (cssRule);
2280: }
1.82 cvs 2281: else if (!strncasecmp (cssRule, "overline", strlen ("overline")))
1.1 cvs 2282: {
2283: decor.typed_data.value = Overline;
2284: cssRule = SkipWord (cssRule);
2285: }
1.82 cvs 2286: else if (!strncasecmp (cssRule, "line-through", strlen ("line-through")))
1.1 cvs 2287: {
2288: decor.typed_data.value = CrossOut;
2289: cssRule = SkipWord (cssRule);
2290: }
1.82 cvs 2291: else if (!strncasecmp (cssRule, "blink", strlen ("blink")))
1.1 cvs 2292: {
1.109 cvs 2293: /* the blink text-decoration attribute is not supported */
1.1 cvs 2294: cssRule = SkipWord (cssRule);
2295: }
1.142 quint 2296: else if (!strncasecmp (cssRule, "inherit", 7))
1.1 cvs 2297: {
1.142 quint 2298: cssRule = SkipWord (cssRule);
2299: return (cssRule);
1.1 cvs 2300: }
2301: else
2302: {
1.168 vatton 2303: ptr = cssRule;
2304: cssRule = SkipWord (cssRule);
2305: CSSParseError ("Invalid text-decoration value", ptr, cssRule);
1.1 cvs 2306: return (cssRule);
2307: }
2308:
2309: /*
2310: * install the new presentation.
2311: */
1.116 vatton 2312: if (decor.typed_data.value && DoApply)
1.1 cvs 2313: {
1.117 vatton 2314: if (tsch)
2315: cssRule = CheckImportantRule (cssRule, context);
1.1 cvs 2316: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
2317: }
2318: return (cssRule);
2319: }
2320:
2321: /*----------------------------------------------------------------------
1.59 cvs 2322: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 2323: ----------------------------------------------------------------------*/
1.79 cvs 2324: static char *ParseCSSHeight (Element element, PSchema tsch,
1.93 vatton 2325: PresentationContext context, char *cssRule,
2326: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2327: {
1.117 vatton 2328: PresentationValue val;
1.168 vatton 2329: char *ptr;
1.93 vatton 2330:
1.117 vatton 2331: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2332: ptr = cssRule;
1.117 vatton 2333: /* first parse the attribute string */
1.164 quint 2334: if (!strncasecmp (cssRule, "auto", 4))
2335: {
1.184 vatton 2336: val.typed_data.unit = VALUE_AUTO;
1.164 quint 2337: val.typed_data.value = 0;
2338: val.typed_data.real = FALSE;
2339: cssRule = SkipWord (cssRule);
2340: }
1.117 vatton 2341: else
1.168 vatton 2342: cssRule = ParseCSSUnit (cssRule, &val);
2343: if (val.typed_data.value != 0 &&
1.184 vatton 2344: (val.typed_data.unit == UNIT_INVALID ||
2345: val.typed_data.unit == UNIT_BOX))
1.168 vatton 2346: CSSParseError ("height value", ptr, cssRule);
2347: else if (DoApply)
1.117 vatton 2348: {
1.164 quint 2349: if (tsch)
2350: cssRule = CheckImportantRule (cssRule, context);
2351: /* install the new presentation */
2352: TtaSetStylePresentation (PRHeight, element, tsch, context, val);
1.117 vatton 2353: }
2354: return (cssRule);
1.1 cvs 2355: }
2356:
2357: /*----------------------------------------------------------------------
1.59 cvs 2358: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 2359: ----------------------------------------------------------------------*/
1.79 cvs 2360: static char *ParseCSSWidth (Element element, PSchema tsch,
1.78 cvs 2361: PresentationContext context,
1.79 cvs 2362: char *cssRule, CSSInfoPtr css,
1.78 cvs 2363: ThotBool isHTML)
1.1 cvs 2364: {
1.117 vatton 2365: PresentationValue val;
1.168 vatton 2366: char *ptr;
1.93 vatton 2367:
1.117 vatton 2368: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2369: ptr = cssRule;
1.117 vatton 2370: /* first parse the attribute string */
1.164 quint 2371: if (!strncasecmp (cssRule, "auto", 4))
2372: {
1.184 vatton 2373: val.typed_data.unit = VALUE_AUTO;
1.164 quint 2374: val.typed_data.value = 0;
2375: val.typed_data.real = FALSE;
2376: cssRule = SkipWord (cssRule);
2377: }
1.117 vatton 2378: else
1.164 quint 2379: cssRule = ParseCSSUnit (cssRule, &val);
1.168 vatton 2380: if (val.typed_data.value != 0 &&
1.184 vatton 2381: (val.typed_data.unit == UNIT_INVALID ||
2382: val.typed_data.unit == UNIT_BOX))
1.168 vatton 2383: CSSParseError ("Invalid width value", ptr, cssRule);
2384: else if (DoApply)
1.117 vatton 2385: {
1.164 quint 2386: if (tsch)
2387: cssRule = CheckImportantRule (cssRule, context);
2388: /* install the new presentation */
2389: TtaSetStylePresentation (PRWidth, element, tsch, context, val);
1.117 vatton 2390: }
2391: return (cssRule);
1.1 cvs 2392: }
2393:
2394: /*----------------------------------------------------------------------
1.59 cvs 2395: ParseCSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 2396: ----------------------------------------------------------------------*/
1.79 cvs 2397: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.78 cvs 2398: PresentationContext context,
1.79 cvs 2399: char *cssRule, CSSInfoPtr css,
1.78 cvs 2400: ThotBool isHTML)
1.1 cvs 2401: {
2402: PresentationValue margin;
1.168 vatton 2403: char *ptr;
1.1 cvs 2404:
1.82 cvs 2405: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2406: ptr = cssRule;
1.1 cvs 2407: /* first parse the attribute string */
1.164 quint 2408: if (!strncasecmp (cssRule, "auto", 4))
2409: {
1.184 vatton 2410: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2411: margin.typed_data.value = 0;
2412: margin.typed_data.real = FALSE;
2413: cssRule = SkipWord (cssRule);
2414: }
2415: else
1.168 vatton 2416: cssRule = ParseCSSUnit (cssRule, &margin);
2417: if (margin.typed_data.value != 0 &&
1.184 vatton 2418: (margin.typed_data.unit == UNIT_INVALID ||
2419: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2420: CSSParseError ("Invalid margin-top value", ptr, cssRule);
1.168 vatton 2421: else if (DoApply)
1.117 vatton 2422: {
2423: if (tsch)
2424: cssRule = CheckImportantRule (cssRule, context);
2425: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
2426: }
1.1 cvs 2427: return (cssRule);
2428: }
2429:
2430: /*----------------------------------------------------------------------
1.59 cvs 2431: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 2432: ----------------------------------------------------------------------*/
1.79 cvs 2433: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.78 cvs 2434: PresentationContext context,
1.79 cvs 2435: char *cssRule, CSSInfoPtr css,
1.78 cvs 2436: ThotBool isHTML)
1.1 cvs 2437: {
2438: PresentationValue margin;
1.168 vatton 2439: char *ptr;
1.1 cvs 2440:
1.82 cvs 2441: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2442: ptr = cssRule;
1.1 cvs 2443: /* first parse the attribute string */
1.164 quint 2444: if (!strncasecmp (cssRule, "auto", 4))
2445: {
1.184 vatton 2446: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2447: margin.typed_data.value = 0;
2448: margin.typed_data.real = FALSE;
2449: cssRule = SkipWord (cssRule);
2450: }
2451: else
1.168 vatton 2452: cssRule = ParseCSSUnit (cssRule, &margin);
2453: if (margin.typed_data.value != 0 &&
1.184 vatton 2454: (margin.typed_data.unit == UNIT_INVALID ||
2455: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2456: CSSParseError ("Invalid margin-bottom value", ptr, cssRule);
1.168 vatton 2457: else if (DoApply)
1.117 vatton 2458: {
2459: if (tsch)
2460: cssRule = CheckImportantRule (cssRule, context);
2461: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
2462: }
1.1 cvs 2463: return (cssRule);
2464: }
2465:
2466: /*----------------------------------------------------------------------
1.59 cvs 2467: ParseCSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 2468: ----------------------------------------------------------------------*/
1.79 cvs 2469: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.78 cvs 2470: PresentationContext context,
1.79 cvs 2471: char *cssRule, CSSInfoPtr css,
1.78 cvs 2472: ThotBool isHTML)
1.1 cvs 2473: {
2474: PresentationValue margin;
1.168 vatton 2475: char *ptr;
1.1 cvs 2476:
1.82 cvs 2477: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2478: ptr = cssRule;
1.1 cvs 2479: /* first parse the attribute string */
1.164 quint 2480: if (!strncasecmp (cssRule, "auto", 4))
2481: {
1.184 vatton 2482: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2483: margin.typed_data.value = 0;
2484: margin.typed_data.real = FALSE;
2485: cssRule = SkipWord (cssRule);
2486: }
2487: else
1.168 vatton 2488: cssRule = ParseCSSUnit (cssRule, &margin);
2489: if (margin.typed_data.value != 0 &&
1.184 vatton 2490: (margin.typed_data.unit == UNIT_INVALID ||
2491: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2492: CSSParseError ("Invalid margin-left value", ptr, cssRule);
1.168 vatton 2493: else if (DoApply)
1.184 vatton 2494: if (margin.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 2495: {
2496: if (tsch)
2497: cssRule = CheckImportantRule (cssRule, context);
2498: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
2499: }
1.1 cvs 2500: return (cssRule);
2501: }
2502:
2503: /*----------------------------------------------------------------------
1.59 cvs 2504: ParseCSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 2505: ----------------------------------------------------------------------*/
1.79 cvs 2506: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.78 cvs 2507: PresentationContext context,
1.79 cvs 2508: char *cssRule, CSSInfoPtr css,
1.78 cvs 2509: ThotBool isHTML)
1.1 cvs 2510: {
2511: PresentationValue margin;
1.168 vatton 2512: char *ptr;
1.1 cvs 2513:
1.82 cvs 2514: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2515: ptr = cssRule;
1.1 cvs 2516: /* first parse the attribute string */
1.164 quint 2517: if (!strncasecmp (cssRule, "auto", 4))
2518: {
1.184 vatton 2519: margin.typed_data.unit = VALUE_AUTO;
1.164 quint 2520: margin.typed_data.value = 0;
2521: margin.typed_data.real = FALSE;
2522: cssRule = SkipWord (cssRule);
2523: }
2524: else
1.168 vatton 2525: cssRule = ParseCSSUnit (cssRule, &margin);
2526: if (margin.typed_data.value != 0 &&
1.184 vatton 2527: (margin.typed_data.unit == UNIT_INVALID ||
2528: margin.typed_data.unit == UNIT_BOX))
1.169 vatton 2529: CSSParseError ("Invalid margin-right value", ptr, cssRule);
1.168 vatton 2530: else if (DoApply)
1.117 vatton 2531: {
2532: if (tsch)
2533: cssRule = CheckImportantRule (cssRule, context);
2534: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
2535: }
1.1 cvs 2536: return (cssRule);
2537: }
2538:
2539: /*----------------------------------------------------------------------
1.59 cvs 2540: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 2541: ----------------------------------------------------------------------*/
1.79 cvs 2542: static char *ParseCSSMargin (Element element, PSchema tsch,
1.78 cvs 2543: PresentationContext context,
1.79 cvs 2544: char *cssRule, CSSInfoPtr css,
1.78 cvs 2545: ThotBool isHTML)
1.1 cvs 2546: {
1.79 cvs 2547: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2548: int skippedNL;
1.1 cvs 2549:
1.82 cvs 2550: ptrT = SkipBlanksAndComments (cssRule);
1.1 cvs 2551: /* First parse Margin-Top */
2552: ptrR = ParseCSSMarginTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2553: ptrR = SkipBlanksAndComments (ptrR);
2554: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.1 cvs 2555: {
1.93 vatton 2556: skippedNL = NewLineSkipped;
1.1 cvs 2557: cssRule = ptrR;
2558: /* apply the Margin-Top to all */
2559: ptrR = ParseCSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2560: NewLineSkipped = skippedNL;
1.1 cvs 2561: ptrR = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2562: NewLineSkipped = skippedNL;
1.1 cvs 2563: ptrR = ParseCSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
2564: }
2565: else
2566: {
2567: /* parse Margin-Right */
2568: ptrB = ParseCSSMarginRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2569: ptrB = SkipBlanksAndComments (ptrB);
2570: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.1 cvs 2571: {
1.93 vatton 2572: skippedNL = NewLineSkipped;
1.1 cvs 2573: cssRule = ptrB;
2574: /* apply the Margin-Top to Margin-Bottom */
2575: ptrB = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2576: NewLineSkipped = skippedNL;
1.1 cvs 2577: /* apply the Margin-Right to Margin-Left */
2578: ptrB = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2579: }
2580: else
2581: {
2582: /* parse Margin-Bottom */
2583: ptrL = ParseCSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2584: ptrL = SkipBlanksAndComments (ptrL);
2585: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.1 cvs 2586: {
2587: cssRule = ptrL;
2588: /* apply the Margin-Right to Margin-Left */
2589: ptrL = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2590: }
2591: else
2592: /* parse Margin-Left */
2593: cssRule = ParseCSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2594: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2595: }
2596: }
2597: return (cssRule);
2598: }
2599:
2600: /*----------------------------------------------------------------------
1.59 cvs 2601: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 2602: ----------------------------------------------------------------------*/
1.79 cvs 2603: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.78 cvs 2604: PresentationContext context,
1.79 cvs 2605: char *cssRule, CSSInfoPtr css,
1.78 cvs 2606: ThotBool isHTML)
1.1 cvs 2607: {
1.43 cvs 2608: PresentationValue padding;
1.168 vatton 2609: char *ptr;
1.43 cvs 2610:
1.82 cvs 2611: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2612: ptr = cssRule;
1.43 cvs 2613: /* first parse the attribute string */
2614: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2615: if (padding.typed_data.value != 0 &&
1.184 vatton 2616: (padding.typed_data.unit == UNIT_INVALID ||
2617: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2618: {
1.169 vatton 2619: CSSParseError ("Invalid padding-top value", ptr, cssRule);
1.168 vatton 2620: padding.typed_data.value = 0;
2621: }
2622: else if (DoApply)
1.117 vatton 2623: {
2624: if (tsch)
2625: cssRule = CheckImportantRule (cssRule, context);
2626: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
2627: }
1.1 cvs 2628: return (cssRule);
2629: }
2630:
2631: /*----------------------------------------------------------------------
1.59 cvs 2632: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 2633: ----------------------------------------------------------------------*/
1.79 cvs 2634: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.78 cvs 2635: PresentationContext context,
1.79 cvs 2636: char *cssRule, CSSInfoPtr css,
1.78 cvs 2637: ThotBool isHTML)
1.1 cvs 2638: {
1.43 cvs 2639: PresentationValue padding;
1.168 vatton 2640: char *ptr;
1.43 cvs 2641:
1.82 cvs 2642: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2643: ptr = cssRule;
1.43 cvs 2644: /* first parse the attribute string */
2645: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2646: if (padding.typed_data.value == 0)
1.184 vatton 2647: padding.typed_data.unit = UNIT_EM;
1.168 vatton 2648: if (padding.typed_data.value != 0 &&
1.184 vatton 2649: (padding.typed_data.unit == UNIT_INVALID ||
2650: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2651: {
1.169 vatton 2652: CSSParseError ("Invalid padding-bottom value", ptr, cssRule);
1.168 vatton 2653: padding.typed_data.value = 0;
2654: }
2655: else if (DoApply)
1.117 vatton 2656: {
2657: if (tsch)
2658: cssRule = CheckImportantRule (cssRule, context);
2659: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
2660: }
1.1 cvs 2661: return (cssRule);
2662: }
2663:
2664: /*----------------------------------------------------------------------
1.59 cvs 2665: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 2666: ----------------------------------------------------------------------*/
1.79 cvs 2667: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.78 cvs 2668: PresentationContext context,
1.79 cvs 2669: char *cssRule, CSSInfoPtr css,
1.78 cvs 2670: ThotBool isHTML)
1.1 cvs 2671: {
1.43 cvs 2672: PresentationValue padding;
1.168 vatton 2673: char *ptr;
1.43 cvs 2674:
1.82 cvs 2675: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2676: ptr = cssRule;
1.43 cvs 2677: /* first parse the attribute string */
2678: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2679: if (padding.typed_data.value == 0)
1.184 vatton 2680: padding.typed_data.unit = UNIT_EM;
1.168 vatton 2681: if (padding.typed_data.value != 0 &&
1.184 vatton 2682: (padding.typed_data.unit == UNIT_INVALID ||
2683: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2684: {
1.169 vatton 2685: CSSParseError ("Invalid padding-left value", ptr, cssRule);
1.168 vatton 2686: padding.typed_data.value = 0;
2687: }
2688: else if (DoApply)
1.117 vatton 2689: {
2690: if (tsch)
2691: cssRule = CheckImportantRule (cssRule, context);
1.43 cvs 2692: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.117 vatton 2693: }
1.1 cvs 2694: return (cssRule);
2695: }
2696:
2697: /*----------------------------------------------------------------------
1.59 cvs 2698: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 2699: ----------------------------------------------------------------------*/
1.79 cvs 2700: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.78 cvs 2701: PresentationContext context,
1.79 cvs 2702: char *cssRule, CSSInfoPtr css,
1.78 cvs 2703: ThotBool isHTML)
1.1 cvs 2704: {
1.43 cvs 2705: PresentationValue padding;
1.168 vatton 2706: char *ptr;
1.43 cvs 2707:
1.82 cvs 2708: cssRule = SkipBlanksAndComments (cssRule);
1.168 vatton 2709: ptr = cssRule;
1.43 cvs 2710: /* first parse the attribute string */
2711: cssRule = ParseCSSUnit (cssRule, &padding);
1.168 vatton 2712: if (padding.typed_data.value == 0)
1.184 vatton 2713: padding.typed_data.unit = UNIT_EM;
1.168 vatton 2714: if (padding.typed_data.value != 0 &&
1.184 vatton 2715: (padding.typed_data.unit == UNIT_INVALID ||
2716: padding.typed_data.unit == UNIT_BOX))
1.168 vatton 2717: {
1.169 vatton 2718: CSSParseError ("Invalid padding-right value", ptr, cssRule);
1.168 vatton 2719: padding.typed_data.value = 0;
2720: }
2721: else if (DoApply)
1.117 vatton 2722: {
2723: if (tsch)
2724: cssRule = CheckImportantRule (cssRule, context);
1.43 cvs 2725: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.117 vatton 2726: }
1.1 cvs 2727: return (cssRule);
2728: }
2729:
2730: /*----------------------------------------------------------------------
1.59 cvs 2731: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 2732: ----------------------------------------------------------------------*/
1.79 cvs 2733: static char *ParseCSSPadding (Element element, PSchema tsch,
1.78 cvs 2734: PresentationContext context,
1.79 cvs 2735: char *cssRule, CSSInfoPtr css,
1.78 cvs 2736: ThotBool isHTML)
1.1 cvs 2737: {
1.79 cvs 2738: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2739: int skippedNL;
1.43 cvs 2740:
1.82 cvs 2741: ptrT = SkipBlanksAndComments (cssRule);
1.43 cvs 2742: /* First parse Padding-Top */
2743: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2744: ptrR = SkipBlanksAndComments (ptrR);
2745: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.43 cvs 2746: {
1.93 vatton 2747: skippedNL = NewLineSkipped;
1.43 cvs 2748: cssRule = ptrR;
2749: /* apply the Padding-Top to all */
2750: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2751: NewLineSkipped = skippedNL;
1.43 cvs 2752: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2753: NewLineSkipped = skippedNL;
1.43 cvs 2754: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
2755: }
2756: else
2757: {
2758: /* parse Padding-Right */
2759: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2760: ptrB = SkipBlanksAndComments (ptrB);
2761: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.43 cvs 2762: {
1.93 vatton 2763: skippedNL = NewLineSkipped;
1.43 cvs 2764: cssRule = ptrB;
2765: /* apply the Padding-Top to Padding-Bottom */
2766: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2767: NewLineSkipped = skippedNL;
1.43 cvs 2768: /* apply the Padding-Right to Padding-Left */
2769: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2770: }
2771: else
2772: {
2773: /* parse Padding-Bottom */
2774: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2775: ptrL = SkipBlanksAndComments (ptrL);
2776: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.43 cvs 2777: {
2778: cssRule = ptrL;
2779: /* apply the Padding-Right to Padding-Left */
2780: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2781: }
2782: else
2783: /* parse Padding-Left */
2784: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2785: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2786: }
2787: }
1.1 cvs 2788: return (cssRule);
2789: }
2790:
2791: /*----------------------------------------------------------------------
1.59 cvs 2792: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 2793: ----------------------------------------------------------------------*/
1.79 cvs 2794: static char *ParseCSSForeground (Element element, PSchema tsch,
1.78 cvs 2795: PresentationContext context,
1.79 cvs 2796: char *cssRule,
1.78 cvs 2797: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2798: {
1.117 vatton 2799: PresentationValue best;
1.1 cvs 2800:
1.117 vatton 2801: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 2802: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 2803: {
2804: if (tsch)
2805: cssRule = CheckImportantRule (cssRule, context);
2806: /* install the new presentation */
2807: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2808: }
1.1 cvs 2809: return (cssRule);
2810: }
2811:
2812: /*----------------------------------------------------------------------
1.59 cvs 2813: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 2814: ----------------------------------------------------------------------*/
1.79 cvs 2815: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.78 cvs 2816: PresentationContext context,
1.79 cvs 2817: char *cssRule,
1.78 cvs 2818: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2819: {
2820: PresentationValue best;
2821:
1.184 vatton 2822: best.typed_data.unit = UNIT_INVALID;
1.1 cvs 2823: best.typed_data.real = FALSE;
1.198 vatton 2824: if (!strncasecmp (cssRule, "transparent", 11))
1.1 cvs 2825: {
1.184 vatton 2826: best.typed_data.value = PATTERN_NONE;
2827: best.typed_data.unit = UNIT_REL;
1.116 vatton 2828: if (DoApply)
1.117 vatton 2829: {
2830: if (tsch)
2831: cssRule = CheckImportantRule (cssRule, context);
2832: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2833: }
1.65 cvs 2834: cssRule = SkipWord (cssRule);
1.1 cvs 2835: }
2836: else
2837: {
2838: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 2839: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.1 cvs 2840: {
1.117 vatton 2841: if (tsch)
2842: cssRule = CheckImportantRule (cssRule, context);
1.1 cvs 2843: /* install the new presentation. */
2844: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59 cvs 2845: /* thot specificity: need to set fill pattern for background color */
1.184 vatton 2846: best.typed_data.value = PATTERN_BACKGROUND;
2847: best.typed_data.unit = UNIT_REL;
1.1 cvs 2848: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2849: best.typed_data.value = 1;
1.184 vatton 2850: best.typed_data.unit = UNIT_REL;
1.1 cvs 2851: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
2852: }
2853: }
2854: return (cssRule);
2855: }
2856:
1.63 cvs 2857: /*----------------------------------------------------------------------
1.65 cvs 2858: ParseSVGStroke: parse a SVG stroke property
2859: ----------------------------------------------------------------------*/
1.79 cvs 2860: static char *ParseSVGStroke (Element element, PSchema tsch,
2861: PresentationContext context, char *cssRule,
2862: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 2863: {
2864: PresentationValue best;
2865:
1.184 vatton 2866: best.typed_data.unit = UNIT_INVALID;
1.65 cvs 2867: best.typed_data.real = FALSE;
1.82 cvs 2868: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 2869: {
2870: best.typed_data.value = -2; /* -2 means transparent */
1.184 vatton 2871: best.typed_data.unit = UNIT_REL;
1.116 vatton 2872: if (DoApply)
1.117 vatton 2873: {
2874: if (tsch)
2875: cssRule = CheckImportantRule (cssRule, context);
2876: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2877: }
1.65 cvs 2878: cssRule = SkipWord (cssRule);
2879: }
2880: else
2881: {
2882: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 2883: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 2884: {
2885: if (tsch)
2886: cssRule = CheckImportantRule (cssRule, context);
2887: /* install the new presentation */
2888: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2889: }
1.65 cvs 2890: }
2891: return (cssRule);
2892: }
2893:
2894: /*----------------------------------------------------------------------
1.63 cvs 2895: ParseSVGFill: parse a SVG fill property
2896: ----------------------------------------------------------------------*/
1.79 cvs 2897: static char *ParseSVGFill (Element element, PSchema tsch,
2898: PresentationContext context, char *cssRule,
2899: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 2900: {
2901: PresentationValue best;
2902:
1.184 vatton 2903: best.typed_data.unit = UNIT_INVALID;
1.63 cvs 2904: best.typed_data.real = FALSE;
1.82 cvs 2905: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 2906: {
1.184 vatton 2907: best.typed_data.value = PATTERN_NONE;
2908: best.typed_data.unit = UNIT_REL;
1.116 vatton 2909: if (DoApply)
1.117 vatton 2910: {
2911: if (tsch)
2912: cssRule = CheckImportantRule (cssRule, context);
2913: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2914: }
1.65 cvs 2915: cssRule = SkipWord (cssRule);
1.63 cvs 2916: }
2917: else
2918: {
2919: cssRule = ParseCSSColor (cssRule, &best);
1.184 vatton 2920: if (best.typed_data.unit != UNIT_INVALID && DoApply)
1.63 cvs 2921: {
1.117 vatton 2922: if (tsch)
2923: cssRule = CheckImportantRule (cssRule, context);
1.63 cvs 2924: /* install the new presentation. */
2925: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
2926: /* thot specificity: need to set fill pattern for background color */
1.184 vatton 2927: best.typed_data.value = PATTERN_BACKGROUND;
2928: best.typed_data.unit = UNIT_REL;
1.63 cvs 2929: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2930: }
2931: }
2932: return (cssRule);
2933: }
1.161 quint 2934:
1.155 cheyroul 2935: /*----------------------------------------------------------------------
2936: ParseSVGOpacity: parse a SVG fill property
2937: ----------------------------------------------------------------------*/
2938: static char *ParseSVGOpacity (Element element, PSchema tsch,
2939: PresentationContext context, char *cssRule,
2940: CSSInfoPtr css, ThotBool isHTML)
2941: {
2942: PresentationValue best;
1.63 cvs 2943:
1.184 vatton 2944: best.typed_data.unit = UNIT_INVALID;
1.155 cheyroul 2945: best.typed_data.real = FALSE;
2946: cssRule = ParseClampedUnit (cssRule, &best);
2947: if (DoApply)
2948: {
2949: if (tsch)
2950: cssRule = CheckImportantRule (cssRule, context);
2951: /* install the new presentation. */
2952: TtaSetStylePresentation (PROpacity, element,
2953: tsch, context, best);
2954: }
2955: return (cssRule);
2956: }
1.170 cheyroul 2957: /*----------------------------------------------------------------------
2958: ParseSVGOpacity: parse a SVG fill property
2959: ----------------------------------------------------------------------*/
2960: static char *ParseSVGStrokeOpacity (Element element, PSchema tsch,
2961: PresentationContext context, char *cssRule,
2962: CSSInfoPtr css, ThotBool isHTML)
2963: {
2964: PresentationValue best;
1.161 quint 2965:
1.184 vatton 2966: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 2967: best.typed_data.real = FALSE;
2968: cssRule = ParseClampedUnit (cssRule, &best);
2969: if (DoApply)
2970: {
2971: if (tsch)
2972: cssRule = CheckImportantRule (cssRule, context);
2973: /* install the new presentation. */
2974: TtaSetStylePresentation (PRStrokeOpacity, element,
2975: tsch, context, best);
2976: }
2977: return (cssRule);
2978: }
2979: /*----------------------------------------------------------------------
2980: ParseSVGOpacity: parse a SVG fill property
2981: ----------------------------------------------------------------------*/
2982: static char *ParseSVGFillOpacity (Element element, PSchema tsch,
2983: PresentationContext context, char *cssRule,
2984: CSSInfoPtr css, ThotBool isHTML)
2985: {
2986: PresentationValue best;
2987:
1.184 vatton 2988: best.typed_data.unit = UNIT_INVALID;
1.170 cheyroul 2989: best.typed_data.real = FALSE;
2990: cssRule = ParseClampedUnit (cssRule, &best);
2991: if (DoApply)
2992: {
2993: if (tsch)
2994: cssRule = CheckImportantRule (cssRule, context);
2995: /* install the new presentation. */
2996: TtaSetStylePresentation (PRFillOpacity, element,
2997: tsch, context, best);
2998: }
2999: return (cssRule);
3000: }
1.207 vatton 3001:
1.1 cvs 3002: /*----------------------------------------------------------------------
1.59 cvs 3003: ParseCSSBackgroundImageCallback: Callback called asynchronously by
3004: FetchImage when a background image has been fetched.
1.1 cvs 3005: ----------------------------------------------------------------------*/
1.82 cvs 3006: void ParseCSSBackgroundImageCallback (Document doc, Element element,
1.203 vatton 3007: char *file, void *extra,
3008: ThotBool isnew)
1.1 cvs 3009: {
1.82 cvs 3010: DisplayMode dispMode;
3011: BackgroundImageCallbackPtr callblock;
3012: Element el;
3013: PSchema tsch;
1.185 vatton 3014: CSSInfoPtr css;
1.206 vatton 3015: PInfoPtr pInfo;
1.207 vatton 3016: PresentationContext ctxt;
1.82 cvs 3017: PresentationValue image;
3018: PresentationValue value;
1.206 vatton 3019: ThotBool enabled;
1.82 cvs 3020: callblock = (BackgroundImageCallbackPtr) extra;
1.34 cvs 3021: if (callblock == NULL)
3022: return;
1.1 cvs 3023:
1.188 cheyroul 3024: css = NULL;
1.34 cvs 3025: el = callblock->el;
3026: tsch = callblock->tsch;
1.207 vatton 3027: ctxt = callblock->ctxt;
1.203 vatton 3028: if (doc == 0 && !isnew)
3029: /* apply to the current document only */
1.207 vatton 3030: doc = ctxt->doc;
1.185 vatton 3031: if (doc)
3032: {
3033: /* avoid too many redisplay */
3034: dispMode = TtaGetDisplayMode (doc);
3035: if (dispMode == DisplayImmediately)
3036: TtaSetDisplayMode (doc, DeferredDisplay);
3037: }
3038: else
3039: {
3040: /* check if the CSS still exists */
3041: css = CSSList;
3042: while (css && css != callblock->css)
3043: css = css->NextCSS;
3044: if (css == NULL)
3045: tsch = NULL;
3046: }
1.34 cvs 3047:
1.185 vatton 3048: if (el || tsch)
3049: {
3050: /* Ok the image was fetched, finish the background-image handling */
1.193 vatton 3051: image.typed_data.unit = UNIT_REL;
3052: image.typed_data.real = FALSE;
1.185 vatton 3053: image.pointer = file;
1.207 vatton 3054: TtaSetStylePresentation (PRBackgroundPicture, el, tsch, ctxt, image);
1.185 vatton 3055:
3056: /* enforce the showbox */
3057: value.typed_data.value = 1;
3058: value.typed_data.unit = UNIT_REL;
3059: value.typed_data.real = FALSE;
1.207 vatton 3060: TtaSetStylePresentation (PRShowBox, el, tsch, ctxt, value);
3061: /* check if the context can be freed */
3062: ctxt->uses -= 1;
3063: if (ctxt->uses == 0)
3064: /* no other image loading */
3065: TtaFreeMemory (ctxt);
1.185 vatton 3066: }
1.34 cvs 3067:
3068: TtaFreeMemory (callblock);
3069: /* restore the display mode */
1.185 vatton 3070: if (doc)
3071: {
3072: if (dispMode == DisplayImmediately)
3073: TtaSetDisplayMode (doc, dispMode);
3074: }
3075: else if (css)
3076: {
3077: for (doc = 1; doc < DocumentTableLength; doc++)
1.206 vatton 3078: if (css->infos[doc] &&
1.185 vatton 3079: /* don't manage a document used by make book */
3080: (DocumentMeta[doc] == NULL ||
3081: DocumentMeta[doc]->method != CE_MAKEBOOK))
3082: {
1.206 vatton 3083: pInfo = css->infos[doc];
3084: enabled = FALSE;
3085: while (pInfo && !enabled)
3086: {
3087: enabled = pInfo->PiEnabled;
3088: pInfo = pInfo->PiNext;
3089: }
1.185 vatton 3090: /* Change the Display Mode to take into account the new presentation */
3091: dispMode = TtaGetDisplayMode (doc);
3092: if (dispMode == DisplayImmediately)
1.194 vatton 3093: {
3094: TtaSetDisplayMode (doc, NoComputedDisplay);
3095: /* Restore the display mode */
3096: TtaSetDisplayMode (doc, dispMode);
3097: }
1.185 vatton 3098: }
3099: }
1.1 cvs 3100: }
3101:
3102: /*----------------------------------------------------------------------
3103: GetCSSBackgroundURL searches a CSS BackgroundImage url within
3104: the styleString.
3105: Returns NULL or a new allocated url string.
3106: ----------------------------------------------------------------------*/
1.79 cvs 3107: char *GetCSSBackgroundURL (char *styleString)
1.1 cvs 3108: {
1.79 cvs 3109: char *b, *e, *ptr;
3110: int len;
1.1 cvs 3111:
3112: ptr = NULL;
1.82 cvs 3113: b = strstr (styleString, "url");
1.1 cvs 3114: if (b != NULL)
3115: {
3116: b += 3;
1.82 cvs 3117: b = SkipBlanksAndComments (b);
3118: if (*b == '(')
1.1 cvs 3119: {
3120: b++;
1.82 cvs 3121: b = SkipBlanksAndComments (b);
1.161 quint 3122: /*** Escaped quotes are not handled. See function SkipQuotedString */
1.82 cvs 3123: if (*b == '"')
1.1 cvs 3124: {
3125: b++;
3126: /* search the url end */
3127: e = b;
1.82 cvs 3128: while (*e != EOS && *e != '"')
1.1 cvs 3129: e++;
3130: }
1.161 quint 3131: else if (*b == '\'')
3132: {
3133: b++;
3134: /* search the url end */
3135: e = b;
3136: while (*e != EOS && *e != '\'')
3137: e++;
3138: }
1.1 cvs 3139: else
3140: {
3141: /* search the url end */
3142: e = b;
1.82 cvs 3143: while (*e != EOS && *e != ')')
1.1 cvs 3144: e++;
3145: }
1.82 cvs 3146: if (*e != EOS)
1.1 cvs 3147: {
3148: len = (int)(e - b);
1.82 cvs 3149: ptr = (char*) TtaGetMemory (len+1);
3150: strncpy (ptr, b, len);
3151: ptr[len] = EOS;
1.1 cvs 3152: }
3153: }
3154: }
3155: return (ptr);
3156: }
3157:
3158:
3159: /*----------------------------------------------------------------------
1.59 cvs 3160: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 3161: ----------------------------------------------------------------------*/
1.79 cvs 3162: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
1.207 vatton 3163: PresentationContext ctxt,
1.79 cvs 3164: char *cssRule, CSSInfoPtr css,
3165: ThotBool isHTML)
1.1 cvs 3166: {
1.49 cvs 3167: Element el;
1.1 cvs 3168: BackgroundImageCallbackPtr callblock;
1.49 cvs 3169: PresentationValue image, value;
1.79 cvs 3170: char *url;
1.82 cvs 3171: char *bg_image;
1.79 cvs 3172: char saved;
3173: char *base;
3174: char tempname[MAX_LENGTH];
3175: char imgname[MAX_LENGTH];
1.148 vatton 3176:
1.163 quint 3177: if (element)
1.148 vatton 3178: el = element;
1.163 quint 3179: else
3180: /* default element for FetchImage */
1.207 vatton 3181: el = TtaGetMainRoot (ctxt->doc);
1.163 quint 3182:
1.1 cvs 3183: url = NULL;
1.82 cvs 3184: cssRule = SkipBlanksAndComments (cssRule);
1.161 quint 3185: if (!strncasecmp (cssRule, "none", 4))
3186: {
3187: image.pointer = NULL;
1.207 vatton 3188: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt, image);
1.198 vatton 3189: cssRule += 4;
1.161 quint 3190: }
3191: else if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 3192: {
3193: cssRule += 3;
1.82 cvs 3194: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 3195: if (*cssRule == '(')
3196: {
3197: cssRule++;
1.82 cvs 3198: cssRule = SkipBlanksAndComments (cssRule);
1.161 quint 3199: /*** Escaped quotes are not handled. See function SkipQuotedString */
1.1 cvs 3200: if (*cssRule == '"')
3201: {
3202: cssRule++;
3203: base = cssRule;
1.82 cvs 3204: while (*cssRule != EOS && *cssRule != '"')
1.1 cvs 3205: cssRule++;
3206: }
1.161 quint 3207: else if (*cssRule == '\'')
3208: {
3209: cssRule++;
3210: base = cssRule;
3211: while (*cssRule != EOS && *cssRule != '\'')
3212: cssRule++;
3213: }
1.1 cvs 3214: else
3215: {
3216: base = cssRule;
3217: while (*cssRule != EOS && *cssRule != ')')
3218: cssRule++;
3219: }
3220: saved = *cssRule;
1.82 cvs 3221: *cssRule = EOS;
3222: url = TtaStrdup (base);
1.1 cvs 3223: *cssRule = saved;
1.161 quint 3224: if (saved == '"' || saved == '\'')
3225: /* we need to skip the quote character and possinble spaces */
3226: {
3227: cssRule++;
3228: cssRule = SkipBlanksAndComments (cssRule);
3229: }
1.1 cvs 3230: }
3231: cssRule++;
3232:
1.207 vatton 3233: if (ctxt->destroy)
1.1 cvs 3234: {
3235: /* remove the background image PRule */
3236: image.pointer = NULL;
1.207 vatton 3237: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, ctxt, image);
3238: if (TtaGetStylePresentation (PRFillPattern, element, tsch, ctxt, &value) < 0)
1.1 cvs 3239: {
3240: /* there is no FillPattern rule -> remove ShowBox rule */
3241: value.typed_data.value = 1;
1.184 vatton 3242: value.typed_data.unit = UNIT_REL;
1.1 cvs 3243: value.typed_data.real = FALSE;
1.207 vatton 3244: TtaSetStylePresentation (PRShowBox, element, tsch, ctxt, value);
1.1 cvs 3245: }
3246: }
3247: else if (url)
3248: {
1.30 cvs 3249: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
1.82 cvs 3250: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
1.161 quint 3251: /* background images are enabled */
1.1 cvs 3252: {
1.185 vatton 3253: callblock = (BackgroundImageCallbackPtr) TtaGetMemory (sizeof (BackgroundImageCallbackBlock));
1.191 vatton 3254: if (callblock)
1.1 cvs 3255: {
3256: callblock->el = element;
3257: callblock->tsch = tsch;
1.185 vatton 3258: callblock->css = css;
1.207 vatton 3259: callblock->ctxt = ctxt;
3260: /* new use of the context */
3261: ctxt->uses += 1;
1.18 cvs 3262: /* check if the image url is related to an external CSS */
1.182 vatton 3263: if (css)
1.18 cvs 3264: {
1.189 vatton 3265: if (css->url)
3266: /* the image concerns a CSS file */
3267: NormalizeURL (url, 0, tempname, imgname, css->url);
3268: else
3269: /* the image concerns a style element */
1.207 vatton 3270: NormalizeURL (url, ctxt->doc, tempname, imgname, NULL);
1.18 cvs 3271: /* fetch and display background image of element */
1.181 vatton 3272: FetchImage (0, el, tempname, AMAYA_LOAD_IMAGE,
1.161 quint 3273: ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 3274: }
3275: else
1.207 vatton 3276: FetchImage (ctxt->doc, el, url, AMAYA_LOAD_IMAGE,
1.161 quint 3277: ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 3278: }
3279: }
3280:
3281: if (url)
3282: TtaFreeMemory (url);
3283: }
3284: }
3285: return (cssRule);
3286: }
3287:
3288: /*----------------------------------------------------------------------
1.59 cvs 3289: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 3290: ----------------------------------------------------------------------*/
1.79 cvs 3291: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.207 vatton 3292: PresentationContext ctxt,
1.97 vatton 3293: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3294: {
3295: PresentationValue repeat;
3296:
1.184 vatton 3297: repeat.typed_data.value = REALSIZE;
1.191 vatton 3298: repeat.typed_data.unit = UNIT_BOX;
1.18 cvs 3299: repeat.typed_data.real = FALSE;
1.82 cvs 3300: cssRule = SkipBlanksAndComments (cssRule);
3301: if (!strncasecmp (cssRule, "no-repeat", 9))
1.184 vatton 3302: repeat.typed_data.value = REALSIZE;
1.82 cvs 3303: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.184 vatton 3304: repeat.typed_data.value = VREPEAT;
1.82 cvs 3305: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.184 vatton 3306: repeat.typed_data.value = HREPEAT;
1.82 cvs 3307: else if (!strncasecmp (cssRule, "repeat", 6))
1.184 vatton 3308: repeat.typed_data.value = REPEAT;
1.18 cvs 3309: else
3310: return (cssRule);
3311:
3312: /* install the new presentation */
1.116 vatton 3313: if (DoApply)
1.117 vatton 3314: {
3315: /* check if it's an important rule */
3316: if (tsch)
1.207 vatton 3317: cssRule = CheckImportantRule (cssRule, ctxt);
3318: TtaSetStylePresentation (PRPictureMode, element, tsch, ctxt, repeat);
1.117 vatton 3319: }
1.18 cvs 3320: cssRule = SkipWord (cssRule);
1.163 quint 3321: return (cssRule);
1.18 cvs 3322: }
3323:
3324: /*----------------------------------------------------------------------
1.59 cvs 3325: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18 cvs 3326: attribute string.
3327: ----------------------------------------------------------------------*/
1.79 cvs 3328: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
1.207 vatton 3329: PresentationContext ctxt,
1.79 cvs 3330: char *cssRule, CSSInfoPtr css,
3331: ThotBool isHTML)
1.18 cvs 3332: {
1.200 vatton 3333: char *ptr;
3334:
1.163 quint 3335: cssRule = SkipBlanksAndComments (cssRule);
3336: if (!strncasecmp (cssRule, "scroll", 6))
1.199 vatton 3337: {
3338: /* force no-repeat for that background image */
1.200 vatton 3339: ptr = "no-repeat";
1.207 vatton 3340: ParseCSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.199 vatton 3341: cssRule = SkipWord (cssRule);
3342: }
1.163 quint 3343: else if (!strncasecmp (cssRule, "fixed", 5))
1.199 vatton 3344: {
3345: /* force no-repeat for that background image */
1.201 vatton 3346: ptr = "no-repeat";
1.207 vatton 3347: ParseCSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.199 vatton 3348: cssRule = SkipWord (cssRule);
3349: }
1.163 quint 3350: return (cssRule);
1.1 cvs 3351: }
3352:
3353: /*----------------------------------------------------------------------
1.59 cvs 3354: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
1.1 cvs 3355: attribute string.
3356: ----------------------------------------------------------------------*/
1.79 cvs 3357: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
1.207 vatton 3358: PresentationContext ctxt,
1.79 cvs 3359: char *cssRule, CSSInfoPtr css,
3360: ThotBool isHTML)
1.1 cvs 3361: {
1.18 cvs 3362: PresentationValue repeat;
1.200 vatton 3363: char *ptr;
1.18 cvs 3364: ThotBool ok;
1.1 cvs 3365:
1.163 quint 3366: cssRule = SkipBlanksAndComments (cssRule);
3367: ok = TRUE;
3368: if (!strncasecmp (cssRule, "left", 4))
3369: cssRule = SkipWord (cssRule);
3370: else if (!strncasecmp (cssRule, "right", 5))
3371: cssRule = SkipWord (cssRule);
3372: else if (!strncasecmp (cssRule, "center", 6))
3373: cssRule = SkipWord (cssRule);
3374: else if (!strncasecmp (cssRule, "top", 3))
3375: cssRule = SkipWord (cssRule);
3376: else if (!strncasecmp (cssRule, "bottom", 6))
3377: cssRule = SkipWord (cssRule);
3378: else if (isdigit (*cssRule) || *cssRule == '.')
1.191 vatton 3379: {
1.206 vatton 3380: while (*cssRule != EOS && *cssRule != SPACE &&
3381: *cssRule != ',' && *cssRule != ';')
3382: cssRule++;
1.191 vatton 3383: }
1.163 quint 3384: else
3385: ok = FALSE;
3386:
3387: if (ok && DoApply)
1.148 vatton 3388: {
1.199 vatton 3389: /* force no-repeat for that background image */
1.200 vatton 3390: ptr = "no-repeat";
1.207 vatton 3391: ParseCSSBackgroundRepeat (element, tsch, ctxt, ptr, css, isHTML);
1.163 quint 3392: /* force realsize for the background image */
1.184 vatton 3393: repeat.typed_data.value = REALSIZE;
3394: repeat.typed_data.unit = UNIT_REL;
1.163 quint 3395: repeat.typed_data.real = FALSE;
3396: /* check if it's an important rule */
3397: if (tsch)
1.207 vatton 3398: cssRule = CheckImportantRule (cssRule, ctxt);
3399: /*TtaSetStylePresentation (PRPictureMode, element, tsch, ctxt, repeat);*/
1.148 vatton 3400: }
1.163 quint 3401: return (cssRule);
1.18 cvs 3402: }
3403:
3404: /*----------------------------------------------------------------------
1.59 cvs 3405: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 3406: ----------------------------------------------------------------------*/
1.79 cvs 3407: static char *ParseCSSBackground (Element element, PSchema tsch,
1.207 vatton 3408: PresentationContext ctxt, char *cssRule,
1.79 cvs 3409: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3410: {
1.79 cvs 3411: char *ptr;
1.93 vatton 3412: int skippedNL;
1.18 cvs 3413:
1.82 cvs 3414: cssRule = SkipBlanksAndComments (cssRule);
3415: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 3416: {
1.71 cvs 3417: /* perhaps a Background Image */
1.198 vatton 3418: if (!strncasecmp (cssRule, "url", 3) || !strncasecmp (cssRule, "none", 4))
1.207 vatton 3419: cssRule = ParseCSSBackgroundImage (element, tsch, ctxt, cssRule,
1.63 cvs 3420: css, isHTML);
1.18 cvs 3421: /* perhaps a Background Attachment */
1.82 cvs 3422: else if (!strncasecmp (cssRule, "scroll", 6) ||
3423: !strncasecmp (cssRule, "fixed", 5))
1.207 vatton 3424: cssRule = ParseCSSBackgroundAttachment (element, tsch, ctxt,
1.63 cvs 3425: cssRule, css, isHTML);
1.18 cvs 3426: /* perhaps a Background Repeat */
1.82 cvs 3427: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
3428: !strncasecmp (cssRule, "repeat-y", 8) ||
3429: !strncasecmp (cssRule, "repeat-x", 8) ||
3430: !strncasecmp (cssRule, "repeat", 6))
1.207 vatton 3431: cssRule = ParseCSSBackgroundRepeat (element, tsch, ctxt,
1.82 cvs 3432: cssRule, css, isHTML);
1.18 cvs 3433: /* perhaps a Background Position */
1.82 cvs 3434: else if (!strncasecmp (cssRule, "left", 4) ||
3435: !strncasecmp (cssRule, "right", 5) ||
3436: !strncasecmp (cssRule, "center", 6) ||
3437: !strncasecmp (cssRule, "top", 3) ||
3438: !strncasecmp (cssRule, "bottom", 6) ||
1.110 vatton 3439: isdigit (*cssRule) || *cssRule == '.')
1.207 vatton 3440: cssRule = ParseCSSBackgroundPosition (element, tsch, ctxt,
1.63 cvs 3441: cssRule, css, isHTML);
1.18 cvs 3442: /* perhaps a Background Color */
3443: else
3444: {
1.93 vatton 3445: skippedNL = NewLineSkipped;
1.18 cvs 3446: /* check if the rule has been found */
3447: ptr = cssRule;
1.207 vatton 3448: cssRule = ParseCSSBackgroundColor (element, tsch, ctxt,
1.82 cvs 3449: cssRule, css, isHTML);
1.43 cvs 3450: if (ptr == cssRule)
1.93 vatton 3451: {
3452: NewLineSkipped = skippedNL;
3453: /* rule not found */
3454: cssRule = SkipProperty (cssRule);
3455: }
1.18 cvs 3456: }
1.82 cvs 3457: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3458: }
3459: return (cssRule);
3460: }
3461:
1.59 cvs 3462: /*----------------------------------------------------------------------
1.60 cvs 3463: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 3464: ----------------------------------------------------------------------*/
1.79 cvs 3465: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
1.207 vatton 3466: PresentationContext ctxt, char *cssRule,
1.79 cvs 3467: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 3468: {
3469: PresentationValue page;
3470:
1.184 vatton 3471: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 3472: page.typed_data.real = FALSE;
1.82 cvs 3473: cssRule = SkipBlanksAndComments (cssRule);
3474: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 3475: page.typed_data.value = PageAuto;
1.82 cvs 3476: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3477: {
1.184 vatton 3478: page.typed_data.unit = UNIT_REL;
3479: page.typed_data.value = PageAlways;
1.59 cvs 3480: }
1.82 cvs 3481: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3482: {
1.184 vatton 3483: page.typed_data.unit = UNIT_REL;
3484: page.typed_data.value = PageAvoid;
1.59 cvs 3485: }
1.82 cvs 3486: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 3487: {
1.184 vatton 3488: page.typed_data.unit = UNIT_REL;
3489: page.typed_data.value = PageLeft;
1.59 cvs 3490: }
1.82 cvs 3491: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3492: {
1.184 vatton 3493: page.typed_data.unit = UNIT_REL;
3494: page.typed_data.value = PageRight;
1.59 cvs 3495: }
1.82 cvs 3496: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3497: {
1.184 vatton 3498: /*page.typed_data.unit = UNIT_REL;*/
3499: page.typed_data.value = PageInherit;
1.59 cvs 3500: }
3501: cssRule = SkipWord (cssRule);
3502: /* install the new presentation */
1.184 vatton 3503: if (page.typed_data.unit == UNIT_REL &&
3504: page.typed_data.value == PageAlways && DoApply)
1.117 vatton 3505: {
3506: /* check if it's an important rule */
3507: if (tsch)
1.207 vatton 3508: cssRule = CheckImportantRule (cssRule, ctxt);
3509: TtaSetStylePresentation (PRPageBefore, element, tsch, ctxt, page);
1.117 vatton 3510: }
1.59 cvs 3511: return (cssRule);
3512: }
3513:
3514: /*----------------------------------------------------------------------
1.60 cvs 3515: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 3516: ----------------------------------------------------------------------*/
1.79 cvs 3517: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
1.207 vatton 3518: PresentationContext ctxt,
1.79 cvs 3519: char *cssRule, CSSInfoPtr css,
3520: ThotBool isHTML)
1.59 cvs 3521: {
3522: PresentationValue page;
3523:
1.184 vatton 3524: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 3525: page.typed_data.real = FALSE;
1.82 cvs 3526: cssRule = SkipBlanksAndComments (cssRule);
3527: if (!strncasecmp (cssRule, "auto", 4))
1.184 vatton 3528: page.typed_data.value = PageAuto;
1.82 cvs 3529: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3530: {
1.184 vatton 3531: page.typed_data.unit = UNIT_REL;
3532: page.typed_data.value = PageAlways;
1.59 cvs 3533: }
1.82 cvs 3534: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3535: {
1.184 vatton 3536: page.typed_data.unit = UNIT_REL;
3537: page.typed_data.value = PageAvoid;
1.59 cvs 3538: }
1.82 cvs 3539: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 3540: {
1.184 vatton 3541: page.typed_data.unit = UNIT_REL;
3542: page.typed_data.value = PageLeft;
1.59 cvs 3543: }
1.82 cvs 3544: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3545: {
1.184 vatton 3546: page.typed_data.unit = UNIT_REL;
3547: page.typed_data.value = PageRight;
1.59 cvs 3548: }
1.82 cvs 3549: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3550: {
1.184 vatton 3551: /*page.typed_data.unit = UNIT_REL;*/
3552: page.typed_data.value = PageInherit;
1.59 cvs 3553: }
3554: cssRule = SkipWord (cssRule);
3555: /* install the new presentation */
1.184 vatton 3556: /*if (page.typed_data.unit == UNIT_REL && DoApply)
1.117 vatton 3557: {
3558: if (tsch)
1.207 vatton 3559: cssRule = CheckImportantRule (cssRule, ctxt);
3560: TtaSetStylePresentation (PRPageAfter, element, tsch, ctxt, page);
1.117 vatton 3561: }*/
1.59 cvs 3562: return (cssRule);
3563: }
3564:
3565: /*----------------------------------------------------------------------
1.60 cvs 3566: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 3567: ----------------------------------------------------------------------*/
1.79 cvs 3568: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
1.207 vatton 3569: PresentationContext ctxt,
1.79 cvs 3570: char *cssRule, CSSInfoPtr css,
3571: ThotBool isHTML)
1.59 cvs 3572: {
3573: PresentationValue page;
3574:
1.184 vatton 3575: page.typed_data.unit = UNIT_INVALID;
1.59 cvs 3576: page.typed_data.real = FALSE;
1.82 cvs 3577: cssRule = SkipBlanksAndComments (cssRule);
3578: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3579: {
1.184 vatton 3580: /*page.typed_data.unit = UNIT_REL;*/
3581: page.typed_data.value = PageAuto;
1.59 cvs 3582: }
1.82 cvs 3583: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3584: {
1.184 vatton 3585: page.typed_data.unit = UNIT_REL;
3586: page.typed_data.value = PageAvoid;
1.59 cvs 3587: }
1.82 cvs 3588: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3589: {
1.184 vatton 3590: /*page.typed_data.unit = UNIT_REL;*/
3591: page.typed_data.value = PageInherit;
1.59 cvs 3592: }
3593: cssRule = SkipWord (cssRule);
3594: /* install the new presentation */
1.184 vatton 3595: /*if (page.typed_data.unit == UNIT_REL &&
3596: page.typed_data.value == PageAvoid && DoApply)
1.117 vatton 3597: {
3598: if (tsch)
1.207 vatton 3599: cssRule = CheckImportantRule (cssRule, ctxt);
3600: TtaSetStylePresentation (PRPageInside, element, tsch, ctxt, page);
1.117 vatton 3601: }*/
1.59 cvs 3602: return (cssRule);
3603: }
1.18 cvs 3604:
3605:
1.60 cvs 3606: /*----------------------------------------------------------------------
1.117 vatton 3607: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 3608: ----------------------------------------------------------------------*/
1.79 cvs 3609: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
1.207 vatton 3610: PresentationContext ctxt, char *cssRule,
1.79 cvs 3611: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 3612: {
3613: PresentationValue width;
3614:
1.82 cvs 3615: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 3616: width.typed_data.value = 0;
1.184 vatton 3617: width.typed_data.unit = UNIT_INVALID;
1.60 cvs 3618: width.typed_data.real = FALSE;
1.110 vatton 3619: if (isdigit (*cssRule) || *cssRule == '.')
1.166 vatton 3620: {
1.60 cvs 3621: cssRule = ParseCSSUnit (cssRule, &width);
1.184 vatton 3622: if (width.typed_data.unit == UNIT_BOX)
3623: width.typed_data.unit = UNIT_PX;
1.166 vatton 3624: }
1.184 vatton 3625: if (width.typed_data.unit != UNIT_INVALID && DoApply)
1.117 vatton 3626: {
3627: /* check if it's an important rule */
3628: if (tsch)
1.207 vatton 3629: cssRule = CheckImportantRule (cssRule, ctxt);
3630: TtaSetStylePresentation (PRLineWeight, element, tsch, ctxt, width);
1.117 vatton 3631: width.typed_data.value = 1;
1.184 vatton 3632: width.typed_data.unit = UNIT_REL;
1.117 vatton 3633: }
1.60 cvs 3634: return (cssRule);
3635: }
3636:
1.18 cvs 3637: /************************************************************************
3638: * *
3639: * FUNCTIONS STYLE DECLARATIONS *
3640: * *
3641: ************************************************************************/
3642: /*
1.59 cvs 3643: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 3644: * e.g. "FONT-SIZE" must be placed before "FONT"
3645: */
3646: static CSSProperty CSSProperties[] =
3647: {
1.82 cvs 3648: {"font-family", ParseCSSFontFamily},
3649: {"font-style", ParseCSSFontStyle},
3650: {"font-variant", ParseCSSFontVariant},
3651: {"font-weight", ParseCSSFontWeight},
3652: {"font-size", ParseCSSFontSize},
3653: {"font", ParseCSSFont},
3654:
3655: {"color", ParseCSSForeground},
3656: {"background-color", ParseCSSBackgroundColor},
3657: {"background-image", ParseCSSBackgroundImage},
3658: {"background-repeat", ParseCSSBackgroundRepeat},
3659: {"background-attachment", ParseCSSBackgroundAttachment},
3660: {"background-position", ParseCSSBackgroundPosition},
3661: {"background", ParseCSSBackground},
3662:
3663: {"word-spacing", ParseCSSWordSpacing},
3664: {"letter-spacing", ParseCSSLetterSpacing},
3665: {"text-decoration", ParseCSSTextDecoration},
3666: {"vertical-align", ParseCSSVerticalAlign},
3667: {"text-transform", ParseCSSTextTransform},
3668: {"text-align", ParseCSSTextAlign},
3669: {"text-indent", ParseCSSTextIndent},
1.162 quint 3670: {"line-height", ParseCSSLineHeight},
1.82 cvs 3671:
1.112 quint 3672: {"direction", ParseCSSDirection},
1.113 quint 3673: {"unicode-bidi", ParseCSSUnicodeBidi},
1.112 quint 3674:
1.82 cvs 3675: {"margin-top", ParseCSSMarginTop},
3676: {"margin-right", ParseCSSMarginRight},
3677: {"margin-bottom", ParseCSSMarginBottom},
3678: {"margin-left", ParseCSSMarginLeft},
3679: {"margin", ParseCSSMargin},
3680:
3681: {"padding-top", ParseCSSPaddingTop},
3682: {"padding-right", ParseCSSPaddingRight},
3683: {"padding-bottom", ParseCSSPaddingBottom},
3684: {"padding-left", ParseCSSPaddingLeft},
3685: {"padding", ParseCSSPadding},
3686:
3687: {"border-top-width", ParseCSSBorderTopWidth},
3688: {"border-right-width", ParseCSSBorderRightWidth},
3689: {"border-bottom-width", ParseCSSBorderBottomWidth},
3690: {"border-left-width", ParseCSSBorderLeftWidth},
3691: {"border-width", ParseCSSBorderWidth},
3692: {"border-top-color", ParseCSSBorderColorTop},
3693: {"border-right-color", ParseCSSBorderColorRight},
3694: {"border-bottom-color", ParseCSSBorderColorBottom},
3695: {"border-left-color", ParseCSSBorderColorLeft},
3696: {"border-color", ParseCSSBorderColor},
3697: {"border-top-style", ParseCSSBorderStyleTop},
3698: {"border-right-style", ParseCSSBorderStyleRight},
3699: {"border-bottom-style", ParseCSSBorderStyleBottom},
3700: {"border-left-style", ParseCSSBorderStyleLeft},
3701: {"border-style", ParseCSSBorderStyle},
3702: {"border-top", ParseCSSBorderTop},
3703: {"border-right", ParseCSSBorderRight},
3704: {"border-bottom", ParseCSSBorderBottom},
3705: {"border-left", ParseCSSBorderLeft},
3706: {"border", ParseCSSBorder},
3707:
3708: {"width", ParseCSSWidth},
3709: {"height", ParseCSSHeight},
3710: {"float", ParseCSSFloat},
3711: {"clear", ParseCSSClear},
1.184 vatton 3712: {"content", ParseCSSContent},
1.82 cvs 3713:
3714: {"display", ParseCSSDisplay},
3715: {"white-space", ParseCSSWhiteSpace},
3716:
3717: {"list-style-type", ParseCSSListStyleType},
3718: {"list-style-image", ParseCSSListStyleImage},
3719: {"list-style-position", ParseCSSListStylePosition},
3720: {"list-style", ParseCSSListStyle},
3721:
3722: {"page-break-before", ParseCSSPageBreakBefore},
3723: {"page-break-after", ParseCSSPageBreakAfter},
3724: {"page-break-inside", ParseCSSPageBreakInside},
1.60 cvs 3725:
3726: /* SVG extensions */
1.170 cheyroul 3727: {"stroke-opacity", ParseSVGStrokeOpacity},
1.82 cvs 3728: {"stroke-width", ParseSVGStrokeWidth},
3729: {"stroke", ParseSVGStroke},
1.170 cheyroul 3730:
3731: {"fill-opacity", ParseSVGFillOpacity},
1.155 cheyroul 3732: {"fill", ParseSVGFill},
1.170 cheyroul 3733:
1.155 cheyroul 3734: {"opacity", ParseSVGOpacity}
1.18 cvs 3735: };
1.155 cheyroul 3736:
1.18 cvs 3737: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
3738:
3739: /*----------------------------------------------------------------------
1.59 cvs 3740: ParseCSSRule: parse a CSS Style string
1.18 cvs 3741: we expect the input string describing the style to be of the
1.59 cvs 3742: form: PRORPERTY: DESCRIPTION [ ; PROPERTY: DESCRIPTION ] *
1.18 cvs 3743: but tolerate incorrect or incomplete input
3744: ----------------------------------------------------------------------*/
1.79 cvs 3745: static void ParseCSSRule (Element element, PSchema tsch,
1.207 vatton 3746: PresentationContext ctxt, char *cssRule,
1.79 cvs 3747: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3748: {
1.34 cvs 3749: DisplayMode dispMode;
1.79 cvs 3750: char *p = NULL;
1.18 cvs 3751: int lg;
1.34 cvs 3752: unsigned int i;
1.76 cvs 3753: ThotBool found;
1.18 cvs 3754:
1.34 cvs 3755: /* avoid too many redisplay */
1.207 vatton 3756: dispMode = TtaGetDisplayMode (ctxt->doc);
1.34 cvs 3757: if (dispMode == DisplayImmediately)
1.207 vatton 3758: TtaSetDisplayMode (ctxt->doc, DeferredDisplay);
1.34 cvs 3759:
1.82 cvs 3760: while (*cssRule != EOS)
1.18 cvs 3761: {
1.82 cvs 3762: cssRule = SkipBlanksAndComments (cssRule);
1.153 vatton 3763: if (*cssRule < 0x41 || *cssRule > 0x7A ||
1.133 vatton 3764: (*cssRule > 0x5A && *cssRule < 0x60))
1.153 vatton 3765: cssRule++;
1.194 vatton 3766: else if (*cssRule != EOS)
1.89 cvs 3767: {
1.153 vatton 3768: found = FALSE;
3769: /* look for the type of property */
3770: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
1.18 cvs 3771: {
1.153 vatton 3772: lg = strlen (CSSProperties[i].name);
3773: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
3774: {
3775: p = cssRule + lg;
3776: found = TRUE;
3777: i--;
3778: }
1.18 cvs 3779: }
1.153 vatton 3780: if (i == NB_CSSSTYLEATTRIBUTE)
3781: cssRule = SkipProperty (cssRule);
3782: else
1.18 cvs 3783: {
1.153 vatton 3784: /* update index and skip the ":" indicator if present */
1.86 cvs 3785: p = SkipBlanksAndComments (p);
1.153 vatton 3786: if (*p == ':')
1.61 cvs 3787: {
1.153 vatton 3788: p++;
3789: p = SkipBlanksAndComments (p);
3790: /* try to parse the value associated with this property */
3791: if (CSSProperties[i].parsing_function != NULL)
3792: {
1.207 vatton 3793: p = CSSProperties[i].parsing_function (element, tsch, ctxt,
1.153 vatton 3794: p, css, isHTML);
3795: /* update index and skip the ";" separator if present */
3796: cssRule = p;
3797: }
1.61 cvs 3798: }
1.153 vatton 3799: else
3800: cssRule = SkipProperty (cssRule);
1.18 cvs 3801: }
3802: }
3803: /* next property */
1.82 cvs 3804: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 3805: if (*cssRule == '}')
3806: {
3807: cssRule++;
1.168 vatton 3808: CSSPrintError ("Invalid character", "}");
1.89 cvs 3809: cssRule = SkipBlanksAndComments (cssRule);
3810: }
1.155 cheyroul 3811: if (*cssRule == ',' ||
3812: *cssRule == ';')
1.18 cvs 3813: {
3814: cssRule++;
1.82 cvs 3815: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3816: }
3817: }
1.34 cvs 3818:
3819: /* restore the display mode */
3820: if (dispMode == DisplayImmediately)
1.207 vatton 3821: TtaSetDisplayMode (ctxt->doc, dispMode);
1.18 cvs 3822: }
1.1 cvs 3823:
1.111 cvs 3824: /*----------------------------------------------------------------------
3825: AddBorderStyleValue
3826: -----------------------------------------------------------------------*/
3827: static void AddBorderStyleValue (char *buffer, int value)
3828: {
3829: switch (value)
3830: {
1.184 vatton 3831: case BorderStyleNone:
1.111 cvs 3832: strcat (buffer, "none");
3833: break;
1.184 vatton 3834: case BorderStyleHidden:
1.111 cvs 3835: strcat (buffer, "hidden");
3836: break;
1.184 vatton 3837: case BorderStyleDotted:
1.111 cvs 3838: strcat (buffer, "dotted");
3839: break;
1.184 vatton 3840: case BorderStyleDashed:
1.111 cvs 3841: strcat (buffer, "dashed");
3842: break;
1.184 vatton 3843: case BorderStyleSolid:
1.111 cvs 3844: strcat (buffer, "solid");
3845: break;
1.184 vatton 3846: case BorderStyleDouble:
1.111 cvs 3847: strcat (buffer, "double");
3848: break;
1.184 vatton 3849: case BorderStyleGroove:
1.111 cvs 3850: strcat (buffer, "groove");
3851: break;
1.184 vatton 3852: case BorderStyleRidge:
1.111 cvs 3853: strcat (buffer, "ridge");
3854: break;
1.184 vatton 3855: case BorderStyleInset:
1.111 cvs 3856: strcat (buffer, "inset");
3857: break;
1.184 vatton 3858: case BorderStyleOutset:
1.111 cvs 3859: strcat (buffer, "outset");
3860: break;
3861: }
3862: }
1.1 cvs 3863:
3864: /*----------------------------------------------------------------------
1.59 cvs 3865: PToCss: translate a PresentationSetting to the
1.18 cvs 3866: equivalent CSS string, and add it to the buffer given as the
1.67 cvs 3867: argument. It is used when extracting the CSS string from actual
3868: presentation.
3869: el is the element for which the style rule is generated
1.18 cvs 3870:
3871: All the possible values returned by the presentation drivers are
3872: described in thotlib/include/presentation.h
3873: -----------------------------------------------------------------------*/
1.79 cvs 3874: void PToCss (PresentationSetting settings, char *buffer, int len, Element el)
1.1 cvs 3875: {
1.76 cvs 3876: ElementType elType;
1.18 cvs 3877: float fval = 0;
3878: unsigned short red, green, blue;
3879: int add_unit = 0;
3880: unsigned int unit, i;
3881: ThotBool real = FALSE;
3882:
1.82 cvs 3883: buffer[0] = EOS;
1.18 cvs 3884: if (len < 40)
3885: return;
3886:
3887: unit = settings->value.typed_data.unit;
3888: if (settings->value.typed_data.real)
3889: {
3890: real = TRUE;
3891: fval = (float) settings->value.typed_data.value;
1.195 vatton 3892: fval /= 1000.;
1.18 cvs 3893: }
1.1 cvs 3894:
1.18 cvs 3895: switch (settings->type)
1.1 cvs 3896: {
1.18 cvs 3897: case PRVisibility:
3898: break;
1.111 cvs 3899: case PRHeight:
3900: if (real)
3901: sprintf (buffer, "height: %g", fval);
3902: else
3903: sprintf (buffer, "height: %d", settings->value.typed_data.value);
3904: add_unit = 1;
3905: break;
3906: case PRWidth:
3907: if (real)
3908: sprintf (buffer, "width: %g", fval);
3909: else
3910: sprintf (buffer, "width: %d", settings->value.typed_data.value);
3911: add_unit = 1;
3912: break;
3913: case PRMarginTop:
3914: if (real)
3915: sprintf (buffer, "margin-top: %g", fval);
3916: else
3917: sprintf (buffer, "margin-top: %d",settings->value.typed_data.value);
3918: add_unit = 1;
3919: break;
3920: case PRMarginBottom:
3921: if (real)
3922: sprintf (buffer, "margin-bottom: %g", fval);
3923: else
3924: sprintf (buffer, "margin-bottom: %d",
3925: settings->value.typed_data.value);
3926: add_unit = 1;
3927: break;
3928: case PRMarginLeft:
3929: if (real)
3930: sprintf (buffer, "margin-left: %g", fval);
3931: else
1.164 quint 3932: sprintf (buffer, "margin-left: %d", settings->value.typed_data.value);
1.111 cvs 3933: add_unit = 1;
3934: break;
3935: case PRMarginRight:
3936: if (real)
3937: sprintf (buffer, "margin-right: %g", fval);
3938: else
1.164 quint 3939: sprintf (buffer, "margin-right: %d", settings->value.typed_data.value);
1.111 cvs 3940: add_unit = 1;
3941: break;
3942: case PRPaddingTop:
3943: if (real)
3944: sprintf (buffer, "padding-top: %g", fval);
3945: else
1.164 quint 3946: sprintf (buffer, "padding-top: %d", settings->value.typed_data.value);
1.111 cvs 3947: add_unit = 1;
3948: break;
3949: case PRPaddingBottom:
3950: if (real)
3951: sprintf (buffer, "padding-bottom: %g", fval);
3952: else
3953: sprintf (buffer, "padding-bottom: %d",
3954: settings->value.typed_data.value);
3955: add_unit = 1;
3956: break;
3957: case PRPaddingLeft:
3958: if (real)
3959: sprintf (buffer, "padding-left: %g", fval);
3960: else
1.164 quint 3961: sprintf (buffer, "padding-left: %d", settings->value.typed_data.value);
1.111 cvs 3962: add_unit = 1;
3963: break;
3964: case PRPaddingRight:
3965: if (real)
3966: sprintf (buffer, "padding-right: %g", fval);
3967: else
3968: sprintf (buffer, "padding-right: %d",
3969: settings->value.typed_data.value);
3970: add_unit = 1;
3971: break;
3972: case PRBorderTopWidth:
3973: if (real)
3974: sprintf (buffer, "border-top-width: %g", fval);
3975: else
3976: sprintf (buffer, "border-top-width: %d",
3977: settings->value.typed_data.value);
3978: add_unit = 1;
3979: break;
3980: case PRBorderBottomWidth:
3981: if (real)
3982: sprintf (buffer, "border-bottom-width: %g", fval);
3983: else
3984: sprintf (buffer, "border-bottom-width: %d",
3985: settings->value.typed_data.value);
3986: add_unit = 1;
3987: break;
3988: case PRBorderLeftWidth:
3989: if (real)
3990: sprintf (buffer, "border-left-width: %g", fval);
3991: else
3992: sprintf (buffer, "border-left-width: %d",
3993: settings->value.typed_data.value);
3994: add_unit = 1;
3995: break;
3996: case PRBorderRightWidth:
3997: if (real)
3998: sprintf (buffer, "border-right-width: %g", fval);
3999: else
4000: sprintf (buffer, "border-right-width: %d",
4001: settings->value.typed_data.value);
4002: add_unit = 1;
4003: break;
4004: case PRBorderTopColor:
4005: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4006: elType = TtaGetElementType(el);
4007: sprintf (buffer, "border-top-color: #%02X%02X%02X", red, green, blue);
4008: break;
4009: case PRBorderRightColor:
4010: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4011: elType = TtaGetElementType(el);
4012: sprintf (buffer, "border-right-color: #%02X%02X%02X", red, green, blue);
4013: break;
4014: case PRBorderBottomColor:
4015: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4016: elType = TtaGetElementType(el);
4017: sprintf (buffer, "border-bottom-color: #%02X%02X%02X", red, green, blue);
1.18 cvs 4018: break;
1.111 cvs 4019: case PRBorderLeftColor:
4020: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
4021: elType = TtaGetElementType(el);
4022: sprintf (buffer, "border-left-color: #%02X%02X%02X", red, green, blue);
1.20 cvs 4023: break;
1.111 cvs 4024: case PRBorderTopStyle:
4025: strcpy (buffer, "border-top-style: ");
4026: AddBorderStyleValue (buffer, settings->value.typed_data.value);
4027: break;
4028: case PRBorderRightStyle:
4029: strcpy (buffer, "border-right-style: ");
4030: AddBorderStyleValue (buffer, settings->value.typed_data.value);
4031: break;
4032: case PRBorderBottomStyle:
4033: strcpy (buffer, "border-bottom-style: ");
4034: AddBorderStyleValue (buffer, settings->value.typed_data.value);
4035: break;
4036: case PRBorderLeftStyle:
4037: strcpy (buffer, "border-left-style: ");
4038: AddBorderStyleValue (buffer, settings->value.typed_data.value);
1.18 cvs 4039: break;
4040: case PRSize:
1.184 vatton 4041: if (unit == UNIT_REL)
1.18 cvs 4042: {
4043: if (real)
4044: {
1.82 cvs 4045: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 4046: add_unit = 1;
4047: }
4048: else
4049: switch (settings->value.typed_data.value)
4050: {
4051: case 1:
1.82 cvs 4052: strcpy (buffer, "font-size: xx-small");
1.18 cvs 4053: break;
4054: case 2:
1.82 cvs 4055: strcpy (buffer, "font-size: x-small");
1.18 cvs 4056: break;
4057: case 3:
1.82 cvs 4058: strcpy (buffer, "font-size: small");
1.18 cvs 4059: break;
4060: case 4:
1.82 cvs 4061: strcpy (buffer, "font-size: medium");
1.18 cvs 4062: break;
4063: case 5:
1.82 cvs 4064: strcpy (buffer, "font-size: large");
1.18 cvs 4065: break;
4066: case 6:
1.82 cvs 4067: strcpy (buffer, "font-size: x-large");
1.18 cvs 4068: break;
4069: case 7:
4070: case 8:
4071: case 9:
4072: case 10:
4073: case 11:
4074: case 12:
1.82 cvs 4075: strcpy (buffer, "font-size: xx-large");
1.18 cvs 4076: break;
4077: }
4078: }
4079: else
4080: {
4081: if (real)
1.82 cvs 4082: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 4083: else
1.82 cvs 4084: sprintf (buffer, "font-size: %d",
1.67 cvs 4085: settings->value.typed_data.value);
1.18 cvs 4086: add_unit = 1;
4087: }
4088: break;
1.111 cvs 4089: case PRStyle:
4090: switch (settings->value.typed_data.value)
4091: {
1.184 vatton 4092: case StyleRoman:
1.111 cvs 4093: strcpy (buffer, "font-style: normal");
4094: break;
1.184 vatton 4095: case StyleItalics:
1.111 cvs 4096: strcpy (buffer, "font-style: italic");
4097: break;
1.184 vatton 4098: case StyleOblique:
1.111 cvs 4099: strcpy (buffer, "font-style: oblique");
4100: break;
4101: }
4102: break;
4103: case PRWeight:
4104: switch (settings->value.typed_data.value)
4105: {
1.184 vatton 4106: case WeightBold:
1.111 cvs 4107: strcpy (buffer, "font-weight: bold");
4108: break;
1.184 vatton 4109: case WeightNormal:
1.111 cvs 4110: strcpy (buffer, "font-weight: normal");
4111: break;
4112: }
4113: break;
4114: case PRFont:
4115: switch (settings->value.typed_data.value)
4116: {
1.184 vatton 4117: case FontHelvetica:
1.111 cvs 4118: strcpy (buffer, "font-family: helvetica");
4119: break;
1.184 vatton 4120: case FontTimes:
1.111 cvs 4121: strcpy (buffer, "font-family: times");
4122: break;
1.184 vatton 4123: case FontCourier:
1.111 cvs 4124: strcpy (buffer, "font-family: courier");
4125: break;
4126: }
4127: break;
1.18 cvs 4128: case PRUnderline:
4129: switch (settings->value.typed_data.value)
4130: {
1.184 vatton 4131: case Underline:
1.82 cvs 4132: strcpy (buffer, "text-decoration: underline");
1.18 cvs 4133: break;
1.184 vatton 4134: case Overline:
1.82 cvs 4135: strcpy (buffer, "text-decoration: overline");
1.18 cvs 4136: break;
1.184 vatton 4137: case CrossOut:
1.82 cvs 4138: strcpy (buffer, "text-decoration: line-through");
1.18 cvs 4139: break;
4140: }
4141: break;
1.111 cvs 4142: case PRThickness:
4143: break;
1.18 cvs 4144: case PRIndent:
4145: if (real)
1.82 cvs 4146: sprintf (buffer, "text-indent: %g", fval);
1.18 cvs 4147: else
1.82 cvs 4148: sprintf (buffer, "text-indent: %d",
1.67 cvs 4149: settings->value.typed_data.value);
1.18 cvs 4150: add_unit = 1;
4151: break;
4152: case PRLineSpacing:
4153: if (real)
1.82 cvs 4154: sprintf (buffer, "line-height: %g", fval);
1.1 cvs 4155: else
1.82 cvs 4156: sprintf (buffer, "line-height: %d",
1.67 cvs 4157: settings->value.typed_data.value);
1.18 cvs 4158: add_unit = 1;
4159: break;
1.111 cvs 4160: case PRDepth:
4161: break;
1.18 cvs 4162: case PRAdjust:
4163: switch (settings->value.typed_data.value)
1.1 cvs 4164: {
1.184 vatton 4165: case AdjustLeft:
1.82 cvs 4166: strcpy (buffer, "text-align: left");
1.18 cvs 4167: break;
1.184 vatton 4168: case AdjustRight:
1.82 cvs 4169: strcpy (buffer, "text-align: right");
1.18 cvs 4170: break;
1.184 vatton 4171: case Centered:
1.82 cvs 4172: strcpy (buffer, "text-align: center");
1.18 cvs 4173: break;
1.184 vatton 4174: case LeftWithDots:
1.82 cvs 4175: strcpy (buffer, "text-align: left");
1.81 cvs 4176: break;
1.184 vatton 4177: case Justify:
1.82 cvs 4178: strcpy (buffer, "text-align: justify");
1.112 quint 4179: break;
4180: }
4181: break;
4182: case PRDirection:
4183: switch (settings->value.typed_data.value)
4184: {
1.184 vatton 4185: case LeftToRight:
1.112 quint 4186: strcpy (buffer, "direction: ltr");
4187: break;
1.184 vatton 4188: case RightToLeft:
1.112 quint 4189: strcpy (buffer, "direction: rtl");
1.113 quint 4190: break;
4191: }
4192: break;
4193: case PRUnicodeBidi:
4194: switch (settings->value.typed_data.value)
4195: {
1.184 vatton 4196: case Normal:
1.113 quint 4197: strcpy (buffer, "unicode-bidi: normal");
4198: break;
1.184 vatton 4199: case Embed:
1.113 quint 4200: strcpy (buffer, "unicode-bidi: embed");
4201: break;
1.184 vatton 4202: case Override:
1.113 quint 4203: strcpy (buffer, "unicode-bidi: bidi-override");
1.18 cvs 4204: break;
1.1 cvs 4205: }
1.18 cvs 4206: break;
1.111 cvs 4207: case PRLineStyle:
4208: break;
1.126 vatton 4209: case PRDisplay:
4210: switch (settings->value.typed_data.value)
4211: {
1.184 vatton 4212: case Inline:
1.126 vatton 4213: strcpy (buffer, "display: inline");
4214: break;
1.184 vatton 4215: case Block:
1.126 vatton 4216: strcpy (buffer, "display: block");
4217: break;
1.184 vatton 4218: case ListItem:
1.126 vatton 4219: strcpy (buffer, "display: list-item");
4220: break;
1.184 vatton 4221: case RunIn:
1.126 vatton 4222: strcpy (buffer, "display: runin");
4223: break;
1.184 vatton 4224: case Compact:
1.126 vatton 4225: strcpy (buffer, "display: compact");
4226: break;
1.184 vatton 4227: case Marker:
1.126 vatton 4228: strcpy (buffer, "display: marker");
1.196 vatton 4229: break;
4230: default:
4231: break;
4232: }
4233: break;
4234: case PRFloat:
4235: switch (settings->value.typed_data.value)
4236: {
4237: case FloatNone:
4238: strcpy (buffer, "float: none");
4239: break;
4240: case FloatLeft:
4241: strcpy (buffer, "float: left");
4242: break;
4243: case FloatRight:
4244: strcpy (buffer, "float: right");
4245: break;
4246: default:
4247: break;
4248: }
4249: break;
4250: case PRClear:
4251: switch (settings->value.typed_data.value)
4252: {
4253: case ClearNone:
4254: strcpy (buffer, "clear: none");
4255: break;
4256: case ClearLeft:
4257: strcpy (buffer, "clear: left");
4258: break;
4259: case ClearRight:
4260: strcpy (buffer, "clear: right");
4261: break;
4262: case ClearBoth:
4263: strcpy (buffer, "clear: both");
1.126 vatton 4264: break;
4265: default:
4266: break;
4267: }
4268: break;
1.111 cvs 4269: case PRLineWeight:
4270: elType = TtaGetElementType(el);
4271: #ifdef _SVG
4272: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
4273: #endif /* _SVG */
4274: {
4275: if (real)
4276: sprintf (buffer, "stroke-width: %g", fval);
4277: else
4278: sprintf (buffer, "stroke-width: %d",
4279: settings->value.typed_data.value);
4280: }
4281: add_unit = 1;
1.18 cvs 4282: break;
4283: case PRFillPattern:
4284: break;
4285: case PRBackground:
4286: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 4287: elType = TtaGetElementType(el);
1.100 vatton 4288: #ifdef _SVG
4289: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 4290: sprintf (buffer, "fill: #%02X%02X%02X", red, green, blue);
1.67 cvs 4291: else
1.100 vatton 4292: #endif /* _SVG */
1.82 cvs 4293: sprintf (buffer, "background-color: #%02X%02X%02X", red, green,
1.67 cvs 4294: blue);
1.18 cvs 4295: break;
4296: case PRForeground:
4297: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 4298: elType = TtaGetElementType(el);
1.100 vatton 4299: #ifdef _SVG
4300: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 4301: sprintf (buffer, "stroke: #%02X%02X%02X", red, green, blue);
1.67 cvs 4302: else
1.100 vatton 4303: #endif /* _SVG */
1.82 cvs 4304: sprintf (buffer, "color: #%02X%02X%02X", red, green, blue);
1.67 cvs 4305: break;
1.111 cvs 4306: case PRHyphenate:
1.195 vatton 4307: case PRVertOverflow:
4308: case PRHorizOverflow:
4309: break;
4310: case PROpacity:
4311: sprintf (buffer, "opacity: %g", fval);
1.18 cvs 4312: break;
1.195 vatton 4313: case PRStrokeOpacity:
4314: sprintf (buffer, "stroke-opacity: %g", fval);
1.18 cvs 4315: break;
1.195 vatton 4316: case PRFillOpacity:
4317: sprintf (buffer, "fill-opacity: %g", fval);
1.18 cvs 4318: break;
4319: case PRBackgroundPicture:
4320: if (settings->value.pointer != NULL)
1.82 cvs 4321: sprintf (buffer, "background-image: url(%s)",
1.67 cvs 4322: (char*)(settings->value.pointer));
1.1 cvs 4323: else
1.82 cvs 4324: sprintf (buffer, "background-image: none");
1.18 cvs 4325: break;
4326: case PRPictureMode:
4327: switch (settings->value.typed_data.value)
1.1 cvs 4328: {
1.184 vatton 4329: case REALSIZE:
1.82 cvs 4330: sprintf (buffer, "background-repeat: no-repeat");
1.18 cvs 4331: break;
1.184 vatton 4332: case REPEAT:
1.82 cvs 4333: sprintf (buffer, "background-repeat: repeat");
1.18 cvs 4334: break;
1.184 vatton 4335: case VREPEAT:
1.82 cvs 4336: sprintf (buffer, "background-repeat: repeat-y");
1.18 cvs 4337: break;
1.184 vatton 4338: case HREPEAT:
1.82 cvs 4339: sprintf (buffer, "background-repeat: repeat-x");
1.18 cvs 4340: break;
1.1 cvs 4341: }
1.18 cvs 4342: break;
4343: default:
4344: break;
1.1 cvs 4345: }
4346:
1.18 cvs 4347: if (add_unit)
1.1 cvs 4348: {
1.18 cvs 4349: /* add the unit string to the CSS string */
4350: for (i = 0; i < NB_UNITS; i++)
1.1 cvs 4351: {
1.18 cvs 4352: if (CSSUnitNames[i].unit == unit)
1.1 cvs 4353: {
1.82 cvs 4354: strcat (buffer, CSSUnitNames[i].sign);
1.18 cvs 4355: break;
1.1 cvs 4356: }
4357: }
4358: }
4359: }
4360:
4361: /*----------------------------------------------------------------------
1.59 cvs 4362: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18 cvs 4363: This function must be called when a specific style is applied to an
4364: element.
1.114 quint 4365: The parameter specificity is the specificity of the style, 0 if it is
4366: not really a CSS rule.
1.1 cvs 4367: ----------------------------------------------------------------------*/
1.79 cvs 4368: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.114 quint 4369: int specificity, ThotBool destroy)
1.1 cvs 4370: {
1.207 vatton 4371: PresentationContext ctxt;
4372: ElementType elType;
4373: ThotBool isHTML;
1.1 cvs 4374:
1.207 vatton 4375: /* A rule applying to BODY is really meant to address HTML */
4376: elType = TtaGetElementType (el);
1.89 cvs 4377:
1.207 vatton 4378: /* store the current line for eventually reported errors */
4379: LineNumber = TtaGetElementLineNumber (el);
4380: if (destroy)
4381: /* no reported errors */
4382: ParsedDoc = 0;
4383: else if (ParsedDoc != doc)
4384: {
4385: /* update the context for reported errors */
4386: ParsedDoc = doc;
4387: DocURL = DocumentURLs[doc];
4388: }
4389: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
4390: /* create the context of the Specific presentation driver */
4391: ctxt = TtaGetSpecificStyleContext (doc);
4392: if (ctxt == NULL)
4393: return;
4394: ctxt->type = elType.ElTypeNum;
4395: ctxt->cssSpecificity = specificity;
4396: ctxt->destroy = destroy;
4397: /* first use of the context */
4398: ctxt->uses = 1;
4399: /* Call the parser */
4400: ParseCSSRule (el, NULL, (PresentationContext) ctxt, cssRule, NULL, isHTML);
4401: /* check if the context can be freed */
4402: ctxt->uses -= 1;
4403: if (ctxt->uses == 0)
4404: /* no image loading */
4405: TtaFreeMemory(ctxt);
1.1 cvs 4406: }
4407:
1.68 cvs 4408:
1.1 cvs 4409: /*----------------------------------------------------------------------
1.207 vatton 4410: ParseGenericSelector: Create a generic context for a given selector
4411: string.
4412: If the selector is made of multiple comma, it parses them one at a time
4413: and return the end of the selector string to be handled or NULL.
1.1 cvs 4414: ----------------------------------------------------------------------*/
1.207 vatton 4415: static char *ParseGenericSelector (char *selector, char *cssRule,
1.79 cvs 4416: GenericContext ctxt, Document doc,
1.206 vatton 4417: CSSInfoPtr css, Element link)
1.79 cvs 4418: {
4419: ElementType elType;
4420: PSchema tsch;
1.119 vatton 4421: AttributeType attrType;
1.207 vatton 4422: char *deb, *cur, *sel, c;
1.118 vatton 4423: char *schemaName, *mappedName;
1.79 cvs 4424: char *names[MAX_ANCESTORS];
4425: char *ids[MAX_ANCESTORS];
4426: char *classes[MAX_ANCESTORS];
4427: char *pseudoclasses[MAX_ANCESTORS];
4428: char *attrs[MAX_ANCESTORS];
4429: char *attrvals[MAX_ANCESTORS];
1.133 vatton 4430: AttrMatch attrmatch[MAX_ANCESTORS];
1.91 cvs 4431: int i, j, k, max;
1.125 vatton 4432: int att, maxAttr, kind;
1.118 vatton 4433: int specificity, xmlType;
1.79 cvs 4434: ThotBool isHTML;
1.183 vatton 4435: ThotBool level, quoted;
1.1 cvs 4436:
1.207 vatton 4437: sel = ctxt->sel;
1.82 cvs 4438: sel[0] = EOS;
1.117 vatton 4439: specificity = 0;
1.1 cvs 4440: for (i = 0; i < MAX_ANCESTORS; i++)
4441: {
1.25 cvs 4442: names[i] = NULL;
4443: ids[i] = NULL;
4444: classes[i] = NULL;
4445: pseudoclasses[i] = NULL;
4446: attrs[i] = NULL;
4447: attrvals[i] = NULL;
1.133 vatton 4448: attrmatch[i] = Txtmatch;
1.25 cvs 4449: ctxt->name[i] = 0;
4450: ctxt->names_nb[i] = 0;
4451: ctxt->attrType[i] = 0;
1.129 vatton 4452: ctxt->attrLevel[i] = 0;
1.25 cvs 4453: ctxt->attrText[i] = NULL;
1.178 quint 4454: ctxt->attrMatch[i] = Txtmatch;
1.1 cvs 4455: }
1.25 cvs 4456: ctxt->box = 0;
4457: ctxt->type = 0;
1.114 quint 4458: /* the specificity of the rule depends on the selector */
4459: ctxt->cssSpecificity = 0;
1.25 cvs 4460:
1.82 cvs 4461: selector = SkipBlanksAndComments (selector);
1.27 cvs 4462: cur = &sel[0];
1.25 cvs 4463: max = 0; /* number of loops */
1.1 cvs 4464: while (1)
4465: {
1.85 cvs 4466: /* point to the following word in sel[] */
1.27 cvs 4467: deb = cur;
1.25 cvs 4468: /* copy an item of the selector into sel[] */
1.1 cvs 4469: /* put one word in the sel buffer */
1.82 cvs 4470: while (*selector != EOS && *selector != ',' &&
4471: *selector != '.' && *selector != ':' &&
1.118 vatton 4472: *selector != '#' && *selector != '[' &&
1.130 vatton 4473: *selector != '*' && *selector != '>' &&
1.118 vatton 4474: !TtaIsBlank (selector))
1.50 cvs 4475: *cur++ = *selector++;
1.82 cvs 4476: *cur++ = EOS; /* close the first string in sel[] */
4477: if (deb[0] != EOS)
1.117 vatton 4478: {
4479: names[0] = deb;
1.150 vatton 4480: if (!strcmp (names[0], "html"))
1.149 vatton 4481: /* give a greater priority to the backgoud color of html */
4482: specificity += 3;
4483: else
4484: specificity += 1;
1.117 vatton 4485: }
1.25 cvs 4486: else
1.27 cvs 4487: names[0] = NULL;
4488: classes[0] = NULL;
4489: pseudoclasses[0] = NULL;
4490: ids[0] = NULL;
4491: attrs[0] = NULL;
4492: attrvals[0] = NULL;
1.25 cvs 4493:
1.27 cvs 4494: /* now names[0] points to the beginning of the parsed item
1.25 cvs 4495: and cur to the next chain to be parsed */
1.129 vatton 4496: while (*selector == '.' || *selector == ':' ||
1.130 vatton 4497: *selector == '#' || *selector == '[' ||
1.183 vatton 4498: *selector == '*')
1.129 vatton 4499: {
1.85 cvs 4500: /* point to the following word in sel[] */
4501: deb = cur;
1.202 vatton 4502: if (*selector == '*' &&
4503: (selector[1] == '.' || selector[1] == ':' ||
4504: selector[1] == '#' || selector[1] == '['))
4505: selector++;
1.129 vatton 4506: if (*selector == '.')
4507: {
4508: selector++;
4509: while (*selector != EOS && *selector != ',' &&
4510: *selector != '.' && *selector != ':' &&
4511: !TtaIsBlank (selector))
4512: *cur++ = *selector++;
4513: /* close the word */
4514: *cur++ = EOS;
4515: /* point to the class in sel[] if it's valid name */
4516: if (deb[0] <= 64)
4517: {
1.168 vatton 4518: CSSPrintError ("Invalid class", deb);
1.116 vatton 4519: DoApply = FALSE;
1.129 vatton 4520: }
4521: else
4522: {
4523: classes[0] = deb;
1.178 quint 4524: /* a "class" attribute on an element may contain several
4525: words, one for each class it matches */
4526: attrmatch[0] = Txtword;
1.117 vatton 4527: specificity += 10;
1.129 vatton 4528: }
4529: }
4530: else if (*selector == ':')
4531: {
4532: selector++;
4533: while (*selector != EOS && *selector != ',' &&
4534: *selector != '.' && *selector != ':' &&
4535: !TtaIsBlank (selector))
4536: *cur++ = *selector++;
4537: /* close the word */
4538: *cur++ = EOS;
4539: /* point to the pseudoclass in sel[] if it's valid name */
4540: if (deb[0] <= 64)
4541: {
1.168 vatton 4542: CSSPrintError ("Invalid pseudoclass", deb);
1.129 vatton 4543: DoApply = FALSE;
4544: }
4545: else
4546: {
4547: if (!strcmp (deb, "first-letter") ||
4548: !strcmp (deb, "first-line") ||
4549: !strcmp (deb, "before") ||
4550: !strcmp (deb, "after"))
4551: /* not supported */
1.116 vatton 4552: DoApply = FALSE;
1.129 vatton 4553: else
4554: specificity += 10;
4555: pseudoclasses[0]= deb;
4556: }
4557: }
4558: else if (*selector == '#')
4559: {
4560: selector++;
4561: while (*selector != EOS && *selector != ',' &&
4562: *selector != '.' && *selector != ':' &&
4563: !TtaIsBlank (selector))
4564: *cur++ = *selector++;
4565: /* close the word */
4566: *cur++ = EOS;
4567: /* point to the attribute in sel[] if it's valid name */
4568: if (deb[0] <= 64)
4569: {
1.168 vatton 4570: CSSPrintError ("Invalid id", deb);
1.129 vatton 4571: DoApply = FALSE;
4572: }
4573: else
4574: {
4575: ids[0] = deb;
4576: specificity += 100;
4577: }
4578: }
4579: else if (*selector == '[')
4580: {
1.118 vatton 4581: selector++;
1.129 vatton 4582: while (*selector != EOS && *selector != ']' &&
1.131 vatton 4583: *selector != '=' && *selector != '~' &&
1.133 vatton 4584: *selector != '|' && *selector != '^' &&
4585: *selector != '!')
1.129 vatton 4586: *cur++ = *selector++;
1.133 vatton 4587: /* check matching */
4588: if (*selector == '~')
4589: {
4590: attrmatch[0] = Txtword;
4591: selector++;
4592: }
4593: else if (*selector == '|')
4594: {
4595: attrmatch[0] = Txtsubstring;
4596: selector++;
4597: }
4598: else
4599: attrmatch[0] = Txtmatch;
1.129 vatton 4600: /* close the word */
4601: *cur++ = EOS;
4602: /* point to the attribute in sel[] if it's valid name */
4603: if (deb[0] <= 64)
4604: {
1.168 vatton 4605: CSSPrintError ("Invalid attribute", deb);
1.129 vatton 4606: DoApply = FALSE;
4607: }
4608: else
4609: {
4610: attrs[0] = deb;
4611: specificity += 10;
4612: }
4613: if (*selector == '=')
4614: {
4615: /* look for a value "xxxx" */
4616: selector++;
4617: if (*selector != '"')
1.183 vatton 4618: quoted = FALSE;
1.129 vatton 4619: else
4620: {
1.183 vatton 4621: quoted = TRUE;
1.129 vatton 4622: /* we are now parsing the attribute value */
4623: selector++;
1.183 vatton 4624: }
4625: deb = cur;
4626: while ((quoted &&
4627: (*selector != '"' ||
4628: (*selector == '"' && selector[-1] == '\\'))) ||
4629: (!quoted && *selector != ']'))
4630: {
4631: if (*selector == EOS)
1.129 vatton 4632: {
1.183 vatton 4633: CSSPrintError ("Invalid attribute value", deb);
4634: DoApply = FALSE;
1.129 vatton 4635: }
1.183 vatton 4636: else
1.129 vatton 4637: {
1.183 vatton 4638: *cur++ = tolower (*selector);
1.129 vatton 4639: selector++;
4640: }
4641: }
1.183 vatton 4642: /* there is a value */
1.204 quint 4643: if (quoted && *selector == '"')
1.183 vatton 4644: {
4645: selector++;
4646: quoted = FALSE;
4647: }
4648: if (*selector != ']')
4649: {
4650: CSSPrintError ("Invalid attribute value", deb);
4651: DoApply = FALSE;
4652: }
4653: else
4654: {
4655: *cur++ = EOS;
4656: attrvals[0] = deb;
4657: selector++;
4658: }
1.129 vatton 4659: }
4660: /* end of the attribute */
1.183 vatton 4661: else if (*selector != ']')
1.129 vatton 4662: {
1.133 vatton 4663: selector[1] = EOS;
1.183 vatton 4664: CSSPrintError ("Invalid attribute", selector);
1.133 vatton 4665: selector += 2;
1.129 vatton 4666: DoApply = FALSE;
4667: }
4668: else
4669: selector++;
1.130 vatton 4670: }
4671: else
4672: {
4673: /* not supported selector */
4674: while (*selector != EOS && *selector != ',' &&
4675: *selector != '.' && *selector != ':' &&
4676: !TtaIsBlank (selector))
4677: *cur++ = *selector++;
4678: /* close the word */
4679: *cur++ = EOS;
1.205 quint 4680: CSSPrintError ("Selector not supported:", deb);
1.130 vatton 4681: DoApply = FALSE;
1.129 vatton 4682: }
4683: }
1.1 cvs 4684:
1.82 cvs 4685: selector = SkipBlanksAndComments (selector);
1.25 cvs 4686: /* is it a multi-level selector? */
1.82 cvs 4687: if (*selector == EOS)
1.1 cvs 4688: /* end of the selector */
4689: break;
1.82 cvs 4690: else if (*selector == ',')
1.1 cvs 4691: {
4692: /* end of the current selector */
4693: selector++;
4694: break;
4695: }
1.25 cvs 4696: else
4697: {
1.143 vatton 4698: if (*selector == '>')
4699: {
4700: /* handle immediat parent as a simple parent */
4701: selector++;
4702: selector = SkipBlanksAndComments (selector);
4703: }
1.25 cvs 4704: /* shifts the list to make room for the new name */
4705: max++; /* a new level in ancestor tables */
4706: if (max == MAX_ANCESTORS)
4707: /* abort the CSS parsing */
4708: return (selector);
4709: for (i = max; i > 0; i--)
4710: {
4711: names[i] = names[i - 1];
4712: ids[i] = ids[i - 1];
4713: classes[i] = classes[i - 1];
1.133 vatton 4714: pseudoclasses[i] = pseudoclasses[i - 1];
1.25 cvs 4715: attrs[i] = attrs[i - 1];
4716: attrvals[i] = attrvals[i - 1];
1.133 vatton 4717: attrmatch[i] = attrmatch[i - 1];
1.25 cvs 4718: }
4719: }
1.1 cvs 4720: }
4721:
4722: /* Now set up the context block */
1.25 cvs 4723: i = 0;
4724: k = 0;
4725: j = 0;
1.35 cvs 4726: maxAttr = 0;
1.91 cvs 4727: /* default schema name */
1.119 vatton 4728: ctxt->schema = NULL;
1.122 vatton 4729: elType.ElSSchema = NULL;
4730: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 4731: if (!strcmp (schemaName, "HTML"))
4732: xmlType = XHTML_TYPE;
4733: else if (!strcmp (schemaName, "MathML"))
4734: xmlType = MATH_TYPE;
4735: else if (!strcmp (schemaName, "SVG"))
4736: xmlType = SVG_TYPE;
4737: else if (!strcmp (schemaName, "XLink"))
4738: xmlType = XLINK_TYPE;
4739: else if (!strcmp (schemaName, "Annot"))
4740: xmlType = ANNOT_TYPE;
4741: else
4742: xmlType = XML_TYPE;
1.25 cvs 4743: while (i <= max)
4744: {
4745: if (names[i])
4746: {
1.118 vatton 4747: /* get the element type of this name in the current document */
4748: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c, &level, doc);
1.25 cvs 4749: if (i == 0)
4750: {
1.106 cvs 4751: if (elType.ElSSchema == NULL)
4752: {
1.119 vatton 4753: /* Search in the list of loaded schemas */
1.106 cvs 4754: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.119 vatton 4755: if (elType.ElSSchema)
4756: {
1.154 vatton 4757: /* the element type concerns an imported nature */
1.119 vatton 4758: schemaName = TtaGetSSchemaName(elType.ElSSchema);
4759: if (!strcmp (schemaName, "HTML"))
4760: xmlType = XHTML_TYPE;
4761: else if (!strcmp (schemaName, "MathML"))
4762: xmlType = MATH_TYPE;
4763: else if (!strcmp (schemaName, "SVG"))
4764: xmlType = SVG_TYPE;
4765: else if (!strcmp (schemaName, "XLink"))
4766: xmlType = XLINK_TYPE;
4767: else if (!strcmp (schemaName, "Annot"))
4768: xmlType = ANNOT_TYPE;
4769: else
4770: xmlType = XML_TYPE;
4771: }
1.118 vatton 4772: #ifdef XML_GENERIC
1.119 vatton 4773: else if (xmlType == XML_TYPE)
1.106 cvs 4774: {
4775: /* Creation of a new element type in the main schema */
4776: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.118 vatton 4777: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.106 cvs 4778: }
1.118 vatton 4779: #endif /* XML_GENERIC */
1.122 vatton 4780: else
4781: {
4782: if (xmlType != XHTML_TYPE)
4783: {
4784: MapXMLElementType (XHTML_TYPE, names[i], &elType,
4785: &mappedName, &c, &level, doc);
4786: if (elType.ElSSchema)
1.123 vatton 4787: elType.ElSSchema = GetXHTMLSSchema (doc);
1.122 vatton 4788: }
4789: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
4790: {
4791: MapXMLElementType (MATH_TYPE, names[i], &elType,
4792: &mappedName, &c, &level, doc);
4793: if (elType.ElSSchema)
1.123 vatton 4794: elType.ElSSchema = GetMathMLSSchema (doc);
1.122 vatton 4795: }
4796: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
4797: {
4798: MapXMLElementType (SVG_TYPE, names[i], &elType,
4799: &mappedName, &c, &level, doc);
4800: if (elType.ElSSchema)
1.123 vatton 4801: elType.ElSSchema = GetSVGSSchema (doc);
1.122 vatton 4802: }
4803: }
1.118 vatton 4804: }
1.119 vatton 4805:
1.118 vatton 4806: if (elType.ElSSchema == NULL)
4807: /* cannot apply these CSS rules */
4808: DoApply = FALSE;
4809: else
4810: {
4811: /* Store the element type */
4812: ctxt->type = elType.ElTypeNum;
4813: ctxt->name[0] = elType.ElTypeNum;
4814: ctxt->names_nb[0] = 0;
4815: ctxt->schema = elType.ElSSchema;
1.106 cvs 4816: }
1.25 cvs 4817: }
4818: else if (elType.ElTypeNum != 0)
4819: {
4820: /* look at the current context to see if the type is already
4821: stored */
1.121 vatton 4822: j = 1;
1.32 cvs 4823: while (j < k && ctxt->name[j] != elType.ElTypeNum)
1.25 cvs 4824: j++;
4825: if (j == k)
4826: {
4827: ctxt->name[j] = elType.ElTypeNum;
4828: if (j != 0)
1.121 vatton 4829: ctxt->names_nb[j] = 1;
1.25 cvs 4830: }
4831: else
4832: /* increment the number of ancestor levels */
4833: ctxt->names_nb[j]++;
4834: }
1.154 vatton 4835: #ifdef XML_GENERIC
4836: else if (xmlType == XML_TYPE)
4837: {
1.158 vatton 4838: TtaGetXmlElementType (names[i], &elType, NULL, doc);
4839: if (elType.ElTypeNum == 0)
4840: {
4841: /* Creation of a new element type in the main schema */
4842: elType.ElSSchema = TtaGetDocumentSSchema (doc);
4843: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
4844: }
1.154 vatton 4845: if (elType.ElTypeNum != 0)
4846: {
4847: /* look at the current context to see if the type is already
4848: stored */
4849: j = 1;
4850: while (j < k && ctxt->name[j] != elType.ElTypeNum)
4851: j++;
4852: if (j == k)
4853: {
4854: ctxt->name[j] = elType.ElTypeNum;
4855: if (j != 0)
4856: ctxt->names_nb[j] = 1;
4857: }
4858: else
4859: /* increment the number of ancestor levels */
4860: ctxt->names_nb[j]++;
4861: }
4862: }
4863: #endif /* XML_GENERIC */
1.25 cvs 4864: else
1.117 vatton 4865: j = k;
1.25 cvs 4866: }
1.117 vatton 4867: else
4868: j = k;
1.1 cvs 4869:
1.25 cvs 4870: /* store attributes information */
4871: if (classes[i])
4872: {
4873: ctxt->attrText[j] = classes[i];
1.119 vatton 4874: if (xmlType == SVG_TYPE)
1.100 vatton 4875: ctxt->attrType[j] = SVG_ATTR_class;
1.119 vatton 4876: else if (xmlType == MATH_TYPE)
1.91 cvs 4877: ctxt->attrType[j] = MathML_ATTR_class;
1.119 vatton 4878: else if (xmlType == XHTML_TYPE)
1.107 cvs 4879: ctxt->attrType[j] = HTML_ATTR_Class;
4880: else
1.119 vatton 4881: #ifdef XML_GENERIC
1.107 cvs 4882: ctxt->attrType[j] = XML_ATTR_class;
4883: #else /* XML_GENERIC */
1.91 cvs 4884: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 4885: #endif /* XML_GENERIC */
1.157 vatton 4886: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4887: /* add a new entry */
1.80 cvs 4888: maxAttr = i + 1;
1.129 vatton 4889: /* update attrLevel */
4890: ctxt->attrLevel[j] = i;
4891: j++;
1.25 cvs 4892: }
1.79 cvs 4893: if (pseudoclasses[i])
1.25 cvs 4894: {
4895: ctxt->attrText[j] = pseudoclasses[i];
1.119 vatton 4896: if (xmlType == SVG_TYPE)
1.100 vatton 4897: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
1.119 vatton 4898: else if (xmlType == MATH_TYPE)
1.91 cvs 4899: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
1.119 vatton 4900: else if (xmlType == XHTML_TYPE)
1.107 cvs 4901: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
4902: else
1.119 vatton 4903: #ifdef XML_GENERIC
1.107 cvs 4904: ctxt->attrType[j] = XML_ATTR_PseudoClass;
4905: #else /* XML_GENERIC */
1.91 cvs 4906: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 4907: #endif /* XML_GENERIC */
1.157 vatton 4908: ctxt->attrMatch[j] = attrmatch[i];
1.79 cvs 4909: /* add a new entry */
1.80 cvs 4910: maxAttr = i + 1;
1.129 vatton 4911: /* update attrLevel */
4912: ctxt->attrLevel[j] = i;
4913: j++;
1.25 cvs 4914: }
1.79 cvs 4915: if (ids[i])
1.25 cvs 4916: {
4917: ctxt->attrText[j] = ids[i];
1.119 vatton 4918: if (xmlType == SVG_TYPE)
1.100 vatton 4919: ctxt->attrType[j] = SVG_ATTR_id;
1.119 vatton 4920: else if (xmlType == MATH_TYPE)
1.91 cvs 4921: ctxt->attrType[j] = MathML_ATTR_id;
1.119 vatton 4922: else if (xmlType == XHTML_TYPE)
1.107 cvs 4923: ctxt->attrType[j] = HTML_ATTR_ID;
4924: else
1.119 vatton 4925: #ifdef XML_GENERIC
1.107 cvs 4926: ctxt->attrType[j] = XML_ATTR_id;
4927: #else /* XML_GENERIC */
1.91 cvs 4928: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 4929: #endif /* XML_GENERIC */
1.157 vatton 4930: ctxt->attrMatch[j] = attrmatch[i];
1.80 cvs 4931: /* add a new entry */
4932: maxAttr = i + 1;
1.129 vatton 4933: /* update attrLevel */
4934: ctxt->attrLevel[j] = i;
4935: j++;
1.25 cvs 4936: }
1.79 cvs 4937: if (attrs[i])
1.25 cvs 4938: {
1.125 vatton 4939: /* it's an attribute */
1.119 vatton 4940: MapXMLAttribute (xmlType, attrs[i], names[i], &level, doc, &att);
1.127 quint 4941: if (att == DummyAttribute && !strcmp (schemaName, "HTML"))
4942: /* it's the "type" attribute for an "input" element. In the tree
4943: it's represented by the element type, not by an attribute */
4944: att = 0;
1.119 vatton 4945: ctxt->attrType[j] = att;
1.133 vatton 4946: ctxt->attrMatch[j] = attrmatch[i];
1.125 vatton 4947: attrType.AttrSSchema = ctxt->schema;
4948: attrType.AttrTypeNum = att;
1.119 vatton 4949: if (i == 0 && att == 0 && ctxt->schema == NULL)
4950: {
1.125 vatton 4951: /* Not found -> search in the list of loaded schemas */
1.119 vatton 4952: attrType.AttrSSchema = NULL;
4953: TtaGetXmlAttributeType (attrs[i], &attrType, doc);
4954: ctxt->attrType[j] = attrType.AttrTypeNum;
4955: if (attrType.AttrSSchema)
1.125 vatton 4956: /* the element type concerns an imported nature */
4957: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
1.119 vatton 4958: #ifdef XML_GENERIC
4959: else if (xmlType == XML_TYPE)
4960: {
4961: /* The attribute is not yet present in the tree */
4962: /* Create a new global attribute */
4963: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
4964: TtaAppendXmlAttribute (attrs[i], &attrType, doc);
4965: }
4966: #endif /* XML_GENERIC */
4967:
4968: if (attrType.AttrSSchema == NULL)
4969: /* cannot apply these CSS rules */
4970: DoApply = FALSE;
1.136 quint 4971: else if (elType.ElSSchema)
4972: ctxt->schema = elType.ElSSchema;
1.119 vatton 4973: else
1.136 quint 4974: ctxt->schema = attrType.AttrSSchema;
1.119 vatton 4975: }
1.125 vatton 4976: /* check the attribute type */
4977: if (!strcmp (schemaName, "HTML"))
4978: xmlType = XHTML_TYPE;
4979: else if (!strcmp (schemaName, "MathML"))
4980: xmlType = MATH_TYPE;
4981: else if (!strcmp (schemaName, "SVG"))
4982: xmlType = SVG_TYPE;
4983: else if (!strcmp (schemaName, "XLink"))
4984: xmlType = XLINK_TYPE;
4985: else if (!strcmp (schemaName, "Annot"))
4986: xmlType = ANNOT_TYPE;
4987: else
4988: xmlType = XML_TYPE;
4989: kind = TtaGetAttributeKind (attrType);
4990: if (kind == 0 && attrvals[i])
4991: {
4992: /* enumerated value */
4993: MapXMLAttributeValue (xmlType, attrvals[i], attrType, &kind);
4994: /* store the attribute value */
4995: ctxt->attrText[j] = (char *) kind;
4996: }
4997: else
4998: ctxt->attrText[j] = attrvals[i];
1.80 cvs 4999: maxAttr = i + 1;
1.129 vatton 5000: /* update attrLevel */
5001: ctxt->attrLevel[j] = i;
5002: j++;
1.25 cvs 5003: }
5004: i++;
1.117 vatton 5005: /* add a new entry */
5006: k++;
1.129 vatton 5007: if (k < j)
5008: k = j;
1.119 vatton 5009: if (i == 1 && ctxt->schema == NULL)
5010: /* use the document schema */
5011: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 5012: }
1.117 vatton 5013: /* set the selector specificity */
5014: ctxt->cssSpecificity = specificity;
1.25 cvs 5015: /* sort the list of ancestors by name order */
5016: max = k;
5017: i = 1;
5018: while (i < max)
1.28 cvs 5019: {
5020: for (k = i + 1; k < max; k++)
5021: if (ctxt->name[i] > ctxt->name[k])
5022: {
5023: j = ctxt->name[i];
5024: ctxt->name[i] = ctxt->name[k];
5025: ctxt->name[k] = j;
5026: j = ctxt->names_nb[i];
5027: ctxt->names_nb[i] = ctxt->names_nb[k];
5028: ctxt->names_nb[k] = j;
5029: j = ctxt->attrType[i];
5030: ctxt->attrType[i] = ctxt->attrType[k];
5031: ctxt->attrType[k] = j;
5032: cur = ctxt->attrText[i];
5033: ctxt->attrText[i] = ctxt->attrText[k];
5034: ctxt->attrText[k] = cur;
5035: }
5036: i++;
5037: }
1.84 cvs 5038:
1.25 cvs 5039: /* Get the schema name of the main element */
1.119 vatton 5040: schemaName = TtaGetSSchemaName (ctxt->schema);
5041: isHTML = (strcmp (schemaName, "HTML") == 0);
1.206 vatton 5042: tsch = GetPExtension (doc, ctxt->schema, css, link);
1.119 vatton 5043: if (tsch && cssRule)
5044: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.116 vatton 5045: /* future CSS rules should apply */
5046: DoApply = TRUE;
1.1 cvs 5047: return (selector);
5048: }
5049:
5050: /*----------------------------------------------------------------------
1.206 vatton 5051: ParseStyleDeclaration: parse a style declaration stored in the style
5052: element of a document
5053: We expect the style string to be of the form:
5054: .pinky, .awful { color: pink; font-family: helvetica }
1.1 cvs 5055: ----------------------------------------------------------------------*/
1.206 vatton 5056: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
5057: CSSInfoPtr css, Element link, ThotBool destroy)
1.1 cvs 5058: {
1.79 cvs 5059: GenericContext ctxt;
5060: char *decl_end;
5061: char *sel_end;
5062: char *selector;
1.1 cvs 5063:
5064: /* separate the selectors string */
1.82 cvs 5065: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 5066: decl_end = cssRule;
1.82 cvs 5067: while (*decl_end != EOS && *decl_end != '{')
1.1 cvs 5068: decl_end++;
1.82 cvs 5069: if (*decl_end == EOS)
1.86 cvs 5070: {
1.168 vatton 5071: CSSPrintError ("Invalid selector", cssRule);
1.86 cvs 5072: return;
5073: }
1.1 cvs 5074: /* verify and clean the selector string */
5075: sel_end = decl_end - 1;
1.82 cvs 5076: while (*sel_end == SPACE || *sel_end == BSPACE ||
5077: *sel_end == EOL || *sel_end == CR)
1.1 cvs 5078: sel_end--;
5079: sel_end++;
1.82 cvs 5080: *sel_end = EOS;
1.1 cvs 5081: selector = cssRule;
5082:
5083: /* now, deal with the content ... */
5084: decl_end++;
5085: cssRule = decl_end;
1.137 vatton 5086: decl_end = &cssRule[strlen (cssRule) - 1];
5087: if (*decl_end != '{')
5088: *decl_end = EOS;
1.1 cvs 5089: /*
5090: * parse the style attribute string and install the corresponding
5091: * presentation attributes on the new element
5092: */
5093: ctxt = TtaGetGenericStyleContext (doc);
5094: if (ctxt == NULL)
5095: return;
5096: ctxt->destroy = destroy;
1.207 vatton 5097: /* first use of the context */
5098: ctxt->uses = 1;
1.197 vatton 5099: while (selector && *selector != EOS)
1.207 vatton 5100: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css, link);
5101: /* check if the context can be freed */
5102: ctxt->uses -= 1;
5103: if (ctxt->uses == 0)
5104: /* no image loading */
5105: TtaFreeMemory (ctxt);
1.1 cvs 5106: }
5107:
5108: /************************************************************************
5109: * *
5110: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
5111: * *
5112: ************************************************************************/
5113:
5114: /*----------------------------------------------------------------------
1.59 cvs 5115: IsImplicitClassName: return wether the Class name is an
1.1 cvs 5116: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
5117: or an HTML context name.
5118: ----------------------------------------------------------------------*/
1.206 vatton 5119: int IsImplicitClassName (char *class, Document doc)
1.1 cvs 5120: {
1.79 cvs 5121: char name[200];
5122: char *cur = name;
5123: char *first;
5124: char save;
5125: SSchema schema;
1.1 cvs 5126:
5127: /* make a local copy */
1.82 cvs 5128: strncpy (name, class, 199);
1.1 cvs 5129: name[199] = 0;
5130:
5131: /* loop looking if each word is a GI */
5132: while (*cur != 0)
5133: {
5134: first = cur;
5135: cur = SkipWord (cur);
5136: save = *cur;
5137: *cur = 0;
5138: schema = NULL;
5139: if (MapGI (first, &schema, doc) == -1)
5140: {
5141: return (0);
5142: }
5143: *cur = save;
1.82 cvs 5144: cur = SkipBlanksAndComments (cur);
1.1 cvs 5145: }
5146: return (1);
5147: }
5148:
5149: /************************************************************************
5150: * *
1.114 quint 5151: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 5152: * *
5153: ************************************************************************/
5154:
5155: /*----------------------------------------------------------------------
1.59 cvs 5156: HTMLSetBackgroundColor:
1.1 cvs 5157: ----------------------------------------------------------------------*/
1.79 cvs 5158: void HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1 cvs 5159: {
1.79 cvs 5160: char css_command[100];
1.1 cvs 5161:
1.82 cvs 5162: sprintf (css_command, "background-color: %s", color);
1.114 quint 5163: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 5164: }
5165:
5166: /*----------------------------------------------------------------------
1.59 cvs 5167: HTMLSetForegroundColor:
1.1 cvs 5168: ----------------------------------------------------------------------*/
1.97 vatton 5169: void HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1 cvs 5170: {
1.79 cvs 5171: char css_command[100];
1.1 cvs 5172:
1.82 cvs 5173: sprintf (css_command, "color: %s", color);
1.114 quint 5174: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 5175: }
5176:
5177: /*----------------------------------------------------------------------
1.59 cvs 5178: HTMLResetBackgroundColor:
1.1 cvs 5179: ----------------------------------------------------------------------*/
1.97 vatton 5180: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 5181: {
1.79 cvs 5182: char css_command[100];
1.1 cvs 5183:
1.82 cvs 5184: sprintf (css_command, "background: red");
1.114 quint 5185: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5186: }
5187:
5188: /*----------------------------------------------------------------------
1.59 cvs 5189: HTMLResetBackgroundImage:
1.1 cvs 5190: ----------------------------------------------------------------------*/
1.97 vatton 5191: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 5192: {
1.79 cvs 5193: char css_command[1000];
1.1 cvs 5194:
1.82 cvs 5195: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.114 quint 5196: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5197: }
5198:
5199: /*----------------------------------------------------------------------
1.59 cvs 5200: HTMLResetForegroundColor:
1.1 cvs 5201: ----------------------------------------------------------------------*/
1.97 vatton 5202: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 5203: {
1.79 cvs 5204: char css_command[100];
1.1 cvs 5205:
1.36 cvs 5206: /* it's not necessary to well know the current color but it must be valid */
1.82 cvs 5207: sprintf (css_command, "color: red");
1.114 quint 5208: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 5209: }
5210:
5211: /*----------------------------------------------------------------------
1.59 cvs 5212: HTMLSetAlinkColor:
1.1 cvs 5213: ----------------------------------------------------------------------*/
1.208 vatton 5214: void HTMLSetAlinkColor (Document doc, Element el, char *color)
1.1 cvs 5215: {
1.79 cvs 5216: char css_command[100];
1.1 cvs 5217:
1.82 cvs 5218: sprintf (css_command, "a:link { color: %s }", color);
1.208 vatton 5219: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5220: }
5221:
5222: /*----------------------------------------------------------------------
1.59 cvs 5223: HTMLSetAactiveColor:
1.1 cvs 5224: ----------------------------------------------------------------------*/
1.208 vatton 5225: void HTMLSetAactiveColor (Document doc, Element el, char *color)
1.1 cvs 5226: {
1.79 cvs 5227: char css_command[100];
1.1 cvs 5228:
1.82 cvs 5229: sprintf (css_command, "a:active { color: %s }", color);
1.208 vatton 5230: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5231: }
5232:
5233: /*----------------------------------------------------------------------
1.59 cvs 5234: HTMLSetAvisitedColor:
1.1 cvs 5235: ----------------------------------------------------------------------*/
1.208 vatton 5236: void HTMLSetAvisitedColor (Document doc, Element el, char *color)
1.1 cvs 5237: {
1.79 cvs 5238: char css_command[100];
1.1 cvs 5239:
1.82 cvs 5240: sprintf (css_command, "a:visited { color: %s }", color);
1.208 vatton 5241: ApplyCSSRules (el, css_command, doc, FALSE);
1.1 cvs 5242: }
5243:
5244: /*----------------------------------------------------------------------
1.59 cvs 5245: HTMLResetAlinkColor:
1.1 cvs 5246: ----------------------------------------------------------------------*/
1.208 vatton 5247: void HTMLResetAlinkColor (Document doc, Element el)
1.1 cvs 5248: {
1.79 cvs 5249: char css_command[100];
1.1 cvs 5250:
1.82 cvs 5251: sprintf (css_command, "a:link { color: red }");
1.208 vatton 5252: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5253: }
5254:
5255: /*----------------------------------------------------------------------
1.59 cvs 5256: HTMLResetAactiveColor:
1.1 cvs 5257: ----------------------------------------------------------------------*/
1.208 vatton 5258: void HTMLResetAactiveColor (Document doc, Element el)
1.1 cvs 5259: {
1.79 cvs 5260: char css_command[100];
1.1 cvs 5261:
1.82 cvs 5262: sprintf (css_command, "a:active { color: red }");
1.208 vatton 5263: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5264: }
5265:
5266: /*----------------------------------------------------------------------
1.59 cvs 5267: HTMLResetAvisitedColor:
1.1 cvs 5268: ----------------------------------------------------------------------*/
1.208 vatton 5269: void HTMLResetAvisitedColor (Document doc, Element el)
1.1 cvs 5270: {
1.79 cvs 5271: char css_command[100];
1.1 cvs 5272:
1.82 cvs 5273: sprintf (css_command, "a:visited { color: red }");
1.208 vatton 5274: ApplyCSSRules (el, css_command, doc, TRUE);
1.1 cvs 5275: }
5276:
5277: /*----------------------------------------------------------------------
1.206 vatton 5278: ApplyCSSRules: parse a CSS Style description stored in the header of
5279: a HTML document.
1.1 cvs 5280: ----------------------------------------------------------------------*/
1.79 cvs 5281: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 5282: {
1.206 vatton 5283: CSSInfoPtr css;
5284: PInfoPtr pInfo;
1.207 vatton 5285: ThotBool loadcss;
5286:
5287: /* check if we have to load CSS */
5288: TtaGetEnvBoolean ("LOAD_CSS", &loadcss);
5289: if (!loadcss)
5290: return;
1.1 cvs 5291:
1.206 vatton 5292: css = SearchCSS (doc, NULL, el, &pInfo);
1.1 cvs 5293: if (css == NULL)
1.209 vatton 5294: {
5295: /* create the document css context */
5296: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, el);
5297: pInfo = css->infos[doc];
5298: }
1.206 vatton 5299: else if (pInfo == NULL)
5300: /* create the entry into the css context */
5301: pInfo = AddInfoCSS (doc, css, CSS_DOCUMENT_STYLE, CSS_ALL, el);
1.209 vatton 5302: if (pInfo->PiEnabled)
5303: ParseStyleDeclaration (el, cssRule, doc, css, el, destroy);
1.1 cvs 5304: }
5305:
5306: /*----------------------------------------------------------------------
1.145 quint 5307: ReadCSSRules: is the front-end function called by the document parser
5308: when detecting a <style type="text/css"> indicating it's the
1.1 cvs 5309: beginning of a CSS fragment or when reading a file .css.
5310:
5311: The CSS parser has to handle <!-- ... --> constructs used to
5312: prevent prehistoric browser from displaying the CSS as a text
5313: content. It will stop on any sequence "<x" where x is different
5314: from ! and will return x as to the caller. Theorically x should
1.145 quint 5315: be equal to / for the </style> end of style.
1.1 cvs 5316: The parameter doc gives the document tree that contains CSS information.
5317: The parameter docRef gives the document to which CSS are to be applied.
5318: This function uses the current css context or creates it. It's able
1.23 cvs 5319: to work on the given buffer or call GetNextChar to read the parsed
1.1 cvs 5320: file.
1.133 vatton 5321: The parameter url gives the URL of the style shheet parsed.
1.86 cvs 5322: Parameter numberOfLinesRead indicates the number of lines already
5323: read in the file.
1.1 cvs 5324: Parameter withUndo indicates whether the changes made in the document
1.145 quint 5325: structure and content have to be registered in the Undo queue or not.
1.1 cvs 5326: ----------------------------------------------------------------------*/
1.133 vatton 5327: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, char *url,
1.144 quint 5328: int numberOfLinesRead, ThotBool withUndo,
1.206 vatton 5329: Element link)
1.1 cvs 5330: {
1.6 cvs 5331: DisplayMode dispMode;
1.206 vatton 5332: CSSInfoPtr refcss = NULL;
5333: PInfoPtr pInfo;
1.82 cvs 5334: char c;
1.138 vatton 5335: char *cssRule, *base, *saveDocURL, *ptr;
1.19 cvs 5336: int index;
1.1 cvs 5337: int CSSindex;
5338: int CSScomment;
5339: int import;
5340: int openRule;
1.93 vatton 5341: int newlines;
1.14 cvs 5342: ThotBool HTMLcomment;
1.102 vatton 5343: ThotBool toParse, eof, quoted;
1.36 cvs 5344: ThotBool ignoreMedia, media;
1.186 vatton 5345: ThotBool noRule, ignoreImport, skip;
1.1 cvs 5346:
5347: CSScomment = MAX_CSS_LENGTH;
5348: HTMLcomment = FALSE;
5349: CSSindex = 0;
5350: toParse = FALSE;
5351: noRule = FALSE;
1.36 cvs 5352: media = FALSE;
1.88 cvs 5353: ignoreImport = FALSE;
1.1 cvs 5354: ignoreMedia = FALSE;
5355: import = MAX_CSS_LENGTH;
5356: eof = FALSE;
5357: openRule = 0;
1.82 cvs 5358: c = SPACE;
1.1 cvs 5359: index = 0;
1.134 vatton 5360: base = NULL;
1.135 vatton 5361: quoted = FALSE;
1.186 vatton 5362: skip = FALSE;
1.93 vatton 5363: /* number of new lines parsed */
5364: newlines = 0;
1.6 cvs 5365: /* avoid too many redisplay */
5366: dispMode = TtaGetDisplayMode (docRef);
5367: if (dispMode == DisplayImmediately)
5368: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 5369:
5370: /* look for the CSS context */
5371: if (css == NULL)
1.206 vatton 5372: css = SearchCSS (docRef, NULL, link, &pInfo);
1.207 vatton 5373: else
5374: pInfo = css->infos[docRef];
1.18 cvs 5375: if (css == NULL)
1.206 vatton 5376: {
5377: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, CSS_ALL, NULL, NULL, link);
5378: pInfo = css->infos[docRef];
5379: }
5380: else if (pInfo == NULL)
5381: pInfo = AddInfoCSS (docRef, css, CSS_DOCUMENT_STYLE, CSS_ALL, link);
1.174 vatton 5382: /* look for the CSS descriptor that points to the extension schema */
5383: refcss = css;
5384: if (import)
1.173 cvs 5385: {
1.206 vatton 5386: while (refcss &&
5387: refcss->infos[docRef] && refcss->infos[docRef]->PiCategory == CSS_IMPORT)
1.174 vatton 5388: refcss = refcss->NextCSS;
1.206 vatton 5389: if (refcss)
5390: pInfo = refcss->infos[docRef];
1.173 cvs 5391: }
5392:
1.144 quint 5393: /* register parsed CSS file and the document to which CSS are to be applied*/
1.86 cvs 5394: ParsedDoc = docRef;
1.133 vatton 5395: if (url)
5396: DocURL = url;
1.86 cvs 5397: else
5398: /* the CSS source in within the document itself */
5399: DocURL = DocumentURLs[docRef];
5400: LineNumber = numberOfLinesRead + 1;
1.93 vatton 5401: NewLineSkipped = 0;
1.82 cvs 5402: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
5403: {
5404: c = buffer[index++];
5405: eof = (c == EOS);
5406: CSSbuffer[CSSindex] = c;
1.186 vatton 5407: if (skip)
5408: {
5409: if (c == '}')
5410: {
5411: /* end of the @font-face */
5412: skip = FALSE;
5413: import = MAX_CSS_LENGTH;
5414: noRule = TRUE;
5415: CSSindex = 0;
5416: }
5417: if (c == EOL)
5418: LineNumber++;
5419: c = CR;
5420: }
5421: else if (CSScomment == MAX_CSS_LENGTH ||
1.82 cvs 5422: c == '*' || c == '/' || c == '<')
5423: {
5424: /* we're not within a comment or we're parsing * or / */
5425: switch (c)
5426: {
5427: case '@': /* perhaps an import primitive */
1.135 vatton 5428: if (!quoted)
5429: import = CSSindex;
1.82 cvs 5430: break;
5431: case ';':
1.135 vatton 5432: if (!quoted && !media && import != MAX_CSS_LENGTH)
1.82 cvs 5433: {
5434: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
5435: /* it's not an import */
5436: import = MAX_CSS_LENGTH;
5437: /* save the text */
5438: noRule = TRUE;
5439: }
5440: break;
5441: case '*':
1.135 vatton 5442: if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5443: CSSbuffer[CSSindex - 1] == '/')
5444: /* start a comment */
5445: CSScomment = CSSindex - 1;
5446: break;
5447: case '/':
1.135 vatton 5448: if (!quoted && CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
1.82 cvs 5449: CSSbuffer[CSSindex - 1] == '*')
5450: {
5451: /* close a comment:and ignore its contents */
5452: CSSindex = CSScomment - 1; /* will be incremented later */
5453: CSScomment = MAX_CSS_LENGTH;
1.93 vatton 5454: /* clean up the buffer */
1.103 vatton 5455: if (newlines && CSSindex > 0)
5456: while (CSSindex > 0 &&
5457: (CSSbuffer[CSSindex] == SPACE ||
5458: CSSbuffer[CSSindex] == BSPACE ||
5459: CSSbuffer[CSSindex] == EOL ||
5460: CSSbuffer[CSSindex] == TAB ||
5461: CSSbuffer[CSSindex] == __CR__))
1.93 vatton 5462: {
5463: if ( CSSbuffer[CSSindex] == EOL)
5464: {
5465: LineNumber ++;
5466: newlines --;
5467: }
5468: CSSindex--;
5469: }
1.82 cvs 5470: }
1.135 vatton 5471: else if (!quoted && CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
1.82 cvs 5472: CSSbuffer[CSSindex - 1] == '<')
5473: {
5474: /* this is the closing tag ! */
5475: CSSindex -= 2; /* remove </ from the CSS string */
5476: noRule = TRUE;
5477: }
5478: break;
5479: case '<':
1.135 vatton 5480: if (!quoted && CSScomment == MAX_CSS_LENGTH)
1.82 cvs 5481: {
5482: /* only if we're not parsing a comment */
5483: c = buffer[index++];
5484: eof = (c == EOS);
5485: if (c == '!')
5486: {
5487: /* CSS within an HTML comment */
5488: HTMLcomment = TRUE;
5489: CSSindex++;
5490: CSSbuffer[CSSindex] = c;
5491: }
5492: else if (c == EOS)
5493: CSSindex++;
5494: }
5495: break;
5496: case '-':
1.135 vatton 5497: if (!quoted && CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
1.82 cvs 5498: HTMLcomment)
5499: /* CSS within an HTML comment */
5500: noRule = TRUE;
5501: break;
5502: case '>':
1.135 vatton 5503: if (!quoted && HTMLcomment)
1.82 cvs 5504: noRule = TRUE;
5505: break;
5506: case ' ':
1.135 vatton 5507: if (!quoted && import != MAX_CSS_LENGTH && openRule == 0)
1.162 quint 5508: media = !strncasecmp (&CSSbuffer[import+1], "media", 5);
1.82 cvs 5509: break;
5510: case '{':
1.135 vatton 5511: if (!quoted)
1.82 cvs 5512: {
1.135 vatton 5513: openRule++;
5514: if (import != MAX_CSS_LENGTH && openRule == 1 && media)
5515: {
5516: /* is it the screen concerned? */
5517: CSSbuffer[CSSindex+1] = EOS;
5518: if (TtaIsPrinting ())
5519: base = strstr (&CSSbuffer[import], "print");
5520: else
5521: base = strstr (&CSSbuffer[import], "screen");
5522: if (base == NULL)
5523: base = strstr (&CSSbuffer[import], "all");
5524: if (base == NULL)
5525: ignoreMedia = TRUE;
5526: noRule = TRUE;
5527: }
1.186 vatton 5528: else if (import != MAX_CSS_LENGTH &&
5529: !strncasecmp (&CSSbuffer[import], "@font-face", 10))
5530: skip = TRUE;
1.135 vatton 5531: }
5532: break;
5533: case '}':
5534: if (!quoted)
5535: {
5536: openRule--;
5537: if (import != MAX_CSS_LENGTH && openRule == 0)
5538: {
5539: import = MAX_CSS_LENGTH;
5540: noRule = TRUE;
5541: ignoreMedia = FALSE;
5542: media = FALSE;
5543: }
1.82 cvs 5544: else
1.135 vatton 5545: toParse = TRUE;
1.82 cvs 5546: }
5547: break;
1.135 vatton 5548: case '"':
5549: if (quoted)
1.82 cvs 5550: {
1.135 vatton 5551: if (CSSbuffer[CSSindex - 1] != '\\')
5552: quoted = FALSE;
1.82 cvs 5553: }
5554: else
1.135 vatton 5555: quoted = TRUE;
1.82 cvs 5556: break;
5557: default:
1.86 cvs 5558: if (c == EOL)
1.93 vatton 5559: newlines++;
1.82 cvs 5560: break;
5561: }
5562: }
1.93 vatton 5563: else if (c == EOL)
5564: LineNumber++;
1.82 cvs 5565: if (c != CR)
5566: CSSindex++;
5567:
5568: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
5569: /* we're still parsing a comment: remove the text comment */
5570: CSSindex = CSScomment;
5571:
5572: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
5573: {
5574: CSSbuffer[CSSindex] = EOS;
5575: /* parse a not empty string */
5576: if (CSSindex > 0)
5577: {
1.50 cvs 5578: /* apply CSS rule if it's not just a saving of text */
5579: if (!noRule && !ignoreMedia)
1.88 cvs 5580: {
5581: /* future import rules must be ignored */
5582: ignoreImport = TRUE;
1.210 ! vatton 5583: ParseStyleDeclaration (NULL, CSSbuffer, docRef, refcss,
! 5584: pInfo->PiLink, FALSE);
1.93 vatton 5585: LineNumber += newlines;
5586: newlines = 0;
5587: NewLineSkipped = 0;
1.88 cvs 5588: }
1.82 cvs 5589: else if (import != MAX_CSS_LENGTH &&
5590: !strncasecmp (&CSSbuffer[import+1], "import", 6))
5591: {
5592: /* import section */
5593: cssRule = &CSSbuffer[import+7];
5594: cssRule = TtaSkipBlanks (cssRule);
1.93 vatton 5595: /* save the current line number */
5596: newlines += LineNumber;
1.82 cvs 5597: if (!strncasecmp (cssRule, "url", 3))
5598: {
1.50 cvs 5599: cssRule = &cssRule[3];
1.82 cvs 5600: cssRule = TtaSkipBlanks (cssRule);
5601: if (*cssRule == '(')
5602: {
5603: cssRule++;
5604: cssRule = TtaSkipBlanks (cssRule);
1.102 vatton 5605: quoted = (*cssRule == '"' || *cssRule == '\'');
5606: if (quoted)
5607: cssRule++;
1.82 cvs 5608: base = cssRule;
5609: while (*cssRule != EOS && *cssRule != ')')
5610: cssRule++;
1.102 vatton 5611: if (quoted)
1.167 vatton 5612: {
5613: /* isolate the file name */
5614: cssRule[-1] = EOS;
5615: quoted = FALSE;
5616: }
1.160 vatton 5617: *cssRule = EOS;
1.82 cvs 5618: }
5619: }
1.87 cvs 5620: else if (*cssRule == '"')
5621: {
1.88 cvs 5622: /*
5623: Do we have to accept single quotes?
5624: Double quotes are acceted here.
5625: Escaped quotes are not handled. See function SkipQuotedString
5626: */
1.87 cvs 5627: cssRule++;
5628: cssRule = TtaSkipBlanks (cssRule);
5629: base = cssRule;
1.179 vatton 5630: while (*cssRule != EOS &&
5631: (*cssRule != '"' ||
1.180 vatton 5632: (*cssRule == '"' && cssRule[-1] == '\\')))
1.87 cvs 5633: cssRule++;
1.160 vatton 5634: /* isolate the file name */
5635: *cssRule = EOS;
1.133 vatton 5636: }
5637: /* check if a media is defined */
5638: cssRule++;
5639: cssRule = TtaSkipBlanks (cssRule);
5640: if (*cssRule != ';')
5641: {
5642: if (TtaIsPrinting ())
5643: ignoreImport = (strncasecmp (cssRule, "print", 5) &&
5644: strncasecmp (cssRule, "all", 3));
5645: else
5646: ignoreImport = (strncasecmp (cssRule, "screen", 6) &&
5647: strncasecmp (cssRule, "all", 3));
5648: }
5649: if (!ignoreImport)
5650: {
5651: /* save the displayed URL when an error is reported */
5652: saveDocURL = DocURL;
1.138 vatton 5653: ptr = TtaStrdup (base);
5654: /* get the CSS URI in UTF-8 */
5655: ptr = ReallocUTF8String (ptr, docRef);
1.206 vatton 5656: LoadStyleSheet (base, docRef, (Element) css, css,
5657: pInfo->PiMedia,
5658: pInfo->PiCategory == CSS_USER_STYLE);
1.133 vatton 5659: /* restore the displayed URL when an error is reported */
5660: DocURL = saveDocURL;
1.138 vatton 5661: TtaFreeMemory (ptr);
1.82 cvs 5662: }
1.93 vatton 5663: /* restore the number of lines */
5664: LineNumber = newlines;
5665: newlines = 0;
1.82 cvs 5666: import = MAX_CSS_LENGTH;
5667: }
1.93 vatton 5668:
1.82 cvs 5669: }
5670: toParse = FALSE;
5671: noRule = FALSE;
5672: CSSindex = 0;
1.50 cvs 5673: }
1.82 cvs 5674: }
1.6 cvs 5675: /* restore the display mode */
5676: if (dispMode == DisplayImmediately)
1.82 cvs 5677: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 5678:
5679: /* Prepare the context for style attributes */
5680: DocURL = DocumentURLs[docRef];
5681: LineNumber = -1;
1.1 cvs 5682: return (c);
5683: }
1.89 cvs 5684:
Webmaster