Annotation of Amaya/amaya/styleparser.c, revision 1.126
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;
! 1172: else if (!strncasecmp (cssRule, "runin", 5))
! 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: {
! 1180: CSSParseError ("Invalid display value", cssRule);
! 1181: cssRule = SkipWord (cssRule);
! 1182: return (cssRule);
! 1183: }
1.34 cvs 1184:
1.126 ! vatton 1185: if (DoApply)
! 1186: {
! 1187: if (tsch)
! 1188: cssRule = CheckImportantRule (cssRule, context);
! 1189: TtaSetStylePresentation (PRDisplay, element, tsch, context, pval);
! 1190: }
! 1191: cssRule = SkipWord (cssRule);
! 1192: }
1.1 cvs 1193: return (cssRule);
1194: }
1195:
1196: /*----------------------------------------------------------------------
1.59 cvs 1197: ParseCSSFloat: parse a CSS float attribute string
1.1 cvs 1198: ----------------------------------------------------------------------*/
1.79 cvs 1199: static char *ParseCSSFloat (Element element, PSchema tsch,
1200: PresentationContext context, char *cssRule,
1201: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1202: {
1.99 vatton 1203: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1204: return (cssRule);
1205: }
1206:
1207: /*----------------------------------------------------------------------
1.59 cvs 1208: ParseCSSLetterSpacing: parse a CSS letter-spacing
1.1 cvs 1209: attribute string.
1210: ----------------------------------------------------------------------*/
1.79 cvs 1211: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
1212: PresentationContext context, char *cssRule,
1213: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1214: {
1.99 vatton 1215: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1216: return (cssRule);
1217: }
1218:
1219: /*----------------------------------------------------------------------
1.59 cvs 1220: ParseCSSListStyleType: parse a CSS list-style-type
1.1 cvs 1221: attribute string.
1222: ----------------------------------------------------------------------*/
1.79 cvs 1223: static char *ParseCSSListStyleType (Element element, PSchema tsch,
1224: PresentationContext context, char *cssRule,
1225: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1226: {
1.99 vatton 1227: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1228: return (cssRule);
1229: }
1230:
1231: /*----------------------------------------------------------------------
1.59 cvs 1232: ParseCSSListStyleImage: parse a CSS list-style-image
1.1 cvs 1233: attribute string.
1234: ----------------------------------------------------------------------*/
1.79 cvs 1235: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1236: PresentationContext context, char *cssRule,
1237: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1238: {
1.99 vatton 1239: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1240: return (cssRule);
1241: }
1242:
1243: /*----------------------------------------------------------------------
1.59 cvs 1244: ParseCSSListStylePosition: parse a CSS list-style-position
1.1 cvs 1245: attribute string.
1246: ----------------------------------------------------------------------*/
1.79 cvs 1247: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
1248: PresentationContext context,
1249: char *cssRule, CSSInfoPtr css,
1250: ThotBool isHTML)
1.1 cvs 1251: {
1.99 vatton 1252: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1253: return (cssRule);
1254: }
1255:
1256: /*----------------------------------------------------------------------
1.59 cvs 1257: ParseCSSListStyle: parse a CSS list-style
1.1 cvs 1258: attribute string.
1259: ----------------------------------------------------------------------*/
1.79 cvs 1260: static char *ParseCSSListStyle (Element element, PSchema tsch,
1261: PresentationContext context, char *cssRule,
1262: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1263: {
1.99 vatton 1264: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1265: return (cssRule);
1266: }
1267:
1268: /*----------------------------------------------------------------------
1.59 cvs 1269: ParseCSSTextAlign: parse a CSS text-align
1.1 cvs 1270: attribute string.
1271: ----------------------------------------------------------------------*/
1.79 cvs 1272: static char *ParseCSSTextAlign (Element element, PSchema tsch,
1273: PresentationContext context, char *cssRule,
1274: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1275: {
1276: PresentationValue align;
1277:
1278: align.typed_data.value = 0;
1279: align.typed_data.unit = STYLE_UNIT_REL;
1280: align.typed_data.real = FALSE;
1281:
1.82 cvs 1282: cssRule = SkipBlanksAndComments (cssRule);
1283: if (!strncasecmp (cssRule, "left", 4))
1.1 cvs 1284: {
1285: align.typed_data.value = AdjustLeft;
1286: cssRule = SkipWord (cssRule);
1287: }
1.82 cvs 1288: else if (!strncasecmp (cssRule, "right", 5))
1.1 cvs 1289: {
1290: align.typed_data.value = AdjustRight;
1291: cssRule = SkipWord (cssRule);
1292: }
1.82 cvs 1293: else if (!strncasecmp (cssRule, "center", 6))
1.1 cvs 1294: {
1295: align.typed_data.value = Centered;
1296: cssRule = SkipWord (cssRule);
1297: }
1.82 cvs 1298: else if (!strncasecmp (cssRule, "justify", 7))
1.1 cvs 1299: {
1.81 cvs 1300: align.typed_data.value = Justify;
1.1 cvs 1301: cssRule = SkipWord (cssRule);
1302: }
1303: else
1304: {
1.86 cvs 1305: CSSParseError ("Invalid align value", cssRule);
1.1 cvs 1306: return (cssRule);
1307: }
1308:
1309: /*
1310: * install the new presentation.
1311: */
1.116 vatton 1312: if (align.typed_data.value && DoApply)
1.117 vatton 1313: {
1314: if (tsch)
1315: cssRule = CheckImportantRule (cssRule, context);
1316: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
1317: }
1.1 cvs 1318: return (cssRule);
1319: }
1320:
1321: /*----------------------------------------------------------------------
1.112 quint 1322: ParseCSSDirection: parse a CSS direction property
1323: ----------------------------------------------------------------------*/
1324: static char *ParseCSSDirection (Element element, PSchema tsch,
1325: PresentationContext context, char *cssRule,
1326: CSSInfoPtr css, ThotBool isHTML)
1327: {
1328: PresentationValue direction;
1329:
1330: direction.typed_data.value = 0;
1331: direction.typed_data.unit = STYLE_UNIT_REL;
1332: direction.typed_data.real = FALSE;
1333:
1334: cssRule = SkipBlanksAndComments (cssRule);
1335: if (!strncasecmp (cssRule, "ltr", 3))
1336: {
1337: direction.typed_data.value = STYLE_LEFTTORIGHT;
1338: cssRule = SkipWord (cssRule);
1339: }
1340: else if (!strncasecmp (cssRule, "rtl", 3))
1341: {
1342: direction.typed_data.value = STYLE_RIGHTTOLEFT;
1343: cssRule = SkipWord (cssRule);
1344: }
1345: else if (!strncasecmp (cssRule, "inherit", 7))
1346: {
1347: /* not implemented */
1348: cssRule = SkipWord (cssRule);
1349: return (cssRule);
1350: }
1351: else
1352: {
1353: CSSParseError ("Invalid direction value", cssRule);
1354: return (cssRule);
1355: }
1356:
1357: /*
1358: * install the new presentation.
1359: */
1.116 vatton 1360: if (direction.typed_data.value && DoApply)
1.117 vatton 1361: {
1362: if (tsch)
1363: cssRule = CheckImportantRule (cssRule, context);
1364: TtaSetStylePresentation (PRDirection, element, tsch, context, direction);
1365: }
1.112 quint 1366: return (cssRule);
1367: }
1368:
1369: /*----------------------------------------------------------------------
1.113 quint 1370: ParseCSSUnicodeBidi: parse a CSS unicode-bidi property
1371: ----------------------------------------------------------------------*/
1372: static char *ParseCSSUnicodeBidi (Element element, PSchema tsch,
1373: PresentationContext context, char *cssRule,
1374: CSSInfoPtr css, ThotBool isHTML)
1375: {
1376: PresentationValue bidi;
1377:
1378: bidi.typed_data.value = 0;
1379: bidi.typed_data.unit = STYLE_UNIT_REL;
1380: bidi.typed_data.real = FALSE;
1381:
1382: cssRule = SkipBlanksAndComments (cssRule);
1383: if (!strncasecmp (cssRule, "normal", 6))
1384: {
1385: bidi.typed_data.value = STYLE_BIDINORMAL;
1386: cssRule = SkipWord (cssRule);
1387: }
1388: else if (!strncasecmp (cssRule, "embed", 5))
1389: {
1390: bidi.typed_data.value = STYLE_BIDIEMBED;
1391: cssRule = SkipWord (cssRule);
1392: }
1393: else if (!strncasecmp (cssRule, "override", 8))
1394: {
1395: bidi.typed_data.value = STYLE_BIDIOVERRIDE;
1396: cssRule = SkipWord (cssRule);
1397: }
1398: else if (!strncasecmp (cssRule, "inherit", 7))
1399: {
1400: /* not implemented */
1401: cssRule = SkipWord (cssRule);
1402: return (cssRule);
1403: }
1404: else
1405: {
1406: CSSParseError ("Invalid unicode-bidi value", cssRule);
1407: return (cssRule);
1408: }
1409:
1410: /*
1411: * install the new presentation.
1412: */
1.116 vatton 1413: if (bidi.typed_data.value && DoApply)
1.117 vatton 1414: {
1415: if (tsch)
1416: cssRule = CheckImportantRule (cssRule, context);
1417: TtaSetStylePresentation (PRUnicodeBidi, element, tsch, context, bidi);
1418: }
1.113 quint 1419: return (cssRule);
1420: }
1421:
1422: /*----------------------------------------------------------------------
1.59 cvs 1423: ParseCSSTextIndent: parse a CSS text-indent
1.1 cvs 1424: attribute string.
1425: ----------------------------------------------------------------------*/
1.79 cvs 1426: static char *ParseCSSTextIndent (Element element, PSchema tsch,
1427: PresentationContext context, char *cssRule,
1428: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1429: {
1430: PresentationValue pval;
1431:
1.82 cvs 1432: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1433: cssRule = ParseCSSUnit (cssRule, &pval);
1434: if (pval.typed_data.unit == STYLE_UNIT_INVALID)
1435: return (cssRule);
1436: /* install the attribute */
1.116 vatton 1437: if (DoApply)
1.117 vatton 1438: {
1439: if (tsch)
1440: cssRule = CheckImportantRule (cssRule, context);
1441: TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
1442: }
1.1 cvs 1443: return (cssRule);
1444: }
1445:
1446: /*----------------------------------------------------------------------
1.59 cvs 1447: ParseCSSTextTransform: parse a CSS text-transform
1.1 cvs 1448: attribute string.
1449: ----------------------------------------------------------------------*/
1.79 cvs 1450: static char *ParseCSSTextTransform (Element element, PSchema tsch,
1451: PresentationContext context, char *cssRule,
1452: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1453: {
1.99 vatton 1454: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1455: return (cssRule);
1456: }
1457:
1458: /*----------------------------------------------------------------------
1.59 cvs 1459: ParseCSSVerticalAlign: parse a CSS vertical-align
1.1 cvs 1460: attribute string.
1461: ----------------------------------------------------------------------*/
1.79 cvs 1462: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
1463: PresentationContext context, char *cssRule,
1464: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1465: {
1.99 vatton 1466: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1467: return (cssRule);
1468: }
1469:
1470: /*----------------------------------------------------------------------
1.59 cvs 1471: ParseCSSWhiteSpace: parse a CSS white-space
1.1 cvs 1472: attribute string.
1473: ----------------------------------------------------------------------*/
1.79 cvs 1474: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
1475: PresentationContext context, char *cssRule,
1476: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1477: {
1.82 cvs 1478: cssRule = SkipBlanksAndComments (cssRule);
1479: if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1480: cssRule = SkipWord (cssRule);
1.82 cvs 1481: else if (!strncasecmp (cssRule, "pre", 3))
1.1 cvs 1482: cssRule = SkipWord (cssRule);
1483: else
1484: return (cssRule);
1485: return (cssRule);
1486: }
1487:
1488: /*----------------------------------------------------------------------
1.59 cvs 1489: ParseCSSWordSpacing: parse a CSS word-spacing
1.1 cvs 1490: attribute string.
1491: ----------------------------------------------------------------------*/
1.79 cvs 1492: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
1493: PresentationContext context, char *cssRule,
1494: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1495: {
1.99 vatton 1496: cssRule = SkipValue (cssRule, FALSE);
1.1 cvs 1497: return (cssRule);
1498: }
1499:
1500: /*----------------------------------------------------------------------
1.59 cvs 1501: ParseCSSLineSpacing: parse a CSS font leading string
1.25 cvs 1502: we expect the input string describing the attribute to be
1503: value% or value
1504: ----------------------------------------------------------------------*/
1.79 cvs 1505: static char *ParseCSSLineSpacing (Element element, PSchema tsch,
1506: PresentationContext context, char *cssRule,
1507: CSSInfoPtr css, ThotBool isHTML)
1.25 cvs 1508: {
1509: PresentationValue lead;
1510:
1511: cssRule = ParseCSSUnit (cssRule, &lead);
1.117 vatton 1512: if (lead.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.93 vatton 1513: /* install the new presentation */
1.117 vatton 1514: {
1515: if (tsch)
1516: cssRule = CheckImportantRule (cssRule, context);
1.116 vatton 1517: TtaSetStylePresentation (PRLineSpacing, element, tsch, context, lead);
1.117 vatton 1518: }
1.25 cvs 1519: return (cssRule);
1520: }
1521:
1522: /*----------------------------------------------------------------------
1.59 cvs 1523: ParseCSSFontSize: parse a CSS font size attr string
1.1 cvs 1524: we expect the input string describing the attribute to be
1525: xx-small, x-small, small, medium, large, x-large, xx-large
1526: or an absolute size, or an imcrement relative to the parent
1527: ----------------------------------------------------------------------*/
1.79 cvs 1528: static char *ParseCSSFontSize (Element element, PSchema tsch,
1529: PresentationContext context, char *cssRule,
1530: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1531: {
1532: PresentationValue pval;
1.79 cvs 1533: char *ptr = NULL;
1.14 cvs 1534: ThotBool real;
1.1 cvs 1535:
1536: pval.typed_data.real = FALSE;
1.82 cvs 1537: cssRule = SkipBlanksAndComments (cssRule);
1538: if (!strncasecmp (cssRule, "larger", 6))
1.1 cvs 1539: {
1540: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1541: pval.typed_data.value = 130;
1542: cssRule = SkipWord (cssRule);
1543: }
1.82 cvs 1544: else if (!strncasecmp (cssRule, "smaller", 7))
1.1 cvs 1545: {
1546: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1547: pval.typed_data.value = 80;
1548: cssRule = SkipWord (cssRule);
1549: }
1.82 cvs 1550: else if (!strncasecmp (cssRule, "xx-small", 8))
1.1 cvs 1551: {
1552: pval.typed_data.unit = STYLE_UNIT_REL;
1553: pval.typed_data.value = 1;
1554: cssRule = SkipWord (cssRule);
1555: }
1.82 cvs 1556: else if (!strncasecmp (cssRule, "x-small", 7))
1.1 cvs 1557: {
1558: pval.typed_data.unit = STYLE_UNIT_REL;
1559: pval.typed_data.value = 2;
1560: cssRule = SkipWord (cssRule);
1561: }
1.82 cvs 1562: else if (!strncasecmp (cssRule, "small", 5))
1.1 cvs 1563: {
1564: pval.typed_data.unit = STYLE_UNIT_REL;
1565: pval.typed_data.value = 3;
1566: cssRule = SkipWord (cssRule);
1567: }
1.82 cvs 1568: else if (!strncasecmp (cssRule, "medium", 6))
1.1 cvs 1569: {
1570: pval.typed_data.unit = STYLE_UNIT_REL;
1571: pval.typed_data.value = 4;
1572: cssRule = SkipWord (cssRule);
1573: }
1.82 cvs 1574: else if (!strncasecmp (cssRule, "large", 5))
1.1 cvs 1575: {
1576: pval.typed_data.unit = STYLE_UNIT_REL;
1577: pval.typed_data.value = 5;
1578: cssRule = SkipWord (cssRule);
1579: }
1.82 cvs 1580: else if (!strncasecmp (cssRule, "x-large", 7))
1.1 cvs 1581: {
1582: pval.typed_data.unit = STYLE_UNIT_REL;
1583: pval.typed_data.value = 6;
1584: cssRule = SkipWord (cssRule);
1585: }
1.82 cvs 1586: else if (!strncasecmp (cssRule, "xx-large", 8))
1.1 cvs 1587: {
1588: pval.typed_data.unit = STYLE_UNIT_REL;
1589: pval.typed_data.value = 7;
1590: cssRule = SkipWord (cssRule);
1591: }
1592: else
1593: {
1.25 cvs 1594: /* look for a '/' within the current cssRule */
1.82 cvs 1595: ptr = strchr (cssRule, '/');
1.25 cvs 1596: if (ptr != NULL)
1597: {
1598: /* keep the line spacing rule */
1.82 cvs 1599: ptr[0] = EOS;
1.25 cvs 1600: ptr = &ptr[1];
1601: }
1.1 cvs 1602: cssRule = ParseCSSUnit (cssRule, &pval);
1603: if (pval.typed_data.unit == STYLE_UNIT_INVALID ||
1604: pval.typed_data.value < 0)
1605: return (cssRule);
1606: if (pval.typed_data.unit == STYLE_UNIT_REL && pval.typed_data.value > 0)
1607: /* CSS relative sizes have to be higher than Thot ones */
1608: pval.typed_data.value += 1;
1609: else
1610: {
1611: real = pval.typed_data.real;
1612: if (pval.typed_data.unit == STYLE_UNIT_EM)
1613: {
1614: if (real)
1615: {
1616: pval.typed_data.value /= 10;
1.11 cvs 1617: pval.typed_data.real = FALSE;
1.1 cvs 1618: real = FALSE;
1619: }
1620: else
1621: pval.typed_data.value *= 100;
1622: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1623: }
1624: }
1.25 cvs 1625:
1.1 cvs 1626: }
1627:
1.25 cvs 1628: /* install the presentation style */
1.116 vatton 1629: if (DoApply)
1.117 vatton 1630: {
1631: if (tsch)
1632: cssRule = CheckImportantRule (cssRule, context);
1633: TtaSetStylePresentation (PRSize, element, tsch, context, pval);
1634: }
1635: if (ptr)
1.25 cvs 1636: cssRule = ParseCSSLineSpacing (element, tsch, context, ptr, css, isHTML);
1.1 cvs 1637: return (cssRule);
1638: }
1639:
1640: /*----------------------------------------------------------------------
1.59 cvs 1641: ParseCSSFontFamily: parse a CSS font family string
1.1 cvs 1642: we expect the input string describing the attribute to be
1643: a common generic font style name
1644: ----------------------------------------------------------------------*/
1.79 cvs 1645: static char *ParseCSSFontFamily (Element element, PSchema tsch,
1646: PresentationContext context, char *cssRule,
1647: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1648: {
1649: PresentationValue font;
1.79 cvs 1650: char quoteChar;
1.1 cvs 1651:
1652: font.typed_data.value = 0;
1653: font.typed_data.unit = STYLE_UNIT_REL;
1654: font.typed_data.real = FALSE;
1.82 cvs 1655: cssRule = SkipBlanksAndComments (cssRule);
1656: if (*cssRule == '"' || *cssRule == '\'')
1.1 cvs 1657: {
1658: quoteChar = *cssRule;
1659: cssRule++;
1660: }
1661: else
1.82 cvs 1662: quoteChar = EOS;
1.1 cvs 1663:
1.92 cvs 1664: if (!strncasecmp (cssRule, "times", 5) &&
1665: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 1666: {
1.1 cvs 1667: font.typed_data.value = STYLE_FONT_TIMES;
1.86 cvs 1668: cssRule += 5;
1669: }
1.92 cvs 1670: else if (!strncasecmp (cssRule, "serif", 5) &&
1671: (quoteChar == EOS || quoteChar == cssRule[5]))
1.86 cvs 1672: {
1.1 cvs 1673: font.typed_data.value = STYLE_FONT_TIMES;
1.86 cvs 1674: cssRule += 5;
1.92 cvs 1675: if (quoteChar != EOS)
1676: cssRule++;
1.86 cvs 1677: }
1.92 cvs 1678: else if (!strncasecmp (cssRule, "helvetica", 9) &&
1679: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 1680: {
1681: font.typed_data.value = STYLE_FONT_HELVETICA;
1682: cssRule += 9;
1.92 cvs 1683: if (quoteChar != EOS)
1684: cssRule++;
1.86 cvs 1685: }
1.92 cvs 1686: else if (!strncasecmp (cssRule, "verdana", 7) &&
1687: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 1688: {
1.1 cvs 1689: font.typed_data.value = STYLE_FONT_HELVETICA;
1.86 cvs 1690: cssRule += 7;
1.92 cvs 1691: if (quoteChar != EOS)
1692: cssRule++;
1.86 cvs 1693: }
1.92 cvs 1694: else if (!strncasecmp (cssRule, "sans-serif", 10) &&
1695: (quoteChar == EOS || quoteChar == cssRule[10]))
1.86 cvs 1696: {
1.1 cvs 1697: font.typed_data.value = STYLE_FONT_HELVETICA;
1.86 cvs 1698: cssRule += 10;
1.92 cvs 1699: if (quoteChar != EOS)
1700: cssRule++;
1.86 cvs 1701: }
1.92 cvs 1702: else if (!strncasecmp (cssRule, "courier", 7) &&
1703: (quoteChar == EOS || quoteChar == cssRule[7]))
1.86 cvs 1704: {
1.1 cvs 1705: font.typed_data.value = STYLE_FONT_COURIER;
1.86 cvs 1706: cssRule += 7;
1.92 cvs 1707: if (quoteChar != EOS)
1708: cssRule++;
1.86 cvs 1709: }
1.92 cvs 1710: else if (!strncasecmp (cssRule, "monospace", 9) &&
1711: (quoteChar == EOS || quoteChar == cssRule[9]))
1.86 cvs 1712: {
1.1 cvs 1713: font.typed_data.value = STYLE_FONT_COURIER;
1.86 cvs 1714: cssRule += 9;
1.92 cvs 1715: if (quoteChar != EOS)
1716: cssRule++;
1.86 cvs 1717: }
1.1 cvs 1718: else
1719: /* unknown font name. Skip it */
1720: {
1.92 cvs 1721: if (quoteChar != EOS)
1.54 cvs 1722: cssRule = SkipQuotedString (cssRule, quoteChar);
1.86 cvs 1723: else
1.1 cvs 1724: cssRule = SkipWord (cssRule);
1.82 cvs 1725: cssRule = SkipBlanksAndComments (cssRule);
1726: if (*cssRule == ',')
1.1 cvs 1727: {
1.86 cvs 1728: cssRule++;
1729: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1730: return (cssRule);
1.1 cvs 1731: }
1732: }
1733:
1734: if (font.typed_data.value != 0)
1735: {
1.93 vatton 1736: cssRule = SkipBlanksAndComments (cssRule);
1.99 vatton 1737: cssRule = SkipValue (cssRule, FALSE);
1.93 vatton 1738: /* install the new presentation */
1.116 vatton 1739: if (DoApply)
1.117 vatton 1740: {
1741: if (tsch)
1742: cssRule = CheckImportantRule (cssRule, context);
1743: TtaSetStylePresentation (PRFont, element, tsch, context, font);
1744: }
1.1 cvs 1745: }
1746: return (cssRule);
1747: }
1748:
1749: /*----------------------------------------------------------------------
1.59 cvs 1750: ParseCSSFontWeight: parse a CSS font weight string
1.1 cvs 1751: we expect the input string describing the attribute to be
1.20 cvs 1752: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 1753: ----------------------------------------------------------------------*/
1.79 cvs 1754: static char *ParseCSSFontWeight (Element element, PSchema tsch,
1755: PresentationContext context, char *cssRule,
1756: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1757: {
1.20 cvs 1758: PresentationValue weight;
1.1 cvs 1759:
1760: weight.typed_data.value = 0;
1761: weight.typed_data.unit = STYLE_UNIT_REL;
1762: weight.typed_data.real = FALSE;
1.82 cvs 1763: cssRule = SkipBlanksAndComments (cssRule);
1764: if (!strncasecmp (cssRule, "100", 3) && !isalpha (cssRule[3]))
1.1 cvs 1765: {
1766: weight.typed_data.value = -3;
1767: cssRule = SkipWord (cssRule);
1768: }
1.82 cvs 1769: else if (!strncasecmp (cssRule, "200", 3) && !isalpha (cssRule[3]))
1.1 cvs 1770: {
1771: weight.typed_data.value = -2;
1772: cssRule = SkipWord (cssRule);
1773: }
1.82 cvs 1774: else if (!strncasecmp (cssRule, "300", 3) && ! isalpha(cssRule[3]))
1.1 cvs 1775: {
1776: weight.typed_data.value = -1;
1777: cssRule = SkipWord (cssRule);
1778: }
1.82 cvs 1779: else if (!strncasecmp (cssRule, "normal", 6) || (!strncasecmp (cssRule, "400", 3) && !isalpha (cssRule[3])))
1.1 cvs 1780: {
1781: weight.typed_data.value = 0;
1782: cssRule = SkipWord (cssRule);
1783: }
1.82 cvs 1784: else if (!strncasecmp (cssRule, "500", 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, "600", 3) && !isalpha (cssRule[3]))
1.1 cvs 1790: {
1791: weight.typed_data.value = +2;
1792: cssRule = SkipWord (cssRule);
1793: }
1.82 cvs 1794: else if (!strncasecmp (cssRule, "bold", 4) || (!strncasecmp (cssRule, "700", 3) && !isalpha (cssRule[3])))
1.1 cvs 1795: {
1796: weight.typed_data.value = +3;
1797: cssRule = SkipWord (cssRule);
1798: }
1.82 cvs 1799: else if (!strncasecmp (cssRule, "800", 3) && !isalpha (cssRule[3]))
1.1 cvs 1800: {
1801: weight.typed_data.value = +4;
1802: cssRule = SkipWord (cssRule);
1803: }
1.82 cvs 1804: else if (!strncasecmp (cssRule, "900", 3) && !isalpha (cssRule[3]))
1.1 cvs 1805: {
1806: weight.typed_data.value = +5;
1807: cssRule = SkipWord (cssRule);
1808: }
1.82 cvs 1809: else if (!strncasecmp (cssRule, "inherit", 7) || !strncasecmp (cssRule, "bolder", 6) || !strncasecmp (cssRule, "lighter", 7))
1.1 cvs 1810: {
1811: /* not implemented */
1812: cssRule = SkipWord (cssRule);
1813: return (cssRule);
1814: }
1815: else
1816: return (cssRule);
1817:
1818: /*
1.20 cvs 1819: * Here we have to reduce since only two font weight values are supported
1.1 cvs 1820: * by the Thot presentation API.
1821: */
1.20 cvs 1822: if (weight.typed_data.value > 0)
1823: weight.typed_data.value = STYLE_WEIGHT_BOLD;
1824: else
1825: weight.typed_data.value = STYLE_WEIGHT_NORMAL;
1.1 cvs 1826:
1827: /* install the new presentation */
1.116 vatton 1828: if (DoApply)
1.117 vatton 1829: {
1830: if (tsch)
1831: cssRule = CheckImportantRule (cssRule, context);
1832: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
1833: }
1.1 cvs 1834: return (cssRule);
1835: }
1836:
1837: /*----------------------------------------------------------------------
1.59 cvs 1838: ParseCSSFontVariant: parse a CSS font variant string
1.1 cvs 1839: we expect the input string describing the attribute to be
1840: normal or small-caps
1841: ----------------------------------------------------------------------*/
1.79 cvs 1842: static char *ParseCSSFontVariant (Element element, PSchema tsch,
1843: PresentationContext context, char *cssRule,
1844: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1845: {
1846: PresentationValue style;
1847:
1848: style.typed_data.value = 0;
1849: style.typed_data.unit = STYLE_UNIT_REL;
1850: style.typed_data.real = FALSE;
1.82 cvs 1851: cssRule = SkipBlanksAndComments (cssRule);
1852: if (!strncasecmp (cssRule, "small-caps", 10))
1.1 cvs 1853: {
1854: /* Not supported yet */
1855: cssRule = SkipWord (cssRule);
1856: }
1.82 cvs 1857: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1858: {
1859: /* Not supported yet */
1860: cssRule = SkipWord (cssRule);
1861: }
1.82 cvs 1862: else if (!strncasecmp (cssRule, "inherit", 7))
1.1 cvs 1863: {
1864: /* Not supported yet */
1865: cssRule = SkipWord (cssRule);
1866: }
1867: else
1868: return (cssRule);
1869:
1870: return (cssRule);
1871: }
1872:
1873:
1874: /*----------------------------------------------------------------------
1.59 cvs 1875: ParseCSSFontStyle: parse a CSS font style string
1.1 cvs 1876: we expect the input string describing the attribute to be
1877: italic, oblique or normal
1878: ----------------------------------------------------------------------*/
1.79 cvs 1879: static char *ParseCSSFontStyle (Element element, PSchema tsch,
1880: PresentationContext context, char *cssRule,
1881: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1882: {
1883: PresentationValue style;
1884: PresentationValue size;
1885:
1886: style.typed_data.value = 0;
1887: style.typed_data.unit = STYLE_UNIT_REL;
1888: style.typed_data.real = FALSE;
1889: size.typed_data.value = 0;
1890: size.typed_data.unit = STYLE_UNIT_REL;
1891: size.typed_data.real = FALSE;
1.82 cvs 1892: cssRule = SkipBlanksAndComments (cssRule);
1893: if (!strncasecmp (cssRule, "italic", 6))
1.1 cvs 1894: {
1895: style.typed_data.value = STYLE_FONT_ITALICS;
1896: cssRule = SkipWord (cssRule);
1897: }
1.82 cvs 1898: else if (!strncasecmp (cssRule, "oblique", 7))
1.1 cvs 1899: {
1900: style.typed_data.value = STYLE_FONT_OBLIQUE;
1901: cssRule = SkipWord (cssRule);
1902: }
1.82 cvs 1903: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1904: {
1905: style.typed_data.value = STYLE_FONT_ROMAN;
1906: cssRule = SkipWord (cssRule);
1907: }
1.108 cvs 1908: else if (!strncasecmp (cssRule, "inherit", 7))
1909: {
1910: /* not implemented */
1911: cssRule = SkipWord (cssRule);
1912: return (cssRule);
1913: }
1.1 cvs 1914: else
1915: {
1916: /* invalid font style */
1.108 cvs 1917: return (cssRule);
1.1 cvs 1918: }
1919:
1920: /*
1921: * install the new presentation.
1922: */
1.116 vatton 1923: if (style.typed_data.value != 0 && DoApply)
1.117 vatton 1924: {
1925: if (tsch)
1926: cssRule = CheckImportantRule (cssRule, context);
1.20 cvs 1927: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.117 vatton 1928: }
1.116 vatton 1929: if (size.typed_data.value != 0 && DoApply)
1.1 cvs 1930: {
1931: PresentationValue previous_size;
1932:
1933: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
1934: {
1935: /* !!!!!!!!!!!!!!!!!!!!!!!! Unite + relatif !!!!!!!!!!!!!!!! */
1936: size.typed_data.value += previous_size.typed_data.value;
1937: TtaSetStylePresentation (PRSize, element, tsch, context, size);
1938: }
1939: else
1940: {
1941: size.typed_data.value = 10;
1942: TtaSetStylePresentation (PRSize, element, tsch, context, size);
1943: }
1944: }
1945: return (cssRule);
1946: }
1947:
1948: /*----------------------------------------------------------------------
1.59 cvs 1949: ParseCSSFont: parse a CSS font attribute string
1950: we expect the input string describing the attribute to be
1951: !!!!!!
1.1 cvs 1952: ----------------------------------------------------------------------*/
1.79 cvs 1953: static char *ParseCSSFont (Element element, PSchema tsch,
1954: PresentationContext context, char *cssRule,
1955: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1956: {
1.79 cvs 1957: char *ptr;
1.93 vatton 1958: int skippedNL;
1.1 cvs 1959:
1.82 cvs 1960: cssRule = SkipBlanksAndComments (cssRule);
1961: if (!strncasecmp (cssRule, "caption", 7))
1.1 cvs 1962: ;
1.82 cvs 1963: else if (!strncasecmp (cssRule, "icon", 4))
1.1 cvs 1964: ;
1.82 cvs 1965: else if (!strncasecmp (cssRule, "menu", 4))
1.1 cvs 1966: ;
1.82 cvs 1967: else if (!strncasecmp (cssRule, "message-box", 11))
1.1 cvs 1968: ;
1.82 cvs 1969: else if (!strncasecmp (cssRule, "small-caption", 13))
1.1 cvs 1970: ;
1.82 cvs 1971: else if (!strncasecmp (cssRule, "status-bar", 10))
1.1 cvs 1972: ;
1973: else
1.43 cvs 1974: {
1.82 cvs 1975: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1976: {
1.72 cvs 1977: ptr = cssRule;
1.93 vatton 1978: skippedNL = NewLineSkipped;
1.72 cvs 1979: cssRule = ParseCSSFontStyle (element, tsch, context, cssRule, css, isHTML);
1980: if (ptr == cssRule)
1.93 vatton 1981: {
1982: NewLineSkipped = skippedNL;
1983: cssRule = ParseCSSFontVariant (element, tsch, context, cssRule, css, isHTML);
1984: }
1.72 cvs 1985: if (ptr == cssRule)
1.93 vatton 1986: {
1987: NewLineSkipped = skippedNL;
1988: cssRule = ParseCSSFontWeight (element, tsch, context, cssRule, css, isHTML);
1989: }
1.72 cvs 1990: if (ptr == cssRule)
1.93 vatton 1991: {
1992: NewLineSkipped = skippedNL;
1993: cssRule = ParseCSSFontSize (element, tsch, context, cssRule, css, isHTML);
1994: }
1.72 cvs 1995: if (ptr == cssRule)
1.93 vatton 1996: {
1997: NewLineSkipped = skippedNL;
1998: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1999: }
1.99 vatton 2000: if (ptr == cssRule)
2001: cssRule = SkipValue (cssRule, TRUE);
1.82 cvs 2002: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2003: }
2004: }
2005: return (cssRule);
1.1 cvs 2006: }
2007:
2008: /*----------------------------------------------------------------------
1.59 cvs 2009: ParseCSSTextDecoration: parse a CSS text decor string
2010: we expect the input string describing the attribute to be
1.109 cvs 2011: underline, overline, line-through, blink or none.
1.1 cvs 2012: ----------------------------------------------------------------------*/
1.79 cvs 2013: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
2014: PresentationContext context, char *cssRule,
2015: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2016: {
2017: PresentationValue decor;
2018:
2019: decor.typed_data.value = 0;
2020: decor.typed_data.unit = STYLE_UNIT_REL;
2021: decor.typed_data.real = FALSE;
1.82 cvs 2022: cssRule = SkipBlanksAndComments (cssRule);
2023: if (!strncasecmp (cssRule, "underline", strlen ("underline")))
1.1 cvs 2024: {
2025: decor.typed_data.value = Underline;
2026: cssRule = SkipWord (cssRule);
2027: }
1.82 cvs 2028: else if (!strncasecmp (cssRule, "overline", strlen ("overline")))
1.1 cvs 2029: {
2030: decor.typed_data.value = Overline;
2031: cssRule = SkipWord (cssRule);
2032: }
1.82 cvs 2033: else if (!strncasecmp (cssRule, "line-through", strlen ("line-through")))
1.1 cvs 2034: {
2035: decor.typed_data.value = CrossOut;
2036: cssRule = SkipWord (cssRule);
2037: }
1.82 cvs 2038: else if (!strncasecmp (cssRule, "blink", strlen ("blink")))
1.1 cvs 2039: {
1.109 cvs 2040: /* the blink text-decoration attribute is not supported */
1.1 cvs 2041: cssRule = SkipWord (cssRule);
2042: }
1.82 cvs 2043: else if (!strncasecmp (cssRule, "none", strlen ("none")))
1.1 cvs 2044: {
2045: decor.typed_data.value = NoUnderline;
2046: cssRule = SkipWord (cssRule);
2047: }
2048: else
2049: {
1.86 cvs 2050: CSSParseError ("Invalid text decoration", cssRule);
1.1 cvs 2051: return (cssRule);
2052: }
2053:
2054: /*
2055: * install the new presentation.
2056: */
1.116 vatton 2057: if (decor.typed_data.value && DoApply)
1.1 cvs 2058: {
1.117 vatton 2059: if (tsch)
2060: cssRule = CheckImportantRule (cssRule, context);
1.1 cvs 2061: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
2062: }
2063: return (cssRule);
2064: }
2065:
2066: /*----------------------------------------------------------------------
1.59 cvs 2067: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 2068: ----------------------------------------------------------------------*/
1.79 cvs 2069: static char *ParseCSSHeight (Element element, PSchema tsch,
1.93 vatton 2070: PresentationContext context, char *cssRule,
2071: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2072: {
1.117 vatton 2073: PresentationValue val;
1.93 vatton 2074:
1.117 vatton 2075: cssRule = SkipBlanksAndComments (cssRule);
2076: /* first parse the attribute string */
2077: if (!strcasecmp (cssRule, "auto"))
2078: cssRule = SkipWord (cssRule);
2079: else
2080: {
2081: cssRule = ParseCSSUnit (cssRule, &val);
2082: if (val.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
2083: {
2084: if (tsch)
2085: cssRule = CheckImportantRule (cssRule, context);
2086: /* install the new presentation */
2087: TtaSetStylePresentation (PRHeight, element, tsch, context, val);
2088: }
2089: }
2090: return (cssRule);
1.1 cvs 2091: }
2092:
2093: /*----------------------------------------------------------------------
1.59 cvs 2094: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 2095: ----------------------------------------------------------------------*/
1.79 cvs 2096: static char *ParseCSSWidth (Element element, PSchema tsch,
1.78 cvs 2097: PresentationContext context,
1.79 cvs 2098: char *cssRule, CSSInfoPtr css,
1.78 cvs 2099: ThotBool isHTML)
1.1 cvs 2100: {
1.117 vatton 2101: PresentationValue val;
1.93 vatton 2102:
1.117 vatton 2103: cssRule = SkipBlanksAndComments (cssRule);
2104: /* first parse the attribute string */
2105: if (!strcasecmp (cssRule, "auto"))
2106: cssRule = SkipWord (cssRule);
2107: else
2108: {
2109: cssRule = ParseCSSUnit (cssRule, &val);
2110: if (val.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
2111: {
2112: if (tsch)
2113: cssRule = CheckImportantRule (cssRule, context);
2114: /* install the new presentation */
2115: TtaSetStylePresentation (PRWidth, element, tsch, context, val);
2116: }
2117: }
2118: return (cssRule);
1.1 cvs 2119: }
2120:
2121: /*----------------------------------------------------------------------
1.59 cvs 2122: ParseCSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 2123: ----------------------------------------------------------------------*/
1.79 cvs 2124: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.78 cvs 2125: PresentationContext context,
1.79 cvs 2126: char *cssRule, CSSInfoPtr css,
1.78 cvs 2127: ThotBool isHTML)
1.1 cvs 2128: {
2129: PresentationValue margin;
2130:
1.82 cvs 2131: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2132: /* first parse the attribute string */
2133: cssRule = ParseCSSUnit (cssRule, &margin);
1.116 vatton 2134: if (margin.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2135: {
2136: if (tsch)
2137: cssRule = CheckImportantRule (cssRule, context);
2138: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
2139: }
1.1 cvs 2140: return (cssRule);
2141: }
2142:
2143: /*----------------------------------------------------------------------
1.59 cvs 2144: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 2145: ----------------------------------------------------------------------*/
1.79 cvs 2146: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.78 cvs 2147: PresentationContext context,
1.79 cvs 2148: char *cssRule, CSSInfoPtr css,
1.78 cvs 2149: ThotBool isHTML)
1.1 cvs 2150: {
2151: PresentationValue margin;
2152:
1.82 cvs 2153: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2154: /* first parse the attribute string */
2155: cssRule = ParseCSSUnit (cssRule, &margin);
1.116 vatton 2156: if (margin.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2157: {
2158: if (tsch)
2159: cssRule = CheckImportantRule (cssRule, context);
2160: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
2161: }
1.1 cvs 2162: return (cssRule);
2163: }
2164:
2165: /*----------------------------------------------------------------------
1.59 cvs 2166: ParseCSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 2167: ----------------------------------------------------------------------*/
1.79 cvs 2168: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.78 cvs 2169: PresentationContext context,
1.79 cvs 2170: char *cssRule, CSSInfoPtr css,
1.78 cvs 2171: ThotBool isHTML)
1.1 cvs 2172: {
2173: PresentationValue margin;
2174:
1.82 cvs 2175: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2176: /* first parse the attribute string */
2177: cssRule = ParseCSSUnit (cssRule, &margin);
1.116 vatton 2178: if (margin.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2179: {
2180: if (tsch)
2181: cssRule = CheckImportantRule (cssRule, context);
2182: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
2183: }
1.1 cvs 2184: return (cssRule);
2185: }
2186:
2187: /*----------------------------------------------------------------------
1.59 cvs 2188: ParseCSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 2189: ----------------------------------------------------------------------*/
1.79 cvs 2190: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.78 cvs 2191: PresentationContext context,
1.79 cvs 2192: char *cssRule, CSSInfoPtr css,
1.78 cvs 2193: ThotBool isHTML)
1.1 cvs 2194: {
2195: PresentationValue margin;
2196:
1.82 cvs 2197: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2198: /* first parse the attribute string */
2199: cssRule = ParseCSSUnit (cssRule, &margin);
1.116 vatton 2200: if (margin.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2201: {
2202: if (tsch)
2203: cssRule = CheckImportantRule (cssRule, context);
2204: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
2205: }
1.1 cvs 2206: return (cssRule);
2207: }
2208:
2209: /*----------------------------------------------------------------------
1.59 cvs 2210: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 2211: ----------------------------------------------------------------------*/
1.79 cvs 2212: static char *ParseCSSMargin (Element element, PSchema tsch,
1.78 cvs 2213: PresentationContext context,
1.79 cvs 2214: char *cssRule, CSSInfoPtr css,
1.78 cvs 2215: ThotBool isHTML)
1.1 cvs 2216: {
1.79 cvs 2217: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2218: int skippedNL;
1.1 cvs 2219:
1.82 cvs 2220: ptrT = SkipBlanksAndComments (cssRule);
1.1 cvs 2221: /* First parse Margin-Top */
2222: ptrR = ParseCSSMarginTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2223: ptrR = SkipBlanksAndComments (ptrR);
2224: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.1 cvs 2225: {
1.93 vatton 2226: skippedNL = NewLineSkipped;
1.1 cvs 2227: cssRule = ptrR;
2228: /* apply the Margin-Top to all */
2229: ptrR = ParseCSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2230: NewLineSkipped = skippedNL;
1.1 cvs 2231: ptrR = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2232: NewLineSkipped = skippedNL;
1.1 cvs 2233: ptrR = ParseCSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
2234: }
2235: else
2236: {
2237: /* parse Margin-Right */
2238: ptrB = ParseCSSMarginRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2239: ptrB = SkipBlanksAndComments (ptrB);
2240: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.1 cvs 2241: {
1.93 vatton 2242: skippedNL = NewLineSkipped;
1.1 cvs 2243: cssRule = ptrB;
2244: /* apply the Margin-Top to Margin-Bottom */
2245: ptrB = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2246: NewLineSkipped = skippedNL;
1.1 cvs 2247: /* apply the Margin-Right to Margin-Left */
2248: ptrB = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2249: }
2250: else
2251: {
2252: /* parse Margin-Bottom */
2253: ptrL = ParseCSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2254: ptrL = SkipBlanksAndComments (ptrL);
2255: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.1 cvs 2256: {
2257: cssRule = ptrL;
2258: /* apply the Margin-Right to Margin-Left */
2259: ptrL = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
2260: }
2261: else
2262: /* parse Margin-Left */
2263: cssRule = ParseCSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2264: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2265: }
2266: }
2267: return (cssRule);
2268: }
2269:
2270: /*----------------------------------------------------------------------
1.59 cvs 2271: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 2272: ----------------------------------------------------------------------*/
1.79 cvs 2273: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.78 cvs 2274: PresentationContext context,
1.79 cvs 2275: char *cssRule, CSSInfoPtr css,
1.78 cvs 2276: ThotBool isHTML)
1.1 cvs 2277: {
1.43 cvs 2278: PresentationValue padding;
2279:
1.82 cvs 2280: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2281: /* first parse the attribute string */
2282: cssRule = ParseCSSUnit (cssRule, &padding);
1.116 vatton 2283: if (padding.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2284: {
2285: if (tsch)
2286: cssRule = CheckImportantRule (cssRule, context);
2287: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
2288: }
1.1 cvs 2289: return (cssRule);
2290: }
2291:
2292: /*----------------------------------------------------------------------
1.59 cvs 2293: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 2294: ----------------------------------------------------------------------*/
1.79 cvs 2295: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.78 cvs 2296: PresentationContext context,
1.79 cvs 2297: char *cssRule, CSSInfoPtr css,
1.78 cvs 2298: ThotBool isHTML)
1.1 cvs 2299: {
1.43 cvs 2300: PresentationValue padding;
2301:
1.82 cvs 2302: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2303: /* first parse the attribute string */
2304: cssRule = ParseCSSUnit (cssRule, &padding);
1.116 vatton 2305: if (padding.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2306: {
2307: if (tsch)
2308: cssRule = CheckImportantRule (cssRule, context);
2309: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
2310: }
1.1 cvs 2311: return (cssRule);
2312: }
2313:
2314: /*----------------------------------------------------------------------
1.59 cvs 2315: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 2316: ----------------------------------------------------------------------*/
1.79 cvs 2317: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.78 cvs 2318: PresentationContext context,
1.79 cvs 2319: char *cssRule, CSSInfoPtr css,
1.78 cvs 2320: ThotBool isHTML)
1.1 cvs 2321: {
1.43 cvs 2322: PresentationValue padding;
2323:
1.82 cvs 2324: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2325: /* first parse the attribute string */
2326: cssRule = ParseCSSUnit (cssRule, &padding);
1.116 vatton 2327: if (padding.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2328: {
2329: if (tsch)
2330: cssRule = CheckImportantRule (cssRule, context);
1.43 cvs 2331: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.117 vatton 2332: }
1.1 cvs 2333: return (cssRule);
2334: }
2335:
2336: /*----------------------------------------------------------------------
1.59 cvs 2337: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 2338: ----------------------------------------------------------------------*/
1.79 cvs 2339: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.78 cvs 2340: PresentationContext context,
1.79 cvs 2341: char *cssRule, CSSInfoPtr css,
1.78 cvs 2342: ThotBool isHTML)
1.1 cvs 2343: {
1.43 cvs 2344: PresentationValue padding;
2345:
1.82 cvs 2346: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2347: /* first parse the attribute string */
2348: cssRule = ParseCSSUnit (cssRule, &padding);
1.116 vatton 2349: if (padding.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2350: {
2351: if (tsch)
2352: cssRule = CheckImportantRule (cssRule, context);
1.43 cvs 2353: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.117 vatton 2354: }
1.1 cvs 2355: return (cssRule);
2356: }
2357:
2358: /*----------------------------------------------------------------------
1.59 cvs 2359: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 2360: ----------------------------------------------------------------------*/
1.79 cvs 2361: static char *ParseCSSPadding (Element element, PSchema tsch,
1.78 cvs 2362: PresentationContext context,
1.79 cvs 2363: char *cssRule, CSSInfoPtr css,
1.78 cvs 2364: ThotBool isHTML)
1.1 cvs 2365: {
1.79 cvs 2366: char *ptrT, *ptrR, *ptrB, *ptrL;
1.93 vatton 2367: int skippedNL;
1.43 cvs 2368:
1.82 cvs 2369: ptrT = SkipBlanksAndComments (cssRule);
1.43 cvs 2370: /* First parse Padding-Top */
2371: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
1.82 cvs 2372: ptrR = SkipBlanksAndComments (ptrR);
2373: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.43 cvs 2374: {
1.93 vatton 2375: skippedNL = NewLineSkipped;
1.43 cvs 2376: cssRule = ptrR;
2377: /* apply the Padding-Top to all */
2378: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2379: NewLineSkipped = skippedNL;
1.43 cvs 2380: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2381: NewLineSkipped = skippedNL;
1.43 cvs 2382: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
2383: }
2384: else
2385: {
2386: /* parse Padding-Right */
2387: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
1.82 cvs 2388: ptrB = SkipBlanksAndComments (ptrB);
2389: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.43 cvs 2390: {
1.93 vatton 2391: skippedNL = NewLineSkipped;
1.43 cvs 2392: cssRule = ptrB;
2393: /* apply the Padding-Top to Padding-Bottom */
2394: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1.93 vatton 2395: NewLineSkipped = skippedNL;
1.43 cvs 2396: /* apply the Padding-Right to Padding-Left */
2397: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2398: }
2399: else
2400: {
2401: /* parse Padding-Bottom */
2402: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
1.82 cvs 2403: ptrL = SkipBlanksAndComments (ptrL);
2404: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.43 cvs 2405: {
2406: cssRule = ptrL;
2407: /* apply the Padding-Right to Padding-Left */
2408: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
2409: }
2410: else
2411: /* parse Padding-Left */
2412: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
1.82 cvs 2413: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 2414: }
2415: }
1.1 cvs 2416: return (cssRule);
2417: }
2418:
2419: /*----------------------------------------------------------------------
1.59 cvs 2420: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 2421: ----------------------------------------------------------------------*/
1.79 cvs 2422: static char *ParseCSSForeground (Element element, PSchema tsch,
1.78 cvs 2423: PresentationContext context,
1.79 cvs 2424: char *cssRule,
1.78 cvs 2425: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2426: {
1.117 vatton 2427: PresentationValue best;
1.1 cvs 2428:
1.117 vatton 2429: cssRule = ParseCSSColor (cssRule, &best);
2430: if (best.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
2431: {
2432: if (tsch)
2433: cssRule = CheckImportantRule (cssRule, context);
2434: /* install the new presentation */
2435: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2436: }
1.1 cvs 2437: return (cssRule);
2438: }
2439:
2440: /*----------------------------------------------------------------------
1.59 cvs 2441: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 2442: ----------------------------------------------------------------------*/
1.79 cvs 2443: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.78 cvs 2444: PresentationContext context,
1.79 cvs 2445: char *cssRule,
1.78 cvs 2446: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2447: {
2448: PresentationValue best;
2449: unsigned int savedtype = 0;
1.14 cvs 2450: ThotBool moved;
1.1 cvs 2451:
2452: /* move the BODY rule to the HTML element */
2453: moved = (context->type == HTML_EL_BODY && isHTML);
2454: if (moved)
2455: {
2456: if (element)
2457: element = TtaGetMainRoot (context->doc);
2458: else
2459: {
2460: savedtype = context->type;
1.83 cvs 2461: context->type = HTML_EL_Document;
1.1 cvs 2462: }
2463: }
2464:
2465: best.typed_data.unit = STYLE_UNIT_INVALID;
2466: best.typed_data.real = FALSE;
1.82 cvs 2467: if (!strncasecmp (cssRule, "transparent", strlen ("transparent")))
1.1 cvs 2468: {
2469: best.typed_data.value = STYLE_PATTERN_NONE;
2470: best.typed_data.unit = STYLE_UNIT_REL;
1.116 vatton 2471: if (DoApply)
1.117 vatton 2472: {
2473: if (tsch)
2474: cssRule = CheckImportantRule (cssRule, context);
2475: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2476: }
1.65 cvs 2477: cssRule = SkipWord (cssRule);
1.1 cvs 2478: }
2479: else
2480: {
2481: cssRule = ParseCSSColor (cssRule, &best);
1.116 vatton 2482: if (best.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.1 cvs 2483: {
1.117 vatton 2484: if (tsch)
2485: cssRule = CheckImportantRule (cssRule, context);
1.1 cvs 2486: /* install the new presentation. */
2487: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59 cvs 2488: /* thot specificity: need to set fill pattern for background color */
1.1 cvs 2489: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2490: best.typed_data.unit = STYLE_UNIT_REL;
2491: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2492: best.typed_data.value = 1;
2493: best.typed_data.unit = STYLE_UNIT_REL;
2494: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
2495: }
2496: }
2497:
2498: /* restore the refered element */
2499: if (moved && !element)
2500: context->type = savedtype;
2501: return (cssRule);
2502: }
2503:
1.63 cvs 2504:
2505: /*----------------------------------------------------------------------
1.65 cvs 2506: ParseSVGStroke: parse a SVG stroke property
2507: ----------------------------------------------------------------------*/
1.79 cvs 2508: static char *ParseSVGStroke (Element element, PSchema tsch,
2509: PresentationContext context, char *cssRule,
2510: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 2511: {
2512: PresentationValue best;
2513:
2514: best.typed_data.unit = STYLE_UNIT_INVALID;
2515: best.typed_data.real = FALSE;
1.82 cvs 2516: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 2517: {
2518: best.typed_data.value = -2; /* -2 means transparent */
2519: best.typed_data.unit = STYLE_UNIT_REL;
1.116 vatton 2520: if (DoApply)
1.117 vatton 2521: {
2522: if (tsch)
2523: cssRule = CheckImportantRule (cssRule, context);
2524: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2525: }
1.65 cvs 2526: cssRule = SkipWord (cssRule);
2527: }
2528: else
2529: {
2530: cssRule = ParseCSSColor (cssRule, &best);
1.116 vatton 2531: if (best.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 2532: {
2533: if (tsch)
2534: cssRule = CheckImportantRule (cssRule, context);
2535: /* install the new presentation */
2536: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2537: }
1.65 cvs 2538: }
2539: return (cssRule);
2540: }
2541:
2542: /*----------------------------------------------------------------------
1.63 cvs 2543: ParseSVGFill: parse a SVG fill property
2544: ----------------------------------------------------------------------*/
1.79 cvs 2545: static char *ParseSVGFill (Element element, PSchema tsch,
2546: PresentationContext context, char *cssRule,
2547: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 2548: {
2549: PresentationValue best;
2550:
2551: best.typed_data.unit = STYLE_UNIT_INVALID;
2552: best.typed_data.real = FALSE;
1.82 cvs 2553: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 2554: {
2555: best.typed_data.value = STYLE_PATTERN_NONE;
2556: best.typed_data.unit = STYLE_UNIT_REL;
1.116 vatton 2557: if (DoApply)
1.117 vatton 2558: {
2559: if (tsch)
2560: cssRule = CheckImportantRule (cssRule, context);
2561: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2562: }
1.65 cvs 2563: cssRule = SkipWord (cssRule);
1.63 cvs 2564: }
2565: else
2566: {
2567: cssRule = ParseCSSColor (cssRule, &best);
1.116 vatton 2568: if (best.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.63 cvs 2569: {
1.117 vatton 2570: if (tsch)
2571: cssRule = CheckImportantRule (cssRule, context);
1.63 cvs 2572: /* install the new presentation. */
2573: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
2574: /* thot specificity: need to set fill pattern for background color */
2575: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2576: best.typed_data.unit = STYLE_UNIT_REL;
2577: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2578: }
2579: }
2580: return (cssRule);
2581: }
2582:
1.1 cvs 2583: /*----------------------------------------------------------------------
1.59 cvs 2584: ParseCSSBackgroundImageCallback: Callback called asynchronously by
2585: FetchImage when a background image has been fetched.
1.1 cvs 2586: ----------------------------------------------------------------------*/
1.82 cvs 2587: void ParseCSSBackgroundImageCallback (Document doc, Element element,
2588: char *file, void *extra)
1.1 cvs 2589: {
1.82 cvs 2590: DisplayMode dispMode;
2591: BackgroundImageCallbackPtr callblock;
2592: Element el;
2593: PSchema tsch;
2594: PresentationContext context;
2595: PresentationValue image;
2596: PresentationValue value;
1.1 cvs 2597:
1.82 cvs 2598: callblock = (BackgroundImageCallbackPtr) extra;
1.34 cvs 2599: if (callblock == NULL)
2600: return;
1.1 cvs 2601:
1.34 cvs 2602: /* avoid too many redisplay */
2603: dispMode = TtaGetDisplayMode (doc);
2604: if (dispMode == DisplayImmediately)
2605: TtaSetDisplayMode (doc, DeferredDisplay);
2606:
2607: el = callblock->el;
2608: tsch = callblock->tsch;
2609: context = &callblock->context.specific;
2610:
2611: /* Ok the image was fetched, finish the background-image handling */
2612: image.pointer = file;
2613: TtaSetStylePresentation (PRBackgroundPicture, el, tsch, context, image);
1.1 cvs 2614:
1.70 cvs 2615: /* enforce the showbox */
1.34 cvs 2616: value.typed_data.value = 1;
2617: value.typed_data.unit = STYLE_UNIT_REL;
2618: value.typed_data.real = FALSE;
2619: TtaSetStylePresentation (PRShowBox, el, tsch, context, value);
2620:
2621: TtaFreeMemory (callblock);
2622: /* restore the display mode */
2623: if (dispMode == DisplayImmediately)
2624: TtaSetDisplayMode (doc, dispMode);
1.1 cvs 2625: }
2626:
2627:
2628: /*----------------------------------------------------------------------
2629: GetCSSBackgroundURL searches a CSS BackgroundImage url within
2630: the styleString.
2631: Returns NULL or a new allocated url string.
2632: ----------------------------------------------------------------------*/
1.79 cvs 2633: char *GetCSSBackgroundURL (char *styleString)
1.1 cvs 2634: {
1.79 cvs 2635: char *b, *e, *ptr;
2636: int len;
1.1 cvs 2637:
2638: ptr = NULL;
1.82 cvs 2639: b = strstr (styleString, "url");
1.1 cvs 2640: if (b != NULL)
2641: {
2642: b += 3;
1.82 cvs 2643: b = SkipBlanksAndComments (b);
2644: if (*b == '(')
1.1 cvs 2645: {
2646: b++;
1.82 cvs 2647: b = SkipBlanksAndComments (b);
1.1 cvs 2648: /*** Caution: Strings can either be written with double quotes or
2649: with single quotes. Only double quotes are handled here.
2650: Escaped quotes are not handled. See function SkipQuotedString */
1.82 cvs 2651: if (*b == '"')
1.1 cvs 2652: {
2653: b++;
2654: /* search the url end */
2655: e = b;
1.82 cvs 2656: while (*e != EOS && *e != '"')
1.1 cvs 2657: e++;
2658: }
2659: else
2660: {
2661: /* search the url end */
2662: e = b;
1.82 cvs 2663: while (*e != EOS && *e != ')')
1.1 cvs 2664: e++;
2665: }
1.82 cvs 2666: if (*e != EOS)
1.1 cvs 2667: {
2668: len = (int)(e - b);
1.82 cvs 2669: ptr = (char*) TtaGetMemory (len+1);
2670: strncpy (ptr, b, len);
2671: ptr[len] = EOS;
1.1 cvs 2672: }
2673: }
2674: }
2675: return (ptr);
2676: }
2677:
2678:
2679: /*----------------------------------------------------------------------
1.59 cvs 2680: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 2681: ----------------------------------------------------------------------*/
1.79 cvs 2682: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
2683: PresentationContext context,
2684: char *cssRule, CSSInfoPtr css,
2685: ThotBool isHTML)
1.1 cvs 2686: {
1.49 cvs 2687: Element el;
2688: GenericContext gblock;
1.71 cvs 2689: PresentationContext sblock;
1.1 cvs 2690: BackgroundImageCallbackPtr callblock;
1.49 cvs 2691: PresentationValue image, value;
1.79 cvs 2692: char *url;
1.82 cvs 2693: char *bg_image;
1.79 cvs 2694: char saved;
2695: char *base;
2696: char tempname[MAX_LENGTH];
2697: char imgname[MAX_LENGTH];
1.49 cvs 2698: unsigned int savedtype = 0;
2699: ThotBool moved;
1.1 cvs 2700:
2701: /* default element for FetchImage */
2702: el = TtaGetMainRoot (context->doc);
2703: /* move the BODY rule to the HTML element */
2704: moved = (context->type == HTML_EL_BODY && isHTML);
2705: if (moved)
2706: {
2707: if (element)
2708: element = el;
2709: else
2710: {
2711: savedtype = context->type;
1.83 cvs 2712: context->type = HTML_EL_Document;
1.1 cvs 2713: }
2714: }
2715: else if (element)
2716: el = element;
2717:
2718: url = NULL;
1.82 cvs 2719: cssRule = SkipBlanksAndComments (cssRule);
2720: if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 2721: {
2722: cssRule += 3;
1.82 cvs 2723: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2724: if (*cssRule == '(')
2725: {
2726: cssRule++;
1.82 cvs 2727: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2728: /*** Caution: Strings can either be written with double quotes or
2729: with single quotes. Only double quotes are handled here.
2730: Escaped quotes are not handled. See function SkipQuotedString */
2731: if (*cssRule == '"')
2732: {
2733: cssRule++;
2734: base = cssRule;
1.82 cvs 2735: while (*cssRule != EOS && *cssRule != '"')
1.1 cvs 2736: cssRule++;
2737: }
2738: else
2739: {
2740: base = cssRule;
2741: while (*cssRule != EOS && *cssRule != ')')
2742: cssRule++;
2743: }
2744: saved = *cssRule;
1.82 cvs 2745: *cssRule = EOS;
2746: url = TtaStrdup (base);
1.1 cvs 2747: *cssRule = saved;
2748: if (saved == '"')
2749: /* we need to skip two characters */
2750: cssRule++;
2751: }
2752: cssRule++;
2753:
2754: if (context->destroy)
2755: {
2756: /* remove the background image PRule */
2757: image.pointer = NULL;
2758: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, context, image);
2759: if (TtaGetStylePresentation (PRFillPattern, element, tsch, context, &value) < 0)
2760: {
2761: /* there is no FillPattern rule -> remove ShowBox rule */
2762: value.typed_data.value = 1;
2763: value.typed_data.unit = STYLE_UNIT_REL;
2764: value.typed_data.real = FALSE;
2765: TtaSetStylePresentation (PRShowBox, element, tsch, context, value);
2766: }
2767: }
2768: else if (url)
2769: {
1.30 cvs 2770: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
1.82 cvs 2771: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
1.1 cvs 2772: {
2773: callblock = (BackgroundImageCallbackPtr) TtaGetMemory(sizeof(BackgroundImageCallbackBlock));
2774: if (callblock != NULL)
2775: {
2776: callblock->el = element;
2777: callblock->tsch = tsch;
2778: if (element == NULL)
1.18 cvs 2779: {
2780: gblock = (GenericContext) context;
2781: memcpy (&callblock->context.generic, gblock,
2782: sizeof (GenericContextBlock));
2783: }
2784: else
2785: {
2786: sblock = context;
2787: memcpy (&callblock->context.specific, sblock,
2788: sizeof(PresentationContextBlock));
2789: }
2790:
2791: /* check if the image url is related to an external CSS */
2792: if (css != NULL && css->category == CSS_EXTERNAL_STYLE)
2793: {
2794: NormalizeURL (url, 0, tempname, imgname, css->url);
2795: /* fetch and display background image of element */
1.49 cvs 2796: FetchImage (context->doc, el, tempname, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2797: }
2798: else
1.49 cvs 2799: FetchImage (context->doc, el, url, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2800: }
2801: }
2802:
2803: if (url)
2804: TtaFreeMemory (url);
2805: }
2806: }
2807:
2808: /* restore the refered element */
2809: if (moved && !element)
2810: context->type = savedtype;
2811: return (cssRule);
2812: }
2813:
2814: /*----------------------------------------------------------------------
1.59 cvs 2815: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 2816: ----------------------------------------------------------------------*/
1.79 cvs 2817: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
1.97 vatton 2818: PresentationContext context,
2819: char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2820: {
2821: PresentationValue repeat;
2822: unsigned int savedtype = 0;
2823: ThotBool moved;
2824:
2825: /* move the BODY rule to the HTML element */
2826: moved = (context->type == HTML_EL_BODY && isHTML);
2827: if (moved)
2828: {
2829: if (element)
2830: element = TtaGetMainRoot (context->doc);
2831: else
2832: {
2833: savedtype = context->type;
1.83 cvs 2834: context->type = HTML_EL_Document;
1.18 cvs 2835: }
2836: }
2837:
2838: repeat.typed_data.value = STYLE_REALSIZE;
2839: repeat.typed_data.unit = STYLE_UNIT_REL;
2840: repeat.typed_data.real = FALSE;
1.82 cvs 2841: cssRule = SkipBlanksAndComments (cssRule);
2842: if (!strncasecmp (cssRule, "no-repeat", 9))
1.18 cvs 2843: repeat.typed_data.value = STYLE_REALSIZE;
1.82 cvs 2844: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.18 cvs 2845: repeat.typed_data.value = STYLE_VREPEAT;
1.82 cvs 2846: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.18 cvs 2847: repeat.typed_data.value = STYLE_HREPEAT;
1.82 cvs 2848: else if (!strncasecmp (cssRule, "repeat", 6))
1.18 cvs 2849: repeat.typed_data.value = STYLE_REPEAT;
2850: else
2851: return (cssRule);
2852:
2853: /* install the new presentation */
1.116 vatton 2854: if (DoApply)
1.117 vatton 2855: {
2856: /* check if it's an important rule */
2857: if (tsch)
2858: cssRule = CheckImportantRule (cssRule, context);
2859: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
2860: }
1.18 cvs 2861: cssRule = SkipWord (cssRule);
2862:
2863: /* restore the refered element */
2864: if (moved && !element)
2865: context->type = savedtype;
2866: return (cssRule);
2867: }
2868:
2869: /*----------------------------------------------------------------------
1.59 cvs 2870: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18 cvs 2871: attribute string.
2872: ----------------------------------------------------------------------*/
1.79 cvs 2873: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
2874: PresentationContext context,
2875: char *cssRule, CSSInfoPtr css,
2876: ThotBool isHTML)
1.18 cvs 2877: {
2878: unsigned int savedtype = 0;
2879: ThotBool moved;
1.1 cvs 2880:
1.18 cvs 2881: /* move the BODY rule to the HTML element */
2882: moved = (context->type == HTML_EL_BODY && isHTML);
2883: if (moved)
2884: {
2885: if (element)
2886: element = TtaGetMainRoot (context->doc);
2887: else
2888: {
2889: savedtype = context->type;
1.83 cvs 2890: context->type = HTML_EL_Document;
1.1 cvs 2891: }
2892: }
2893:
1.82 cvs 2894: cssRule = SkipBlanksAndComments (cssRule);
2895: if (!strncasecmp (cssRule, "scroll", 6))
1.18 cvs 2896: cssRule = SkipWord (cssRule);
1.82 cvs 2897: else if (!strncasecmp (cssRule, "fixed", 5))
1.18 cvs 2898: cssRule = SkipWord (cssRule);
2899:
1.1 cvs 2900: /* restore the refered element */
2901: if (moved && !element)
2902: context->type = savedtype;
1.18 cvs 2903: return (cssRule);
1.1 cvs 2904: }
2905:
2906: /*----------------------------------------------------------------------
1.59 cvs 2907: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
1.1 cvs 2908: attribute string.
2909: ----------------------------------------------------------------------*/
1.79 cvs 2910: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
2911: PresentationContext context,
2912: char *cssRule, CSSInfoPtr css,
2913: ThotBool isHTML)
1.1 cvs 2914: {
1.18 cvs 2915: PresentationValue repeat;
2916: unsigned int savedtype = 0;
2917: ThotBool moved;
2918: ThotBool ok;
1.1 cvs 2919:
2920: /* move the BODY rule to the HTML element */
2921: moved = (context->type == HTML_EL_BODY && isHTML);
2922: if (moved)
2923: {
2924: if (element)
2925: element = TtaGetMainRoot (context->doc);
2926: else
2927: {
2928: savedtype = context->type;
1.83 cvs 2929: context->type = HTML_EL_Document;
1.1 cvs 2930: }
2931: }
2932:
1.82 cvs 2933: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 2934: ok = TRUE;
1.82 cvs 2935: if (!strncasecmp (cssRule, "left", 4))
1.18 cvs 2936: cssRule = SkipWord (cssRule);
1.82 cvs 2937: else if (!strncasecmp (cssRule, "right", 5))
1.18 cvs 2938: cssRule = SkipWord (cssRule);
1.82 cvs 2939: else if (!strncasecmp (cssRule, "center", 6))
1.18 cvs 2940: cssRule = SkipWord (cssRule);
1.82 cvs 2941: else if (!strncasecmp (cssRule, "top", 3))
1.18 cvs 2942: cssRule = SkipWord (cssRule);
1.82 cvs 2943: else if (!strncasecmp (cssRule, "bottom", 6))
1.18 cvs 2944: cssRule = SkipWord (cssRule);
1.110 vatton 2945: else if (isdigit (*cssRule) || *cssRule == '.')
1.18 cvs 2946: cssRule = SkipWord (cssRule);
2947: else
2948: ok = FALSE;
2949:
1.116 vatton 2950: if (ok && DoApply)
1.18 cvs 2951: {
2952: /* force realsize for the background image */
2953: repeat.typed_data.value = STYLE_REALSIZE;
2954: repeat.typed_data.unit = STYLE_UNIT_REL;
2955: repeat.typed_data.real = FALSE;
1.117 vatton 2956: /* check if it's an important rule */
2957: if (tsch)
2958: cssRule = CheckImportantRule (cssRule, context);
1.18 cvs 2959: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
2960: }
2961:
2962: /* restore the refered element */
2963: if (moved && !element)
2964: context->type = savedtype;
2965: return (cssRule);
2966: }
2967:
2968: /*----------------------------------------------------------------------
1.59 cvs 2969: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 2970: ----------------------------------------------------------------------*/
1.79 cvs 2971: static char *ParseCSSBackground (Element element, PSchema tsch,
2972: PresentationContext context, char *cssRule,
2973: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2974: {
1.79 cvs 2975: char *ptr;
1.93 vatton 2976: int skippedNL;
1.18 cvs 2977:
1.82 cvs 2978: cssRule = SkipBlanksAndComments (cssRule);
2979: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 2980: {
1.71 cvs 2981: /* perhaps a Background Image */
1.82 cvs 2982: if (!strncasecmp (cssRule, "url", 3))
1.63 cvs 2983: cssRule = ParseCSSBackgroundImage (element, tsch, context, cssRule,
2984: css, isHTML);
1.18 cvs 2985: /* perhaps a Background Attachment */
1.82 cvs 2986: else if (!strncasecmp (cssRule, "scroll", 6) ||
2987: !strncasecmp (cssRule, "fixed", 5))
1.63 cvs 2988: cssRule = ParseCSSBackgroundAttachment (element, tsch, context,
2989: cssRule, css, isHTML);
1.18 cvs 2990: /* perhaps a Background Repeat */
1.82 cvs 2991: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
2992: !strncasecmp (cssRule, "repeat-y", 8) ||
2993: !strncasecmp (cssRule, "repeat-x", 8) ||
2994: !strncasecmp (cssRule, "repeat", 6))
2995: cssRule = ParseCSSBackgroundRepeat (element, tsch, context,
2996: cssRule, css, isHTML);
1.18 cvs 2997: /* perhaps a Background Position */
1.82 cvs 2998: else if (!strncasecmp (cssRule, "left", 4) ||
2999: !strncasecmp (cssRule, "right", 5) ||
3000: !strncasecmp (cssRule, "center", 6) ||
3001: !strncasecmp (cssRule, "top", 3) ||
3002: !strncasecmp (cssRule, "bottom", 6) ||
1.110 vatton 3003: isdigit (*cssRule) || *cssRule == '.')
1.63 cvs 3004: cssRule = ParseCSSBackgroundPosition (element, tsch, context,
3005: cssRule, css, isHTML);
1.18 cvs 3006: /* perhaps a Background Color */
3007: else
3008: {
1.93 vatton 3009: skippedNL = NewLineSkipped;
1.18 cvs 3010: /* check if the rule has been found */
3011: ptr = cssRule;
1.82 cvs 3012: cssRule = ParseCSSBackgroundColor (element, tsch, context,
3013: cssRule, css, isHTML);
1.43 cvs 3014: if (ptr == cssRule)
1.93 vatton 3015: {
3016: NewLineSkipped = skippedNL;
3017: /* rule not found */
3018: cssRule = SkipProperty (cssRule);
3019: }
1.18 cvs 3020: }
1.82 cvs 3021: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3022: }
3023: return (cssRule);
3024: }
3025:
1.59 cvs 3026: /*----------------------------------------------------------------------
1.60 cvs 3027: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 3028: ----------------------------------------------------------------------*/
1.79 cvs 3029: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
3030: PresentationContext context, char *cssRule,
3031: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 3032: {
3033: PresentationValue page;
3034:
3035: page.typed_data.unit = STYLE_UNIT_INVALID;
3036: page.typed_data.real = FALSE;
1.82 cvs 3037: cssRule = SkipBlanksAndComments (cssRule);
3038: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3039: {
3040: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3041: page.typed_data.value = STYLE_AUTO;
3042: }
1.82 cvs 3043: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3044: {
3045: page.typed_data.unit = STYLE_UNIT_REL;
3046: page.typed_data.value = STYLE_ALWAYS;
3047: }
1.82 cvs 3048: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3049: {
3050: page.typed_data.unit = STYLE_UNIT_REL;
3051: page.typed_data.value = STYLE_AVOID;
3052: }
1.82 cvs 3053: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 3054: {
3055: page.typed_data.unit = STYLE_UNIT_REL;
3056: page.typed_data.value = STYLE_PAGELEFT;
3057: }
1.82 cvs 3058: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3059: {
3060: page.typed_data.unit = STYLE_UNIT_REL;
3061: page.typed_data.value = STYLE_PAGERIGHT;
3062: }
1.82 cvs 3063: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3064: {
3065: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3066: page.typed_data.value = STYLE_INHERIT;
3067: }
3068: cssRule = SkipWord (cssRule);
3069: /* install the new presentation */
3070: if (page.typed_data.unit == STYLE_UNIT_REL &&
1.116 vatton 3071: page.typed_data.value == STYLE_ALWAYS && DoApply)
1.117 vatton 3072: {
3073: /* check if it's an important rule */
3074: if (tsch)
3075: cssRule = CheckImportantRule (cssRule, context);
3076: TtaSetStylePresentation (PRPageBefore, element, tsch, context, page);
3077: }
1.59 cvs 3078: return (cssRule);
3079: }
3080:
3081: /*----------------------------------------------------------------------
1.60 cvs 3082: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 3083: ----------------------------------------------------------------------*/
1.79 cvs 3084: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
3085: PresentationContext context,
3086: char *cssRule, CSSInfoPtr css,
3087: ThotBool isHTML)
1.59 cvs 3088: {
3089: PresentationValue page;
3090:
3091: page.typed_data.unit = STYLE_UNIT_INVALID;
3092: page.typed_data.real = FALSE;
1.82 cvs 3093: cssRule = SkipBlanksAndComments (cssRule);
3094: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3095: {
3096: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3097: page.typed_data.value = STYLE_AUTO;
3098: }
1.82 cvs 3099: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 3100: {
3101: page.typed_data.unit = STYLE_UNIT_REL;
3102: page.typed_data.value = STYLE_ALWAYS;
3103: }
1.82 cvs 3104: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3105: {
3106: page.typed_data.unit = STYLE_UNIT_REL;
3107: page.typed_data.value = STYLE_AVOID;
3108: }
1.82 cvs 3109: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 3110: {
3111: page.typed_data.unit = STYLE_UNIT_REL;
3112: page.typed_data.value = STYLE_PAGELEFT;
3113: }
1.82 cvs 3114: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 3115: {
3116: page.typed_data.unit = STYLE_UNIT_REL;
3117: page.typed_data.value = STYLE_PAGERIGHT;
3118: }
1.82 cvs 3119: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3120: {
3121: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3122: page.typed_data.value = STYLE_INHERIT;
3123: }
3124: cssRule = SkipWord (cssRule);
3125: /* install the new presentation */
1.116 vatton 3126: /*if (page.typed_data.unit == STYLE_UNIT_REL && DoApply)
1.117 vatton 3127: {
3128: if (tsch)
3129: cssRule = CheckImportantRule (cssRule, context);
3130: TtaSetStylePresentation (PRPageAfter, element, tsch, context, page);
3131: }*/
1.59 cvs 3132: return (cssRule);
3133: }
3134:
3135: /*----------------------------------------------------------------------
1.60 cvs 3136: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 3137: ----------------------------------------------------------------------*/
1.79 cvs 3138: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
3139: PresentationContext context,
3140: char *cssRule, CSSInfoPtr css,
3141: ThotBool isHTML)
1.59 cvs 3142: {
3143: PresentationValue page;
3144:
3145: page.typed_data.unit = STYLE_UNIT_INVALID;
3146: page.typed_data.real = FALSE;
1.82 cvs 3147: cssRule = SkipBlanksAndComments (cssRule);
3148: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 3149: {
3150: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3151: page.typed_data.value = STYLE_AUTO;
3152: }
1.82 cvs 3153: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 3154: {
3155: page.typed_data.unit = STYLE_UNIT_REL;
3156: page.typed_data.value = STYLE_AVOID;
3157: }
1.82 cvs 3158: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 3159: {
3160: /*page.typed_data.unit = STYLE_UNIT_REL;*/
3161: page.typed_data.value = STYLE_INHERIT;
3162: }
3163: cssRule = SkipWord (cssRule);
3164: /* install the new presentation */
1.96 vatton 3165: /*if (page.typed_data.unit == STYLE_UNIT_REL &&
1.117 vatton 3166: page.typed_data.value == STYLE_AVOID && DoApply)
3167: {
3168: if (tsch)
3169: cssRule = CheckImportantRule (cssRule, context);
3170: TtaSetStylePresentation (PRPageInside, element, tsch, context, page);
3171: }*/
1.59 cvs 3172: return (cssRule);
3173: }
1.18 cvs 3174:
3175:
1.60 cvs 3176: /*----------------------------------------------------------------------
1.117 vatton 3177: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 3178: ----------------------------------------------------------------------*/
1.79 cvs 3179: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
3180: PresentationContext context, char *cssRule,
3181: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 3182: {
3183: PresentationValue width;
3184:
1.82 cvs 3185: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 3186: width.typed_data.value = 0;
3187: width.typed_data.unit = STYLE_UNIT_INVALID;
3188: width.typed_data.real = FALSE;
1.110 vatton 3189: if (isdigit (*cssRule) || *cssRule == '.')
1.60 cvs 3190: cssRule = ParseCSSUnit (cssRule, &width);
1.116 vatton 3191: if (width.typed_data.unit != STYLE_UNIT_INVALID && DoApply)
1.117 vatton 3192: {
3193: /* check if it's an important rule */
3194: if (tsch)
3195: cssRule = CheckImportantRule (cssRule, context);
3196: TtaSetStylePresentation (PRLineWeight, element, tsch, context, width);
3197: width.typed_data.value = 1;
3198: width.typed_data.unit = STYLE_UNIT_REL;
3199: }
1.60 cvs 3200: return (cssRule);
3201: }
3202:
1.18 cvs 3203: /************************************************************************
3204: * *
3205: * FUNCTIONS STYLE DECLARATIONS *
3206: * *
3207: ************************************************************************/
3208: /*
1.59 cvs 3209: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 3210: * e.g. "FONT-SIZE" must be placed before "FONT"
3211: */
3212: static CSSProperty CSSProperties[] =
3213: {
1.82 cvs 3214: {"font-family", ParseCSSFontFamily},
3215: {"font-style", ParseCSSFontStyle},
3216: {"font-variant", ParseCSSFontVariant},
3217: {"font-weight", ParseCSSFontWeight},
3218: {"font-size", ParseCSSFontSize},
3219: {"font", ParseCSSFont},
3220:
3221: {"color", ParseCSSForeground},
3222: {"background-color", ParseCSSBackgroundColor},
3223: {"background-image", ParseCSSBackgroundImage},
3224: {"background-repeat", ParseCSSBackgroundRepeat},
3225: {"background-attachment", ParseCSSBackgroundAttachment},
3226: {"background-position", ParseCSSBackgroundPosition},
3227: {"background", ParseCSSBackground},
3228:
3229: {"word-spacing", ParseCSSWordSpacing},
3230: {"letter-spacing", ParseCSSLetterSpacing},
3231: {"text-decoration", ParseCSSTextDecoration},
3232: {"vertical-align", ParseCSSVerticalAlign},
3233: {"text-transform", ParseCSSTextTransform},
3234: {"text-align", ParseCSSTextAlign},
3235: {"text-indent", ParseCSSTextIndent},
3236: {"line-height", ParseCSSLineSpacing},
3237:
1.112 quint 3238: {"direction", ParseCSSDirection},
1.113 quint 3239: {"unicode-bidi", ParseCSSUnicodeBidi},
1.112 quint 3240:
1.82 cvs 3241: {"margin-top", ParseCSSMarginTop},
3242: {"margin-right", ParseCSSMarginRight},
3243: {"margin-bottom", ParseCSSMarginBottom},
3244: {"margin-left", ParseCSSMarginLeft},
3245: {"margin", ParseCSSMargin},
3246:
3247: {"padding-top", ParseCSSPaddingTop},
3248: {"padding-right", ParseCSSPaddingRight},
3249: {"padding-bottom", ParseCSSPaddingBottom},
3250: {"padding-left", ParseCSSPaddingLeft},
3251: {"padding", ParseCSSPadding},
3252:
3253: {"border-top-width", ParseCSSBorderTopWidth},
3254: {"border-right-width", ParseCSSBorderRightWidth},
3255: {"border-bottom-width", ParseCSSBorderBottomWidth},
3256: {"border-left-width", ParseCSSBorderLeftWidth},
3257: {"border-width", ParseCSSBorderWidth},
3258: {"border-top-color", ParseCSSBorderColorTop},
3259: {"border-right-color", ParseCSSBorderColorRight},
3260: {"border-bottom-color", ParseCSSBorderColorBottom},
3261: {"border-left-color", ParseCSSBorderColorLeft},
3262: {"border-color", ParseCSSBorderColor},
3263: {"border-top-style", ParseCSSBorderStyleTop},
3264: {"border-right-style", ParseCSSBorderStyleRight},
3265: {"border-bottom-style", ParseCSSBorderStyleBottom},
3266: {"border-left-style", ParseCSSBorderStyleLeft},
3267: {"border-style", ParseCSSBorderStyle},
3268: {"border-top", ParseCSSBorderTop},
3269: {"border-right", ParseCSSBorderRight},
3270: {"border-bottom", ParseCSSBorderBottom},
3271: {"border-left", ParseCSSBorderLeft},
3272: {"border", ParseCSSBorder},
3273:
3274: {"width", ParseCSSWidth},
3275: {"height", ParseCSSHeight},
3276: {"float", ParseCSSFloat},
3277: {"clear", ParseCSSClear},
3278:
3279: {"display", ParseCSSDisplay},
3280: {"white-space", ParseCSSWhiteSpace},
3281:
3282: {"list-style-type", ParseCSSListStyleType},
3283: {"list-style-image", ParseCSSListStyleImage},
3284: {"list-style-position", ParseCSSListStylePosition},
3285: {"list-style", ParseCSSListStyle},
3286:
3287: {"page-break-before", ParseCSSPageBreakBefore},
3288: {"page-break-after", ParseCSSPageBreakAfter},
3289: {"page-break-inside", ParseCSSPageBreakInside},
1.60 cvs 3290:
3291: /* SVG extensions */
1.82 cvs 3292: {"stroke-width", ParseSVGStrokeWidth},
3293: {"stroke", ParseSVGStroke},
3294: {"fill", ParseSVGFill}
1.18 cvs 3295: };
3296: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
3297:
3298: /*----------------------------------------------------------------------
1.59 cvs 3299: ParseCSSRule: parse a CSS Style string
1.18 cvs 3300: we expect the input string describing the style to be of the
1.59 cvs 3301: form: PRORPERTY: DESCRIPTION [ ; PROPERTY: DESCRIPTION ] *
1.18 cvs 3302: but tolerate incorrect or incomplete input
3303: ----------------------------------------------------------------------*/
1.79 cvs 3304: static void ParseCSSRule (Element element, PSchema tsch,
3305: PresentationContext context, char *cssRule,
3306: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 3307: {
1.34 cvs 3308: DisplayMode dispMode;
1.79 cvs 3309: char *p = NULL;
1.18 cvs 3310: int lg;
1.34 cvs 3311: unsigned int i;
1.76 cvs 3312: ThotBool found;
1.18 cvs 3313:
1.34 cvs 3314: /* avoid too many redisplay */
3315: dispMode = TtaGetDisplayMode (context->doc);
3316: if (dispMode == DisplayImmediately)
3317: TtaSetDisplayMode (context->doc, DeferredDisplay);
3318:
1.82 cvs 3319: while (*cssRule != EOS)
1.18 cvs 3320: {
1.82 cvs 3321: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 3322: if (*cssRule == '{')
3323: {
3324: cssRule++;
3325: CSSParseError ("Invalid character", "{");
3326: cssRule = SkipBlanksAndComments (cssRule);
3327: }
1.18 cvs 3328:
3329: found = FALSE;
3330: /* look for the type of property */
3331: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
3332: {
1.82 cvs 3333: lg = strlen (CSSProperties[i].name);
3334: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
1.18 cvs 3335: {
1.86 cvs 3336: p = cssRule + lg;
1.18 cvs 3337: found = TRUE;
3338: i--;
3339: }
3340: }
3341:
3342: if (i == NB_CSSSTYLEATTRIBUTE)
3343: cssRule = SkipProperty (cssRule);
3344: else
3345: {
3346: /* update index and skip the ":" indicator if present */
1.86 cvs 3347: p = SkipBlanksAndComments (p);
3348: if (*p == ':')
1.18 cvs 3349: {
1.86 cvs 3350: p++;
3351: p = SkipBlanksAndComments (p);
1.74 cvs 3352: /* try to parse the value associated with this property */
3353: if (CSSProperties[i].parsing_function != NULL)
1.61 cvs 3354: {
1.75 cvs 3355: p = CSSProperties[i].parsing_function (element, tsch, context,
1.86 cvs 3356: p, css, isHTML);
1.74 cvs 3357: /* update index and skip the ";" separator if present */
3358: cssRule = p;
1.61 cvs 3359: }
1.18 cvs 3360: }
1.74 cvs 3361: else
3362: cssRule = SkipProperty (cssRule);
1.18 cvs 3363: }
1.89 cvs 3364:
1.18 cvs 3365: /* next property */
1.82 cvs 3366: cssRule = SkipBlanksAndComments (cssRule);
1.89 cvs 3367: if (*cssRule == '}')
3368: {
3369: cssRule++;
3370: CSSParseError ("Invalid character", "}");
3371: cssRule = SkipBlanksAndComments (cssRule);
3372: }
1.82 cvs 3373: if (*cssRule == ',' || *cssRule == ';')
1.18 cvs 3374: {
3375: cssRule++;
1.82 cvs 3376: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 3377: }
3378: }
1.34 cvs 3379:
3380: /* restore the display mode */
3381: if (dispMode == DisplayImmediately)
3382: TtaSetDisplayMode (context->doc, dispMode);
1.18 cvs 3383: }
1.1 cvs 3384:
1.111 cvs 3385: /*----------------------------------------------------------------------
3386: AddBorderStyleValue
3387: -----------------------------------------------------------------------*/
3388: static void AddBorderStyleValue (char *buffer, int value)
3389: {
3390: switch (value)
3391: {
3392: case STYLE_BORDERNONE:
3393: strcat (buffer, "none");
3394: break;
3395: case STYLE_BORDERHIDDEN:
3396: strcat (buffer, "hidden");
3397: break;
3398: case STYLE_BORDERDOTTED:
3399: strcat (buffer, "dotted");
3400: break;
3401: case STYLE_BORDERDASHED:
3402: strcat (buffer, "dashed");
3403: break;
3404: case STYLE_BORDERSOLID:
3405: strcat (buffer, "solid");
3406: break;
3407: case STYLE_BORDERDOUBLE:
3408: strcat (buffer, "double");
3409: break;
3410: case STYLE_BORDERGROOVE:
3411: strcat (buffer, "groove");
3412: break;
3413: case STYLE_BORDERRIDGE:
3414: strcat (buffer, "ridge");
3415: break;
3416: case STYLE_BORDERINSET:
3417: strcat (buffer, "inset");
3418: break;
3419: case STYLE_BORDEROUTSET:
3420: strcat (buffer, "outset");
3421: break;
3422: }
3423: }
1.1 cvs 3424:
3425: /*----------------------------------------------------------------------
1.59 cvs 3426: PToCss: translate a PresentationSetting to the
1.18 cvs 3427: equivalent CSS string, and add it to the buffer given as the
1.67 cvs 3428: argument. It is used when extracting the CSS string from actual
3429: presentation.
3430: el is the element for which the style rule is generated
1.18 cvs 3431:
3432: All the possible values returned by the presentation drivers are
3433: described in thotlib/include/presentation.h
3434: -----------------------------------------------------------------------*/
1.79 cvs 3435: void PToCss (PresentationSetting settings, char *buffer, int len, Element el)
1.1 cvs 3436: {
1.76 cvs 3437: ElementType elType;
1.18 cvs 3438: float fval = 0;
3439: unsigned short red, green, blue;
3440: int add_unit = 0;
3441: unsigned int unit, i;
3442: ThotBool real = FALSE;
3443:
1.82 cvs 3444: buffer[0] = EOS;
1.18 cvs 3445: if (len < 40)
3446: return;
3447:
3448: unit = settings->value.typed_data.unit;
3449: if (settings->value.typed_data.real)
3450: {
3451: real = TRUE;
3452: fval = (float) settings->value.typed_data.value;
3453: fval /= 1000;
3454: }
1.1 cvs 3455:
1.18 cvs 3456: switch (settings->type)
1.1 cvs 3457: {
1.18 cvs 3458: case PRVisibility:
3459: break;
1.111 cvs 3460: case PRHeight:
3461: if (real)
3462: sprintf (buffer, "height: %g", fval);
3463: else
3464: sprintf (buffer, "height: %d", settings->value.typed_data.value);
3465: add_unit = 1;
3466: break;
3467: case PRWidth:
3468: if (real)
3469: sprintf (buffer, "width: %g", fval);
3470: else
3471: sprintf (buffer, "width: %d", settings->value.typed_data.value);
3472: add_unit = 1;
3473: break;
3474: case PRMarginTop:
3475: if (real)
3476: sprintf (buffer, "margin-top: %g", fval);
3477: else
3478: sprintf (buffer, "margin-top: %d",settings->value.typed_data.value);
3479: add_unit = 1;
3480: break;
3481: case PRMarginBottom:
3482: if (real)
3483: sprintf (buffer, "margin-bottom: %g", fval);
3484: else
3485: sprintf (buffer, "margin-bottom: %d",
3486: settings->value.typed_data.value);
3487: add_unit = 1;
3488: break;
3489: case PRMarginLeft:
3490: if (real)
3491: sprintf (buffer, "margin-left: %g", fval);
3492: else
3493: sprintf (buffer, "margin-left: %d",
3494: settings->value.typed_data.value);
3495: add_unit = 1;
3496: break;
3497: case PRMarginRight:
3498: if (real)
3499: sprintf (buffer, "margin-right: %g", fval);
3500: else
3501: sprintf (buffer, "margin-right: %d",
3502: settings->value.typed_data.value);
3503: add_unit = 1;
3504: break;
3505: case PRPaddingTop:
3506: if (real)
3507: sprintf (buffer, "padding-top: %g", fval);
3508: else
3509: sprintf (buffer, "padding-top: %d",settings->value.typed_data.value);
3510: add_unit = 1;
3511: break;
3512: case PRPaddingBottom:
3513: if (real)
3514: sprintf (buffer, "padding-bottom: %g", fval);
3515: else
3516: sprintf (buffer, "padding-bottom: %d",
3517: settings->value.typed_data.value);
3518: add_unit = 1;
3519: break;
3520: case PRPaddingLeft:
3521: if (real)
3522: sprintf (buffer, "padding-left: %g", fval);
3523: else
3524: sprintf (buffer, "padding-left: %d",
3525: settings->value.typed_data.value);
3526: add_unit = 1;
3527: break;
3528: case PRPaddingRight:
3529: if (real)
3530: sprintf (buffer, "padding-right: %g", fval);
3531: else
3532: sprintf (buffer, "padding-right: %d",
3533: settings->value.typed_data.value);
3534: add_unit = 1;
3535: break;
3536: case PRBorderTopWidth:
3537: if (real)
3538: sprintf (buffer, "border-top-width: %g", fval);
3539: else
3540: sprintf (buffer, "border-top-width: %d",
3541: settings->value.typed_data.value);
3542: add_unit = 1;
3543: break;
3544: case PRBorderBottomWidth:
3545: if (real)
3546: sprintf (buffer, "border-bottom-width: %g", fval);
3547: else
3548: sprintf (buffer, "border-bottom-width: %d",
3549: settings->value.typed_data.value);
3550: add_unit = 1;
3551: break;
3552: case PRBorderLeftWidth:
3553: if (real)
3554: sprintf (buffer, "border-left-width: %g", fval);
3555: else
3556: sprintf (buffer, "border-left-width: %d",
3557: settings->value.typed_data.value);
3558: add_unit = 1;
3559: break;
3560: case PRBorderRightWidth:
3561: if (real)
3562: sprintf (buffer, "border-right-width: %g", fval);
3563: else
3564: sprintf (buffer, "border-right-width: %d",
3565: settings->value.typed_data.value);
3566: add_unit = 1;
3567: break;
3568: case PRBorderTopColor:
3569: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3570: elType = TtaGetElementType(el);
3571: sprintf (buffer, "border-top-color: #%02X%02X%02X", red, green, blue);
3572: break;
3573: case PRBorderRightColor:
3574: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3575: elType = TtaGetElementType(el);
3576: sprintf (buffer, "border-right-color: #%02X%02X%02X", red, green, blue);
3577: break;
3578: case PRBorderBottomColor:
3579: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3580: elType = TtaGetElementType(el);
3581: sprintf (buffer, "border-bottom-color: #%02X%02X%02X", red, green, blue);
1.18 cvs 3582: break;
1.111 cvs 3583: case PRBorderLeftColor:
3584: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
3585: elType = TtaGetElementType(el);
3586: sprintf (buffer, "border-left-color: #%02X%02X%02X", red, green, blue);
1.20 cvs 3587: break;
1.111 cvs 3588: case PRBorderTopStyle:
3589: strcpy (buffer, "border-top-style: ");
3590: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3591: break;
3592: case PRBorderRightStyle:
3593: strcpy (buffer, "border-right-style: ");
3594: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3595: break;
3596: case PRBorderBottomStyle:
3597: strcpy (buffer, "border-bottom-style: ");
3598: AddBorderStyleValue (buffer, settings->value.typed_data.value);
3599: break;
3600: case PRBorderLeftStyle:
3601: strcpy (buffer, "border-left-style: ");
3602: AddBorderStyleValue (buffer, settings->value.typed_data.value);
1.18 cvs 3603: break;
3604: case PRSize:
3605: if (unit == STYLE_UNIT_REL)
3606: {
3607: if (real)
3608: {
1.82 cvs 3609: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 3610: add_unit = 1;
3611: }
3612: else
3613: switch (settings->value.typed_data.value)
3614: {
3615: case 1:
1.82 cvs 3616: strcpy (buffer, "font-size: xx-small");
1.18 cvs 3617: break;
3618: case 2:
1.82 cvs 3619: strcpy (buffer, "font-size: x-small");
1.18 cvs 3620: break;
3621: case 3:
1.82 cvs 3622: strcpy (buffer, "font-size: small");
1.18 cvs 3623: break;
3624: case 4:
1.82 cvs 3625: strcpy (buffer, "font-size: medium");
1.18 cvs 3626: break;
3627: case 5:
1.82 cvs 3628: strcpy (buffer, "font-size: large");
1.18 cvs 3629: break;
3630: case 6:
1.82 cvs 3631: strcpy (buffer, "font-size: x-large");
1.18 cvs 3632: break;
3633: case 7:
3634: case 8:
3635: case 9:
3636: case 10:
3637: case 11:
3638: case 12:
1.82 cvs 3639: strcpy (buffer, "font-size: xx-large");
1.18 cvs 3640: break;
3641: }
3642: }
3643: else
3644: {
3645: if (real)
1.82 cvs 3646: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 3647: else
1.82 cvs 3648: sprintf (buffer, "font-size: %d",
1.67 cvs 3649: settings->value.typed_data.value);
1.18 cvs 3650: add_unit = 1;
3651: }
3652: break;
1.111 cvs 3653: case PRStyle:
3654: switch (settings->value.typed_data.value)
3655: {
3656: case STYLE_FONT_ROMAN:
3657: strcpy (buffer, "font-style: normal");
3658: break;
3659: case STYLE_FONT_ITALICS:
3660: strcpy (buffer, "font-style: italic");
3661: break;
3662: case STYLE_FONT_OBLIQUE:
3663: strcpy (buffer, "font-style: oblique");
3664: break;
3665: }
3666: break;
3667: case PRWeight:
3668: switch (settings->value.typed_data.value)
3669: {
3670: case STYLE_WEIGHT_BOLD:
3671: strcpy (buffer, "font-weight: bold");
3672: break;
3673: case STYLE_WEIGHT_NORMAL:
3674: strcpy (buffer, "font-weight: normal");
3675: break;
3676: }
3677: break;
3678: case PRFont:
3679: switch (settings->value.typed_data.value)
3680: {
3681: case STYLE_FONT_HELVETICA:
3682: strcpy (buffer, "font-family: helvetica");
3683: break;
3684: case STYLE_FONT_TIMES:
3685: strcpy (buffer, "font-family: times");
3686: break;
3687: case STYLE_FONT_COURIER:
3688: strcpy (buffer, "font-family: courier");
3689: break;
3690: }
3691: break;
1.18 cvs 3692: case PRUnderline:
3693: switch (settings->value.typed_data.value)
3694: {
3695: case STYLE_UNDERLINE:
1.82 cvs 3696: strcpy (buffer, "text-decoration: underline");
1.18 cvs 3697: break;
3698: case STYLE_OVERLINE:
1.82 cvs 3699: strcpy (buffer, "text-decoration: overline");
1.18 cvs 3700: break;
3701: case STYLE_CROSSOUT:
1.82 cvs 3702: strcpy (buffer, "text-decoration: line-through");
1.18 cvs 3703: break;
3704: }
3705: break;
1.111 cvs 3706: case PRThickness:
3707: break;
1.18 cvs 3708: case PRIndent:
3709: if (real)
1.82 cvs 3710: sprintf (buffer, "text-indent: %g", fval);
1.18 cvs 3711: else
1.82 cvs 3712: sprintf (buffer, "text-indent: %d",
1.67 cvs 3713: settings->value.typed_data.value);
1.18 cvs 3714: add_unit = 1;
3715: break;
3716: case PRLineSpacing:
3717: if (real)
1.82 cvs 3718: sprintf (buffer, "line-height: %g", fval);
1.1 cvs 3719: else
1.82 cvs 3720: sprintf (buffer, "line-height: %d",
1.67 cvs 3721: settings->value.typed_data.value);
1.18 cvs 3722: add_unit = 1;
3723: break;
1.111 cvs 3724: case PRDepth:
3725: break;
1.18 cvs 3726: case PRAdjust:
3727: switch (settings->value.typed_data.value)
1.1 cvs 3728: {
1.18 cvs 3729: case STYLE_ADJUSTLEFT:
1.82 cvs 3730: strcpy (buffer, "text-align: left");
1.18 cvs 3731: break;
3732: case STYLE_ADJUSTRIGHT:
1.82 cvs 3733: strcpy (buffer, "text-align: right");
1.18 cvs 3734: break;
3735: case STYLE_ADJUSTCENTERED:
1.82 cvs 3736: strcpy (buffer, "text-align: center");
1.18 cvs 3737: break;
3738: case STYLE_ADJUSTLEFTWITHDOTS:
1.82 cvs 3739: strcpy (buffer, "text-align: left");
1.81 cvs 3740: break;
3741: case STYLE_ADJUSTJUSTIFY:
1.82 cvs 3742: strcpy (buffer, "text-align: justify");
1.112 quint 3743: break;
3744: }
3745: break;
3746: case PRDirection:
3747: switch (settings->value.typed_data.value)
3748: {
3749: case STYLE_LEFTTORIGHT:
3750: strcpy (buffer, "direction: ltr");
3751: break;
3752: case STYLE_RIGHTTOLEFT:
3753: strcpy (buffer, "direction: rtl");
1.113 quint 3754: break;
3755: }
3756: break;
3757: case PRUnicodeBidi:
3758: switch (settings->value.typed_data.value)
3759: {
3760: case STYLE_BIDINORMAL:
3761: strcpy (buffer, "unicode-bidi: normal");
3762: break;
3763: case STYLE_BIDIEMBED:
3764: strcpy (buffer, "unicode-bidi: embed");
3765: break;
3766: case STYLE_BIDIOVERRIDE:
3767: strcpy (buffer, "unicode-bidi: bidi-override");
1.18 cvs 3768: break;
1.1 cvs 3769: }
1.18 cvs 3770: break;
1.111 cvs 3771: case PRLineStyle:
3772: break;
1.126 ! vatton 3773: case PRDisplay:
! 3774: switch (settings->value.typed_data.value)
! 3775: {
! 3776: case STYLE_DISPLAYINLINE:
! 3777: strcpy (buffer, "display: inline");
! 3778: break;
! 3779: case STYLE_DISPLAYBLOCK:
! 3780: strcpy (buffer, "display: block");
! 3781: break;
! 3782: case STYLE_DISPLAYLISTITEM:
! 3783: strcpy (buffer, "display: list-item");
! 3784: break;
! 3785: case STYLE_DISPLAYRUNIN:
! 3786: strcpy (buffer, "display: runin");
! 3787: break;
! 3788: case STYLE_DISPLAYCOMPACT:
! 3789: strcpy (buffer, "display: compact");
! 3790: break;
! 3791: case STYLE_DISPLAYMARKER:
! 3792: strcpy (buffer, "display: marker");
! 3793: break;
! 3794: default:
! 3795: break;
! 3796: }
! 3797: break;
1.111 cvs 3798: case PRLineWeight:
3799: elType = TtaGetElementType(el);
3800: #ifdef _SVG
3801: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG"))
3802: #endif /* _SVG */
3803: {
3804: if (real)
3805: sprintf (buffer, "stroke-width: %g", fval);
3806: else
3807: sprintf (buffer, "stroke-width: %d",
3808: settings->value.typed_data.value);
3809: }
3810: add_unit = 1;
1.18 cvs 3811: break;
3812: case PRFillPattern:
3813: break;
3814: case PRBackground:
3815: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3816: elType = TtaGetElementType(el);
1.100 vatton 3817: #ifdef _SVG
3818: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 3819: sprintf (buffer, "fill: #%02X%02X%02X", red, green, blue);
1.67 cvs 3820: else
1.100 vatton 3821: #endif /* _SVG */
1.82 cvs 3822: sprintf (buffer, "background-color: #%02X%02X%02X", red, green,
1.67 cvs 3823: blue);
1.18 cvs 3824: break;
3825: case PRForeground:
3826: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3827: elType = TtaGetElementType(el);
1.100 vatton 3828: #ifdef _SVG
3829: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "SVG") == 0)
1.82 cvs 3830: sprintf (buffer, "stroke: #%02X%02X%02X", red, green, blue);
1.67 cvs 3831: else
1.100 vatton 3832: #endif /* _SVG */
1.82 cvs 3833: sprintf (buffer, "color: #%02X%02X%02X", red, green, blue);
1.67 cvs 3834: break;
1.111 cvs 3835: case PRHyphenate:
1.18 cvs 3836: break;
1.111 cvs 3837: case PRVertOverflow:
1.18 cvs 3838: break;
1.111 cvs 3839: case PRHorizOverflow:
1.18 cvs 3840: break;
3841: case PRBackgroundPicture:
3842: if (settings->value.pointer != NULL)
1.82 cvs 3843: sprintf (buffer, "background-image: url(%s)",
1.67 cvs 3844: (char*)(settings->value.pointer));
1.1 cvs 3845: else
1.82 cvs 3846: sprintf (buffer, "background-image: none");
1.18 cvs 3847: break;
3848: case PRPictureMode:
3849: switch (settings->value.typed_data.value)
1.1 cvs 3850: {
1.18 cvs 3851: case STYLE_REALSIZE:
1.82 cvs 3852: sprintf (buffer, "background-repeat: no-repeat");
1.18 cvs 3853: break;
3854: case STYLE_REPEAT:
1.82 cvs 3855: sprintf (buffer, "background-repeat: repeat");
1.18 cvs 3856: break;
3857: case STYLE_VREPEAT:
1.82 cvs 3858: sprintf (buffer, "background-repeat: repeat-y");
1.18 cvs 3859: break;
3860: case STYLE_HREPEAT:
1.82 cvs 3861: sprintf (buffer, "background-repeat: repeat-x");
1.18 cvs 3862: break;
1.1 cvs 3863: }
1.18 cvs 3864: break;
3865: default:
3866: break;
1.1 cvs 3867: }
3868:
1.18 cvs 3869: if (add_unit)
1.1 cvs 3870: {
1.18 cvs 3871: /* add the unit string to the CSS string */
3872: for (i = 0; i < NB_UNITS; i++)
1.1 cvs 3873: {
1.18 cvs 3874: if (CSSUnitNames[i].unit == unit)
1.1 cvs 3875: {
1.82 cvs 3876: strcat (buffer, CSSUnitNames[i].sign);
1.18 cvs 3877: break;
1.1 cvs 3878: }
3879: }
3880: }
3881: }
3882:
3883: /*----------------------------------------------------------------------
1.59 cvs 3884: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18 cvs 3885: This function must be called when a specific style is applied to an
3886: element.
1.114 quint 3887: The parameter specificity is the specificity of the style, 0 if it is
3888: not really a CSS rule.
1.1 cvs 3889: ----------------------------------------------------------------------*/
1.79 cvs 3890: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.114 quint 3891: int specificity, ThotBool destroy)
1.1 cvs 3892: {
3893: PresentationContext context;
3894: ElementType elType;
1.14 cvs 3895: ThotBool isHTML;
1.1 cvs 3896:
3897: /* A rule applying to BODY is really meant to address HTML */
3898: elType = TtaGetElementType (el);
1.89 cvs 3899:
1.86 cvs 3900: /* store the current line for eventually reported errors */
3901: LineNumber = TtaGetElementLineNumber (el);
1.89 cvs 3902: if (destroy)
3903: /* no reported errors */
3904: ParsedDoc = 0;
3905: else if (ParsedDoc != doc)
3906: {
3907: /* update the context for reported errors */
3908: ParsedDoc = doc;
3909: DocURL = DocumentURLs[doc];
3910: }
1.82 cvs 3911: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
1.1 cvs 3912: /* create the context of the Specific presentation driver */
3913: context = TtaGetSpecificStyleContext (doc);
3914: if (context == NULL)
3915: return;
3916: context->type = elType.ElTypeNum;
1.114 quint 3917: context->cssSpecificity = specificity;
1.1 cvs 3918: context->destroy = destroy;
3919: /* Call the parser */
3920: ParseCSSRule (el, NULL, (PresentationContext) context, cssRule, NULL, isHTML);
3921: /* free the context */
3922: TtaFreeMemory(context);
3923: }
3924:
1.68 cvs 3925:
1.1 cvs 3926: /*----------------------------------------------------------------------
1.59 cvs 3927: ParseGenericSelector: Create a generic context for a given
1.1 cvs 3928: selector string. If the selector is made of multiple comma-
3929: separated selector items, it parses them one at a time and
3930: return the end of the selector string to be handled or NULL
3931: ----------------------------------------------------------------------*/
1.79 cvs 3932: static char *ParseGenericSelector (char *selector, char *cssRule,
3933: GenericContext ctxt, Document doc,
3934: CSSInfoPtr css)
3935: {
3936: ElementType elType;
3937: PSchema tsch;
1.119 vatton 3938: AttributeType attrType;
1.79 cvs 3939: char sel[MAX_ANCESTORS * 50];
1.118 vatton 3940: char *deb, *cur, c;
3941: char *schemaName, *mappedName;
1.79 cvs 3942: char *names[MAX_ANCESTORS];
3943: char *ids[MAX_ANCESTORS];
3944: char *classes[MAX_ANCESTORS];
3945: char *pseudoclasses[MAX_ANCESTORS];
3946: char *attrs[MAX_ANCESTORS];
3947: char *attrvals[MAX_ANCESTORS];
1.91 cvs 3948: int i, j, k, max;
1.125 vatton 3949: int att, maxAttr, kind;
1.118 vatton 3950: int specificity, xmlType;
1.79 cvs 3951: ThotBool isHTML;
3952: ThotBool level;
1.1 cvs 3953:
1.82 cvs 3954: sel[0] = EOS;
1.117 vatton 3955: specificity = 0;
1.1 cvs 3956: for (i = 0; i < MAX_ANCESTORS; i++)
3957: {
1.25 cvs 3958: names[i] = NULL;
3959: ids[i] = NULL;
3960: classes[i] = NULL;
3961: pseudoclasses[i] = NULL;
3962: attrs[i] = NULL;
3963: attrvals[i] = NULL;
3964:
3965: ctxt->name[i] = 0;
3966: ctxt->names_nb[i] = 0;
3967: ctxt->attrType[i] = 0;
3968: ctxt->attrText[i] = NULL;
1.1 cvs 3969: }
1.25 cvs 3970: ctxt->box = 0;
3971: ctxt->type = 0;
1.114 quint 3972: /* the specificity of the rule depends on the selector */
3973: ctxt->cssSpecificity = 0;
1.25 cvs 3974:
1.82 cvs 3975: selector = SkipBlanksAndComments (selector);
1.27 cvs 3976: cur = &sel[0];
1.25 cvs 3977: max = 0; /* number of loops */
1.1 cvs 3978: while (1)
3979: {
1.85 cvs 3980: /* point to the following word in sel[] */
1.27 cvs 3981: deb = cur;
1.25 cvs 3982: /* copy an item of the selector into sel[] */
1.1 cvs 3983: /* put one word in the sel buffer */
1.82 cvs 3984: while (*selector != EOS && *selector != ',' &&
3985: *selector != '.' && *selector != ':' &&
1.118 vatton 3986: *selector != '#' && *selector != '[' &&
3987: !TtaIsBlank (selector))
1.50 cvs 3988: *cur++ = *selector++;
1.82 cvs 3989: *cur++ = EOS; /* close the first string in sel[] */
3990: if (deb[0] != EOS)
1.117 vatton 3991: {
3992: names[0] = deb;
3993: specificity += 1;
3994: }
1.25 cvs 3995: else
1.27 cvs 3996: names[0] = NULL;
3997: classes[0] = NULL;
3998: pseudoclasses[0] = NULL;
3999: ids[0] = NULL;
4000: attrs[0] = NULL;
4001: attrvals[0] = NULL;
1.25 cvs 4002:
1.27 cvs 4003: /* now names[0] points to the beginning of the parsed item
1.25 cvs 4004: and cur to the next chain to be parsed */
1.118 vatton 4005: if (*selector == ':' || *selector == '.' ||
4006: *selector == '#' || *selector == '[')
1.85 cvs 4007: /* point to the following word in sel[] */
4008: deb = cur;
1.1 cvs 4009:
1.82 cvs 4010: if (*selector == '.')
1.1 cvs 4011: {
4012: selector++;
1.82 cvs 4013: while (*selector != EOS && *selector != ',' &&
4014: *selector != '.' && *selector != ':' &&
4015: !TtaIsBlank (selector))
1.1 cvs 4016: *cur++ = *selector++;
1.86 cvs 4017: /* close the word */
4018: *cur++ = EOS;
1.85 cvs 4019: /* point to the class in sel[] if it's valid name */
1.86 cvs 4020: if (deb[0] <= 64)
1.116 vatton 4021: {
4022: CSSParseError ("Invalid class", deb);
4023: DoApply = FALSE;
4024: }
1.86 cvs 4025: else
1.117 vatton 4026: {
4027: classes[0] = deb;
4028: specificity += 10;
4029: }
1.1 cvs 4030: }
1.82 cvs 4031: else if (*selector == ':')
1.1 cvs 4032: {
4033: selector++;
1.82 cvs 4034: while (*selector != EOS && *selector != ',' &&
4035: *selector != '.' && *selector != ':' &&
4036: !TtaIsBlank (selector))
1.50 cvs 4037: *cur++ = *selector++;
1.86 cvs 4038: /* close the word */
4039: *cur++ = EOS;
1.85 cvs 4040: /* point to the pseudoclass in sel[] if it's valid name */
1.86 cvs 4041: if (deb[0] <= 64)
1.116 vatton 4042: {
4043: CSSParseError ("Invalid pseudoclass", deb);
4044: DoApply = FALSE;
4045: }
1.86 cvs 4046: else
1.116 vatton 4047: {
4048: if (!strcmp (deb, "first-letter") ||
1.117 vatton 4049: !strcmp (deb, "first-line") ||
4050: !strcmp (deb, "before") ||
4051: !strcmp (deb, "after"))
1.116 vatton 4052: /* not supported */
4053: DoApply = FALSE;
1.117 vatton 4054: else
4055: specificity += 10;
1.116 vatton 4056: pseudoclasses[0]= deb;
4057: }
1.1 cvs 4058: }
1.82 cvs 4059: else if (*selector == '#')
1.1 cvs 4060: {
4061: selector++;
1.82 cvs 4062: while (*selector != EOS && *selector != ',' &&
1.118 vatton 4063: *selector != '.' && *selector != ':' &&
4064: !TtaIsBlank (selector))
1.50 cvs 4065: *cur++ = *selector++;
1.86 cvs 4066: /* close the word */
4067: *cur++ = EOS;
1.85 cvs 4068: /* point to the attribute in sel[] if it's valid name */
1.86 cvs 4069: if (deb[0] <= 64)
1.116 vatton 4070: {
4071: CSSParseError ("Invalid id", deb);
4072: DoApply = FALSE;
4073: }
1.86 cvs 4074: else
1.117 vatton 4075: {
4076: ids[0] = deb;
4077: specificity += 100;
4078: }
1.1 cvs 4079: }
1.82 cvs 4080: else if (*selector == '[')
1.1 cvs 4081: {
1.25 cvs 4082: selector++;
1.85 cvs 4083: while (*selector != EOS && *selector != ']' &&
4084: *selector != '=' && *selector != '~')
1.25 cvs 4085: *cur++ = *selector++;
1.86 cvs 4086: /* close the word */
4087: *cur++ = EOS;
1.85 cvs 4088: /* point to the attribute in sel[] if it's valid name */
1.86 cvs 4089: if (deb[0] <= 64)
1.116 vatton 4090: {
4091: CSSParseError ("Invalid attribute", deb);
4092: DoApply = FALSE;
4093: }
1.86 cvs 4094: else
1.117 vatton 4095: {
4096: attrs[0] = deb;
4097: specificity += 10;
4098: }
1.85 cvs 4099: if (*selector == '=')
1.25 cvs 4100: {
1.85 cvs 4101: /* look for a value "xxxx" */
1.118 vatton 4102: selector++;
4103: if (*selector != '"')
1.116 vatton 4104: {
4105: CSSParseError ("Invalid attribute value", deb);
4106: DoApply = FALSE;
4107: }
1.86 cvs 4108: else
1.25 cvs 4109: {
4110: /* we are now parsing the attribute value */
4111: selector++;
1.118 vatton 4112: deb = cur;
4113: while (*selector != '"')
4114: {
4115: if (*selector == EOS)
4116: {
4117: CSSParseError ("Invalid attribute value", deb);
4118: DoApply = FALSE;
4119: }
4120: else
4121: *cur++ = *selector++;
4122: }
4123: /* there is a value */
4124: if (*selector == '"')
4125: {
1.119 vatton 4126: selector++;
1.118 vatton 4127: *cur++ = EOS;
4128: attrvals[0] = deb;
4129: }
1.25 cvs 4130: }
4131: }
1.118 vatton 4132: /* end of the attribute */
4133: if (*selector != ']')
4134: {
4135: CSSParseError ("Invalid attribute", attrs[0]);
4136: DoApply = FALSE;
4137: }
4138: else
4139: selector++;
1.1 cvs 4140: }
4141:
1.82 cvs 4142: selector = SkipBlanksAndComments (selector);
1.25 cvs 4143: /* is it a multi-level selector? */
1.82 cvs 4144: if (*selector == EOS)
1.1 cvs 4145: /* end of the selector */
4146: break;
1.82 cvs 4147: else if (*selector == ',')
1.1 cvs 4148: {
4149: /* end of the current selector */
4150: selector++;
4151: break;
4152: }
1.25 cvs 4153: else
4154: {
4155: /* shifts the list to make room for the new name */
4156: max++; /* a new level in ancestor tables */
4157: if (max == MAX_ANCESTORS)
4158: /* abort the CSS parsing */
4159: return (selector);
4160: for (i = max; i > 0; i--)
4161: {
4162: names[i] = names[i - 1];
4163: ids[i] = ids[i - 1];
4164: classes[i] = classes[i - 1];
4165: attrs[i] = attrs[i - 1];
4166: attrvals[i] = attrvals[i - 1];
4167: pseudoclasses[i] = pseudoclasses[i - 1];
4168: }
4169: }
1.1 cvs 4170: }
4171:
4172: /* Now set up the context block */
1.25 cvs 4173: i = 0;
4174: k = 0;
4175: j = 0;
1.35 cvs 4176: maxAttr = 0;
1.91 cvs 4177: /* default schema name */
1.119 vatton 4178: ctxt->schema = NULL;
1.122 vatton 4179: elType.ElSSchema = NULL;
4180: schemaName = TtaGetSSchemaName(TtaGetDocumentSSchema (doc));
1.119 vatton 4181: if (!strcmp (schemaName, "HTML"))
4182: xmlType = XHTML_TYPE;
4183: else if (!strcmp (schemaName, "MathML"))
4184: xmlType = MATH_TYPE;
4185: else if (!strcmp (schemaName, "SVG"))
4186: xmlType = SVG_TYPE;
4187: else if (!strcmp (schemaName, "XLink"))
4188: xmlType = XLINK_TYPE;
4189: else if (!strcmp (schemaName, "Annot"))
4190: xmlType = ANNOT_TYPE;
4191: else
4192: xmlType = XML_TYPE;
1.25 cvs 4193: while (i <= max)
4194: {
4195: if (names[i])
4196: {
1.118 vatton 4197: /* get the element type of this name in the current document */
4198: MapXMLElementType (xmlType, names[i], &elType, &mappedName, &c, &level, doc);
1.25 cvs 4199: if (i == 0)
4200: {
1.106 cvs 4201: if (elType.ElSSchema == NULL)
4202: {
1.119 vatton 4203: /* Search in the list of loaded schemas */
1.106 cvs 4204: TtaGetXmlElementType (names[i], &elType, NULL, doc);
1.119 vatton 4205: if (elType.ElSSchema)
4206: {
4207: /* the element type concerns an imprted nature */
4208: schemaName = TtaGetSSchemaName(elType.ElSSchema);
4209: if (!strcmp (schemaName, "HTML"))
4210: xmlType = XHTML_TYPE;
4211: else if (!strcmp (schemaName, "MathML"))
4212: xmlType = MATH_TYPE;
4213: else if (!strcmp (schemaName, "SVG"))
4214: xmlType = SVG_TYPE;
4215: else if (!strcmp (schemaName, "XLink"))
4216: xmlType = XLINK_TYPE;
4217: else if (!strcmp (schemaName, "Annot"))
4218: xmlType = ANNOT_TYPE;
4219: else
4220: xmlType = XML_TYPE;
4221: }
1.118 vatton 4222: #ifdef XML_GENERIC
1.119 vatton 4223: else if (xmlType == XML_TYPE)
1.106 cvs 4224: {
4225: /* Creation of a new element type in the main schema */
4226: elType.ElSSchema = TtaGetDocumentSSchema (doc);
1.118 vatton 4227: TtaAppendXmlElement (names[i], &elType, &mappedName, doc);
1.106 cvs 4228: }
1.118 vatton 4229: #endif /* XML_GENERIC */
1.122 vatton 4230: else
4231: {
4232: if (xmlType != XHTML_TYPE)
4233: {
4234: MapXMLElementType (XHTML_TYPE, names[i], &elType,
4235: &mappedName, &c, &level, doc);
4236: if (elType.ElSSchema)
1.123 vatton 4237: elType.ElSSchema = GetXHTMLSSchema (doc);
1.122 vatton 4238: }
4239: if (elType.ElSSchema == NULL && xmlType != MATH_TYPE)
4240: {
4241: MapXMLElementType (MATH_TYPE, names[i], &elType,
4242: &mappedName, &c, &level, doc);
4243: if (elType.ElSSchema)
1.123 vatton 4244: elType.ElSSchema = GetMathMLSSchema (doc);
1.122 vatton 4245: }
4246: if (elType.ElSSchema == NULL && xmlType != SVG_TYPE)
4247: {
4248: MapXMLElementType (SVG_TYPE, names[i], &elType,
4249: &mappedName, &c, &level, doc);
4250: if (elType.ElSSchema)
1.123 vatton 4251: elType.ElSSchema = GetSVGSSchema (doc);
1.122 vatton 4252: }
4253: }
1.118 vatton 4254: }
1.119 vatton 4255:
1.118 vatton 4256: if (elType.ElSSchema == NULL)
4257: /* cannot apply these CSS rules */
4258: DoApply = FALSE;
4259: else
4260: {
4261: /* Store the element type */
4262: ctxt->type = elType.ElTypeNum;
4263: ctxt->name[0] = elType.ElTypeNum;
4264: ctxt->names_nb[0] = 0;
4265: ctxt->schema = elType.ElSSchema;
1.106 cvs 4266: }
1.25 cvs 4267: }
4268: else if (elType.ElTypeNum != 0)
4269: {
4270: /* look at the current context to see if the type is already
4271: stored */
1.121 vatton 4272: j = 1;
1.32 cvs 4273: while (j < k && ctxt->name[j] != elType.ElTypeNum)
1.25 cvs 4274: j++;
4275: if (j == k)
4276: {
4277: ctxt->name[j] = elType.ElTypeNum;
4278: if (j != 0)
1.121 vatton 4279: ctxt->names_nb[j] = 1;
1.25 cvs 4280: }
4281: else
4282: /* increment the number of ancestor levels */
4283: ctxt->names_nb[j]++;
4284: }
4285: else
1.117 vatton 4286: j = k;
1.25 cvs 4287: }
1.117 vatton 4288: else
4289: j = k;
1.1 cvs 4290:
1.25 cvs 4291: /* store attributes information */
4292: if (classes[i])
4293: {
4294: ctxt->attrText[j] = classes[i];
1.119 vatton 4295: if (xmlType == SVG_TYPE)
1.100 vatton 4296: ctxt->attrType[j] = SVG_ATTR_class;
1.119 vatton 4297: else if (xmlType == MATH_TYPE)
1.91 cvs 4298: ctxt->attrType[j] = MathML_ATTR_class;
1.119 vatton 4299: else if (xmlType == XHTML_TYPE)
1.107 cvs 4300: ctxt->attrType[j] = HTML_ATTR_Class;
4301: else
1.119 vatton 4302: #ifdef XML_GENERIC
1.107 cvs 4303: ctxt->attrType[j] = XML_ATTR_class;
4304: #else /* XML_GENERIC */
1.91 cvs 4305: ctxt->attrType[j] = HTML_ATTR_Class;
1.107 cvs 4306: #endif /* XML_GENERIC */
1.79 cvs 4307: /* add a new entry */
1.80 cvs 4308: maxAttr = i + 1;
1.25 cvs 4309: }
1.79 cvs 4310: if (pseudoclasses[i])
1.25 cvs 4311: {
4312: ctxt->attrText[j] = pseudoclasses[i];
1.119 vatton 4313: if (xmlType == SVG_TYPE)
1.100 vatton 4314: ctxt->attrType[j] = SVG_ATTR_PseudoClass;
1.119 vatton 4315: else if (xmlType == MATH_TYPE)
1.91 cvs 4316: ctxt->attrType[j] = MathML_ATTR_PseudoClass;
1.119 vatton 4317: else if (xmlType == XHTML_TYPE)
1.107 cvs 4318: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
4319: else
1.119 vatton 4320: #ifdef XML_GENERIC
1.107 cvs 4321: ctxt->attrType[j] = XML_ATTR_PseudoClass;
4322: #else /* XML_GENERIC */
1.91 cvs 4323: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.107 cvs 4324: #endif /* XML_GENERIC */
1.79 cvs 4325: /* add a new entry */
1.80 cvs 4326: maxAttr = i + 1;
1.25 cvs 4327: }
1.79 cvs 4328: if (ids[i])
1.25 cvs 4329: {
4330: ctxt->attrText[j] = ids[i];
1.119 vatton 4331: if (xmlType == SVG_TYPE)
1.100 vatton 4332: ctxt->attrType[j] = SVG_ATTR_id;
1.119 vatton 4333: else if (xmlType == MATH_TYPE)
1.91 cvs 4334: ctxt->attrType[j] = MathML_ATTR_id;
1.119 vatton 4335: else if (xmlType == XHTML_TYPE)
1.107 cvs 4336: ctxt->attrType[j] = HTML_ATTR_ID;
4337: else
1.119 vatton 4338: #ifdef XML_GENERIC
1.107 cvs 4339: ctxt->attrType[j] = XML_ATTR_id;
4340: #else /* XML_GENERIC */
1.91 cvs 4341: ctxt->attrType[j] = HTML_ATTR_ID;
1.107 cvs 4342: #endif /* XML_GENERIC */
1.80 cvs 4343: /* add a new entry */
4344: maxAttr = i + 1;
1.25 cvs 4345: }
1.79 cvs 4346: if (attrs[i])
1.25 cvs 4347: {
1.125 vatton 4348: /* it's an attribute */
1.119 vatton 4349: MapXMLAttribute (xmlType, attrs[i], names[i], &level, doc, &att);
4350: ctxt->attrType[j] = att;
1.125 vatton 4351: attrType.AttrSSchema = ctxt->schema;
4352: attrType.AttrTypeNum = att;
1.119 vatton 4353: if (i == 0 && att == 0 && ctxt->schema == NULL)
4354: {
1.125 vatton 4355: /* Not found -> search in the list of loaded schemas */
1.119 vatton 4356: attrType.AttrSSchema = NULL;
4357: TtaGetXmlAttributeType (attrs[i], &attrType, doc);
4358: ctxt->attrType[j] = attrType.AttrTypeNum;
4359: if (attrType.AttrSSchema)
1.125 vatton 4360: /* the element type concerns an imported nature */
4361: schemaName = TtaGetSSchemaName(attrType.AttrSSchema);
1.119 vatton 4362: #ifdef XML_GENERIC
4363: else if (xmlType == XML_TYPE)
4364: {
4365: /* The attribute is not yet present in the tree */
4366: /* Create a new global attribute */
4367: attrType.AttrSSchema = TtaGetDocumentSSchema (doc);
4368: TtaAppendXmlAttribute (attrs[i], &attrType, doc);
4369: }
4370: #endif /* XML_GENERIC */
4371:
4372: if (attrType.AttrSSchema == NULL)
4373: /* cannot apply these CSS rules */
4374: DoApply = FALSE;
4375: else
4376: ctxt->schema = elType.ElSSchema;
4377: }
1.125 vatton 4378: /* check the attribute type */
4379: if (!strcmp (schemaName, "HTML"))
4380: xmlType = XHTML_TYPE;
4381: else if (!strcmp (schemaName, "MathML"))
4382: xmlType = MATH_TYPE;
4383: else if (!strcmp (schemaName, "SVG"))
4384: xmlType = SVG_TYPE;
4385: else if (!strcmp (schemaName, "XLink"))
4386: xmlType = XLINK_TYPE;
4387: else if (!strcmp (schemaName, "Annot"))
4388: xmlType = ANNOT_TYPE;
4389: else
4390: xmlType = XML_TYPE;
4391: kind = TtaGetAttributeKind (attrType);
4392: if (kind == 0 && attrvals[i])
4393: {
4394: /* enumerated value */
4395: MapXMLAttributeValue (xmlType, attrvals[i], attrType, &kind);
4396: /* store the attribute value */
4397: ctxt->attrText[j] = (char *) kind;
4398: }
4399: else
4400: ctxt->attrText[j] = attrvals[i];
1.80 cvs 4401: maxAttr = i + 1;
1.25 cvs 4402: }
4403: i++;
1.117 vatton 4404: /* add a new entry */
4405: k++;
1.119 vatton 4406: if (i == 1 && ctxt->schema == NULL)
4407: /* use the document schema */
4408: ctxt->schema = TtaGetDocumentSSchema (doc);
1.1 cvs 4409: }
1.117 vatton 4410: /* set the selector specificity */
4411: ctxt->cssSpecificity = specificity;
1.25 cvs 4412: /* sort the list of ancestors by name order */
4413: max = k;
4414: i = 1;
4415: while (i < max)
1.28 cvs 4416: {
4417: for (k = i + 1; k < max; k++)
4418: if (ctxt->name[i] > ctxt->name[k])
4419: {
4420: j = ctxt->name[i];
4421: ctxt->name[i] = ctxt->name[k];
4422: ctxt->name[k] = j;
4423: j = ctxt->names_nb[i];
4424: ctxt->names_nb[i] = ctxt->names_nb[k];
4425: ctxt->names_nb[k] = j;
4426: j = ctxt->attrType[i];
4427: ctxt->attrType[i] = ctxt->attrType[k];
4428: ctxt->attrType[k] = j;
4429: cur = ctxt->attrText[i];
4430: ctxt->attrText[i] = ctxt->attrText[k];
4431: ctxt->attrText[k] = cur;
4432: }
4433: i++;
4434: }
1.84 cvs 4435:
1.25 cvs 4436: /* Get the schema name of the main element */
1.119 vatton 4437: schemaName = TtaGetSSchemaName (ctxt->schema);
4438: isHTML = (strcmp (schemaName, "HTML") == 0);
4439: tsch = GetPExtension (doc, ctxt->schema, css);
4440: if (tsch && cssRule)
4441: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
1.116 vatton 4442: /* future CSS rules should apply */
4443: DoApply = TRUE;
1.1 cvs 4444: return (selector);
4445: }
4446:
4447: /*----------------------------------------------------------------------
1.73 cvs 4448: ParseStyleDeclaration: parse a style declaration
4449: stored in the style element of a document
1.59 cvs 4450: We expect the style string to be of the form:
1.1 cvs 4451: [
4452: e.g: pinky, awful { color: pink, font-family: helvetica }
4453: ----------------------------------------------------------------------*/
1.79 cvs 4454: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
4455: CSSInfoPtr css, ThotBool destroy)
1.1 cvs 4456: {
1.79 cvs 4457: GenericContext ctxt;
4458: char *decl_end;
4459: char *sel_end;
4460: char *selector;
4461: char saved1;
4462: char saved2;
1.1 cvs 4463:
4464: /* separate the selectors string */
1.82 cvs 4465: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 4466: decl_end = cssRule;
1.82 cvs 4467: while (*decl_end != EOS && *decl_end != '{')
1.1 cvs 4468: decl_end++;
1.82 cvs 4469: if (*decl_end == EOS)
1.86 cvs 4470: {
4471: CSSParseError ("Invalid selector", cssRule);
4472: return;
4473: }
1.1 cvs 4474: /* verify and clean the selector string */
4475: sel_end = decl_end - 1;
1.82 cvs 4476: while (*sel_end == SPACE || *sel_end == BSPACE ||
4477: *sel_end == EOL || *sel_end == CR)
1.1 cvs 4478: sel_end--;
4479: sel_end++;
4480: saved1 = *sel_end;
1.82 cvs 4481: *sel_end = EOS;
1.1 cvs 4482: selector = cssRule;
4483:
4484: /* now, deal with the content ... */
4485: decl_end++;
4486: cssRule = decl_end;
1.82 cvs 4487: while (*decl_end != EOS && *decl_end != '}')
1.1 cvs 4488: decl_end++;
1.82 cvs 4489: if (*decl_end == EOS)
1.1 cvs 4490: {
1.86 cvs 4491: CSSParseError ("Invalid selector", cssRule);
1.1 cvs 4492: return;
4493: }
4494: saved2 = *decl_end;
1.82 cvs 4495: *decl_end = EOS;
1.1 cvs 4496:
4497: /*
4498: * parse the style attribute string and install the corresponding
4499: * presentation attributes on the new element
4500: */
4501: ctxt = TtaGetGenericStyleContext (doc);
4502: if (ctxt == NULL)
4503: return;
4504: ctxt->destroy = destroy;
4505:
1.82 cvs 4506: while ((selector != NULL) && (*selector != EOS))
1.25 cvs 4507: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css);
1.1 cvs 4508: TtaFreeMemory (ctxt);
4509:
4510: /* restore the string to its original form ! */
4511: *sel_end = saved1;
4512: *decl_end = saved2;
4513: }
4514:
4515: /************************************************************************
4516: * *
4517: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
4518: * *
4519: ************************************************************************/
4520:
4521: /*----------------------------------------------------------------------
1.59 cvs 4522: IsImplicitClassName: return wether the Class name is an
1.1 cvs 4523: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
4524: or an HTML context name.
4525: ----------------------------------------------------------------------*/
1.79 cvs 4526: int IsImplicitClassName (char *class, Document doc)
1.1 cvs 4527: {
1.79 cvs 4528: char name[200];
4529: char *cur = name;
4530: char *first;
4531: char save;
4532: SSchema schema;
1.1 cvs 4533:
4534: /* make a local copy */
1.82 cvs 4535: strncpy (name, class, 199);
1.1 cvs 4536: name[199] = 0;
4537:
4538: /* loop looking if each word is a GI */
4539: while (*cur != 0)
4540: {
4541: first = cur;
4542: cur = SkipWord (cur);
4543: save = *cur;
4544: *cur = 0;
4545: schema = NULL;
4546: if (MapGI (first, &schema, doc) == -1)
4547: {
4548: return (0);
4549: }
4550: *cur = save;
1.82 cvs 4551: cur = SkipBlanksAndComments (cur);
1.1 cvs 4552: }
4553: return (1);
4554: }
4555:
4556: /************************************************************************
4557: * *
1.114 quint 4558: * Functions needed for support of HTML: translate to CSS equivalent *
1.1 cvs 4559: * *
4560: ************************************************************************/
4561:
4562: /*----------------------------------------------------------------------
1.59 cvs 4563: HTMLSetBackgroundColor:
1.1 cvs 4564: ----------------------------------------------------------------------*/
1.79 cvs 4565: void HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1 cvs 4566: {
1.79 cvs 4567: char css_command[100];
1.1 cvs 4568:
1.82 cvs 4569: sprintf (css_command, "background-color: %s", color);
1.114 quint 4570: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4571: }
4572:
4573: /*----------------------------------------------------------------------
1.59 cvs 4574: HTMLSetBackgroundImage:
1.1 cvs 4575: repeat = repeat value
4576: image = url of background image
4577: ----------------------------------------------------------------------*/
1.79 cvs 4578: void HTMLSetBackgroundImage (Document doc, Element el, int repeat, char *image)
1.1 cvs 4579: {
1.79 cvs 4580: char css_command[400];
1.1 cvs 4581:
4582: /******* check buffer overflow ********/
1.82 cvs 4583: sprintf (css_command, "background-image: url(%s); background-repeat: ", image);
1.1 cvs 4584: if (repeat == STYLE_REPEAT)
1.82 cvs 4585: strcat (css_command, "repeat");
1.1 cvs 4586: else if (repeat == STYLE_HREPEAT)
1.82 cvs 4587: strcat (css_command, "repeat-x");
1.1 cvs 4588: else if (repeat == STYLE_VREPEAT)
1.82 cvs 4589: strcat (css_command, "repeat-y");
1.1 cvs 4590: else
1.82 cvs 4591: strcat (css_command, "no-repeat");
1.114 quint 4592: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4593: }
4594:
4595: /*----------------------------------------------------------------------
1.59 cvs 4596: HTMLSetForegroundColor:
1.1 cvs 4597: ----------------------------------------------------------------------*/
1.97 vatton 4598: void HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1 cvs 4599: {
1.79 cvs 4600: char css_command[100];
1.1 cvs 4601:
1.82 cvs 4602: sprintf (css_command, "color: %s", color);
1.114 quint 4603: ParseHTMLSpecificStyle (el, css_command, doc, 0, FALSE);
1.1 cvs 4604: }
4605:
4606: /*----------------------------------------------------------------------
1.59 cvs 4607: HTMLResetBackgroundColor:
1.1 cvs 4608: ----------------------------------------------------------------------*/
1.97 vatton 4609: void HTMLResetBackgroundColor (Document doc, Element el)
1.1 cvs 4610: {
1.79 cvs 4611: char css_command[100];
1.1 cvs 4612:
1.82 cvs 4613: sprintf (css_command, "background: red");
1.114 quint 4614: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4615: }
4616:
4617: /*----------------------------------------------------------------------
1.59 cvs 4618: HTMLResetBackgroundImage:
1.1 cvs 4619: ----------------------------------------------------------------------*/
1.97 vatton 4620: void HTMLResetBackgroundImage (Document doc, Element el)
1.1 cvs 4621: {
1.79 cvs 4622: char css_command[1000];
1.1 cvs 4623:
1.82 cvs 4624: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.114 quint 4625: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4626: }
4627:
4628: /*----------------------------------------------------------------------
1.59 cvs 4629: HTMLResetForegroundColor:
1.1 cvs 4630: ----------------------------------------------------------------------*/
1.97 vatton 4631: void HTMLResetForegroundColor (Document doc, Element el)
1.1 cvs 4632: {
1.79 cvs 4633: char css_command[100];
1.1 cvs 4634:
1.36 cvs 4635: /* it's not necessary to well know the current color but it must be valid */
1.82 cvs 4636: sprintf (css_command, "color: red");
1.114 quint 4637: ParseHTMLSpecificStyle (el, css_command, doc, 0, TRUE);
1.1 cvs 4638: }
4639:
4640: /*----------------------------------------------------------------------
1.59 cvs 4641: HTMLSetAlinkColor:
1.1 cvs 4642: ----------------------------------------------------------------------*/
1.97 vatton 4643: void HTMLSetAlinkColor (Document doc, char *color)
1.1 cvs 4644: {
1.79 cvs 4645: char css_command[100];
1.1 cvs 4646:
1.82 cvs 4647: sprintf (css_command, "a:link { color: %s }", color);
1.1 cvs 4648: ApplyCSSRules (NULL, css_command, doc, FALSE);
4649: }
4650:
4651: /*----------------------------------------------------------------------
1.59 cvs 4652: HTMLSetAactiveColor:
1.1 cvs 4653: ----------------------------------------------------------------------*/
1.97 vatton 4654: void HTMLSetAactiveColor (Document doc, char *color)
1.1 cvs 4655: {
1.79 cvs 4656: char css_command[100];
1.1 cvs 4657:
1.82 cvs 4658: sprintf (css_command, "a:active { color: %s }", color);
1.1 cvs 4659: ApplyCSSRules (NULL, css_command, doc, FALSE);
4660: }
4661:
4662: /*----------------------------------------------------------------------
1.59 cvs 4663: HTMLSetAvisitedColor:
1.1 cvs 4664: ----------------------------------------------------------------------*/
1.79 cvs 4665: void HTMLSetAvisitedColor (Document doc, char *color)
1.1 cvs 4666: {
1.79 cvs 4667: char css_command[100];
1.1 cvs 4668:
1.82 cvs 4669: sprintf (css_command, "a:visited { color: %s }", color);
1.1 cvs 4670: ApplyCSSRules (NULL, css_command, doc, FALSE);
4671: }
4672:
4673: /*----------------------------------------------------------------------
1.59 cvs 4674: HTMLResetAlinkColor:
1.1 cvs 4675: ----------------------------------------------------------------------*/
4676: void HTMLResetAlinkColor (Document doc)
4677: {
1.79 cvs 4678: char css_command[100];
1.1 cvs 4679:
1.82 cvs 4680: sprintf (css_command, "a:link { color: red }");
1.1 cvs 4681: ApplyCSSRules (NULL, css_command, doc, TRUE);
4682: }
4683:
4684: /*----------------------------------------------------------------------
1.59 cvs 4685: HTMLResetAactiveColor:
1.1 cvs 4686: ----------------------------------------------------------------------*/
4687: void HTMLResetAactiveColor (Document doc)
4688: {
1.79 cvs 4689: char css_command[100];
1.1 cvs 4690:
1.82 cvs 4691: sprintf (css_command, "a:active { color: red }");
1.1 cvs 4692: ApplyCSSRules (NULL, css_command, doc, TRUE);
4693: }
4694:
4695: /*----------------------------------------------------------------------
1.59 cvs 4696: HTMLResetAvisitedColor:
1.1 cvs 4697: ----------------------------------------------------------------------*/
4698: void HTMLResetAvisitedColor (Document doc)
4699: {
1.79 cvs 4700: char css_command[100];
1.1 cvs 4701:
1.82 cvs 4702: sprintf (css_command, "a:visited { color: red }");
1.1 cvs 4703: ApplyCSSRules (NULL, css_command, doc, TRUE);
4704: }
4705:
4706: /*----------------------------------------------------------------------
1.73 cvs 4707: ApplyCSSRules: parse a CSS Style description stored in the
1.1 cvs 4708: header of a HTML document.
4709: ----------------------------------------------------------------------*/
1.79 cvs 4710: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 4711: {
4712: CSSInfoPtr css;
4713:
4714: css = SearchCSS (doc, NULL);
4715: if (css == NULL)
4716: /* create the document css */
4717: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, NULL, NULL);
4718: ParseStyleDeclaration (el, cssRule, doc, css, destroy);
4719: }
4720:
4721: /*----------------------------------------------------------------------
1.59 cvs 4722: ReadCSSRules: is the front-end function called by the HTML parser
1.1 cvs 4723: when detecting a <STYLE TYPE="text/css"> indicating it's the
4724: beginning of a CSS fragment or when reading a file .css.
4725:
4726: The CSS parser has to handle <!-- ... --> constructs used to
4727: prevent prehistoric browser from displaying the CSS as a text
4728: content. It will stop on any sequence "<x" where x is different
4729: from ! and will return x as to the caller. Theorically x should
4730: be equal to / for the </STYLE> end of style.
4731:
4732: The parameter doc gives the document tree that contains CSS information.
4733: The parameter docRef gives the document to which CSS are to be applied.
4734: This function uses the current css context or creates it. It's able
1.23 cvs 4735: to work on the given buffer or call GetNextChar to read the parsed
1.1 cvs 4736: file.
1.86 cvs 4737: Parameter numberOfLinesRead indicates the number of lines already
4738: read in the file.
1.1 cvs 4739: Parameter withUndo indicates whether the changes made in the document
4740: structure and content have to be registered in the Undo queue or not
4741: ----------------------------------------------------------------------*/
1.86 cvs 4742: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer,
4743: int numberOfLinesRead, ThotBool withUndo)
1.1 cvs 4744: {
1.6 cvs 4745: DisplayMode dispMode;
1.82 cvs 4746: char c;
4747: char *cssRule, *base;
1.19 cvs 4748: int index;
1.1 cvs 4749: int CSSindex;
4750: int CSScomment;
4751: int import;
4752: int openRule;
1.93 vatton 4753: int newlines;
1.14 cvs 4754: ThotBool HTMLcomment;
1.102 vatton 4755: ThotBool toParse, eof, quoted;
1.36 cvs 4756: ThotBool ignoreMedia, media;
1.88 cvs 4757: ThotBool noRule, ignoreImport;
1.1 cvs 4758:
4759: CSScomment = MAX_CSS_LENGTH;
4760: HTMLcomment = FALSE;
4761: CSSindex = 0;
4762: toParse = FALSE;
4763: noRule = FALSE;
1.36 cvs 4764: media = FALSE;
1.88 cvs 4765: ignoreImport = FALSE;
1.1 cvs 4766: ignoreMedia = FALSE;
4767: import = MAX_CSS_LENGTH;
4768: eof = FALSE;
4769: openRule = 0;
1.82 cvs 4770: c = SPACE;
1.1 cvs 4771: index = 0;
1.93 vatton 4772: /* number of new lines parsed */
4773: newlines = 0;
1.6 cvs 4774: /* avoid too many redisplay */
4775: dispMode = TtaGetDisplayMode (docRef);
4776: if (dispMode == DisplayImmediately)
4777: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 4778:
4779: /* look for the CSS context */
4780: if (css == NULL)
4781: css = SearchCSS (docRef, NULL);
4782: if (css == NULL)
4783: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, NULL, NULL);
1.1 cvs 4784:
1.86 cvs 4785: /* register parsed CSS file and the document to which CSS are to be applied */
4786: ParsedDoc = docRef;
4787: if (css->url)
4788: DocURL = css->url;
4789: else
4790: /* the CSS source in within the document itself */
4791: DocURL = DocumentURLs[docRef];
4792: LineNumber = numberOfLinesRead + 1;
1.93 vatton 4793: NewLineSkipped = 0;
1.82 cvs 4794: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
4795: {
4796: c = buffer[index++];
4797: eof = (c == EOS);
4798: CSSbuffer[CSSindex] = c;
4799: if (CSScomment == MAX_CSS_LENGTH ||
4800: c == '*' || c == '/' || c == '<')
4801: {
4802: /* we're not within a comment or we're parsing * or / */
4803: switch (c)
4804: {
4805: case '@': /* perhaps an import primitive */
4806: import = CSSindex;
4807: break;
4808: case ';':
4809: if (import != MAX_CSS_LENGTH && !media)
4810: {
4811: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
4812: /* it's not an import */
4813: import = MAX_CSS_LENGTH;
4814: /* save the text */
4815: noRule = TRUE;
4816: }
4817: break;
4818: case '*':
4819: if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
4820: CSSbuffer[CSSindex - 1] == '/')
4821: /* start a comment */
4822: CSScomment = CSSindex - 1;
4823: break;
4824: case '/':
4825: if (CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
4826: CSSbuffer[CSSindex - 1] == '*')
4827: {
4828: /* close a comment:and ignore its contents */
4829: CSSindex = CSScomment - 1; /* will be incremented later */
4830: CSScomment = MAX_CSS_LENGTH;
1.93 vatton 4831: /* clean up the buffer */
1.103 vatton 4832: if (newlines && CSSindex > 0)
4833: while (CSSindex > 0 &&
4834: (CSSbuffer[CSSindex] == SPACE ||
4835: CSSbuffer[CSSindex] == BSPACE ||
4836: CSSbuffer[CSSindex] == EOL ||
4837: CSSbuffer[CSSindex] == TAB ||
4838: CSSbuffer[CSSindex] == __CR__))
1.93 vatton 4839: {
4840: if ( CSSbuffer[CSSindex] == EOL)
4841: {
4842: LineNumber ++;
4843: newlines --;
4844: }
4845: CSSindex--;
4846: }
1.82 cvs 4847: }
4848: else if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
4849: CSSbuffer[CSSindex - 1] == '<')
4850: {
4851: /* this is the closing tag ! */
4852: CSSindex -= 2; /* remove </ from the CSS string */
4853: noRule = TRUE;
4854: }
4855: break;
4856: case '<':
4857: if (CSScomment == MAX_CSS_LENGTH)
4858: {
4859: /* only if we're not parsing a comment */
4860: c = buffer[index++];
4861: eof = (c == EOS);
4862: if (c == '!')
4863: {
4864: /* CSS within an HTML comment */
4865: HTMLcomment = TRUE;
4866: CSSindex++;
4867: CSSbuffer[CSSindex] = c;
4868: }
4869: else if (c == EOS)
4870: CSSindex++;
4871: }
4872: break;
4873: case '-':
4874: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
4875: HTMLcomment)
4876: /* CSS within an HTML comment */
4877: noRule = TRUE;
4878: break;
4879: case '>':
4880: if (HTMLcomment)
4881: noRule = TRUE;
4882: break;
4883: case ' ':
4884: if (import != MAX_CSS_LENGTH && openRule == 0)
4885: media = !strncmp (&CSSbuffer[import+1], "media", 5);
4886: break;
4887: case '{':
4888: openRule++;
4889: if (import != MAX_CSS_LENGTH && openRule == 1 && media)
4890: {
4891: /* is it the screen concerned? */
4892: CSSbuffer[CSSindex+1] = EOS;
4893: if (TtaIsPrinting ())
4894: base = strstr (&CSSbuffer[import], "print");
4895: else
4896: base = strstr (&CSSbuffer[import], "screen");
4897: if (base == NULL)
4898: ignoreMedia = TRUE;
4899: noRule = TRUE;
4900: }
4901: break;
4902: case '}':
4903: openRule--;
4904: if (import != MAX_CSS_LENGTH && openRule == 0)
4905: {
4906: import = MAX_CSS_LENGTH;
4907: noRule = TRUE;
4908: ignoreMedia = FALSE;
4909: media = FALSE;
4910: }
4911: else
4912: toParse = TRUE;
4913: break;
4914: default:
1.86 cvs 4915: if (c == EOL)
1.93 vatton 4916: newlines++;
1.82 cvs 4917: break;
4918: }
4919: }
1.93 vatton 4920: else if (c == EOL)
4921: LineNumber++;
1.82 cvs 4922: if (c != CR)
4923: CSSindex++;
4924:
4925: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
4926: /* we're still parsing a comment: remove the text comment */
4927: CSSindex = CSScomment;
4928:
4929: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
4930: {
4931: CSSbuffer[CSSindex] = EOS;
4932: /* parse a not empty string */
4933: if (CSSindex > 0)
4934: {
1.50 cvs 4935: /* apply CSS rule if it's not just a saving of text */
4936: if (!noRule && !ignoreMedia)
1.88 cvs 4937: {
4938: /* future import rules must be ignored */
4939: ignoreImport = TRUE;
4940: ParseStyleDeclaration (NULL, CSSbuffer, docRef, css, FALSE);
1.93 vatton 4941: LineNumber += newlines;
4942: newlines = 0;
4943: NewLineSkipped = 0;
1.88 cvs 4944: }
1.82 cvs 4945: else if (import != MAX_CSS_LENGTH &&
4946: !strncasecmp (&CSSbuffer[import+1], "import", 6))
4947: {
4948: /* import section */
4949: cssRule = &CSSbuffer[import+7];
4950: cssRule = TtaSkipBlanks (cssRule);
1.93 vatton 4951: /* save the current line number */
4952: newlines += LineNumber;
1.82 cvs 4953: if (!strncasecmp (cssRule, "url", 3))
4954: {
1.50 cvs 4955: cssRule = &cssRule[3];
1.82 cvs 4956: cssRule = TtaSkipBlanks (cssRule);
4957: if (*cssRule == '(')
4958: {
4959: cssRule++;
4960: cssRule = TtaSkipBlanks (cssRule);
1.102 vatton 4961: quoted = (*cssRule == '"' || *cssRule == '\'');
4962: if (quoted)
4963: cssRule++;
1.82 cvs 4964: base = cssRule;
4965: while (*cssRule != EOS && *cssRule != ')')
4966: cssRule++;
1.102 vatton 4967: if (quoted)
4968: cssRule--;
1.82 cvs 4969: *cssRule = EOS;
1.88 cvs 4970: if (!ignoreImport)
1.115 quint 4971: LoadStyleSheet (base, docRef, NULL, css,
4972: css->media[docRef],
4973: css->category == CSS_USER_STYLE);
1.82 cvs 4974: }
4975: }
1.87 cvs 4976: else if (*cssRule == '"')
4977: {
1.88 cvs 4978: /*
4979: Do we have to accept single quotes?
4980: Double quotes are acceted here.
4981: Escaped quotes are not handled. See function SkipQuotedString
4982: */
1.87 cvs 4983: cssRule++;
4984: cssRule = TtaSkipBlanks (cssRule);
4985: base = cssRule;
4986: while (*cssRule != EOS && *cssRule != '"')
4987: cssRule++;
4988: *cssRule = EOS;
1.88 cvs 4989: if (!ignoreImport)
1.115 quint 4990: LoadStyleSheet (base, docRef, NULL, css,
4991: css->media[docRef],
4992: css->category == CSS_USER_STYLE);
1.82 cvs 4993: }
1.93 vatton 4994: /* restore the number of lines */
4995: LineNumber = newlines;
4996: newlines = 0;
1.82 cvs 4997: import = MAX_CSS_LENGTH;
4998: }
1.93 vatton 4999:
1.82 cvs 5000: }
5001: toParse = FALSE;
5002: noRule = FALSE;
5003: CSSindex = 0;
1.50 cvs 5004: }
1.82 cvs 5005: }
1.6 cvs 5006: /* restore the display mode */
5007: if (dispMode == DisplayImmediately)
1.82 cvs 5008: TtaSetDisplayMode (docRef, dispMode);
1.86 cvs 5009:
5010: /* Prepare the context for style attributes */
5011: DocURL = DocumentURLs[docRef];
5012: LineNumber = -1;
1.1 cvs 5013: return (c);
5014: }
1.89 cvs 5015:
Webmaster