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