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