Annotation of Amaya/amaya/styleparser.c, revision 1.82
1.1 cvs 1: /*
2: *
1.78 cvs 3: * (c) COPYRIGHT MIT and INRIA, 1996-2001
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"
20: #include "undo.h"
1.52 cvs 21: #include "registry.h"
1.25 cvs 22: #include "fetchHTMLname.h"
1.61 cvs 23: #include "GraphML.h"
1.1 cvs 24:
25: typedef struct _BackgroundImageCallbackBlock
26: {
27: Element el;
28: PSchema tsch;
29: union
30: {
31: PresentationContextBlock specific;
32: GenericContextBlock generic;
33: } context;
34: }
35: BackgroundImageCallbackBlock, *BackgroundImageCallbackPtr;
36:
37: #include "AHTURLTools_f.h"
38: #include "HTMLpresentation_f.h"
39: #include "HTMLimage_f.h"
40: #include "UIcss_f.h"
41: #include "css_f.h"
1.24 cvs 42: #include "fetchHTMLname_f.h"
1.1 cvs 43: #include "html2thot_f.h"
44: #include "styleparser_f.h"
45:
46: #define MAX_BUFFER_LENGTH 200
47: /*
48: * A PropertyParser is a function used to parse the
49: * description substring associated to a given style attribute
1.59 cvs 50: * e.g.: "red" for a color attribute or "12pt bold helvetica"
1.1 cvs 51: * for a font attribute.
52: */
1.79 cvs 53: typedef char *(*PropertyParser) (Element element,
1.56 cvs 54: PSchema tsch,
55: PresentationContext context,
1.79 cvs 56: char *cssRule,
1.56 cvs 57: CSSInfoPtr css,
58: ThotBool isHTML);
1.1 cvs 59:
60: /* Description of the set of CSS properties supported */
61: typedef struct CSSProperty
62: {
1.79 cvs 63: char *name;
1.25 cvs 64: PropertyParser parsing_function;
1.1 cvs 65: }
66: CSSProperty;
67:
68: struct unit_def
69: {
1.79 cvs 70: char *sign;
1.1 cvs 71: unsigned int unit;
72: };
73:
74: static struct unit_def CSSUnitNames[] =
75: {
1.82 ! cvs 76: {"pt", STYLE_UNIT_PT},
! 77: {"pc", STYLE_UNIT_PC},
! 78: {"in", STYLE_UNIT_IN},
! 79: {"cm", STYLE_UNIT_CM},
! 80: {"mm", STYLE_UNIT_MM},
! 81: {"em", STYLE_UNIT_EM},
! 82: {"px", STYLE_UNIT_PX},
! 83: {"ex", STYLE_UNIT_XHEIGHT},
! 84: {"%", STYLE_UNIT_PERCENT}
1.1 cvs 85: };
86:
87: #define NB_UNITS (sizeof(CSSUnitNames) / sizeof(struct unit_def))
88:
89: /*----------------------------------------------------------------------
90: SkipWord:
91: ----------------------------------------------------------------------*/
1.79 cvs 92: static char *SkipWord (char *ptr)
1.1 cvs 93: {
1.50 cvs 94: # ifdef _WINDOWS
95: /* iswalnum is supposed to be supported by the i18n veriosn of libc
96: use it when available */
1.82 ! cvs 97: while (iswalnum (*ptr) || *ptr == '-' || *ptr == '%')
1.50 cvs 98: # else /* !_WINDOWS */
1.82 ! cvs 99: while (isalnum((int)*ptr) || *ptr == '-' || *ptr == '%')
1.50 cvs 100: # endif /* !_WINDOWS */
101: ptr++;
1.1 cvs 102: return (ptr);
103: }
104:
105: /*----------------------------------------------------------------------
1.13 cvs 106: SkipBlanksAndComments:
107: ----------------------------------------------------------------------*/
1.82 ! cvs 108: char *SkipBlanksAndComments (char *ptr)
1.13 cvs 109: {
110: ptr = TtaSkipBlanks (ptr);
111: while (ptr[0] == '/' && ptr[1] == '*')
112: {
113: /* look for the end of the comment */
114: ptr = &ptr[2];
115: while (ptr[0] != EOS && (ptr[0] != '*' || ptr[1] != '/'))
116: ptr++;
117: if (ptr[0] != EOS)
118: ptr = &ptr[2];
119: ptr = TtaSkipBlanks (ptr);
120: }
121: return (ptr);
122: }
123:
1.49 cvs 124:
125: /*----------------------------------------------------------------------
1.1 cvs 126: SkipQuotedString:
127: ----------------------------------------------------------------------*/
1.79 cvs 128: static char *SkipQuotedString (char *ptr, char quote)
1.1 cvs 129: {
1.14 cvs 130: ThotBool stop;
1.1 cvs 131:
132: stop = FALSE;
133: while (!stop)
134: {
135: if (*ptr == quote)
136: {
137: ptr++;
138: stop = TRUE;
139: }
1.82 ! cvs 140: else if (*ptr == EOS)
1.1 cvs 141: stop = TRUE;
1.82 ! cvs 142: else if (*ptr == '\\')
1.1 cvs 143: /* escape character */
144: {
145: ptr++;
1.82 ! cvs 146: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
! 147: (*ptr >= 'a' && *ptr <= 'f'))
1.1 cvs 148: {
149: ptr++;
1.82 ! cvs 150: if ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'A' && *ptr <= 'F') ||
! 151: (*ptr >= 'a' && *ptr <= 'f'))
1.1 cvs 152: ptr++;
153: }
154: else
155: ptr++;
156: }
157: else
158: ptr++;
159: }
160: return (ptr);
161: }
162:
163: /*----------------------------------------------------------------------
164: SkipProperty:
165: ----------------------------------------------------------------------*/
1.79 cvs 166: char *SkipProperty (char *ptr)
1.1 cvs 167: {
1.82 ! cvs 168: while (*ptr != EOS && *ptr != ';' && *ptr != '}')
1.1 cvs 169: ptr++;
170: return (ptr);
171: }
172:
173: /*----------------------------------------------------------------------
1.64 cvs 174: ParseNumber:
175: parse a number and returns the corresponding value.
1.1 cvs 176: ----------------------------------------------------------------------*/
1.79 cvs 177: char *ParseNumber (char *cssRule, PresentationValue *pval)
1.1 cvs 178: {
179: int val = 0;
180: int minus = 0;
181: int valid = 0;
182: int f = 0;
1.14 cvs 183: ThotBool real = FALSE;
1.1 cvs 184:
185: pval->typed_data.unit = STYLE_UNIT_REL;
186: pval->typed_data.real = FALSE;
1.82 ! cvs 187: cssRule = SkipBlanksAndComments (cssRule);
! 188: if (*cssRule == '-')
1.1 cvs 189: {
190: minus = 1;
191: cssRule++;
1.82 ! cvs 192: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 193: }
194:
1.82 ! cvs 195: if (*cssRule == '+')
1.1 cvs 196: {
197: cssRule++;
1.82 ! cvs 198: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 199: }
200:
1.82 ! cvs 201: while ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 202: {
203: val *= 10;
1.82 ! cvs 204: val += *cssRule - '0';
1.1 cvs 205: cssRule++;
206: valid = 1;
207: }
208:
1.82 ! cvs 209: if (*cssRule == '.')
1.1 cvs 210: {
211: real = TRUE;
212: f = val;
213: val = 0;
214: cssRule++;
215: /* keep only 3 digits */
1.82 ! cvs 216: if (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 217: {
1.82 ! cvs 218: val = (*cssRule - '0') * 100;
1.1 cvs 219: cssRule++;
1.82 ! cvs 220: if (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 221: {
1.82 ! cvs 222: val += (*cssRule - '0') * 10;
1.1 cvs 223: cssRule++;
1.82 ! cvs 224: if ((*cssRule >= '0') && (*cssRule <= '9'))
1.1 cvs 225: {
1.82 ! cvs 226: val += *cssRule - '0';
1.1 cvs 227: cssRule++;
228: }
229: }
230:
1.82 ! cvs 231: while (*cssRule >= '0' && *cssRule <= '9')
1.1 cvs 232: cssRule++;
233: valid = 1;
234: }
235: }
236:
237: if (!valid)
238: {
239: pval->typed_data.unit = STYLE_UNIT_INVALID;
240: pval->typed_data.value = 0;
241: }
242: else
243: {
244: pval->typed_data.real = real;
245: if (real)
246: {
247: if (minus)
248: pval->typed_data.value = -(f * 1000 + val);
249: else
250: pval->typed_data.value = f * 1000 + val;
251: }
252: else
253: {
254: if (minus)
255: pval->typed_data.value = -val;
256: else
257: pval->typed_data.value = val;
258: }
1.64 cvs 259: }
260: return (cssRule);
261: }
262:
263: /*----------------------------------------------------------------------
264: ParseCSSUnit:
265: parse a CSS Unit substring and returns the corresponding
266: value and its unit.
267: ----------------------------------------------------------------------*/
1.82 ! cvs 268: char *ParseCSSUnit (char *cssRule, PresentationValue *pval)
1.64 cvs 269: {
270: unsigned int uni;
271:
272: pval->typed_data.unit = STYLE_UNIT_REL;
273: cssRule = ParseNumber (cssRule, pval);
274: if (pval->typed_data.unit == STYLE_UNIT_INVALID)
275: cssRule = SkipWord (cssRule);
276: else
277: {
1.82 ! cvs 278: cssRule = SkipBlanksAndComments (cssRule);
1.64 cvs 279: for (uni = 0; uni < NB_UNITS; uni++)
280: {
1.82 ! cvs 281: if (!strncasecmp (CSSUnitNames[uni].sign, cssRule,
! 282: strlen (CSSUnitNames[uni].sign)))
1.64 cvs 283: {
284: pval->typed_data.unit = CSSUnitNames[uni].unit;
1.82 ! cvs 285: return (cssRule + strlen (CSSUnitNames[uni].sign));
1.64 cvs 286: }
287: }
288: /* not in the list of predefined units */
289: pval->typed_data.unit = STYLE_UNIT_PX;
1.1 cvs 290: }
291: return (cssRule);
292: }
293:
1.43 cvs 294: /*----------------------------------------------------------------------
295: ParseBorderValue
296: ----------------------------------------------------------------------*/
1.79 cvs 297: static char *ParseBorderValue (char *cssRule, PresentationValue *border)
1.43 cvs 298: {
299: /* first parse the attribute string */
300: border->typed_data.value = 0;
1.44 cvs 301: border->typed_data.unit = STYLE_UNIT_INVALID;
1.43 cvs 302: border->typed_data.real = FALSE;
1.82 ! cvs 303: if (!strncasecmp (cssRule, "thin", 4))
1.43 cvs 304: {
1.44 cvs 305: border->typed_data.unit = STYLE_UNIT_PX;
1.43 cvs 306: border->typed_data.value = 1;
307: cssRule = SkipWord (cssRule);
308: }
1.82 ! cvs 309: else if (!strncasecmp (cssRule, "medium", 6))
1.43 cvs 310: {
1.44 cvs 311: border->typed_data.unit = STYLE_UNIT_PX;
1.43 cvs 312: border->typed_data.value = 3;
313: cssRule = SkipWord (cssRule);
314: }
1.82 ! cvs 315: else if (!strncasecmp (cssRule, "thick", 5))
1.43 cvs 316: {
1.44 cvs 317: border->typed_data.unit = STYLE_UNIT_PX;
1.43 cvs 318: border->typed_data.value = 5;
319: cssRule = SkipWord (cssRule);
320: }
1.82 ! cvs 321: else if (isdigit (*cssRule))
1.43 cvs 322: cssRule = ParseCSSUnit (cssRule, border);
323: return (cssRule);
324: }
325:
326: /*----------------------------------------------------------------------
327: ParseBorderStyle
328: ----------------------------------------------------------------------*/
1.79 cvs 329: static char *ParseBorderStyle (char *cssRule, PresentationValue *border)
1.43 cvs 330: {
331: /* first parse the attribute string */
332: border->typed_data.value = 0;
333: border->typed_data.unit = STYLE_UNIT_PX;
334: border->typed_data.real = FALSE;
1.82 ! cvs 335: if (!strncasecmp (cssRule, "none", 4))
1.43 cvs 336: border->typed_data.value = STYLE_BORDERNONE;
1.82 ! cvs 337: else if (!strncasecmp (cssRule, "hidden", 6))
1.43 cvs 338: border->typed_data.value = STYLE_BORDERHIDDEN;
1.82 ! cvs 339: else if (!strncasecmp (cssRule, "dotted", 6))
1.43 cvs 340: border->typed_data.value = STYLE_BORDERDOTTED;
1.82 ! cvs 341: else if (!strncasecmp (cssRule, "dashed", 6))
1.43 cvs 342: border->typed_data.value = STYLE_BORDERDASHED;
1.82 ! cvs 343: else if (!strncasecmp (cssRule, "solid", 5))
1.43 cvs 344: border->typed_data.value = STYLE_BORDERSOLID;
1.82 ! cvs 345: else if (!strncasecmp (cssRule, "double", 6))
1.43 cvs 346: border->typed_data.value = STYLE_BORDERDOUBLE;
1.82 ! cvs 347: else if (!strncasecmp (cssRule, "groove", 6))
1.43 cvs 348: border->typed_data.value = STYLE_BORDERGROOVE;
1.82 ! cvs 349: else if (!strncasecmp (cssRule, "ridge", 5))
1.43 cvs 350: border->typed_data.value = STYLE_BORDERRIDGE;
1.82 ! cvs 351: else if (!strncasecmp (cssRule, "inset", 5))
1.43 cvs 352: border->typed_data.value = STYLE_BORDERINSET;
1.82 ! cvs 353: else if (!strncasecmp (cssRule, "outset", 6))
1.43 cvs 354: border->typed_data.value = STYLE_BORDEROUTSET;
355: else
1.44 cvs 356: {
357: /* invalid style */
358: border->typed_data.unit = STYLE_UNIT_INVALID;
359: return (cssRule);
360: }
1.43 cvs 361: /* the value is parsed now */
362: cssRule = SkipWord (cssRule);
363: return (cssRule);
364: }
365:
366: /*----------------------------------------------------------------------
1.59 cvs 367: ParseCSSColor: parse a CSS color attribute string
1.43 cvs 368: we expect the input string describing the attribute to be
369: either a color name, a 3 tuple or an hexadecimal encoding.
370: The color used will be approximed from the current color
371: table
372: ----------------------------------------------------------------------*/
1.79 cvs 373: static char *ParseCSSColor (char *cssRule, PresentationValue * val)
1.43 cvs 374: {
1.79 cvs 375: char *ptr;
1.43 cvs 376: unsigned short redval = (unsigned short) -1;
377: unsigned short greenval = 0; /* composant of each RGB */
378: unsigned short blueval = 0; /* default to red if unknown ! */
379: int best = 0; /* best color in list found */
380:
1.82 ! cvs 381: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 382: val->typed_data.unit = STYLE_UNIT_INVALID;
383: val->typed_data.real = FALSE;
384: val->typed_data.value = 0;
1.57 cvs 385: ptr = TtaGiveRGB (cssRule, &redval, &greenval, &blueval);
386: if (ptr == cssRule)
1.43 cvs 387: {
1.57 cvs 388: cssRule = SkipProperty (cssRule);
1.43 cvs 389: val->typed_data.value = 0;
390: val->typed_data.unit = STYLE_UNIT_INVALID;
391: }
392: else
393: {
394: best = TtaGetThotColor (redval, greenval, blueval);
395: val->typed_data.value = best;
396: val->typed_data.unit = STYLE_UNIT_REL;
1.57 cvs 397: cssRule = ptr;
1.43 cvs 398: }
399: val->typed_data.real = FALSE;
1.65 cvs 400: return (cssRule);
1.43 cvs 401: }
1.1 cvs 402:
403: /*----------------------------------------------------------------------
1.59 cvs 404: ParseCSSBorderTopWidth: parse a CSS BorderTopWidth
1.1 cvs 405: attribute string.
406: ----------------------------------------------------------------------*/
1.79 cvs 407: static char *ParseCSSBorderTopWidth (Element element, PSchema tsch,
408: PresentationContext context,
409: char *cssRule, CSSInfoPtr css,
410: ThotBool isHTML)
1.1 cvs 411: {
1.41 cvs 412: PresentationValue border;
413:
1.82 ! cvs 414: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 415: cssRule = ParseBorderValue (cssRule, &border);
416: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 417: {
418: TtaSetStylePresentation (PRBorderTopWidth, element, tsch, context, border);
419: border.typed_data.value = 1;
420: border.typed_data.unit = STYLE_UNIT_REL;
421: }
1.1 cvs 422: return (cssRule);
423: }
424:
425: /*----------------------------------------------------------------------
1.59 cvs 426: ParseCSSBorderBottomWidth: parse a CSS BorderBottomWidth
1.1 cvs 427: attribute string.
428: ----------------------------------------------------------------------*/
1.79 cvs 429: static char *ParseCSSBorderBottomWidth (Element element, PSchema tsch,
430: PresentationContext context,
431: char *cssRule, CSSInfoPtr css,
432: ThotBool isHTML)
1.1 cvs 433: {
1.41 cvs 434: PresentationValue border;
435:
1.82 ! cvs 436: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 437: /* first parse the attribute string */
1.43 cvs 438: cssRule = ParseBorderValue (cssRule, &border);
439: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 440: {
441: TtaSetStylePresentation (PRBorderBottomWidth, element, tsch, context, border);
442: border.typed_data.value = 1;
443: border.typed_data.unit = STYLE_UNIT_REL;
444: }
1.1 cvs 445: return (cssRule);
446: }
447:
448: /*----------------------------------------------------------------------
1.59 cvs 449: ParseCSSBorderLeftWidth: parse a CSS BorderLeftWidth
1.1 cvs 450: attribute string.
451: ----------------------------------------------------------------------*/
1.79 cvs 452: static char *ParseCSSBorderLeftWidth (Element element, PSchema tsch,
453: PresentationContext context,
454: char *cssRule, CSSInfoPtr css,
455: ThotBool isHTML)
1.1 cvs 456: {
1.41 cvs 457: PresentationValue border;
458:
1.82 ! cvs 459: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 460: /* first parse the attribute string */
1.43 cvs 461: cssRule = ParseBorderValue (cssRule, &border);
462: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 463: {
464: TtaSetStylePresentation (PRBorderLeftWidth, element, tsch, context, border);
465: border.typed_data.value = 1;
466: border.typed_data.unit = STYLE_UNIT_REL;
467: }
1.1 cvs 468: return (cssRule);
469: }
470:
471: /*----------------------------------------------------------------------
1.59 cvs 472: ParseCSSBorderRightWidth: parse a CSS BorderRightWidth
1.1 cvs 473: attribute string.
474: ----------------------------------------------------------------------*/
1.79 cvs 475: static char *ParseCSSBorderRightWidth (Element element, PSchema tsch,
476: PresentationContext context,
477: char *cssRule, CSSInfoPtr css,
478: ThotBool isHTML)
1.1 cvs 479: {
1.41 cvs 480: PresentationValue border;
481:
1.82 ! cvs 482: cssRule = SkipBlanksAndComments (cssRule);
1.41 cvs 483: /* first parse the attribute string */
1.43 cvs 484: cssRule = ParseBorderValue (cssRule, &border);
485: if (border.typed_data.unit != STYLE_UNIT_INVALID)
1.44 cvs 486: {
487: TtaSetStylePresentation (PRBorderRightWidth, element, tsch, context, border);
488: border.typed_data.value = 1;
489: border.typed_data.unit = STYLE_UNIT_REL;
490: }
1.1 cvs 491: return (cssRule);
492: }
493:
494: /*----------------------------------------------------------------------
1.59 cvs 495: ParseCSSBorderWidth: parse a CSS BorderWidth
1.1 cvs 496: attribute string.
497: ----------------------------------------------------------------------*/
1.79 cvs 498: static char *ParseCSSBorderWidth (Element element, PSchema tsch,
499: PresentationContext context,
500: char *cssRule, CSSInfoPtr css,
501: ThotBool isHTML)
1.1 cvs 502: {
1.79 cvs 503: char *ptrT, *ptrR, *ptrB, *ptrL;
1.41 cvs 504:
1.82 ! cvs 505: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 506: /* First parse Border-Top */
507: ptrR = ParseCSSBorderTopWidth (element, tsch, context, ptrT, css, isHTML);
1.82 ! cvs 508: ptrR = SkipBlanksAndComments (ptrR);
! 509: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 510: {
511: cssRule = ptrR;
512: /* apply the Border-Top to all */
513: ptrR = ParseCSSBorderRightWidth (element, tsch, context, ptrT, css, isHTML);
514: ptrR = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
515: ptrR = ParseCSSBorderLeftWidth (element, tsch, context, ptrT, css, isHTML);
516: }
517: else
518: {
519: /* parse Border-Right */
520: ptrB = ParseCSSBorderRightWidth (element, tsch, context, ptrR, css, isHTML);
1.82 ! cvs 521: ptrB = SkipBlanksAndComments (ptrB);
! 522: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 523: {
524: cssRule = ptrB;
525: /* apply the Border-Top to Border-Bottom */
526: ptrB = ParseCSSBorderBottomWidth (element, tsch, context, ptrT, css, isHTML);
527: /* apply the Border-Right to Border-Left */
528: ptrB = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
529: }
530: else
531: {
532: /* parse Border-Bottom */
533: ptrL = ParseCSSBorderBottomWidth (element, tsch, context, ptrB, css, isHTML);
1.82 ! cvs 534: ptrL = SkipBlanksAndComments (ptrL);
! 535: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 536: {
537: cssRule = ptrL;
538: /* apply the Border-Right to Border-Left */
539: ptrL = ParseCSSBorderLeftWidth (element, tsch, context, ptrR, css, isHTML);
540: }
541: else
542: /* parse Border-Left */
543: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, ptrL, css, isHTML);
1.82 ! cvs 544: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 545: }
546: }
1.1 cvs 547: return (cssRule);
548: }
549:
550: /*----------------------------------------------------------------------
1.59 cvs 551: ParseCSSBorderColorTop: parse a CSS BorderColorTop
1.1 cvs 552: attribute string.
553: ----------------------------------------------------------------------*/
1.79 cvs 554: static char *ParseCSSBorderColorTop (Element element, PSchema tsch,
555: PresentationContext context,
556: char *cssRule, CSSInfoPtr css,
557: ThotBool isHTML)
1.1 cvs 558: {
1.43 cvs 559: PresentationValue best;
560:
561: cssRule = ParseCSSColor (cssRule, &best);
562: if (best.typed_data.unit != STYLE_UNIT_INVALID)
563: /* install the new presentation */
564: TtaSetStylePresentation (PRBorderTopColor, element, tsch, context, best);
1.65 cvs 565: return (cssRule);
1.1 cvs 566: }
567:
568: /*----------------------------------------------------------------------
1.59 cvs 569: ParseCSSBorderColorLeft: parse a CSS BorderColorLeft
1.42 cvs 570: attribute string.
571: ----------------------------------------------------------------------*/
1.79 cvs 572: static char *ParseCSSBorderColorLeft (Element element, PSchema tsch,
573: PresentationContext context,
574: char *cssRule, CSSInfoPtr css,
575: ThotBool isHTML)
1.42 cvs 576: {
1.43 cvs 577: PresentationValue best;
578:
579: cssRule = ParseCSSColor (cssRule, &best);
580: if (best.typed_data.unit != STYLE_UNIT_INVALID)
581: /* install the new presentation */
582: TtaSetStylePresentation (PRBorderLeftColor, element, tsch, context, best);
1.65 cvs 583: return (cssRule);
1.42 cvs 584: }
585:
586: /*----------------------------------------------------------------------
1.59 cvs 587: ParseCSSBorderColorBottom: parse a CSS BorderColorBottom
1.42 cvs 588: attribute string.
589: ----------------------------------------------------------------------*/
1.79 cvs 590: static char *ParseCSSBorderColorBottom (Element element, PSchema tsch,
591: PresentationContext context,
592: char *cssRule, CSSInfoPtr css,
593: ThotBool isHTML)
1.42 cvs 594: {
1.43 cvs 595: PresentationValue best;
596:
597: cssRule = ParseCSSColor (cssRule, &best);
598: if (best.typed_data.unit != STYLE_UNIT_INVALID)
599: /* install the new presentation */
600: TtaSetStylePresentation (PRBorderBottomColor, element, tsch, context, best);
1.65 cvs 601: return (cssRule);
1.42 cvs 602: }
603:
604: /*----------------------------------------------------------------------
1.59 cvs 605: ParseCSSBorderColorRight: parse a CSS BorderColorRight
1.1 cvs 606: attribute string.
607: ----------------------------------------------------------------------*/
1.79 cvs 608: static char *ParseCSSBorderColorRight (Element element, PSchema tsch,
609: PresentationContext context,
610: char *cssRule, CSSInfoPtr css,
611: ThotBool isHTML)
1.1 cvs 612: {
1.43 cvs 613: PresentationValue best;
614:
615: cssRule = ParseCSSColor (cssRule, &best);
616: if (best.typed_data.unit != STYLE_UNIT_INVALID)
617: /* install the new presentation */
618: TtaSetStylePresentation (PRBorderRightColor, element, tsch, context, best);
1.65 cvs 619: return (cssRule);
1.1 cvs 620: }
621:
622: /*----------------------------------------------------------------------
1.59 cvs 623: ParseCSSBorderColor: parse a CSS border-color
1.42 cvs 624: attribute string.
625: ----------------------------------------------------------------------*/
1.79 cvs 626: static char *ParseCSSBorderColor (Element element, PSchema tsch,
627: PresentationContext context,
628: char *cssRule, CSSInfoPtr css,
629: ThotBool isHTML)
1.42 cvs 630: {
1.79 cvs 631: char *ptrT, *ptrR, *ptrB, *ptrL;
1.42 cvs 632:
1.82 ! cvs 633: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 634: /* First parse Border-Top */
1.43 cvs 635: ptrR = ParseCSSBorderColorTop (element, tsch, context, ptrT, css, isHTML);
1.82 ! cvs 636: ptrR = SkipBlanksAndComments (ptrR);
! 637: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 638: {
639: cssRule = ptrR;
640: /* apply the Border-Top to all */
1.43 cvs 641: ptrR = ParseCSSBorderColorRight (element, tsch, context, ptrT, css, isHTML);
642: ptrR = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
643: ptrR = ParseCSSBorderColorLeft (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 644: }
645: else
646: {
647: /* parse Border-Right */
1.43 cvs 648: ptrB = ParseCSSBorderColorRight (element, tsch, context, ptrR, css, isHTML);
1.82 ! cvs 649: ptrB = SkipBlanksAndComments (ptrB);
! 650: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 651: {
652: cssRule = ptrB;
653: /* apply the Border-Top to Border-Bottom */
1.43 cvs 654: ptrB = ParseCSSBorderColorBottom (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 655: /* apply the Border-Right to Border-Left */
1.43 cvs 656: ptrB = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 657: }
658: else
659: {
660: /* parse Border-Bottom */
1.43 cvs 661: ptrL = ParseCSSBorderColorBottom (element, tsch, context, ptrB, css, isHTML);
1.82 ! cvs 662: ptrL = SkipBlanksAndComments (ptrL);
! 663: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 664: {
665: cssRule = ptrL;
666: /* apply the Border-Right to Border-Left */
1.43 cvs 667: ptrL = ParseCSSBorderColorLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 668: }
669: else
670: /* parse Border-Left */
1.43 cvs 671: cssRule = ParseCSSBorderColorLeft (element, tsch, context, ptrL, css, isHTML);
1.82 ! cvs 672: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 673: }
674: }
675: return (cssRule);
676: }
677:
678: /*----------------------------------------------------------------------
1.59 cvs 679: ParseCSSBorderStyleTop: parse a CSS BorderStyleTop
1.42 cvs 680: attribute string.
681: ----------------------------------------------------------------------*/
1.79 cvs 682: static char *ParseCSSBorderStyleTop (Element element, PSchema tsch,
683: PresentationContext context,
684: char *cssRule, CSSInfoPtr css,
685: ThotBool isHTML)
1.42 cvs 686: {
1.43 cvs 687: PresentationValue border;
688:
1.82 ! cvs 689: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 690: cssRule = ParseBorderStyle (cssRule, &border);
691: if (border.typed_data.unit != STYLE_UNIT_INVALID)
692: TtaSetStylePresentation (PRBorderTopStyle, element, tsch, context, border);
1.42 cvs 693: return (cssRule);
694: }
695:
696: /*----------------------------------------------------------------------
1.59 cvs 697: ParseCSSBorderStyleLeft: parse a CSS BorderStyleLeft
1.42 cvs 698: attribute string.
699: ----------------------------------------------------------------------*/
1.79 cvs 700: static char *ParseCSSBorderStyleLeft (Element element, PSchema tsch,
701: PresentationContext context,
702: char *cssRule, CSSInfoPtr css,
703: ThotBool isHTML)
1.42 cvs 704: {
1.43 cvs 705: PresentationValue border;
706:
1.82 ! cvs 707: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 708: cssRule = ParseBorderStyle (cssRule, &border);
709: if (border.typed_data.unit != STYLE_UNIT_INVALID)
710: TtaSetStylePresentation (PRBorderLeftStyle, element, tsch, context, border);
1.42 cvs 711: return (cssRule);
712: }
713:
714: /*----------------------------------------------------------------------
1.59 cvs 715: ParseCSSBorderStyleBottom: parse a CSS BorderStyleBottom
1.1 cvs 716: attribute string.
717: ----------------------------------------------------------------------*/
1.79 cvs 718: static char *ParseCSSBorderStyleBottom (Element element, PSchema tsch,
719: PresentationContext context,
720: char *cssRule, CSSInfoPtr css,
721: ThotBool isHTML)
1.1 cvs 722: {
1.43 cvs 723: PresentationValue border;
724:
1.82 ! cvs 725: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 726: cssRule = ParseBorderStyle (cssRule, &border);
727: if (border.typed_data.unit != STYLE_UNIT_INVALID)
728: TtaSetStylePresentation (PRBorderBottomStyle, element, tsch, context, border);
1.1 cvs 729: return (cssRule);
730: }
731:
732: /*----------------------------------------------------------------------
1.59 cvs 733: ParseCSSBorderStyleRight: parse a CSS BorderStyleRight
1.1 cvs 734: attribute string.
735: ----------------------------------------------------------------------*/
1.79 cvs 736: static char *ParseCSSBorderStyleRight (Element element, PSchema tsch,
737: PresentationContext context,
738: char *cssRule, CSSInfoPtr css,
739: ThotBool isHTML)
1.1 cvs 740: {
1.43 cvs 741: PresentationValue border;
742:
1.82 ! cvs 743: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 744: cssRule = ParseBorderStyle (cssRule, &border);
745: if (border.typed_data.unit != STYLE_UNIT_INVALID)
746: TtaSetStylePresentation (PRBorderRightStyle, element, tsch, context, border);
1.1 cvs 747: return (cssRule);
748: }
749:
750: /*----------------------------------------------------------------------
1.59 cvs 751: ParseCSSBorderStyleStyle: parse a CSS border-style
1.1 cvs 752: attribute string.
753: ----------------------------------------------------------------------*/
1.79 cvs 754: static char *ParseCSSBorderStyle (Element element, PSchema tsch,
755: PresentationContext context,
756: char *cssRule, CSSInfoPtr css,
757: ThotBool isHTML)
1.1 cvs 758: {
1.79 cvs 759: char *ptrT, *ptrR, *ptrB, *ptrL;
1.42 cvs 760:
1.82 ! cvs 761: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 762: /* First parse Border-Top */
1.43 cvs 763: ptrR = ParseCSSBorderStyleTop (element, tsch, context, ptrT, css, isHTML);
1.82 ! cvs 764: ptrR = SkipBlanksAndComments (ptrR);
! 765: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 766: {
767: cssRule = ptrR;
768: /* apply the Border-Top to all */
1.43 cvs 769: ptrR = ParseCSSBorderStyleRight (element, tsch, context, ptrT, css, isHTML);
770: ptrR = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
771: ptrR = ParseCSSBorderStyleLeft (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 772: }
773: else
774: {
775: /* parse Border-Right */
1.43 cvs 776: ptrB = ParseCSSBorderStyleRight (element, tsch, context, ptrR, css, isHTML);
1.82 ! cvs 777: ptrB = SkipBlanksAndComments (ptrB);
! 778: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.42 cvs 779: {
780: cssRule = ptrB;
781: /* apply the Border-Top to Border-Bottom */
1.43 cvs 782: ptrB = ParseCSSBorderStyleBottom (element, tsch, context, ptrT, css, isHTML);
1.42 cvs 783: /* apply the Border-Right to Border-Left */
1.43 cvs 784: ptrB = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 785: }
786: else
787: {
788: /* parse Border-Bottom */
1.43 cvs 789: ptrL = ParseCSSBorderStyleBottom (element, tsch, context, ptrB, css, isHTML);
1.82 ! cvs 790: ptrL = SkipBlanksAndComments (ptrL);
! 791: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.42 cvs 792: {
793: cssRule = ptrL;
794: /* apply the Border-Right to Border-Left */
1.43 cvs 795: ptrL = ParseCSSBorderStyleLeft (element, tsch, context, ptrR, css, isHTML);
1.42 cvs 796: }
797: else
798: /* parse Border-Left */
1.43 cvs 799: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, ptrL, css, isHTML);
1.82 ! cvs 800: cssRule = SkipBlanksAndComments (cssRule);
1.42 cvs 801: }
802: }
803: return (cssRule);
804: }
805:
806: /*----------------------------------------------------------------------
1.59 cvs 807: ParseCSSBorderTop: parse a CSS BorderTop
1.42 cvs 808: attribute string.
809: ----------------------------------------------------------------------*/
1.79 cvs 810: static char *ParseCSSBorderTop (Element element, PSchema tsch,
811: PresentationContext context, char *cssRule,
812: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 813: {
1.79 cvs 814: char *ptr;
1.43 cvs 815:
1.82 ! cvs 816: cssRule = SkipBlanksAndComments (cssRule);
! 817: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 818: {
819: ptr = cssRule;
820: cssRule = ParseCSSBorderStyleTop (element, tsch, context, cssRule, css, isHTML);
821: if (ptr == cssRule)
822: cssRule = ParseCSSBorderTopWidth (element, tsch, context, cssRule, css, isHTML);
823: if (ptr == cssRule)
824: cssRule = ParseCSSBorderColorTop (element, tsch, context, cssRule, css, isHTML);
825: if (ptr == cssRule)
826: /* rule not found */
827: cssRule = SkipProperty (cssRule);
1.82 ! cvs 828: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 829: }
1.42 cvs 830: return (cssRule);
831: }
832:
833: /*----------------------------------------------------------------------
1.59 cvs 834: ParseCSSBorderLeft: parse a CSS BorderLeft
1.42 cvs 835: attribute string.
836: ----------------------------------------------------------------------*/
1.79 cvs 837: static char *ParseCSSBorderLeft (Element element, PSchema tsch,
838: PresentationContext context, char *cssRule,
839: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 840: {
1.79 cvs 841: char *ptr;
1.43 cvs 842:
1.82 ! cvs 843: cssRule = SkipBlanksAndComments (cssRule);
! 844: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 845: {
846: ptr = cssRule;
847: cssRule = ParseCSSBorderStyleLeft (element, tsch, context, cssRule, css, isHTML);
848: if (ptr == cssRule)
849: cssRule = ParseCSSBorderLeftWidth (element, tsch, context, cssRule, css, isHTML);
850: if (ptr == cssRule)
851: cssRule = ParseCSSBorderColorLeft (element, tsch, context, cssRule, css, isHTML);
852: if (ptr == cssRule)
853: /* rule not found */
854: cssRule = SkipProperty (cssRule);
1.82 ! cvs 855: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 856: }
1.1 cvs 857: return (cssRule);
858: }
859:
860: /*----------------------------------------------------------------------
1.59 cvs 861: ParseCSSBorderBottom: parse a CSS BorderBottom
1.1 cvs 862: attribute string.
863: ----------------------------------------------------------------------*/
1.79 cvs 864: static char *ParseCSSBorderBottom (Element element, PSchema tsch,
865: PresentationContext context, char *cssRule,
866: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 867: {
1.79 cvs 868: char *ptr;
1.43 cvs 869:
1.82 ! cvs 870: cssRule = SkipBlanksAndComments (cssRule);
! 871: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 872: {
873: ptr = cssRule;
874: cssRule = ParseCSSBorderStyleBottom (element, tsch, context, cssRule, css, isHTML);
875: if (ptr == cssRule)
876: cssRule = ParseCSSBorderBottomWidth (element, tsch, context, cssRule, css, isHTML);
877: if (ptr == cssRule)
878: cssRule = ParseCSSBorderColorBottom (element, tsch, context, cssRule, css, isHTML);
879: if (ptr == cssRule)
880: /* rule not found */
881: cssRule = SkipProperty (cssRule);
1.82 ! cvs 882: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 883: }
1.1 cvs 884: return (cssRule);
885: }
886:
887: /*----------------------------------------------------------------------
1.59 cvs 888: ParseCSSBorderRight: parse a CSS BorderRight
1.1 cvs 889: attribute string.
890: ----------------------------------------------------------------------*/
1.79 cvs 891: static char *ParseCSSBorderRight (Element element, PSchema tsch,
892: PresentationContext context, char *cssRule,
893: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 894: {
1.79 cvs 895: char *ptr;
1.43 cvs 896:
1.82 ! cvs 897: cssRule = SkipBlanksAndComments (cssRule);
! 898: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 899: {
900: ptr = cssRule;
901: cssRule = ParseCSSBorderStyleRight (element, tsch, context, cssRule, css, isHTML);
902: if (ptr == cssRule)
903: cssRule = ParseCSSBorderRightWidth (element, tsch, context, cssRule, css, isHTML);
904: if (ptr == cssRule)
905: cssRule = ParseCSSBorderColorRight (element, tsch, context, cssRule, css, isHTML);
906: if (ptr == cssRule)
907: /* rule not found */
908: cssRule = SkipProperty (cssRule);
1.82 ! cvs 909: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 910: }
1.1 cvs 911: return (cssRule);
912: }
913:
914: /*----------------------------------------------------------------------
1.59 cvs 915: ParseCSSBorder: parse a CSS border
1.42 cvs 916: attribute string.
917: ----------------------------------------------------------------------*/
1.79 cvs 918: static char *ParseCSSBorder (Element element, PSchema tsch,
919: PresentationContext context, char *cssRule,
920: CSSInfoPtr css, ThotBool isHTML)
1.42 cvs 921: {
1.79 cvs 922: char *ptrT, *ptrR;
1.42 cvs 923:
1.82 ! cvs 924: ptrT = SkipBlanksAndComments (cssRule);
1.42 cvs 925: /* First parse Border-Top */
926: ptrR = ParseCSSBorderTop (element, tsch, context, ptrT, css, isHTML);
1.82 ! cvs 927: ptrR = SkipBlanksAndComments (ptrR);
! 928: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.42 cvs 929: {
930: cssRule = ptrR;
931: /* apply the Border-Top to all */
932: ptrR = ParseCSSBorderRight (element, tsch, context, ptrT, css, isHTML);
933: ptrR = ParseCSSBorderBottom (element, tsch, context, ptrT, css, isHTML);
934: ptrR = ParseCSSBorderLeft (element, tsch, context, ptrT, css, isHTML);
935: }
936: return (cssRule);
937: }
938:
939: /*----------------------------------------------------------------------
1.59 cvs 940: ParseCSSClear: parse a CSS clear attribute string
1.1 cvs 941: ----------------------------------------------------------------------*/
1.79 cvs 942: static char *ParseCSSClear (Element element, PSchema tsch,
943: PresentationContext context, char *cssRule,
944: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 945: {
946: cssRule = SkipProperty (cssRule);
947: return (cssRule);
948: }
949:
950: /*----------------------------------------------------------------------
1.59 cvs 951: ParseCSSDisplay: parse a CSS display attribute string
1.1 cvs 952: ----------------------------------------------------------------------*/
1.79 cvs 953: static char *ParseCSSDisplay (Element element, PSchema tsch,
954: PresentationContext context, char *cssRule,
955: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 956: {
957: PresentationValue pval;
958:
959: pval.typed_data.unit = STYLE_UNIT_REL;
960: pval.typed_data.real = FALSE;
1.82 ! cvs 961: cssRule = SkipBlanksAndComments (cssRule);
! 962: if (!strncasecmp (cssRule, "block", 5))
1.1 cvs 963: {
1.79 cvs 964: /* pval.typed_data.value = STYLE_INLINE;
1.1 cvs 965: TtaSetStylePresentation (PRLine, element, tsch, context, pval);
1.79 cvs 966: cssRule = SkipWord (cssRule); */
1.1 cvs 967: }
1.82 ! cvs 968: else if (!strncasecmp (cssRule, "inline", 6))
1.1 cvs 969: {
1.79 cvs 970: /* pval.typed_data.value = STYLE_INLINE;
1.1 cvs 971: TtaSetStylePresentation (PRLine, element, tsch, context, pval);
1.79 cvs 972: cssRule = SkipWord (cssRule); */
1.1 cvs 973: }
1.82 ! cvs 974: else if (!strncasecmp (cssRule, "none", 4))
1.1 cvs 975: {
976: pval.typed_data.value = STYLE_HIDE;
977: TtaSetStylePresentation (PRVisibility, element, tsch, context, pval);
978: cssRule = SkipWord (cssRule);
979: }
1.82 ! cvs 980: else if (!strncasecmp (cssRule, "list-item", 9))
1.1 cvs 981: cssRule = SkipProperty (cssRule);
982: else
983: fprintf (stderr, "invalid display value %s\n", cssRule);
1.34 cvs 984:
1.1 cvs 985: return (cssRule);
986: }
987:
988: /*----------------------------------------------------------------------
1.59 cvs 989: ParseCSSFloat: parse a CSS float attribute string
1.1 cvs 990: ----------------------------------------------------------------------*/
1.79 cvs 991: static char *ParseCSSFloat (Element element, PSchema tsch,
992: PresentationContext context, char *cssRule,
993: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 994: {
995: cssRule = SkipProperty (cssRule);
996: return (cssRule);
997: }
998:
999: /*----------------------------------------------------------------------
1.59 cvs 1000: ParseCSSLetterSpacing: parse a CSS letter-spacing
1.1 cvs 1001: attribute string.
1002: ----------------------------------------------------------------------*/
1.79 cvs 1003: static char *ParseCSSLetterSpacing (Element element, PSchema tsch,
1004: PresentationContext context, char *cssRule,
1005: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1006: {
1007: cssRule = SkipProperty (cssRule);
1008: return (cssRule);
1009: }
1010:
1011: /*----------------------------------------------------------------------
1.59 cvs 1012: ParseCSSListStyleType: parse a CSS list-style-type
1.1 cvs 1013: attribute string.
1014: ----------------------------------------------------------------------*/
1.79 cvs 1015: static char *ParseCSSListStyleType (Element element, PSchema tsch,
1016: PresentationContext context, char *cssRule,
1017: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1018: {
1019: cssRule = SkipProperty (cssRule);
1020: return (cssRule);
1021: }
1022:
1023: /*----------------------------------------------------------------------
1.59 cvs 1024: ParseCSSListStyleImage: parse a CSS list-style-image
1.1 cvs 1025: attribute string.
1026: ----------------------------------------------------------------------*/
1.79 cvs 1027: static char *ParseCSSListStyleImage (Element element, PSchema tsch,
1028: PresentationContext context, char *cssRule,
1029: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1030: {
1031: cssRule = SkipProperty (cssRule);
1032: return (cssRule);
1033: }
1034:
1035: /*----------------------------------------------------------------------
1.59 cvs 1036: ParseCSSListStylePosition: parse a CSS list-style-position
1.1 cvs 1037: attribute string.
1038: ----------------------------------------------------------------------*/
1.79 cvs 1039: static char *ParseCSSListStylePosition (Element element, PSchema tsch,
1040: PresentationContext context,
1041: char *cssRule, CSSInfoPtr css,
1042: ThotBool isHTML)
1.1 cvs 1043: {
1044: cssRule = SkipProperty (cssRule);
1045: return (cssRule);
1046: }
1047:
1048: /*----------------------------------------------------------------------
1.59 cvs 1049: ParseCSSListStyle: parse a CSS list-style
1.1 cvs 1050: attribute string.
1051: ----------------------------------------------------------------------*/
1.79 cvs 1052: static char *ParseCSSListStyle (Element element, PSchema tsch,
1053: PresentationContext context, char *cssRule,
1054: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1055: {
1056: cssRule = SkipProperty (cssRule);
1057: return (cssRule);
1058: }
1059:
1060: /*----------------------------------------------------------------------
1.59 cvs 1061: ParseCSSTextAlign: parse a CSS text-align
1.1 cvs 1062: attribute string.
1063: ----------------------------------------------------------------------*/
1.79 cvs 1064: static char *ParseCSSTextAlign (Element element, PSchema tsch,
1065: PresentationContext context, char *cssRule,
1066: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1067: {
1068: PresentationValue align;
1069:
1070: align.typed_data.value = 0;
1071: align.typed_data.unit = STYLE_UNIT_REL;
1072: align.typed_data.real = FALSE;
1073:
1.82 ! cvs 1074: cssRule = SkipBlanksAndComments (cssRule);
! 1075: if (!strncasecmp (cssRule, "left", 4))
1.1 cvs 1076: {
1077: align.typed_data.value = AdjustLeft;
1078: cssRule = SkipWord (cssRule);
1079: }
1.82 ! cvs 1080: else if (!strncasecmp (cssRule, "right", 5))
1.1 cvs 1081: {
1082: align.typed_data.value = AdjustRight;
1083: cssRule = SkipWord (cssRule);
1084: }
1.82 ! cvs 1085: else if (!strncasecmp (cssRule, "center", 6))
1.1 cvs 1086: {
1087: align.typed_data.value = Centered;
1088: cssRule = SkipWord (cssRule);
1089: }
1.82 ! cvs 1090: else if (!strncasecmp (cssRule, "justify", 7))
1.1 cvs 1091: {
1.81 cvs 1092: align.typed_data.value = Justify;
1.1 cvs 1093: cssRule = SkipWord (cssRule);
1094: }
1095: else
1096: {
1097: fprintf (stderr, "invalid align value\n");
1098: return (cssRule);
1099: }
1100:
1101: /*
1102: * install the new presentation.
1103: */
1104: if (align.typed_data.value)
1.81 cvs 1105: TtaSetStylePresentation (PRAdjust, element, tsch, context, align);
1.1 cvs 1106: return (cssRule);
1107: }
1108:
1109: /*----------------------------------------------------------------------
1.59 cvs 1110: ParseCSSTextIndent: parse a CSS text-indent
1.1 cvs 1111: attribute string.
1112: ----------------------------------------------------------------------*/
1.79 cvs 1113: static char *ParseCSSTextIndent (Element element, PSchema tsch,
1114: PresentationContext context, char *cssRule,
1115: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1116: {
1117: PresentationValue pval;
1118:
1.82 ! cvs 1119: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1120: cssRule = ParseCSSUnit (cssRule, &pval);
1121: if (pval.typed_data.unit == STYLE_UNIT_INVALID)
1122: return (cssRule);
1123: /* install the attribute */
1124: TtaSetStylePresentation (PRIndent, element, tsch, context, pval);
1125: return (cssRule);
1126: }
1127:
1128: /*----------------------------------------------------------------------
1.59 cvs 1129: ParseCSSTextTransform: parse a CSS text-transform
1.1 cvs 1130: attribute string.
1131: ----------------------------------------------------------------------*/
1.79 cvs 1132: static char *ParseCSSTextTransform (Element element, PSchema tsch,
1133: PresentationContext context, char *cssRule,
1134: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1135: {
1136: cssRule = SkipProperty (cssRule);
1137: return (cssRule);
1138: }
1139:
1140: /*----------------------------------------------------------------------
1.59 cvs 1141: ParseCSSVerticalAlign: parse a CSS vertical-align
1.1 cvs 1142: attribute string.
1143: ----------------------------------------------------------------------*/
1.79 cvs 1144: static char *ParseCSSVerticalAlign (Element element, PSchema tsch,
1145: PresentationContext context, char *cssRule,
1146: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1147: {
1148: cssRule = SkipProperty (cssRule);
1149: return (cssRule);
1150: }
1151:
1152: /*----------------------------------------------------------------------
1.59 cvs 1153: ParseCSSWhiteSpace: parse a CSS white-space
1.1 cvs 1154: attribute string.
1155: ----------------------------------------------------------------------*/
1.79 cvs 1156: static char *ParseCSSWhiteSpace (Element element, PSchema tsch,
1157: PresentationContext context, char *cssRule,
1158: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1159: {
1.82 ! cvs 1160: cssRule = SkipBlanksAndComments (cssRule);
! 1161: if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1162: cssRule = SkipWord (cssRule);
1.82 ! cvs 1163: else if (!strncasecmp (cssRule, "pre", 3))
1.1 cvs 1164: cssRule = SkipWord (cssRule);
1165: else
1166: return (cssRule);
1167: return (cssRule);
1168: }
1169:
1170: /*----------------------------------------------------------------------
1.59 cvs 1171: ParseCSSWordSpacing: parse a CSS word-spacing
1.1 cvs 1172: attribute string.
1173: ----------------------------------------------------------------------*/
1.79 cvs 1174: static char *ParseCSSWordSpacing (Element element, PSchema tsch,
1175: PresentationContext context, char *cssRule,
1176: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1177: {
1178: cssRule = SkipProperty (cssRule);
1179: return (cssRule);
1180: }
1181:
1182: /*----------------------------------------------------------------------
1.59 cvs 1183: ParseCSSLineSpacing: parse a CSS font leading string
1.25 cvs 1184: we expect the input string describing the attribute to be
1185: value% or value
1186: ----------------------------------------------------------------------*/
1.79 cvs 1187: static char *ParseCSSLineSpacing (Element element, PSchema tsch,
1188: PresentationContext context, char *cssRule,
1189: CSSInfoPtr css, ThotBool isHTML)
1.25 cvs 1190: {
1191: PresentationValue lead;
1192:
1193: cssRule = ParseCSSUnit (cssRule, &lead);
1194: if (lead.typed_data.unit == STYLE_UNIT_INVALID)
1195: {
1196: /* invalid line spacing */
1197: return (cssRule);
1198: }
1199: /* install the new presentation */
1200: TtaSetStylePresentation (PRLineSpacing, element, tsch, context, lead);
1201: return (cssRule);
1202: }
1203:
1204: /*----------------------------------------------------------------------
1.59 cvs 1205: ParseCSSFontSize: parse a CSS font size attr string
1.1 cvs 1206: we expect the input string describing the attribute to be
1207: xx-small, x-small, small, medium, large, x-large, xx-large
1208: or an absolute size, or an imcrement relative to the parent
1209: ----------------------------------------------------------------------*/
1.79 cvs 1210: static char *ParseCSSFontSize (Element element, PSchema tsch,
1211: PresentationContext context, char *cssRule,
1212: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1213: {
1214: PresentationValue pval;
1.79 cvs 1215: char *ptr = NULL;
1.14 cvs 1216: ThotBool real;
1.1 cvs 1217:
1218: pval.typed_data.real = FALSE;
1.82 ! cvs 1219: cssRule = SkipBlanksAndComments (cssRule);
! 1220: if (!strncasecmp (cssRule, "larger", 6))
1.1 cvs 1221: {
1222: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1223: pval.typed_data.value = 130;
1224: cssRule = SkipWord (cssRule);
1225: }
1.82 ! cvs 1226: else if (!strncasecmp (cssRule, "smaller", 7))
1.1 cvs 1227: {
1228: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1229: pval.typed_data.value = 80;
1230: cssRule = SkipWord (cssRule);
1231: }
1.82 ! cvs 1232: else if (!strncasecmp (cssRule, "xx-small", 8))
1.1 cvs 1233: {
1234: pval.typed_data.unit = STYLE_UNIT_REL;
1235: pval.typed_data.value = 1;
1236: cssRule = SkipWord (cssRule);
1237: }
1.82 ! cvs 1238: else if (!strncasecmp (cssRule, "x-small", 7))
1.1 cvs 1239: {
1240: pval.typed_data.unit = STYLE_UNIT_REL;
1241: pval.typed_data.value = 2;
1242: cssRule = SkipWord (cssRule);
1243: }
1.82 ! cvs 1244: else if (!strncasecmp (cssRule, "small", 5))
1.1 cvs 1245: {
1246: pval.typed_data.unit = STYLE_UNIT_REL;
1247: pval.typed_data.value = 3;
1248: cssRule = SkipWord (cssRule);
1249: }
1.82 ! cvs 1250: else if (!strncasecmp (cssRule, "medium", 6))
1.1 cvs 1251: {
1252: pval.typed_data.unit = STYLE_UNIT_REL;
1253: pval.typed_data.value = 4;
1254: cssRule = SkipWord (cssRule);
1255: }
1.82 ! cvs 1256: else if (!strncasecmp (cssRule, "large", 5))
1.1 cvs 1257: {
1258: pval.typed_data.unit = STYLE_UNIT_REL;
1259: pval.typed_data.value = 5;
1260: cssRule = SkipWord (cssRule);
1261: }
1.82 ! cvs 1262: else if (!strncasecmp (cssRule, "x-large", 7))
1.1 cvs 1263: {
1264: pval.typed_data.unit = STYLE_UNIT_REL;
1265: pval.typed_data.value = 6;
1266: cssRule = SkipWord (cssRule);
1267: }
1.82 ! cvs 1268: else if (!strncasecmp (cssRule, "xx-large", 8))
1.1 cvs 1269: {
1270: pval.typed_data.unit = STYLE_UNIT_REL;
1271: pval.typed_data.value = 7;
1272: cssRule = SkipWord (cssRule);
1273: }
1274: else
1275: {
1.25 cvs 1276: /* look for a '/' within the current cssRule */
1.82 ! cvs 1277: ptr = strchr (cssRule, '/');
1.25 cvs 1278: if (ptr != NULL)
1279: {
1280: /* keep the line spacing rule */
1.82 ! cvs 1281: ptr[0] = EOS;
1.25 cvs 1282: ptr = &ptr[1];
1283: }
1.1 cvs 1284: cssRule = ParseCSSUnit (cssRule, &pval);
1285: if (pval.typed_data.unit == STYLE_UNIT_INVALID ||
1286: pval.typed_data.value < 0)
1287: return (cssRule);
1288: if (pval.typed_data.unit == STYLE_UNIT_REL && pval.typed_data.value > 0)
1289: /* CSS relative sizes have to be higher than Thot ones */
1290: pval.typed_data.value += 1;
1291: else
1292: {
1293: real = pval.typed_data.real;
1294: if (pval.typed_data.unit == STYLE_UNIT_EM)
1295: {
1296: if (real)
1297: {
1298: pval.typed_data.value /= 10;
1.11 cvs 1299: pval.typed_data.real = FALSE;
1.1 cvs 1300: real = FALSE;
1301: }
1302: else
1303: pval.typed_data.value *= 100;
1304: pval.typed_data.unit = STYLE_UNIT_PERCENT;
1305: }
1306: }
1.25 cvs 1307:
1.1 cvs 1308: }
1309:
1.25 cvs 1310: /* install the presentation style */
1.1 cvs 1311: TtaSetStylePresentation (PRSize, element, tsch, context, pval);
1.25 cvs 1312:
1313: if (ptr != NULL)
1314: cssRule = ParseCSSLineSpacing (element, tsch, context, ptr, css, isHTML);
1.1 cvs 1315: return (cssRule);
1316: }
1317:
1318: /*----------------------------------------------------------------------
1.59 cvs 1319: ParseCSSFontFamily: parse a CSS font family string
1.1 cvs 1320: we expect the input string describing the attribute to be
1321: a common generic font style name
1322: ----------------------------------------------------------------------*/
1.79 cvs 1323: static char *ParseCSSFontFamily (Element element, PSchema tsch,
1324: PresentationContext context, char *cssRule,
1325: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1326: {
1327: PresentationValue font;
1.79 cvs 1328: char quoteChar;
1.1 cvs 1329:
1330: font.typed_data.value = 0;
1331: font.typed_data.unit = STYLE_UNIT_REL;
1332: font.typed_data.real = FALSE;
1.82 ! cvs 1333: cssRule = SkipBlanksAndComments (cssRule);
! 1334: if (*cssRule == '"' || *cssRule == '\'')
1.1 cvs 1335: {
1336: quoteChar = *cssRule;
1337: cssRule++;
1338: }
1339: else
1.82 ! cvs 1340: quoteChar = EOS;
1.1 cvs 1341:
1.82 ! cvs 1342: if (!strncasecmp (cssRule, "times", 5))
1.1 cvs 1343: font.typed_data.value = STYLE_FONT_TIMES;
1.82 ! cvs 1344: else if (!strncasecmp (cssRule, "serif", 5))
1.1 cvs 1345: font.typed_data.value = STYLE_FONT_TIMES;
1.82 ! cvs 1346: else if (!strncasecmp (cssRule, "helvetica", 9) ||
! 1347: !strncasecmp (cssRule, "verdana", 7))
1.1 cvs 1348: font.typed_data.value = STYLE_FONT_HELVETICA;
1.82 ! cvs 1349: else if (!strncasecmp (cssRule, "sans-serif", 10))
1.1 cvs 1350: font.typed_data.value = STYLE_FONT_HELVETICA;
1.82 ! cvs 1351: else if (!strncasecmp (cssRule, "courier", 7))
1.1 cvs 1352: font.typed_data.value = STYLE_FONT_COURIER;
1.82 ! cvs 1353: else if (!strncasecmp (cssRule, "monospace", 9))
1.1 cvs 1354: font.typed_data.value = STYLE_FONT_COURIER;
1355: else
1356: /* unknown font name. Skip it */
1357: {
1.54 cvs 1358: if (quoteChar) {
1359: cssRule = SkipQuotedString (cssRule, quoteChar);
1360: } else
1.1 cvs 1361: cssRule = SkipWord (cssRule);
1.82 ! cvs 1362: cssRule = SkipBlanksAndComments (cssRule);
! 1363: if (*cssRule == ',')
1.1 cvs 1364: {
1365: cssRule++;
1366: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1367: return (cssRule);
1368: }
1369: }
1370:
1371: if (font.typed_data.value != 0)
1372: {
1373: cssRule = SkipProperty (cssRule);
1374: /* install the new presentation */
1375: TtaSetStylePresentation (PRFont, element, tsch, context, font);
1376: }
1377: return (cssRule);
1378: }
1379:
1380: /*----------------------------------------------------------------------
1.59 cvs 1381: ParseCSSFontWeight: parse a CSS font weight string
1.1 cvs 1382: we expect the input string describing the attribute to be
1.20 cvs 1383: normal, bold, bolder, lighter, 100, 200, 300, ... 900, inherit.
1.1 cvs 1384: ----------------------------------------------------------------------*/
1.79 cvs 1385: static char *ParseCSSFontWeight (Element element, PSchema tsch,
1386: PresentationContext context, char *cssRule,
1387: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1388: {
1.20 cvs 1389: PresentationValue weight;
1.1 cvs 1390:
1391: weight.typed_data.value = 0;
1392: weight.typed_data.unit = STYLE_UNIT_REL;
1393: weight.typed_data.real = FALSE;
1.82 ! cvs 1394: cssRule = SkipBlanksAndComments (cssRule);
! 1395: if (!strncasecmp (cssRule, "100", 3) && !isalpha (cssRule[3]))
1.1 cvs 1396: {
1397: weight.typed_data.value = -3;
1398: cssRule = SkipWord (cssRule);
1399: }
1.82 ! cvs 1400: else if (!strncasecmp (cssRule, "200", 3) && !isalpha (cssRule[3]))
1.1 cvs 1401: {
1402: weight.typed_data.value = -2;
1403: cssRule = SkipWord (cssRule);
1404: }
1.82 ! cvs 1405: else if (!strncasecmp (cssRule, "300", 3) && ! isalpha(cssRule[3]))
1.1 cvs 1406: {
1407: weight.typed_data.value = -1;
1408: cssRule = SkipWord (cssRule);
1409: }
1.82 ! cvs 1410: else if (!strncasecmp (cssRule, "normal", 6) || (!strncasecmp (cssRule, "400", 3) && !isalpha (cssRule[3])))
1.1 cvs 1411: {
1412: weight.typed_data.value = 0;
1413: cssRule = SkipWord (cssRule);
1414: }
1.82 ! cvs 1415: else if (!strncasecmp (cssRule, "500", 3) && !isalpha (cssRule[3]))
1.1 cvs 1416: {
1417: weight.typed_data.value = +1;
1418: cssRule = SkipWord (cssRule);
1419: }
1.82 ! cvs 1420: else if (!strncasecmp (cssRule, "600", 3) && !isalpha (cssRule[3]))
1.1 cvs 1421: {
1422: weight.typed_data.value = +2;
1423: cssRule = SkipWord (cssRule);
1424: }
1.82 ! cvs 1425: else if (!strncasecmp (cssRule, "bold", 4) || (!strncasecmp (cssRule, "700", 3) && !isalpha (cssRule[3])))
1.1 cvs 1426: {
1427: weight.typed_data.value = +3;
1428: cssRule = SkipWord (cssRule);
1429: }
1.82 ! cvs 1430: else if (!strncasecmp (cssRule, "800", 3) && !isalpha (cssRule[3]))
1.1 cvs 1431: {
1432: weight.typed_data.value = +4;
1433: cssRule = SkipWord (cssRule);
1434: }
1.82 ! cvs 1435: else if (!strncasecmp (cssRule, "900", 3) && !isalpha (cssRule[3]))
1.1 cvs 1436: {
1437: weight.typed_data.value = +5;
1438: cssRule = SkipWord (cssRule);
1439: }
1.82 ! cvs 1440: else if (!strncasecmp (cssRule, "inherit", 7) || !strncasecmp (cssRule, "bolder", 6) || !strncasecmp (cssRule, "lighter", 7))
1.1 cvs 1441: {
1442: /* not implemented */
1443: cssRule = SkipWord (cssRule);
1444: return (cssRule);
1445: }
1446: else
1447: return (cssRule);
1448:
1449: /*
1.20 cvs 1450: * Here we have to reduce since only two font weight values are supported
1.1 cvs 1451: * by the Thot presentation API.
1452: */
1.20 cvs 1453: if (weight.typed_data.value > 0)
1454: weight.typed_data.value = STYLE_WEIGHT_BOLD;
1455: else
1456: weight.typed_data.value = STYLE_WEIGHT_NORMAL;
1.1 cvs 1457:
1458: /* install the new presentation */
1.21 cvs 1459: TtaSetStylePresentation (PRWeight, element, tsch, context, weight);
1.1 cvs 1460: return (cssRule);
1461: }
1462:
1463: /*----------------------------------------------------------------------
1.59 cvs 1464: ParseCSSFontVariant: parse a CSS font variant string
1.1 cvs 1465: we expect the input string describing the attribute to be
1466: normal or small-caps
1467: ----------------------------------------------------------------------*/
1.79 cvs 1468: static char *ParseCSSFontVariant (Element element, PSchema tsch,
1469: PresentationContext context, char *cssRule,
1470: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1471: {
1472: PresentationValue style;
1473:
1474: style.typed_data.value = 0;
1475: style.typed_data.unit = STYLE_UNIT_REL;
1476: style.typed_data.real = FALSE;
1.82 ! cvs 1477: cssRule = SkipBlanksAndComments (cssRule);
! 1478: if (!strncasecmp (cssRule, "small-caps", 10))
1.1 cvs 1479: {
1480: /* Not supported yet */
1481: cssRule = SkipWord (cssRule);
1482: }
1.82 ! cvs 1483: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1484: {
1485: /* Not supported yet */
1486: cssRule = SkipWord (cssRule);
1487: }
1.82 ! cvs 1488: else if (!strncasecmp (cssRule, "inherit", 7))
1.1 cvs 1489: {
1490: /* Not supported yet */
1491: cssRule = SkipWord (cssRule);
1492: }
1493: else
1494: return (cssRule);
1495:
1496: return (cssRule);
1497: }
1498:
1499:
1500: /*----------------------------------------------------------------------
1.59 cvs 1501: ParseCSSFontStyle: parse a CSS font style string
1.1 cvs 1502: we expect the input string describing the attribute to be
1503: italic, oblique or normal
1504: ----------------------------------------------------------------------*/
1.79 cvs 1505: static char *ParseCSSFontStyle (Element element, PSchema tsch,
1506: PresentationContext context, char *cssRule,
1507: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1508: {
1509: PresentationValue style;
1510: PresentationValue size;
1511:
1512: style.typed_data.value = 0;
1513: style.typed_data.unit = STYLE_UNIT_REL;
1514: style.typed_data.real = FALSE;
1515: size.typed_data.value = 0;
1516: size.typed_data.unit = STYLE_UNIT_REL;
1517: size.typed_data.real = FALSE;
1.82 ! cvs 1518: cssRule = SkipBlanksAndComments (cssRule);
! 1519: if (!strncasecmp (cssRule, "italic", 6))
1.1 cvs 1520: {
1521: style.typed_data.value = STYLE_FONT_ITALICS;
1522: cssRule = SkipWord (cssRule);
1523: }
1.82 ! cvs 1524: else if (!strncasecmp (cssRule, "oblique", 7))
1.1 cvs 1525: {
1526: style.typed_data.value = STYLE_FONT_OBLIQUE;
1527: cssRule = SkipWord (cssRule);
1528: }
1.82 ! cvs 1529: else if (!strncasecmp (cssRule, "normal", 6))
1.1 cvs 1530: {
1531: style.typed_data.value = STYLE_FONT_ROMAN;
1532: cssRule = SkipWord (cssRule);
1533: }
1534: else
1535: {
1536: /* invalid font style */
1537: return (cssRule);
1538: }
1539:
1540: /*
1541: * install the new presentation.
1542: */
1543: if (style.typed_data.value != 0)
1.20 cvs 1544: TtaSetStylePresentation (PRStyle, element, tsch, context, style);
1.1 cvs 1545: if (size.typed_data.value != 0)
1546: {
1547: PresentationValue previous_size;
1548:
1549: if (!TtaGetStylePresentation (PRSize, element, tsch, context, &previous_size))
1550: {
1551: /* !!!!!!!!!!!!!!!!!!!!!!!! Unite + relatif !!!!!!!!!!!!!!!! */
1552: size.typed_data.value += previous_size.typed_data.value;
1553: TtaSetStylePresentation (PRSize, element, tsch, context, size);
1554: }
1555: else
1556: {
1557: size.typed_data.value = 10;
1558: TtaSetStylePresentation (PRSize, element, tsch, context, size);
1559: }
1560: }
1561: return (cssRule);
1562: }
1563:
1564: /*----------------------------------------------------------------------
1.59 cvs 1565: ParseCSSFont: parse a CSS font attribute string
1566: we expect the input string describing the attribute to be
1567: !!!!!!
1.1 cvs 1568: ----------------------------------------------------------------------*/
1.79 cvs 1569: static char *ParseCSSFont (Element element, PSchema tsch,
1570: PresentationContext context, char *cssRule,
1571: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1572: {
1.79 cvs 1573: char *ptr;
1.1 cvs 1574:
1.82 ! cvs 1575: cssRule = SkipBlanksAndComments (cssRule);
! 1576: if (!strncasecmp (cssRule, "caption", 7))
1.1 cvs 1577: ;
1.82 ! cvs 1578: else if (!strncasecmp (cssRule, "icon", 4))
1.1 cvs 1579: ;
1.82 ! cvs 1580: else if (!strncasecmp (cssRule, "menu", 4))
1.1 cvs 1581: ;
1.82 ! cvs 1582: else if (!strncasecmp (cssRule, "message-box", 11))
1.1 cvs 1583: ;
1.82 ! cvs 1584: else if (!strncasecmp (cssRule, "small-caption", 13))
1.1 cvs 1585: ;
1.82 ! cvs 1586: else if (!strncasecmp (cssRule, "status-bar", 10))
1.1 cvs 1587: ;
1588: else
1.43 cvs 1589: {
1.82 ! cvs 1590: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.43 cvs 1591: {
1.72 cvs 1592: ptr = cssRule;
1593: cssRule = ParseCSSFontStyle (element, tsch, context, cssRule, css, isHTML);
1594: if (ptr == cssRule)
1595: cssRule = ParseCSSFontVariant (element, tsch, context, cssRule, css, isHTML);
1596: if (ptr == cssRule)
1597: cssRule = ParseCSSFontWeight (element, tsch, context, cssRule, css, isHTML);
1598: if (ptr == cssRule)
1599: cssRule = ParseCSSFontSize (element, tsch, context, cssRule, css, isHTML);
1600: if (ptr == cssRule)
1601: cssRule = ParseCSSFontFamily (element, tsch, context, cssRule, css, isHTML);
1.82 ! cvs 1602: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1603: }
1604: }
1605: return (cssRule);
1.1 cvs 1606: }
1607:
1608: /*----------------------------------------------------------------------
1.59 cvs 1609: ParseCSSTextDecoration: parse a CSS text decor string
1610: we expect the input string describing the attribute to be
1611: underline, overline, line-through, box, shadowbox, box3d,
1612: cartouche, blink or none
1.1 cvs 1613: ----------------------------------------------------------------------*/
1.79 cvs 1614: static char *ParseCSSTextDecoration (Element element, PSchema tsch,
1615: PresentationContext context, char *cssRule,
1616: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1617: {
1618: PresentationValue decor;
1619:
1620: decor.typed_data.value = 0;
1621: decor.typed_data.unit = STYLE_UNIT_REL;
1622: decor.typed_data.real = FALSE;
1.82 ! cvs 1623: cssRule = SkipBlanksAndComments (cssRule);
! 1624: if (!strncasecmp (cssRule, "underline", strlen ("underline")))
1.1 cvs 1625: {
1626: decor.typed_data.value = Underline;
1627: cssRule = SkipWord (cssRule);
1628: }
1.82 ! cvs 1629: else if (!strncasecmp (cssRule, "overline", strlen ("overline")))
1.1 cvs 1630: {
1631: decor.typed_data.value = Overline;
1632: cssRule = SkipWord (cssRule);
1633: }
1.82 ! cvs 1634: else if (!strncasecmp (cssRule, "line-through", strlen ("line-through")))
1.1 cvs 1635: {
1636: decor.typed_data.value = CrossOut;
1637: cssRule = SkipWord (cssRule);
1638: }
1.82 ! cvs 1639: else if (!strncasecmp (cssRule, "box", strlen ("box")))
1.1 cvs 1640: {
1641: /* the box text-decoration attribute is not yet supported */
1642: cssRule = SkipWord (cssRule);
1643: }
1.82 ! cvs 1644: else if (!strncasecmp (cssRule, "boxshadow", strlen ("boxshadow")))
1.1 cvs 1645: {
1646: /* the boxshadow text-decoration attribute is not yet supported */
1647: cssRule = SkipWord (cssRule);
1648: }
1.82 ! cvs 1649: else if (!strncasecmp (cssRule, "box3d", strlen ("box3d")))
1.1 cvs 1650: {
1651: /* the box3d text-decoration attribute is not yet supported */
1652: cssRule = SkipWord (cssRule);
1653: }
1.82 ! cvs 1654: else if (!strncasecmp (cssRule, "cartouche", strlen ("cartouche")))
1.1 cvs 1655: {
1656: /*the cartouche text-decoration attribute is not yet supported */
1657: cssRule = SkipWord (cssRule);
1658: }
1.82 ! cvs 1659: else if (!strncasecmp (cssRule, "blink", strlen ("blink")))
1.1 cvs 1660: {
1661: /*the blink text-decoration attribute will not be supported */
1662: cssRule = SkipWord (cssRule);
1663: }
1.82 ! cvs 1664: else if (!strncasecmp (cssRule, "none", strlen ("none")))
1.1 cvs 1665: {
1666: decor.typed_data.value = NoUnderline;
1667: cssRule = SkipWord (cssRule);
1668: }
1669: else
1670: {
1671: fprintf (stderr, "invalid text decoration\n");
1672: return (cssRule);
1673: }
1674:
1675: /*
1676: * install the new presentation.
1677: */
1678: if (decor.typed_data.value)
1679: {
1680: TtaSetStylePresentation (PRUnderline, element, tsch, context, decor);
1681: }
1682: return (cssRule);
1683: }
1684:
1685: /*----------------------------------------------------------------------
1.59 cvs 1686: ParseCSSHeight: parse a CSS height attribute
1.1 cvs 1687: ----------------------------------------------------------------------*/
1.79 cvs 1688: static char *ParseCSSHeight (Element element, PSchema tsch,
1689: PresentationContext context, char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1690: {
1.82 ! cvs 1691: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1692:
1693: /* first parse the attribute string */
1.82 ! cvs 1694: if (!strcasecmp (cssRule, "auto"))
1.1 cvs 1695: {
1696: cssRule = SkipWord (cssRule);
1.59 cvs 1697: /* ParseCSSHeight: auto */
1.1 cvs 1698: return (cssRule);
1699: }
1700: else
1701: cssRule = SkipProperty (cssRule);
1702: return (cssRule);
1703: }
1704:
1705: /*----------------------------------------------------------------------
1.59 cvs 1706: ParseCSSWidth: parse a CSS width attribute
1.1 cvs 1707: ----------------------------------------------------------------------*/
1.79 cvs 1708: static char *ParseCSSWidth (Element element, PSchema tsch,
1.78 cvs 1709: PresentationContext context,
1.79 cvs 1710: char *cssRule, CSSInfoPtr css,
1.78 cvs 1711: ThotBool isHTML)
1.1 cvs 1712: {
1.82 ! cvs 1713: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1714:
1715: /* first parse the attribute string */
1.82 ! cvs 1716: if (!strcasecmp (cssRule, "auto"))
1.1 cvs 1717: {
1718: cssRule = SkipWord (cssRule);
1719: return (cssRule);
1720: }
1721: else
1722: cssRule = SkipProperty (cssRule);
1723: return (cssRule);
1724: }
1725:
1726: /*----------------------------------------------------------------------
1.59 cvs 1727: ParseCSSMarginTop: parse a CSS margin-top attribute
1.1 cvs 1728: ----------------------------------------------------------------------*/
1.79 cvs 1729: static char *ParseCSSMarginTop (Element element, PSchema tsch,
1.78 cvs 1730: PresentationContext context,
1.79 cvs 1731: char *cssRule, CSSInfoPtr css,
1.78 cvs 1732: ThotBool isHTML)
1.1 cvs 1733: {
1734: PresentationValue margin;
1735:
1.82 ! cvs 1736: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1737: /* first parse the attribute string */
1738: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 1739: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1.1 cvs 1740: {
1.40 cvs 1741: TtaSetStylePresentation (PRMarginTop, element, tsch, context, margin);
1.1 cvs 1742: if (margin.typed_data.value < 0)
1743: TtaSetStylePresentation (PRVertOverflow, element, tsch, context, margin);
1744: }
1745: return (cssRule);
1746: }
1747:
1748: /*----------------------------------------------------------------------
1.59 cvs 1749: ParseCSSMarginBottom: parse a CSS margin-bottom attribute
1.1 cvs 1750: ----------------------------------------------------------------------*/
1.79 cvs 1751: static char *ParseCSSMarginBottom (Element element, PSchema tsch,
1.78 cvs 1752: PresentationContext context,
1.79 cvs 1753: char *cssRule, CSSInfoPtr css,
1.78 cvs 1754: ThotBool isHTML)
1.1 cvs 1755: {
1756: PresentationValue margin;
1757:
1.82 ! cvs 1758: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1759: /* first parse the attribute string */
1760: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 1761: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1762: TtaSetStylePresentation (PRMarginBottom, element, tsch, context, margin);
1.1 cvs 1763: return (cssRule);
1764: }
1765:
1766: /*----------------------------------------------------------------------
1.59 cvs 1767: ParseCSSMarginLeft: parse a CSS margin-left attribute string
1.1 cvs 1768: ----------------------------------------------------------------------*/
1.79 cvs 1769: static char *ParseCSSMarginLeft (Element element, PSchema tsch,
1.78 cvs 1770: PresentationContext context,
1.79 cvs 1771: char *cssRule, CSSInfoPtr css,
1.78 cvs 1772: ThotBool isHTML)
1.1 cvs 1773: {
1774: PresentationValue margin;
1775:
1.82 ! cvs 1776: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1777: /* first parse the attribute string */
1778: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 1779: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1.1 cvs 1780: {
1.40 cvs 1781: TtaSetStylePresentation (PRMarginLeft, element, tsch, context, margin);
1.1 cvs 1782: if (margin.typed_data.value < 0)
1783: TtaSetStylePresentation (PRHorizOverflow, element, tsch, context, margin);
1784: }
1785: return (cssRule);
1786: }
1787:
1788: /*----------------------------------------------------------------------
1.59 cvs 1789: ParseCSSMarginRight: parse a CSS margin-right attribute string
1.1 cvs 1790: ----------------------------------------------------------------------*/
1.79 cvs 1791: static char *ParseCSSMarginRight (Element element, PSchema tsch,
1.78 cvs 1792: PresentationContext context,
1.79 cvs 1793: char *cssRule, CSSInfoPtr css,
1.78 cvs 1794: ThotBool isHTML)
1.1 cvs 1795: {
1796: PresentationValue margin;
1797:
1.82 ! cvs 1798: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1799: /* first parse the attribute string */
1800: cssRule = ParseCSSUnit (cssRule, &margin);
1.43 cvs 1801: if (margin.typed_data.unit != STYLE_UNIT_INVALID)
1802: TtaSetStylePresentation (PRMarginRight, element, tsch, context, margin);
1.1 cvs 1803: return (cssRule);
1804: }
1805:
1806: /*----------------------------------------------------------------------
1.59 cvs 1807: ParseCSSMargin: parse a CSS margin attribute string
1.1 cvs 1808: ----------------------------------------------------------------------*/
1.79 cvs 1809: static char *ParseCSSMargin (Element element, PSchema tsch,
1.78 cvs 1810: PresentationContext context,
1.79 cvs 1811: char *cssRule, CSSInfoPtr css,
1.78 cvs 1812: ThotBool isHTML)
1.1 cvs 1813: {
1.79 cvs 1814: char *ptrT, *ptrR, *ptrB, *ptrL;
1.1 cvs 1815:
1.82 ! cvs 1816: ptrT = SkipBlanksAndComments (cssRule);
1.1 cvs 1817: /* First parse Margin-Top */
1818: ptrR = ParseCSSMarginTop (element, tsch, context, ptrT, css, isHTML);
1.82 ! cvs 1819: ptrR = SkipBlanksAndComments (ptrR);
! 1820: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.1 cvs 1821: {
1822: cssRule = ptrR;
1823: /* apply the Margin-Top to all */
1824: ptrR = ParseCSSMarginRight (element, tsch, context, ptrT, css, isHTML);
1825: ptrR = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1826: ptrR = ParseCSSMarginLeft (element, tsch, context, ptrT, css, isHTML);
1827: }
1828: else
1829: {
1830: /* parse Margin-Right */
1831: ptrB = ParseCSSMarginRight (element, tsch, context, ptrR, css, isHTML);
1.82 ! cvs 1832: ptrB = SkipBlanksAndComments (ptrB);
! 1833: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.1 cvs 1834: {
1835: cssRule = ptrB;
1836: /* apply the Margin-Top to Margin-Bottom */
1837: ptrB = ParseCSSMarginBottom (element, tsch, context, ptrT, css, isHTML);
1838: /* apply the Margin-Right to Margin-Left */
1839: ptrB = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
1840: }
1841: else
1842: {
1843: /* parse Margin-Bottom */
1844: ptrL = ParseCSSMarginBottom (element, tsch, context, ptrB, css, isHTML);
1.82 ! cvs 1845: ptrL = SkipBlanksAndComments (ptrL);
! 1846: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.1 cvs 1847: {
1848: cssRule = ptrL;
1849: /* apply the Margin-Right to Margin-Left */
1850: ptrL = ParseCSSMarginLeft (element, tsch, context, ptrR, css, isHTML);
1851: }
1852: else
1853: /* parse Margin-Left */
1854: cssRule = ParseCSSMarginLeft (element, tsch, context, ptrL, css, isHTML);
1.82 ! cvs 1855: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 1856: }
1857: }
1858: return (cssRule);
1859: }
1860:
1861: /*----------------------------------------------------------------------
1.59 cvs 1862: ParseCSSPaddingTop: parse a CSS PaddingTop attribute string
1.1 cvs 1863: ----------------------------------------------------------------------*/
1.79 cvs 1864: static char *ParseCSSPaddingTop (Element element, PSchema tsch,
1.78 cvs 1865: PresentationContext context,
1.79 cvs 1866: char *cssRule, CSSInfoPtr css,
1.78 cvs 1867: ThotBool isHTML)
1.1 cvs 1868: {
1.43 cvs 1869: PresentationValue padding;
1870:
1.82 ! cvs 1871: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1872: /* first parse the attribute string */
1873: cssRule = ParseCSSUnit (cssRule, &padding);
1874: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
1875: TtaSetStylePresentation (PRPaddingTop, element, tsch, context, padding);
1.1 cvs 1876: return (cssRule);
1877: }
1878:
1879: /*----------------------------------------------------------------------
1.59 cvs 1880: ParseCSSPaddingBottom: parse a CSS PaddingBottom attribute string
1.1 cvs 1881: ----------------------------------------------------------------------*/
1.79 cvs 1882: static char *ParseCSSPaddingBottom (Element element, PSchema tsch,
1.78 cvs 1883: PresentationContext context,
1.79 cvs 1884: char *cssRule, CSSInfoPtr css,
1.78 cvs 1885: ThotBool isHTML)
1.1 cvs 1886: {
1.43 cvs 1887: PresentationValue padding;
1888:
1.82 ! cvs 1889: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1890: /* first parse the attribute string */
1891: cssRule = ParseCSSUnit (cssRule, &padding);
1892: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
1893: TtaSetStylePresentation (PRPaddingBottom, element, tsch, context, padding);
1.1 cvs 1894: return (cssRule);
1895: }
1896:
1897: /*----------------------------------------------------------------------
1.59 cvs 1898: ParseCSSPaddingLeft: parse a CSS PaddingLeft attribute string.
1.1 cvs 1899: ----------------------------------------------------------------------*/
1.79 cvs 1900: static char *ParseCSSPaddingLeft (Element element, PSchema tsch,
1.78 cvs 1901: PresentationContext context,
1.79 cvs 1902: char *cssRule, CSSInfoPtr css,
1.78 cvs 1903: ThotBool isHTML)
1.1 cvs 1904: {
1.43 cvs 1905: PresentationValue padding;
1906:
1.82 ! cvs 1907: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1908: /* first parse the attribute string */
1909: cssRule = ParseCSSUnit (cssRule, &padding);
1910: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
1911: TtaSetStylePresentation (PRPaddingLeft, element, tsch, context, padding);
1.1 cvs 1912: return (cssRule);
1913: }
1914:
1915: /*----------------------------------------------------------------------
1.59 cvs 1916: ParseCSSPaddingRight: parse a CSS PaddingRight attribute string.
1.1 cvs 1917: ----------------------------------------------------------------------*/
1.79 cvs 1918: static char *ParseCSSPaddingRight (Element element, PSchema tsch,
1.78 cvs 1919: PresentationContext context,
1.79 cvs 1920: char *cssRule, CSSInfoPtr css,
1.78 cvs 1921: ThotBool isHTML)
1.1 cvs 1922: {
1.43 cvs 1923: PresentationValue padding;
1924:
1.82 ! cvs 1925: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1926: /* first parse the attribute string */
1927: cssRule = ParseCSSUnit (cssRule, &padding);
1928: if (padding.typed_data.unit != STYLE_UNIT_INVALID)
1929: TtaSetStylePresentation (PRPaddingRight, element, tsch, context, padding);
1.1 cvs 1930: return (cssRule);
1931: }
1932:
1933: /*----------------------------------------------------------------------
1.59 cvs 1934: ParseCSSPadding: parse a CSS padding attribute string.
1.1 cvs 1935: ----------------------------------------------------------------------*/
1.79 cvs 1936: static char *ParseCSSPadding (Element element, PSchema tsch,
1.78 cvs 1937: PresentationContext context,
1.79 cvs 1938: char *cssRule, CSSInfoPtr css,
1.78 cvs 1939: ThotBool isHTML)
1.1 cvs 1940: {
1.79 cvs 1941: char *ptrT, *ptrR, *ptrB, *ptrL;
1.43 cvs 1942:
1.82 ! cvs 1943: ptrT = SkipBlanksAndComments (cssRule);
1.43 cvs 1944: /* First parse Padding-Top */
1945: ptrR = ParseCSSPaddingTop (element, tsch, context, ptrT, css, isHTML);
1.82 ! cvs 1946: ptrR = SkipBlanksAndComments (ptrR);
! 1947: if (*ptrR == ';' || *ptrR == EOS || *ptrR == ',')
1.43 cvs 1948: {
1949: cssRule = ptrR;
1950: /* apply the Padding-Top to all */
1951: ptrR = ParseCSSPaddingRight (element, tsch, context, ptrT, css, isHTML);
1952: ptrR = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1953: ptrR = ParseCSSPaddingLeft (element, tsch, context, ptrT, css, isHTML);
1954: }
1955: else
1956: {
1957: /* parse Padding-Right */
1958: ptrB = ParseCSSPaddingRight (element, tsch, context, ptrR, css, isHTML);
1.82 ! cvs 1959: ptrB = SkipBlanksAndComments (ptrB);
! 1960: if (*ptrB == ';' || *ptrB == EOS || *ptrB == ',')
1.43 cvs 1961: {
1962: cssRule = ptrB;
1963: /* apply the Padding-Top to Padding-Bottom */
1964: ptrB = ParseCSSPaddingBottom (element, tsch, context, ptrT, css, isHTML);
1965: /* apply the Padding-Right to Padding-Left */
1966: ptrB = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
1967: }
1968: else
1969: {
1970: /* parse Padding-Bottom */
1971: ptrL = ParseCSSPaddingBottom (element, tsch, context, ptrB, css, isHTML);
1.82 ! cvs 1972: ptrL = SkipBlanksAndComments (ptrL);
! 1973: if (*ptrL == ';' || *ptrL == EOS || *ptrL == ',')
1.43 cvs 1974: {
1975: cssRule = ptrL;
1976: /* apply the Padding-Right to Padding-Left */
1977: ptrL = ParseCSSPaddingLeft (element, tsch, context, ptrR, css, isHTML);
1978: }
1979: else
1980: /* parse Padding-Left */
1981: cssRule = ParseCSSPaddingLeft (element, tsch, context, ptrL, css, isHTML);
1.82 ! cvs 1982: cssRule = SkipBlanksAndComments (cssRule);
1.43 cvs 1983: }
1984: }
1.1 cvs 1985: return (cssRule);
1986: }
1987:
1988: /*----------------------------------------------------------------------
1.59 cvs 1989: ParseCSSForeground: parse a CSS foreground attribute
1.1 cvs 1990: ----------------------------------------------------------------------*/
1.79 cvs 1991: static char *ParseCSSForeground (Element element, PSchema tsch,
1.78 cvs 1992: PresentationContext context,
1.79 cvs 1993: char *cssRule,
1.78 cvs 1994: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 1995: {
1996: PresentationValue best;
1997:
1998: cssRule = ParseCSSColor (cssRule, &best);
1.25 cvs 1999: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2000: /* install the new presentation */
2001: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
1.1 cvs 2002: return (cssRule);
2003: }
2004:
2005: /*----------------------------------------------------------------------
1.59 cvs 2006: ParseCSSBackgroundColor: parse a CSS background color attribute
1.1 cvs 2007: ----------------------------------------------------------------------*/
1.79 cvs 2008: static char *ParseCSSBackgroundColor (Element element, PSchema tsch,
1.78 cvs 2009: PresentationContext context,
1.79 cvs 2010: char *cssRule,
1.78 cvs 2011: CSSInfoPtr css, ThotBool isHTML)
1.1 cvs 2012: {
2013: PresentationValue best;
2014: unsigned int savedtype = 0;
1.14 cvs 2015: ThotBool moved;
1.1 cvs 2016:
2017: /* move the BODY rule to the HTML element */
2018: moved = (context->type == HTML_EL_BODY && isHTML);
2019: if (moved)
2020: {
2021: if (element)
2022: element = TtaGetMainRoot (context->doc);
2023: else
2024: {
2025: savedtype = context->type;
2026: context->type = HTML_EL_HTML;
2027: }
2028: }
2029:
2030: best.typed_data.unit = STYLE_UNIT_INVALID;
2031: best.typed_data.real = FALSE;
1.82 ! cvs 2032: if (!strncasecmp (cssRule, "transparent", strlen ("transparent")))
1.1 cvs 2033: {
2034: best.typed_data.value = STYLE_PATTERN_NONE;
2035: best.typed_data.unit = STYLE_UNIT_REL;
2036: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 2037: cssRule = SkipWord (cssRule);
1.1 cvs 2038: }
2039: else
2040: {
2041: cssRule = ParseCSSColor (cssRule, &best);
2042: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2043: {
2044: /* install the new presentation. */
2045: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
1.59 cvs 2046: /* thot specificity: need to set fill pattern for background color */
1.1 cvs 2047: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2048: best.typed_data.unit = STYLE_UNIT_REL;
2049: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2050: best.typed_data.value = 1;
2051: best.typed_data.unit = STYLE_UNIT_REL;
2052: TtaSetStylePresentation (PRShowBox, element, tsch, context, best);
2053: }
2054: }
2055:
2056: /* restore the refered element */
2057: if (moved && !element)
2058: context->type = savedtype;
2059: return (cssRule);
2060: }
2061:
1.63 cvs 2062:
2063: /*----------------------------------------------------------------------
1.65 cvs 2064: ParseSVGStroke: parse a SVG stroke property
2065: ----------------------------------------------------------------------*/
1.79 cvs 2066: static char *ParseSVGStroke (Element element, PSchema tsch,
2067: PresentationContext context, char *cssRule,
2068: CSSInfoPtr css, ThotBool isHTML)
1.65 cvs 2069: {
2070: PresentationValue best;
2071:
2072: best.typed_data.unit = STYLE_UNIT_INVALID;
2073: best.typed_data.real = FALSE;
1.82 ! cvs 2074: if (!strncasecmp (cssRule, "none", 4))
1.65 cvs 2075: {
2076: best.typed_data.value = -2; /* -2 means transparent */
2077: best.typed_data.unit = STYLE_UNIT_REL;
2078: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2079: cssRule = SkipWord (cssRule);
2080: }
2081: else
2082: {
2083: cssRule = ParseCSSColor (cssRule, &best);
2084: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2085: /* install the new presentation */
2086: TtaSetStylePresentation (PRForeground, element, tsch, context, best);
2087: }
2088: return (cssRule);
2089: }
2090:
2091: /*----------------------------------------------------------------------
1.63 cvs 2092: ParseSVGFill: parse a SVG fill property
2093: ----------------------------------------------------------------------*/
1.79 cvs 2094: static char *ParseSVGFill (Element element, PSchema tsch,
2095: PresentationContext context, char *cssRule,
2096: CSSInfoPtr css, ThotBool isHTML)
1.63 cvs 2097: {
2098: PresentationValue best;
2099:
2100: best.typed_data.unit = STYLE_UNIT_INVALID;
2101: best.typed_data.real = FALSE;
1.82 ! cvs 2102: if (!strncasecmp (cssRule, "none", 4))
1.63 cvs 2103: {
2104: best.typed_data.value = STYLE_PATTERN_NONE;
2105: best.typed_data.unit = STYLE_UNIT_REL;
2106: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
1.65 cvs 2107: cssRule = SkipWord (cssRule);
1.63 cvs 2108: }
2109: else
2110: {
2111: cssRule = ParseCSSColor (cssRule, &best);
2112: if (best.typed_data.unit != STYLE_UNIT_INVALID)
2113: {
2114: /* install the new presentation. */
2115: TtaSetStylePresentation (PRBackground, element, tsch, context, best);
2116: /* thot specificity: need to set fill pattern for background color */
2117: best.typed_data.value = STYLE_PATTERN_BACKGROUND;
2118: best.typed_data.unit = STYLE_UNIT_REL;
2119: TtaSetStylePresentation (PRFillPattern, element, tsch, context, best);
2120: }
2121: }
2122: return (cssRule);
2123: }
2124:
1.1 cvs 2125: /*----------------------------------------------------------------------
1.59 cvs 2126: ParseCSSBackgroundImageCallback: Callback called asynchronously by
2127: FetchImage when a background image has been fetched.
1.1 cvs 2128: ----------------------------------------------------------------------*/
1.82 ! cvs 2129: void ParseCSSBackgroundImageCallback (Document doc, Element element,
! 2130: char *file, void *extra)
1.1 cvs 2131: {
1.82 ! cvs 2132: DisplayMode dispMode;
! 2133: BackgroundImageCallbackPtr callblock;
! 2134: Element el;
! 2135: PSchema tsch;
! 2136: PresentationContext context;
! 2137: PresentationValue image;
! 2138: PresentationValue value;
1.1 cvs 2139:
1.82 ! cvs 2140: callblock = (BackgroundImageCallbackPtr) extra;
1.34 cvs 2141: if (callblock == NULL)
2142: return;
1.1 cvs 2143:
1.34 cvs 2144: /* avoid too many redisplay */
2145: dispMode = TtaGetDisplayMode (doc);
2146: if (dispMode == DisplayImmediately)
2147: TtaSetDisplayMode (doc, DeferredDisplay);
2148:
2149: el = callblock->el;
2150: tsch = callblock->tsch;
2151: context = &callblock->context.specific;
2152:
2153: /* Ok the image was fetched, finish the background-image handling */
2154: image.pointer = file;
2155: TtaSetStylePresentation (PRBackgroundPicture, el, tsch, context, image);
1.1 cvs 2156:
1.70 cvs 2157: /* enforce the showbox */
1.34 cvs 2158: value.typed_data.value = 1;
2159: value.typed_data.unit = STYLE_UNIT_REL;
2160: value.typed_data.real = FALSE;
2161: TtaSetStylePresentation (PRShowBox, el, tsch, context, value);
2162:
2163: TtaFreeMemory (callblock);
2164: /* restore the display mode */
2165: if (dispMode == DisplayImmediately)
2166: TtaSetDisplayMode (doc, dispMode);
1.1 cvs 2167: }
2168:
2169:
2170: /*----------------------------------------------------------------------
2171: GetCSSBackgroundURL searches a CSS BackgroundImage url within
2172: the styleString.
2173: Returns NULL or a new allocated url string.
2174: ----------------------------------------------------------------------*/
1.79 cvs 2175: char *GetCSSBackgroundURL (char *styleString)
1.1 cvs 2176: {
1.79 cvs 2177: char *b, *e, *ptr;
2178: int len;
1.1 cvs 2179:
2180: ptr = NULL;
1.82 ! cvs 2181: b = strstr (styleString, "url");
1.1 cvs 2182: if (b != NULL)
2183: {
2184: b += 3;
1.82 ! cvs 2185: b = SkipBlanksAndComments (b);
! 2186: if (*b == '(')
1.1 cvs 2187: {
2188: b++;
1.82 ! cvs 2189: b = SkipBlanksAndComments (b);
1.1 cvs 2190: /*** Caution: Strings can either be written with double quotes or
2191: with single quotes. Only double quotes are handled here.
2192: Escaped quotes are not handled. See function SkipQuotedString */
1.82 ! cvs 2193: if (*b == '"')
1.1 cvs 2194: {
2195: b++;
2196: /* search the url end */
2197: e = b;
1.82 ! cvs 2198: while (*e != EOS && *e != '"')
1.1 cvs 2199: e++;
2200: }
2201: else
2202: {
2203: /* search the url end */
2204: e = b;
1.82 ! cvs 2205: while (*e != EOS && *e != ')')
1.1 cvs 2206: e++;
2207: }
1.82 ! cvs 2208: if (*e != EOS)
1.1 cvs 2209: {
2210: len = (int)(e - b);
1.82 ! cvs 2211: ptr = (char*) TtaGetMemory (len+1);
! 2212: strncpy (ptr, b, len);
! 2213: ptr[len] = EOS;
1.1 cvs 2214: }
2215: }
2216: }
2217: return (ptr);
2218: }
2219:
2220:
2221: /*----------------------------------------------------------------------
1.59 cvs 2222: ParseCSSBackgroundImage: parse a CSS BackgroundImage attribute string.
1.1 cvs 2223: ----------------------------------------------------------------------*/
1.79 cvs 2224: static char *ParseCSSBackgroundImage (Element element, PSchema tsch,
2225: PresentationContext context,
2226: char *cssRule, CSSInfoPtr css,
2227: ThotBool isHTML)
1.1 cvs 2228: {
1.49 cvs 2229: Element el;
2230: GenericContext gblock;
1.71 cvs 2231: PresentationContext sblock;
1.1 cvs 2232: BackgroundImageCallbackPtr callblock;
1.49 cvs 2233: PresentationValue image, value;
1.79 cvs 2234: char *url;
1.82 ! cvs 2235: char *bg_image;
1.79 cvs 2236: char saved;
2237: char *base;
2238: char tempname[MAX_LENGTH];
2239: char imgname[MAX_LENGTH];
1.49 cvs 2240: unsigned int savedtype = 0;
2241: ThotBool moved;
1.1 cvs 2242:
2243: /* default element for FetchImage */
2244: el = TtaGetMainRoot (context->doc);
2245: /* move the BODY rule to the HTML element */
2246: moved = (context->type == HTML_EL_BODY && isHTML);
2247: if (moved)
2248: {
2249: if (element)
2250: element = el;
2251: else
2252: {
2253: savedtype = context->type;
2254: context->type = HTML_EL_HTML;
2255: }
2256: }
2257: else if (element)
2258: el = element;
2259:
2260: url = NULL;
1.82 ! cvs 2261: cssRule = SkipBlanksAndComments (cssRule);
! 2262: if (!strncasecmp (cssRule, "url", 3))
1.1 cvs 2263: {
2264: cssRule += 3;
1.82 ! cvs 2265: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2266: if (*cssRule == '(')
2267: {
2268: cssRule++;
1.82 ! cvs 2269: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 2270: /*** Caution: Strings can either be written with double quotes or
2271: with single quotes. Only double quotes are handled here.
2272: Escaped quotes are not handled. See function SkipQuotedString */
2273: if (*cssRule == '"')
2274: {
2275: cssRule++;
2276: base = cssRule;
1.82 ! cvs 2277: while (*cssRule != EOS && *cssRule != '"')
1.1 cvs 2278: cssRule++;
2279: }
2280: else
2281: {
2282: base = cssRule;
2283: while (*cssRule != EOS && *cssRule != ')')
2284: cssRule++;
2285: }
2286: saved = *cssRule;
1.82 ! cvs 2287: *cssRule = EOS;
! 2288: url = TtaStrdup (base);
1.1 cvs 2289: *cssRule = saved;
2290: if (saved == '"')
2291: /* we need to skip two characters */
2292: cssRule++;
2293: }
2294: cssRule++;
2295:
2296: if (context->destroy)
2297: {
2298: /* remove the background image PRule */
2299: image.pointer = NULL;
2300: TtaSetStylePresentation (PRBackgroundPicture, element, tsch, context, image);
2301: if (TtaGetStylePresentation (PRFillPattern, element, tsch, context, &value) < 0)
2302: {
2303: /* there is no FillPattern rule -> remove ShowBox rule */
2304: value.typed_data.value = 1;
2305: value.typed_data.unit = STYLE_UNIT_REL;
2306: value.typed_data.real = FALSE;
2307: TtaSetStylePresentation (PRShowBox, element, tsch, context, value);
2308: }
2309: }
2310: else if (url)
2311: {
1.30 cvs 2312: bg_image = TtaGetEnvString ("ENABLE_BG_IMAGES");
1.82 ! cvs 2313: if (bg_image == NULL || !strcasecmp (bg_image, "yes"))
1.1 cvs 2314: {
2315: callblock = (BackgroundImageCallbackPtr) TtaGetMemory(sizeof(BackgroundImageCallbackBlock));
2316: if (callblock != NULL)
2317: {
2318: callblock->el = element;
2319: callblock->tsch = tsch;
2320: if (element == NULL)
1.18 cvs 2321: {
2322: gblock = (GenericContext) context;
2323: memcpy (&callblock->context.generic, gblock,
2324: sizeof (GenericContextBlock));
2325: }
2326: else
2327: {
2328: sblock = context;
2329: memcpy (&callblock->context.specific, sblock,
2330: sizeof(PresentationContextBlock));
2331: }
2332:
2333: /* check if the image url is related to an external CSS */
2334: if (css != NULL && css->category == CSS_EXTERNAL_STYLE)
2335: {
2336: NormalizeURL (url, 0, tempname, imgname, css->url);
2337: /* fetch and display background image of element */
1.49 cvs 2338: FetchImage (context->doc, el, tempname, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2339: }
2340: else
1.49 cvs 2341: FetchImage (context->doc, el, url, AMAYA_LOAD_IMAGE, ParseCSSBackgroundImageCallback, callblock);
1.18 cvs 2342: }
2343: }
2344:
2345: if (url)
2346: TtaFreeMemory (url);
2347: }
2348: }
2349:
2350: /* restore the refered element */
2351: if (moved && !element)
2352: context->type = savedtype;
2353: return (cssRule);
2354: }
2355:
2356: /*----------------------------------------------------------------------
1.59 cvs 2357: ParseCSSBackgroundRepeat: parse a CSS BackgroundRepeat attribute string.
1.18 cvs 2358: ----------------------------------------------------------------------*/
1.79 cvs 2359: static char *ParseCSSBackgroundRepeat (Element element, PSchema tsch,
2360: PresentationContext context, char *cssRule, CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2361: {
2362: PresentationValue repeat;
2363: unsigned int savedtype = 0;
2364: ThotBool moved;
2365:
2366: /* move the BODY rule to the HTML element */
2367: moved = (context->type == HTML_EL_BODY && isHTML);
2368: if (moved)
2369: {
2370: if (element)
2371: element = TtaGetMainRoot (context->doc);
2372: else
2373: {
2374: savedtype = context->type;
2375: context->type = HTML_EL_HTML;
2376: }
2377: }
2378:
2379: repeat.typed_data.value = STYLE_REALSIZE;
2380: repeat.typed_data.unit = STYLE_UNIT_REL;
2381: repeat.typed_data.real = FALSE;
1.82 ! cvs 2382: cssRule = SkipBlanksAndComments (cssRule);
! 2383: if (!strncasecmp (cssRule, "no-repeat", 9))
1.18 cvs 2384: repeat.typed_data.value = STYLE_REALSIZE;
1.82 ! cvs 2385: else if (!strncasecmp (cssRule, "repeat-y", 8))
1.18 cvs 2386: repeat.typed_data.value = STYLE_VREPEAT;
1.82 ! cvs 2387: else if (!strncasecmp (cssRule, "repeat-x", 8))
1.18 cvs 2388: repeat.typed_data.value = STYLE_HREPEAT;
1.82 ! cvs 2389: else if (!strncasecmp (cssRule, "repeat", 6))
1.18 cvs 2390: repeat.typed_data.value = STYLE_REPEAT;
2391: else
2392: return (cssRule);
2393:
2394: /* install the new presentation */
2395: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
2396: cssRule = SkipWord (cssRule);
2397:
2398: /* restore the refered element */
2399: if (moved && !element)
2400: context->type = savedtype;
2401: return (cssRule);
2402: }
2403:
2404: /*----------------------------------------------------------------------
1.59 cvs 2405: ParseCSSBackgroundAttachment: parse a CSS BackgroundAttachment
1.18 cvs 2406: attribute string.
2407: ----------------------------------------------------------------------*/
1.79 cvs 2408: static char *ParseCSSBackgroundAttachment (Element element, PSchema tsch,
2409: PresentationContext context,
2410: char *cssRule, CSSInfoPtr css,
2411: ThotBool isHTML)
1.18 cvs 2412: {
2413: unsigned int savedtype = 0;
2414: ThotBool moved;
1.1 cvs 2415:
1.18 cvs 2416: /* move the BODY rule to the HTML element */
2417: moved = (context->type == HTML_EL_BODY && isHTML);
2418: if (moved)
2419: {
2420: if (element)
2421: element = TtaGetMainRoot (context->doc);
2422: else
2423: {
2424: savedtype = context->type;
2425: context->type = HTML_EL_HTML;
1.1 cvs 2426: }
2427: }
2428:
1.82 ! cvs 2429: cssRule = SkipBlanksAndComments (cssRule);
! 2430: if (!strncasecmp (cssRule, "scroll", 6))
1.18 cvs 2431: cssRule = SkipWord (cssRule);
1.82 ! cvs 2432: else if (!strncasecmp (cssRule, "fixed", 5))
1.18 cvs 2433: cssRule = SkipWord (cssRule);
2434:
1.1 cvs 2435: /* restore the refered element */
2436: if (moved && !element)
2437: context->type = savedtype;
1.18 cvs 2438: return (cssRule);
1.1 cvs 2439: }
2440:
2441: /*----------------------------------------------------------------------
1.59 cvs 2442: ParseCSSBackgroundPosition: parse a CSS BackgroundPosition
1.1 cvs 2443: attribute string.
2444: ----------------------------------------------------------------------*/
1.79 cvs 2445: static char *ParseCSSBackgroundPosition (Element element, PSchema tsch,
2446: PresentationContext context,
2447: char *cssRule, CSSInfoPtr css,
2448: ThotBool isHTML)
1.1 cvs 2449: {
1.18 cvs 2450: PresentationValue repeat;
2451: unsigned int savedtype = 0;
2452: ThotBool moved;
2453: ThotBool ok;
1.1 cvs 2454:
2455: /* move the BODY rule to the HTML element */
2456: moved = (context->type == HTML_EL_BODY && isHTML);
2457: if (moved)
2458: {
2459: if (element)
2460: element = TtaGetMainRoot (context->doc);
2461: else
2462: {
2463: savedtype = context->type;
2464: context->type = HTML_EL_HTML;
2465: }
2466: }
2467:
1.82 ! cvs 2468: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 2469: ok = TRUE;
1.82 ! cvs 2470: if (!strncasecmp (cssRule, "left", 4))
1.18 cvs 2471: cssRule = SkipWord (cssRule);
1.82 ! cvs 2472: else if (!strncasecmp (cssRule, "right", 5))
1.18 cvs 2473: cssRule = SkipWord (cssRule);
1.82 ! cvs 2474: else if (!strncasecmp (cssRule, "center", 6))
1.18 cvs 2475: cssRule = SkipWord (cssRule);
1.82 ! cvs 2476: else if (!strncasecmp (cssRule, "top", 3))
1.18 cvs 2477: cssRule = SkipWord (cssRule);
1.82 ! cvs 2478: else if (!strncasecmp (cssRule, "bottom", 6))
1.18 cvs 2479: cssRule = SkipWord (cssRule);
1.82 ! cvs 2480: else if (isdigit (*cssRule))
1.18 cvs 2481: cssRule = SkipWord (cssRule);
2482: else
2483: ok = FALSE;
2484:
2485: if (ok)
2486: {
2487: /* force realsize for the background image */
2488: repeat.typed_data.value = STYLE_REALSIZE;
2489: repeat.typed_data.unit = STYLE_UNIT_REL;
2490: repeat.typed_data.real = FALSE;
2491: TtaSetStylePresentation (PRPictureMode, element, tsch, context, repeat);
2492: }
2493:
2494: /* restore the refered element */
2495: if (moved && !element)
2496: context->type = savedtype;
2497: return (cssRule);
2498: }
2499:
2500: /*----------------------------------------------------------------------
1.59 cvs 2501: ParseCSSBackground: parse a CSS background attribute
1.18 cvs 2502: ----------------------------------------------------------------------*/
1.79 cvs 2503: static char *ParseCSSBackground (Element element, PSchema tsch,
2504: PresentationContext context, char *cssRule,
2505: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2506: {
1.79 cvs 2507: char *ptr;
1.18 cvs 2508:
1.82 ! cvs 2509: cssRule = SkipBlanksAndComments (cssRule);
! 2510: while (*cssRule != ';' && *cssRule != EOS && *cssRule != ',')
1.18 cvs 2511: {
1.71 cvs 2512: /* perhaps a Background Image */
1.82 ! cvs 2513: if (!strncasecmp (cssRule, "url", 3))
1.63 cvs 2514: cssRule = ParseCSSBackgroundImage (element, tsch, context, cssRule,
2515: css, isHTML);
1.18 cvs 2516: /* perhaps a Background Attachment */
1.82 ! cvs 2517: else if (!strncasecmp (cssRule, "scroll", 6) ||
! 2518: !strncasecmp (cssRule, "fixed", 5))
1.63 cvs 2519: cssRule = ParseCSSBackgroundAttachment (element, tsch, context,
2520: cssRule, css, isHTML);
1.18 cvs 2521: /* perhaps a Background Repeat */
1.82 ! cvs 2522: else if (!strncasecmp (cssRule, "no-repeat", 9) ||
! 2523: !strncasecmp (cssRule, "repeat-y", 8) ||
! 2524: !strncasecmp (cssRule, "repeat-x", 8) ||
! 2525: !strncasecmp (cssRule, "repeat", 6))
! 2526: cssRule = ParseCSSBackgroundRepeat (element, tsch, context,
! 2527: cssRule, css, isHTML);
1.18 cvs 2528: /* perhaps a Background Position */
1.82 ! cvs 2529: else if (!strncasecmp (cssRule, "left", 4) ||
! 2530: !strncasecmp (cssRule, "right", 5) ||
! 2531: !strncasecmp (cssRule, "center", 6) ||
! 2532: !strncasecmp (cssRule, "top", 3) ||
! 2533: !strncasecmp (cssRule, "bottom", 6) ||
! 2534: isdigit (*cssRule))
1.63 cvs 2535: cssRule = ParseCSSBackgroundPosition (element, tsch, context,
2536: cssRule, css, isHTML);
1.18 cvs 2537: /* perhaps a Background Color */
2538: else
2539: {
2540: /* check if the rule has been found */
2541: ptr = cssRule;
1.82 ! cvs 2542: cssRule = ParseCSSBackgroundColor (element, tsch, context,
! 2543: cssRule, css, isHTML);
1.43 cvs 2544: if (ptr == cssRule)
1.18 cvs 2545: /* rule not found */
2546: cssRule = SkipProperty (cssRule);
2547: }
1.82 ! cvs 2548: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 2549: }
2550: return (cssRule);
2551: }
2552:
1.59 cvs 2553: /*----------------------------------------------------------------------
1.60 cvs 2554: ParseCSSPageBreakBefore: parse a CSS page-break-before attribute
1.59 cvs 2555: ----------------------------------------------------------------------*/
1.79 cvs 2556: static char *ParseCSSPageBreakBefore (Element element, PSchema tsch,
2557: PresentationContext context, char *cssRule,
2558: CSSInfoPtr css, ThotBool isHTML)
1.59 cvs 2559: {
2560: PresentationValue page;
2561:
2562: page.typed_data.unit = STYLE_UNIT_INVALID;
2563: page.typed_data.real = FALSE;
1.82 ! cvs 2564: cssRule = SkipBlanksAndComments (cssRule);
! 2565: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 2566: {
2567: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2568: page.typed_data.value = STYLE_AUTO;
2569: }
1.82 ! cvs 2570: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 2571: {
2572: page.typed_data.unit = STYLE_UNIT_REL;
2573: page.typed_data.value = STYLE_ALWAYS;
2574: }
1.82 ! cvs 2575: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 2576: {
2577: page.typed_data.unit = STYLE_UNIT_REL;
2578: page.typed_data.value = STYLE_AVOID;
2579: }
1.82 ! cvs 2580: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 2581: {
2582: page.typed_data.unit = STYLE_UNIT_REL;
2583: page.typed_data.value = STYLE_PAGELEFT;
2584: }
1.82 ! cvs 2585: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 2586: {
2587: page.typed_data.unit = STYLE_UNIT_REL;
2588: page.typed_data.value = STYLE_PAGERIGHT;
2589: }
1.82 ! cvs 2590: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 2591: {
2592: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2593: page.typed_data.value = STYLE_INHERIT;
2594: }
2595: cssRule = SkipWord (cssRule);
2596: /* install the new presentation */
2597: if (page.typed_data.unit == STYLE_UNIT_REL &&
2598: page.typed_data.value == STYLE_ALWAYS)
2599: TtaSetStylePresentation (PRPageBefore, element, tsch, context, page);
2600: return (cssRule);
2601: }
2602:
2603: /*----------------------------------------------------------------------
1.60 cvs 2604: ParseCSSPageBreakAfter: parse a CSS page-break-after attribute
1.59 cvs 2605: ----------------------------------------------------------------------*/
1.79 cvs 2606: static char *ParseCSSPageBreakAfter (Element element, PSchema tsch,
2607: PresentationContext context,
2608: char *cssRule, CSSInfoPtr css,
2609: ThotBool isHTML)
1.59 cvs 2610: {
2611: PresentationValue page;
2612:
2613: page.typed_data.unit = STYLE_UNIT_INVALID;
2614: page.typed_data.real = FALSE;
1.82 ! cvs 2615: cssRule = SkipBlanksAndComments (cssRule);
! 2616: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 2617: {
2618: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2619: page.typed_data.value = STYLE_AUTO;
2620: }
1.82 ! cvs 2621: else if (!strncasecmp (cssRule, "always", 6))
1.59 cvs 2622: {
2623: page.typed_data.unit = STYLE_UNIT_REL;
2624: page.typed_data.value = STYLE_ALWAYS;
2625: }
1.82 ! cvs 2626: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 2627: {
2628: page.typed_data.unit = STYLE_UNIT_REL;
2629: page.typed_data.value = STYLE_AVOID;
2630: }
1.82 ! cvs 2631: else if (!strncasecmp (cssRule, "left", 4))
1.59 cvs 2632: {
2633: page.typed_data.unit = STYLE_UNIT_REL;
2634: page.typed_data.value = STYLE_PAGELEFT;
2635: }
1.82 ! cvs 2636: else if (!strncasecmp (cssRule, "right", 5))
1.59 cvs 2637: {
2638: page.typed_data.unit = STYLE_UNIT_REL;
2639: page.typed_data.value = STYLE_PAGERIGHT;
2640: }
1.82 ! cvs 2641: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 2642: {
2643: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2644: page.typed_data.value = STYLE_INHERIT;
2645: }
2646: cssRule = SkipWord (cssRule);
2647: /* install the new presentation */
2648: /*if (page.typed_data.unit == STYLE_UNIT_REL)
2649: TtaSetStylePresentation (PRPageAfter, element, tsch, context, page);*/
2650: return (cssRule);
2651: }
2652:
2653: /*----------------------------------------------------------------------
1.60 cvs 2654: ParseCSSPageBreakInside: parse a CSS page-break-inside attribute
1.59 cvs 2655: ----------------------------------------------------------------------*/
1.79 cvs 2656: static char *ParseCSSPageBreakInside (Element element, PSchema tsch,
2657: PresentationContext context,
2658: char *cssRule, CSSInfoPtr css,
2659: ThotBool isHTML)
1.59 cvs 2660: {
2661: PresentationValue page;
2662:
2663: page.typed_data.unit = STYLE_UNIT_INVALID;
2664: page.typed_data.real = FALSE;
1.82 ! cvs 2665: cssRule = SkipBlanksAndComments (cssRule);
! 2666: if (!strncasecmp (cssRule, "auto", 4))
1.59 cvs 2667: {
2668: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2669: page.typed_data.value = STYLE_AUTO;
2670: }
1.82 ! cvs 2671: else if (!strncasecmp (cssRule, "avoid", 5))
1.59 cvs 2672: {
2673: page.typed_data.unit = STYLE_UNIT_REL;
2674: page.typed_data.value = STYLE_AVOID;
2675: }
1.82 ! cvs 2676: else if (!strncasecmp (cssRule, "inherit", 7))
1.59 cvs 2677: {
2678: /*page.typed_data.unit = STYLE_UNIT_REL;*/
2679: page.typed_data.value = STYLE_INHERIT;
2680: }
2681: cssRule = SkipWord (cssRule);
2682: /* install the new presentation */
2683: if (page.typed_data.unit == STYLE_UNIT_REL &&
2684: page.typed_data.value == STYLE_AVOID)
2685: TtaSetStylePresentation (PRPageInside, element, tsch, context, page);
2686: return (cssRule);
2687: }
1.18 cvs 2688:
2689:
1.60 cvs 2690: /*----------------------------------------------------------------------
1.63 cvs 2691: ParseSVGStrokeWidth: parse a SVG stroke-width property value.
1.60 cvs 2692: ----------------------------------------------------------------------*/
1.79 cvs 2693: static char *ParseSVGStrokeWidth (Element element, PSchema tsch,
2694: PresentationContext context, char *cssRule,
2695: CSSInfoPtr css, ThotBool isHTML)
1.60 cvs 2696: {
2697: PresentationValue width;
2698:
1.82 ! cvs 2699: cssRule = SkipBlanksAndComments (cssRule);
1.60 cvs 2700: width.typed_data.value = 0;
2701: width.typed_data.unit = STYLE_UNIT_INVALID;
2702: width.typed_data.real = FALSE;
1.82 ! cvs 2703: if (isdigit (*cssRule))
1.60 cvs 2704: cssRule = ParseCSSUnit (cssRule, &width);
2705: if (width.typed_data.unit != STYLE_UNIT_INVALID)
2706: {
2707: TtaSetStylePresentation (PRLineWeight, element, tsch, context, width);
2708: width.typed_data.value = 1;
2709: width.typed_data.unit = STYLE_UNIT_REL;
2710: }
2711: return (cssRule);
2712: }
2713:
1.18 cvs 2714: /************************************************************************
2715: * *
2716: * FUNCTIONS STYLE DECLARATIONS *
2717: * *
2718: ************************************************************************/
2719: /*
1.59 cvs 2720: * NOTE: Long attribute name MUST be placed before shortened ones !
1.18 cvs 2721: * e.g. "FONT-SIZE" must be placed before "FONT"
2722: */
2723: static CSSProperty CSSProperties[] =
2724: {
1.82 ! cvs 2725: {"font-family", ParseCSSFontFamily},
! 2726: {"font-style", ParseCSSFontStyle},
! 2727: {"font-variant", ParseCSSFontVariant},
! 2728: {"font-weight", ParseCSSFontWeight},
! 2729: {"font-size", ParseCSSFontSize},
! 2730: {"font", ParseCSSFont},
! 2731:
! 2732: {"color", ParseCSSForeground},
! 2733: {"background-color", ParseCSSBackgroundColor},
! 2734: {"background-image", ParseCSSBackgroundImage},
! 2735: {"background-repeat", ParseCSSBackgroundRepeat},
! 2736: {"background-attachment", ParseCSSBackgroundAttachment},
! 2737: {"background-position", ParseCSSBackgroundPosition},
! 2738: {"background", ParseCSSBackground},
! 2739:
! 2740: {"word-spacing", ParseCSSWordSpacing},
! 2741: {"letter-spacing", ParseCSSLetterSpacing},
! 2742: {"text-decoration", ParseCSSTextDecoration},
! 2743: {"vertical-align", ParseCSSVerticalAlign},
! 2744: {"text-transform", ParseCSSTextTransform},
! 2745: {"text-align", ParseCSSTextAlign},
! 2746: {"text-indent", ParseCSSTextIndent},
! 2747: {"line-height", ParseCSSLineSpacing},
! 2748:
! 2749: {"margin-top", ParseCSSMarginTop},
! 2750: {"margin-right", ParseCSSMarginRight},
! 2751: {"margin-bottom", ParseCSSMarginBottom},
! 2752: {"margin-left", ParseCSSMarginLeft},
! 2753: {"margin", ParseCSSMargin},
! 2754:
! 2755: {"padding-top", ParseCSSPaddingTop},
! 2756: {"padding-right", ParseCSSPaddingRight},
! 2757: {"padding-bottom", ParseCSSPaddingBottom},
! 2758: {"padding-left", ParseCSSPaddingLeft},
! 2759: {"padding", ParseCSSPadding},
! 2760:
! 2761: {"border-top-width", ParseCSSBorderTopWidth},
! 2762: {"border-right-width", ParseCSSBorderRightWidth},
! 2763: {"border-bottom-width", ParseCSSBorderBottomWidth},
! 2764: {"border-left-width", ParseCSSBorderLeftWidth},
! 2765: {"border-width", ParseCSSBorderWidth},
! 2766: {"border-top-color", ParseCSSBorderColorTop},
! 2767: {"border-right-color", ParseCSSBorderColorRight},
! 2768: {"border-bottom-color", ParseCSSBorderColorBottom},
! 2769: {"border-left-color", ParseCSSBorderColorLeft},
! 2770: {"border-color", ParseCSSBorderColor},
! 2771: {"border-top-style", ParseCSSBorderStyleTop},
! 2772: {"border-right-style", ParseCSSBorderStyleRight},
! 2773: {"border-bottom-style", ParseCSSBorderStyleBottom},
! 2774: {"border-left-style", ParseCSSBorderStyleLeft},
! 2775: {"border-style", ParseCSSBorderStyle},
! 2776: {"border-top", ParseCSSBorderTop},
! 2777: {"border-right", ParseCSSBorderRight},
! 2778: {"border-bottom", ParseCSSBorderBottom},
! 2779: {"border-left", ParseCSSBorderLeft},
! 2780: {"border", ParseCSSBorder},
! 2781:
! 2782: {"width", ParseCSSWidth},
! 2783: {"height", ParseCSSHeight},
! 2784: {"float", ParseCSSFloat},
! 2785: {"clear", ParseCSSClear},
! 2786:
! 2787: {"display", ParseCSSDisplay},
! 2788: {"white-space", ParseCSSWhiteSpace},
! 2789:
! 2790: {"list-style-type", ParseCSSListStyleType},
! 2791: {"list-style-image", ParseCSSListStyleImage},
! 2792: {"list-style-position", ParseCSSListStylePosition},
! 2793: {"list-style", ParseCSSListStyle},
! 2794:
! 2795: {"page-break-before", ParseCSSPageBreakBefore},
! 2796: {"page-break-after", ParseCSSPageBreakAfter},
! 2797: {"page-break-inside", ParseCSSPageBreakInside},
1.60 cvs 2798:
2799: /* SVG extensions */
1.82 ! cvs 2800: {"stroke-width", ParseSVGStrokeWidth},
! 2801: {"stroke", ParseSVGStroke},
! 2802: {"fill", ParseSVGFill}
1.18 cvs 2803: };
2804: #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSProperties) / sizeof(CSSProperty))
2805:
2806: /*----------------------------------------------------------------------
1.59 cvs 2807: ParseCSSRule: parse a CSS Style string
1.18 cvs 2808: we expect the input string describing the style to be of the
1.59 cvs 2809: form: PRORPERTY: DESCRIPTION [ ; PROPERTY: DESCRIPTION ] *
1.18 cvs 2810: but tolerate incorrect or incomplete input
2811: ----------------------------------------------------------------------*/
1.79 cvs 2812: static void ParseCSSRule (Element element, PSchema tsch,
2813: PresentationContext context, char *cssRule,
2814: CSSInfoPtr css, ThotBool isHTML)
1.18 cvs 2815: {
1.34 cvs 2816: DisplayMode dispMode;
1.79 cvs 2817: char *p = NULL;
1.18 cvs 2818: int lg;
1.34 cvs 2819: unsigned int i;
1.76 cvs 2820: ThotBool found;
1.18 cvs 2821:
1.34 cvs 2822: /* avoid too many redisplay */
2823: dispMode = TtaGetDisplayMode (context->doc);
2824: if (dispMode == DisplayImmediately)
2825: TtaSetDisplayMode (context->doc, DeferredDisplay);
2826:
1.82 ! cvs 2827: while (*cssRule != EOS)
1.18 cvs 2828: {
1.82 ! cvs 2829: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 2830:
2831: found = FALSE;
2832: /* look for the type of property */
2833: for (i = 0; i < NB_CSSSTYLEATTRIBUTE && !found; i++)
2834: {
1.82 ! cvs 2835: lg = strlen (CSSProperties[i].name);
! 2836: if (!strncasecmp (cssRule, CSSProperties[i].name, lg))
1.18 cvs 2837: {
2838: cssRule += lg;
2839: found = TRUE;
2840: i--;
2841: }
2842: }
2843:
2844: if (i == NB_CSSSTYLEATTRIBUTE)
2845: cssRule = SkipProperty (cssRule);
2846: else
2847: {
2848: /* update index and skip the ":" indicator if present */
1.82 ! cvs 2849: cssRule = SkipBlanksAndComments (cssRule);
! 2850: if (*cssRule == ':')
1.18 cvs 2851: {
2852: cssRule++;
1.82 ! cvs 2853: cssRule = SkipBlanksAndComments (cssRule);
1.74 cvs 2854: /* try to parse the value associated with this property */
2855: if (CSSProperties[i].parsing_function != NULL)
1.61 cvs 2856: {
1.75 cvs 2857: p = CSSProperties[i].parsing_function (element, tsch, context,
2858: cssRule, css, isHTML);
1.74 cvs 2859: /* update index and skip the ";" separator if present */
2860: cssRule = p;
1.61 cvs 2861: }
1.18 cvs 2862: }
1.74 cvs 2863: else
2864: cssRule = SkipProperty (cssRule);
1.18 cvs 2865: }
2866: /* next property */
1.82 ! cvs 2867: cssRule = SkipBlanksAndComments (cssRule);
! 2868: if (*cssRule == ',' || *cssRule == ';')
1.18 cvs 2869: {
2870: cssRule++;
1.82 ! cvs 2871: cssRule = SkipBlanksAndComments (cssRule);
1.18 cvs 2872: }
2873: }
1.34 cvs 2874:
2875: /* restore the display mode */
2876: if (dispMode == DisplayImmediately)
2877: TtaSetDisplayMode (context->doc, dispMode);
1.18 cvs 2878: }
1.1 cvs 2879:
2880:
2881: /*----------------------------------------------------------------------
1.59 cvs 2882: PToCss: translate a PresentationSetting to the
1.18 cvs 2883: equivalent CSS string, and add it to the buffer given as the
1.67 cvs 2884: argument. It is used when extracting the CSS string from actual
2885: presentation.
2886: el is the element for which the style rule is generated
1.18 cvs 2887:
2888: All the possible values returned by the presentation drivers are
2889: described in thotlib/include/presentation.h
2890: -----------------------------------------------------------------------*/
1.79 cvs 2891: void PToCss (PresentationSetting settings, char *buffer, int len, Element el)
1.1 cvs 2892: {
1.76 cvs 2893: ElementType elType;
1.18 cvs 2894: float fval = 0;
2895: unsigned short red, green, blue;
2896: int add_unit = 0;
2897: unsigned int unit, i;
2898: ThotBool real = FALSE;
2899:
1.82 ! cvs 2900: buffer[0] = EOS;
1.18 cvs 2901: if (len < 40)
2902: return;
2903:
2904: unit = settings->value.typed_data.unit;
2905: if (settings->value.typed_data.real)
2906: {
2907: real = TRUE;
2908: fval = (float) settings->value.typed_data.value;
2909: fval /= 1000;
2910: }
1.1 cvs 2911:
1.18 cvs 2912: switch (settings->type)
1.1 cvs 2913: {
1.18 cvs 2914: case PRVisibility:
2915: break;
2916: case PRFont:
2917: switch (settings->value.typed_data.value)
2918: {
2919: case STYLE_FONT_HELVETICA:
1.82 ! cvs 2920: strcpy (buffer, "font-family: helvetica");
1.18 cvs 2921: break;
2922: case STYLE_FONT_TIMES:
1.82 ! cvs 2923: strcpy (buffer, "font-family: times");
1.18 cvs 2924: break;
2925: case STYLE_FONT_COURIER:
1.82 ! cvs 2926: strcpy (buffer, "font-family: courier");
1.18 cvs 2927: break;
2928: }
2929: break;
2930: case PRStyle:
2931: switch (settings->value.typed_data.value)
2932: {
2933: case STYLE_FONT_ROMAN:
1.82 ! cvs 2934: strcpy (buffer, "font-style: normal");
1.18 cvs 2935: break;
2936: case STYLE_FONT_ITALICS:
1.82 ! cvs 2937: strcpy (buffer, "font-style: italic");
1.18 cvs 2938: break;
2939: case STYLE_FONT_OBLIQUE:
1.82 ! cvs 2940: strcpy (buffer, "font-style: oblique");
1.18 cvs 2941: break;
1.20 cvs 2942: }
2943: break;
2944: case PRWeight:
2945: switch (settings->value.typed_data.value)
2946: {
2947: case STYLE_WEIGHT_BOLD:
1.82 ! cvs 2948: strcpy (buffer, "font-weight: bold");
1.20 cvs 2949: break;
2950: case STYLE_WEIGHT_NORMAL:
1.82 ! cvs 2951: strcpy (buffer, "font-weight: normal");
1.18 cvs 2952: break;
2953: }
2954: break;
2955: case PRSize:
2956: if (unit == STYLE_UNIT_REL)
2957: {
2958: if (real)
2959: {
1.82 ! cvs 2960: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 2961: add_unit = 1;
2962: }
2963: else
2964: switch (settings->value.typed_data.value)
2965: {
2966: case 1:
1.82 ! cvs 2967: strcpy (buffer, "font-size: xx-small");
1.18 cvs 2968: break;
2969: case 2:
1.82 ! cvs 2970: strcpy (buffer, "font-size: x-small");
1.18 cvs 2971: break;
2972: case 3:
1.82 ! cvs 2973: strcpy (buffer, "font-size: small");
1.18 cvs 2974: break;
2975: case 4:
1.82 ! cvs 2976: strcpy (buffer, "font-size: medium");
1.18 cvs 2977: break;
2978: case 5:
1.82 ! cvs 2979: strcpy (buffer, "font-size: large");
1.18 cvs 2980: break;
2981: case 6:
1.82 ! cvs 2982: strcpy (buffer, "font-size: x-large");
1.18 cvs 2983: break;
2984: case 7:
2985: case 8:
2986: case 9:
2987: case 10:
2988: case 11:
2989: case 12:
1.82 ! cvs 2990: strcpy (buffer, "font-size: xx-large");
1.18 cvs 2991: break;
2992: }
2993: }
2994: else
2995: {
2996: if (real)
1.82 ! cvs 2997: sprintf (buffer, "font-size: %g", fval);
1.18 cvs 2998: else
1.82 ! cvs 2999: sprintf (buffer, "font-size: %d",
1.67 cvs 3000: settings->value.typed_data.value);
1.18 cvs 3001: add_unit = 1;
3002: }
3003: break;
3004: case PRUnderline:
3005: switch (settings->value.typed_data.value)
3006: {
3007: case STYLE_UNDERLINE:
1.82 ! cvs 3008: strcpy (buffer, "text-decoration: underline");
1.18 cvs 3009: break;
3010: case STYLE_OVERLINE:
1.82 ! cvs 3011: strcpy (buffer, "text-decoration: overline");
1.18 cvs 3012: break;
3013: case STYLE_CROSSOUT:
1.82 ! cvs 3014: strcpy (buffer, "text-decoration: line-through");
1.18 cvs 3015: break;
3016: }
3017: break;
3018: case PRIndent:
3019: if (real)
1.82 ! cvs 3020: sprintf (buffer, "text-indent: %g", fval);
1.18 cvs 3021: else
1.82 ! cvs 3022: sprintf (buffer, "text-indent: %d",
1.67 cvs 3023: settings->value.typed_data.value);
1.18 cvs 3024: add_unit = 1;
3025: break;
3026: case PRLineSpacing:
3027: if (real)
1.82 ! cvs 3028: sprintf (buffer, "line-height: %g", fval);
1.1 cvs 3029: else
1.82 ! cvs 3030: sprintf (buffer, "line-height: %d",
1.67 cvs 3031: settings->value.typed_data.value);
1.18 cvs 3032: add_unit = 1;
3033: break;
3034: case PRAdjust:
3035: switch (settings->value.typed_data.value)
1.1 cvs 3036: {
1.18 cvs 3037: case STYLE_ADJUSTLEFT:
1.82 ! cvs 3038: strcpy (buffer, "text-align: left");
1.18 cvs 3039: break;
3040: case STYLE_ADJUSTRIGHT:
1.82 ! cvs 3041: strcpy (buffer, "text-align: right");
1.18 cvs 3042: break;
3043: case STYLE_ADJUSTCENTERED:
1.82 ! cvs 3044: strcpy (buffer, "text-align: center");
1.18 cvs 3045: break;
3046: case STYLE_ADJUSTLEFTWITHDOTS:
1.82 ! cvs 3047: strcpy (buffer, "text-align: left");
1.81 cvs 3048: break;
3049: case STYLE_ADJUSTJUSTIFY:
1.82 ! cvs 3050: strcpy (buffer, "text-align: justify");
1.18 cvs 3051: break;
1.1 cvs 3052: }
1.18 cvs 3053: break;
3054: case PRHyphenate:
3055: break;
3056: case PRFillPattern:
3057: break;
3058: case PRBackground:
3059: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3060: elType = TtaGetElementType(el);
3061: #ifdef GRAPHML
1.82 ! cvs 3062: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "GraphML") == 0)
! 3063: sprintf (buffer, "fill: #%02X%02X%02X", red, green, blue);
1.67 cvs 3064: else
1.76 cvs 3065: #endif /* GRAPHML */
1.82 ! cvs 3066: sprintf (buffer, "background-color: #%02X%02X%02X", red, green,
1.67 cvs 3067: blue);
1.18 cvs 3068: break;
3069: case PRForeground:
3070: TtaGiveThotRGB (settings->value.typed_data.value, &red, &green, &blue);
1.76 cvs 3071: elType = TtaGetElementType(el);
3072: #ifdef GRAPHML
1.82 ! cvs 3073: if (strcmp(TtaGetSSchemaName (elType.ElSSchema), "GraphML") == 0)
! 3074: sprintf (buffer, "stroke: #%02X%02X%02X", red, green, blue);
1.67 cvs 3075: else
1.76 cvs 3076: #endif /* GRAPHML */
1.82 ! cvs 3077: sprintf (buffer, "color: #%02X%02X%02X", red, green, blue);
1.67 cvs 3078: break;
3079: case PRLineWeight:
1.76 cvs 3080: elType = TtaGetElementType(el);
3081: #ifdef GRAPHML
1.82 ! cvs 3082: if (!strcmp(TtaGetSSchemaName (elType.ElSSchema), "GraphML"))
1.76 cvs 3083: #endif /* GRAPHML */
1.69 cvs 3084: {
3085: if (real)
1.82 ! cvs 3086: sprintf (buffer, "stroke-width: %g", fval);
1.69 cvs 3087: else
1.82 ! cvs 3088: sprintf (buffer, "stroke-width: %d",
1.69 cvs 3089: settings->value.typed_data.value);
3090: }
1.67 cvs 3091: add_unit = 1;
1.18 cvs 3092: break;
1.67 cvs 3093:
1.40 cvs 3094: case PRMarginTop:
1.18 cvs 3095: if (real)
1.82 ! cvs 3096: sprintf (buffer, "marging-top: %g", fval);
1.18 cvs 3097: else
1.82 ! cvs 3098: sprintf (buffer, "marging-top: %d",
1.67 cvs 3099: settings->value.typed_data.value);
1.18 cvs 3100: add_unit = 1;
3101: break;
1.40 cvs 3102: case PRMarginLeft:
1.18 cvs 3103: if (real)
1.82 ! cvs 3104: sprintf (buffer, "margin-left: %g", fval);
1.18 cvs 3105: else
1.82 ! cvs 3106: sprintf (buffer, "margin-left: %d",
1.67 cvs 3107: settings->value.typed_data.value);
1.18 cvs 3108: add_unit = 1;
3109: break;
3110: case PRHeight:
3111: if (real)
1.82 ! cvs 3112: sprintf (buffer, "height: %g", fval);
1.18 cvs 3113: else
1.82 ! cvs 3114: sprintf (buffer, "height: %d", settings->value.typed_data.value);
1.18 cvs 3115: add_unit = 1;
3116: break;
3117: case PRWidth:
3118: if (real)
1.82 ! cvs 3119: sprintf (buffer, "width: %g", fval);
1.1 cvs 3120: else
1.82 ! cvs 3121: sprintf (buffer, "width: %d", settings->value.typed_data.value);
1.18 cvs 3122: add_unit = 1;
3123: break;
3124: case PRLine:
3125: if (settings->value.typed_data.value == STYLE_INLINE)
1.82 ! cvs 3126: strcpy (buffer, "display: inline");
1.18 cvs 3127: else if (settings->value.typed_data.value == STYLE_NOTINLINE)
1.82 ! cvs 3128: strcpy (buffer, "display: block");
1.18 cvs 3129: break;
3130: case PRBackgroundPicture:
3131: if (settings->value.pointer != NULL)
1.82 ! cvs 3132: sprintf (buffer, "background-image: url(%s)",
1.67 cvs 3133: (char*)(settings->value.pointer));
1.1 cvs 3134: else
1.82 ! cvs 3135: sprintf (buffer, "background-image: none");
1.18 cvs 3136: break;
3137: case PRPictureMode:
3138: switch (settings->value.typed_data.value)
1.1 cvs 3139: {
1.18 cvs 3140: case STYLE_REALSIZE:
1.82 ! cvs 3141: sprintf (buffer, "background-repeat: no-repeat");
1.18 cvs 3142: break;
3143: case STYLE_REPEAT:
1.82 ! cvs 3144: sprintf (buffer, "background-repeat: repeat");
1.18 cvs 3145: break;
3146: case STYLE_VREPEAT:
1.82 ! cvs 3147: sprintf (buffer, "background-repeat: repeat-y");
1.18 cvs 3148: break;
3149: case STYLE_HREPEAT:
1.82 ! cvs 3150: sprintf (buffer, "background-repeat: repeat-x");
1.18 cvs 3151: break;
1.1 cvs 3152: }
1.18 cvs 3153: break;
3154: default:
3155: break;
1.1 cvs 3156: }
3157:
1.18 cvs 3158: if (add_unit)
1.1 cvs 3159: {
1.18 cvs 3160: /* add the unit string to the CSS string */
3161: for (i = 0; i < NB_UNITS; i++)
1.1 cvs 3162: {
1.18 cvs 3163: if (CSSUnitNames[i].unit == unit)
1.1 cvs 3164: {
1.82 ! cvs 3165: strcat (buffer, CSSUnitNames[i].sign);
1.18 cvs 3166: break;
1.1 cvs 3167: }
3168: }
3169: }
3170: }
3171:
3172: /*----------------------------------------------------------------------
1.59 cvs 3173: ParseHTMLSpecificStyle: parse and apply a CSS Style string.
1.18 cvs 3174: This function must be called when a specific style is applied to an
3175: element.
1.68 cvs 3176: The parameter isCSS is 1 when the specific presentation should be
3177: translated into a CSS rule, 0 if it should be translated into a
3178: presentation attribute.
1.1 cvs 3179: ----------------------------------------------------------------------*/
1.79 cvs 3180: void ParseHTMLSpecificStyle (Element el, char *cssRule, Document doc,
1.78 cvs 3181: int isCSS, ThotBool destroy)
1.1 cvs 3182: {
3183: PresentationContext context;
3184: ElementType elType;
1.14 cvs 3185: ThotBool isHTML;
1.1 cvs 3186:
3187: /* A rule applying to BODY is really meant to address HTML */
3188: elType = TtaGetElementType (el);
1.82 ! cvs 3189: isHTML = (strcmp (TtaGetSSchemaName (elType.ElSSchema), "HTML") == 0);
1.1 cvs 3190: /* create the context of the Specific presentation driver */
3191: context = TtaGetSpecificStyleContext (doc);
3192: if (context == NULL)
3193: return;
3194: context->type = elType.ElTypeNum;
1.68 cvs 3195: context->cssLevel = isCSS;
1.1 cvs 3196: context->destroy = destroy;
3197: /* Call the parser */
3198: ParseCSSRule (el, NULL, (PresentationContext) context, cssRule, NULL, isHTML);
3199: /* free the context */
3200: TtaFreeMemory(context);
3201: }
3202:
1.68 cvs 3203:
1.1 cvs 3204: /*----------------------------------------------------------------------
1.59 cvs 3205: ParseGenericSelector: Create a generic context for a given
1.1 cvs 3206: selector string. If the selector is made of multiple comma-
3207: separated selector items, it parses them one at a time and
3208: return the end of the selector string to be handled or NULL
3209: ----------------------------------------------------------------------*/
1.79 cvs 3210: static char *ParseGenericSelector (char *selector, char *cssRule,
3211: GenericContext ctxt, Document doc,
3212: CSSInfoPtr css)
3213: {
3214: ElementType elType;
3215: PSchema tsch;
3216: AttributeType attrType;
3217: char sel[MAX_ANCESTORS * 50];
3218: char *deb, *cur;
3219: char *structName;
3220: char *names[MAX_ANCESTORS];
3221: char *ids[MAX_ANCESTORS];
3222: char *classes[MAX_ANCESTORS];
3223: char *pseudoclasses[MAX_ANCESTORS];
3224: char *attrs[MAX_ANCESTORS];
3225: char *attrvals[MAX_ANCESTORS];
3226: int i, j, k, max, maxAttr;
3227: ThotBool isHTML;
3228: ThotBool level;
1.1 cvs 3229:
1.82 ! cvs 3230: sel[0] = EOS;
1.1 cvs 3231: for (i = 0; i < MAX_ANCESTORS; i++)
3232: {
1.25 cvs 3233: names[i] = NULL;
3234: ids[i] = NULL;
3235: classes[i] = NULL;
3236: pseudoclasses[i] = NULL;
3237: attrs[i] = NULL;
3238: attrvals[i] = NULL;
3239:
3240: ctxt->name[i] = 0;
3241: ctxt->names_nb[i] = 0;
3242: ctxt->attrType[i] = 0;
3243: ctxt->attrText[i] = NULL;
1.1 cvs 3244: }
1.25 cvs 3245: ctxt->box = 0;
3246: ctxt->type = 0;
1.68 cvs 3247: /* the priority level of the rule depends on the selector */
3248: ctxt->cssLevel = 0;
1.25 cvs 3249:
1.82 ! cvs 3250: selector = SkipBlanksAndComments (selector);
1.27 cvs 3251: cur = &sel[0];
1.25 cvs 3252: max = 0; /* number of loops */
1.1 cvs 3253: while (1)
3254: {
1.27 cvs 3255: deb = cur;
1.25 cvs 3256: /* copy an item of the selector into sel[] */
1.1 cvs 3257: /* put one word in the sel buffer */
1.82 ! cvs 3258: while (*selector != EOS && *selector != ',' &&
! 3259: *selector != '.' && *selector != ':' &&
! 3260: *selector != '#' && !TtaIsBlank (selector))
1.50 cvs 3261: *cur++ = *selector++;
1.82 ! cvs 3262: *cur++ = EOS; /* close the first string in sel[] */
! 3263: if (deb[0] != EOS)
1.27 cvs 3264: names[0] = deb;
1.25 cvs 3265: else
1.27 cvs 3266: names[0] = NULL;
3267: classes[0] = NULL;
3268: pseudoclasses[0] = NULL;
3269: ids[0] = NULL;
3270: attrs[0] = NULL;
3271: attrvals[0] = NULL;
1.25 cvs 3272:
1.27 cvs 3273: /* now names[0] points to the beginning of the parsed item
1.25 cvs 3274: and cur to the next chain to be parsed */
1.82 ! cvs 3275: if (*selector == ':' || *selector == '.' || *selector == '#')
1.25 cvs 3276: /* keep the element name which precedes the id or
3277: pseudo class or the class */
1.27 cvs 3278: deb = cur;
1.1 cvs 3279:
1.82 ! cvs 3280: if (*selector == '.')
1.1 cvs 3281: {
1.25 cvs 3282: /* copy into sel[] the class */
1.27 cvs 3283: classes[0] = cur;
1.1 cvs 3284: selector++;
1.82 ! cvs 3285: while (*selector != EOS && *selector != ',' &&
! 3286: *selector != '.' && *selector != ':' &&
! 3287: !TtaIsBlank (selector))
1.1 cvs 3288: *cur++ = *selector++;
1.82 ! cvs 3289: *cur++ = EOS;
1.1 cvs 3290: }
1.82 ! cvs 3291: else if (*selector == ':')
1.1 cvs 3292: {
1.25 cvs 3293: /* copy into sel[] the pseudoclass */
1.27 cvs 3294: pseudoclasses[0]= cur;
1.1 cvs 3295: selector++;
1.82 ! cvs 3296: while (*selector != EOS && *selector != ',' &&
! 3297: *selector != '.' && *selector != ':' &&
! 3298: !TtaIsBlank (selector))
1.50 cvs 3299: *cur++ = *selector++;
1.82 ! cvs 3300: *cur++ = EOS;
1.1 cvs 3301: }
1.82 ! cvs 3302: else if (*selector == '#')
1.1 cvs 3303: {
1.25 cvs 3304: /* copy into sel[] the attribute */
1.27 cvs 3305: ids[0] = cur;
1.1 cvs 3306: selector++;
1.82 ! cvs 3307: while (*selector != EOS && *selector != ',' &&
! 3308: *selector != '.' && *selector != ':' &&
! 3309: !TtaIsBlank (selector))
1.50 cvs 3310: *cur++ = *selector++;
1.82 ! cvs 3311: *cur++ = EOS;
1.1 cvs 3312: }
1.82 ! cvs 3313: else if (*selector == '[')
1.1 cvs 3314: {
1.25 cvs 3315: /* copy into sel[] the attribute */
1.27 cvs 3316: attrs[0] = cur;
1.25 cvs 3317: selector++;
1.82 ! cvs 3318: while (*selector != EOS && *selector != ']' && *selector != '=')
1.25 cvs 3319: *cur++ = *selector++;
1.82 ! cvs 3320: if (*cur == '=')
1.25 cvs 3321: {
3322: /* there is a value "xxxx" */
1.82 ! cvs 3323: *cur++ = EOS;
! 3324: while (*selector != EOS && *selector != ']' && *selector != '"')
1.25 cvs 3325: selector++;
1.82 ! cvs 3326: if (*selector != EOS)
1.25 cvs 3327: {
3328: /* we are now parsing the attribute value */
1.27 cvs 3329: attrvals[0] = cur;
1.25 cvs 3330: selector++;
1.82 ! cvs 3331: while (*selector != EOS && *selector != '"')
1.25 cvs 3332: *cur++ = *selector++;
1.82 ! cvs 3333: if (*selector != EOS)
1.25 cvs 3334: selector++;
3335: }
3336: }
1.82 ! cvs 3337: *cur++ = EOS;
1.1 cvs 3338: }
3339:
1.82 ! cvs 3340: selector = SkipBlanksAndComments (selector);
1.1 cvs 3341:
1.25 cvs 3342: /* is it a multi-level selector? */
1.82 ! cvs 3343: if (*selector == EOS)
1.1 cvs 3344: /* end of the selector */
3345: break;
1.82 ! cvs 3346: else if (*selector == ',')
1.1 cvs 3347: {
3348: /* end of the current selector */
3349: selector++;
3350: break;
3351: }
1.25 cvs 3352: else
3353: {
3354: /* shifts the list to make room for the new name */
3355: max++; /* a new level in ancestor tables */
3356: if (max == MAX_ANCESTORS)
3357: /* abort the CSS parsing */
3358: return (selector);
3359: for (i = max; i > 0; i--)
3360: {
3361: names[i] = names[i - 1];
3362: ids[i] = ids[i - 1];
3363: classes[i] = classes[i - 1];
3364: attrs[i] = attrs[i - 1];
3365: attrvals[i] = attrvals[i - 1];
3366: pseudoclasses[i] = pseudoclasses[i - 1];
3367: }
3368: }
1.1 cvs 3369: }
3370:
3371: /* Now set up the context block */
1.25 cvs 3372: i = 0;
3373: k = 0;
3374: j = 0;
1.35 cvs 3375: maxAttr = 0;
1.25 cvs 3376: while (i <= max)
3377: {
3378: if (names[i])
3379: {
3380: /* get the new element type of this name */
3381: GIType (names[i], &elType, doc);
3382: if (i == 0)
3383: {
3384: /* Store the element type */
3385: ctxt->type = elType.ElTypeNum;
1.32 cvs 3386: ctxt->name[0] = elType.ElTypeNum;
3387: ctxt->names_nb[0] = 0;
1.25 cvs 3388: ctxt->schema = elType.ElSSchema;
1.27 cvs 3389: k++;
1.25 cvs 3390: }
3391: else if (elType.ElTypeNum != 0)
3392: {
3393: /* look at the current context to see if the type is already
3394: stored */
3395: j = 0;
1.32 cvs 3396: while (j < k && ctxt->name[j] != elType.ElTypeNum)
1.25 cvs 3397: j++;
3398: if (j == k)
3399: {
3400: /* add a new entry */
3401: k++;
3402: ctxt->name[j] = elType.ElTypeNum;
3403: if (j != 0)
3404: ctxt->names_nb[j] = 1;
3405: }
3406: else
3407: /* increment the number of ancestor levels */
3408: ctxt->names_nb[j]++;
3409: }
3410: else
3411: {
3412: /* add a new entry */
3413: j = k;
3414: k++;
3415: }
3416: }
1.1 cvs 3417:
1.25 cvs 3418: /* store attributes information */
3419: if (classes[i])
3420: {
3421: ctxt->attrText[j] = classes[i];
3422: ctxt->attrType[j] = HTML_ATTR_Class;
1.79 cvs 3423: /* add a new entry */
1.80 cvs 3424: maxAttr = i + 1;
1.25 cvs 3425: }
1.79 cvs 3426: if (pseudoclasses[i])
1.25 cvs 3427: {
3428: ctxt->attrText[j] = pseudoclasses[i];
3429: ctxt->attrType[j] = HTML_ATTR_PseudoClass;
1.79 cvs 3430: /* add a new entry */
1.80 cvs 3431: maxAttr = i + 1;
1.25 cvs 3432: }
1.79 cvs 3433: if (ids[i])
1.25 cvs 3434: {
3435: ctxt->attrText[j] = ids[i];
3436: ctxt->attrType[j] = HTML_ATTR_ID;
1.80 cvs 3437: /* add a new entry */
3438: maxAttr = i + 1;
1.25 cvs 3439: }
1.79 cvs 3440: if (attrs[i])
1.25 cvs 3441: {
1.77 cvs 3442: MapHTMLAttribute (attrs[i], &attrType, names[i], &level, doc);
1.25 cvs 3443: ctxt->attrText[j] = attrvals[i];
3444: ctxt->attrType[j] = attrType.AttrTypeNum;
1.80 cvs 3445: maxAttr = i + 1;
1.25 cvs 3446: }
3447: i++;
1.1 cvs 3448: }
3449:
1.25 cvs 3450: /* sort the list of ancestors by name order */
3451: max = k;
3452: i = 1;
3453: while (i < max)
1.28 cvs 3454: {
3455: for (k = i + 1; k < max; k++)
3456: if (ctxt->name[i] > ctxt->name[k])
3457: {
3458: j = ctxt->name[i];
3459: ctxt->name[i] = ctxt->name[k];
3460: ctxt->name[k] = j;
3461: j = ctxt->names_nb[i];
3462: ctxt->names_nb[i] = ctxt->names_nb[k];
3463: ctxt->names_nb[k] = j;
3464: j = ctxt->attrType[i];
3465: ctxt->attrType[i] = ctxt->attrType[k];
3466: ctxt->attrType[k] = j;
3467: cur = ctxt->attrText[i];
3468: ctxt->attrText[i] = ctxt->attrText[k];
3469: ctxt->attrText[k] = cur;
3470: }
3471: i++;
3472: }
1.25 cvs 3473:
3474: /* Get the schema name of the main element */
3475: if (ctxt->schema == NULL)
1.1 cvs 3476: ctxt->schema = TtaGetDocumentSSchema (doc);
1.82 ! cvs 3477: isHTML = (strcmp (TtaGetSSchemaName (ctxt->schema), "HTML") == 0);
1.1 cvs 3478: tsch = GetPExtension (doc, ctxt->schema, css);
3479: structName = TtaGetSSchemaName (ctxt->schema);
3480: if (cssRule)
3481: ParseCSSRule (NULL, tsch, (PresentationContext) ctxt, cssRule, css, isHTML);
3482: return (selector);
3483: }
3484:
3485: /*----------------------------------------------------------------------
1.73 cvs 3486: ParseStyleDeclaration: parse a style declaration
3487: stored in the style element of a document
1.59 cvs 3488: We expect the style string to be of the form:
1.1 cvs 3489: [
3490: e.g: pinky, awful { color: pink, font-family: helvetica }
3491: ----------------------------------------------------------------------*/
1.79 cvs 3492: static void ParseStyleDeclaration (Element el, char *cssRule, Document doc,
3493: CSSInfoPtr css, ThotBool destroy)
1.1 cvs 3494: {
1.79 cvs 3495: GenericContext ctxt;
3496: char *decl_end;
3497: char *sel_end;
3498: char *selector;
3499: char saved1;
3500: char saved2;
1.1 cvs 3501:
3502: /* separate the selectors string */
1.82 ! cvs 3503: cssRule = SkipBlanksAndComments (cssRule);
1.1 cvs 3504: decl_end = cssRule;
1.82 ! cvs 3505: while (*decl_end != EOS && *decl_end != '{')
1.1 cvs 3506: decl_end++;
1.82 ! cvs 3507: if (*decl_end == EOS)
1.1 cvs 3508: return;
3509: /* verify and clean the selector string */
3510: sel_end = decl_end - 1;
1.82 ! cvs 3511: while (*sel_end == SPACE || *sel_end == BSPACE ||
! 3512: *sel_end == EOL || *sel_end == CR)
1.1 cvs 3513: sel_end--;
3514: sel_end++;
3515: saved1 = *sel_end;
1.82 ! cvs 3516: *sel_end = EOS;
1.1 cvs 3517: selector = cssRule;
3518:
3519: /* now, deal with the content ... */
3520: decl_end++;
3521: cssRule = decl_end;
1.82 ! cvs 3522: while (*decl_end != EOS && *decl_end != '}')
1.1 cvs 3523: decl_end++;
1.82 ! cvs 3524: if (*decl_end == EOS)
1.1 cvs 3525: {
1.59 cvs 3526: fprintf (stderr, "Invalid STYLE declaration: %s\n", cssRule);
1.1 cvs 3527: return;
3528: }
3529: saved2 = *decl_end;
1.82 ! cvs 3530: *decl_end = EOS;
1.1 cvs 3531:
3532: /*
3533: * parse the style attribute string and install the corresponding
3534: * presentation attributes on the new element
3535: */
3536: ctxt = TtaGetGenericStyleContext (doc);
3537: if (ctxt == NULL)
3538: return;
3539: ctxt->destroy = destroy;
3540:
1.82 ! cvs 3541: while ((selector != NULL) && (*selector != EOS))
1.25 cvs 3542: selector = ParseGenericSelector (selector, cssRule, ctxt, doc, css);
1.1 cvs 3543: TtaFreeMemory (ctxt);
3544:
3545: /* restore the string to its original form ! */
3546: *sel_end = saved1;
3547: *decl_end = saved2;
3548: }
3549:
3550: /************************************************************************
3551: * *
3552: * EVALUATION FUNCTIONS / CASCADING AND OVERLOADING *
3553: * *
3554: ************************************************************************/
3555:
3556: /*----------------------------------------------------------------------
1.59 cvs 3557: IsImplicitClassName: return wether the Class name is an
1.1 cvs 3558: implicit one, eg "H1" or "H2 EM" meaning it's a GI name
3559: or an HTML context name.
3560: ----------------------------------------------------------------------*/
1.79 cvs 3561: int IsImplicitClassName (char *class, Document doc)
1.1 cvs 3562: {
1.79 cvs 3563: char name[200];
3564: char *cur = name;
3565: char *first;
3566: char save;
3567: SSchema schema;
1.1 cvs 3568:
3569: /* make a local copy */
1.82 ! cvs 3570: strncpy (name, class, 199);
1.1 cvs 3571: name[199] = 0;
3572:
3573: /* loop looking if each word is a GI */
3574: while (*cur != 0)
3575: {
3576: first = cur;
3577: cur = SkipWord (cur);
3578: save = *cur;
3579: *cur = 0;
3580: schema = NULL;
3581: if (MapGI (first, &schema, doc) == -1)
3582: {
3583: return (0);
3584: }
3585: *cur = save;
1.82 ! cvs 3586: cur = SkipBlanksAndComments (cur);
1.1 cvs 3587: }
3588: return (1);
3589: }
3590:
3591: /************************************************************************
3592: * *
1.59 cvs 3593: * Functions Needed for support of HTML 3.2: translate to CSS equiv *
1.1 cvs 3594: * *
3595: ************************************************************************/
3596:
3597: /*----------------------------------------------------------------------
1.59 cvs 3598: HTMLSetBackgroundColor:
1.1 cvs 3599: ----------------------------------------------------------------------*/
1.79 cvs 3600: void HTMLSetBackgroundColor (Document doc, Element el, char *color)
1.1 cvs 3601: {
1.79 cvs 3602: char css_command[100];
1.1 cvs 3603:
1.82 ! cvs 3604: sprintf (css_command, "background-color: %s", color);
1.68 cvs 3605: ParseHTMLSpecificStyle (el, css_command, doc, 1, FALSE);
1.1 cvs 3606: }
3607:
3608: /*----------------------------------------------------------------------
1.59 cvs 3609: HTMLSetBackgroundImage:
1.1 cvs 3610: repeat = repeat value
3611: image = url of background image
3612: ----------------------------------------------------------------------*/
1.79 cvs 3613: void HTMLSetBackgroundImage (Document doc, Element el, int repeat, char *image)
1.1 cvs 3614: {
1.79 cvs 3615: char css_command[400];
1.1 cvs 3616:
3617: /******* check buffer overflow ********/
1.82 ! cvs 3618: sprintf (css_command, "background-image: url(%s); background-repeat: ", image);
1.1 cvs 3619: if (repeat == STYLE_REPEAT)
1.82 ! cvs 3620: strcat (css_command, "repeat");
1.1 cvs 3621: else if (repeat == STYLE_HREPEAT)
1.82 ! cvs 3622: strcat (css_command, "repeat-x");
1.1 cvs 3623: else if (repeat == STYLE_VREPEAT)
1.82 ! cvs 3624: strcat (css_command, "repeat-y");
1.1 cvs 3625: else
1.82 ! cvs 3626: strcat (css_command, "no-repeat");
1.68 cvs 3627: ParseHTMLSpecificStyle (el, css_command, doc, 1, FALSE);
1.1 cvs 3628: }
3629:
3630: /*----------------------------------------------------------------------
1.59 cvs 3631: HTMLSetForegroundColor:
1.1 cvs 3632: ----------------------------------------------------------------------*/
1.79 cvs 3633: void HTMLSetForegroundColor (Document doc, Element el, char *color)
1.1 cvs 3634: {
1.79 cvs 3635: char css_command[100];
1.1 cvs 3636:
1.82 ! cvs 3637: sprintf (css_command, "color: %s", color);
1.68 cvs 3638: ParseHTMLSpecificStyle (el, css_command, doc, 1, FALSE);
1.1 cvs 3639: }
3640:
3641: /*----------------------------------------------------------------------
1.59 cvs 3642: HTMLResetBackgroundColor:
1.1 cvs 3643: ----------------------------------------------------------------------*/
3644: void HTMLResetBackgroundColor (Document doc, Element el)
3645: {
1.79 cvs 3646: char css_command[100];
1.1 cvs 3647:
1.82 ! cvs 3648: sprintf (css_command, "background: red");
1.68 cvs 3649: ParseHTMLSpecificStyle (el, css_command, doc, 1, TRUE);
1.1 cvs 3650: }
3651:
3652: /*----------------------------------------------------------------------
1.59 cvs 3653: HTMLResetBackgroundImage:
1.1 cvs 3654: ----------------------------------------------------------------------*/
3655: void HTMLResetBackgroundImage (Document doc, Element el)
3656: {
1.79 cvs 3657: char css_command[1000];
1.1 cvs 3658:
1.82 ! cvs 3659: sprintf (css_command, "background-image: url(xx); background-repeat: repeat");
1.68 cvs 3660: ParseHTMLSpecificStyle (el, css_command, doc, 1, TRUE);
1.1 cvs 3661: }
3662:
3663: /*----------------------------------------------------------------------
1.59 cvs 3664: HTMLResetForegroundColor:
1.1 cvs 3665: ----------------------------------------------------------------------*/
3666: void HTMLResetForegroundColor (Document doc, Element el)
3667: {
1.79 cvs 3668: char css_command[100];
1.1 cvs 3669:
1.36 cvs 3670: /* it's not necessary to well know the current color but it must be valid */
1.82 ! cvs 3671: sprintf (css_command, "color: red");
1.68 cvs 3672: ParseHTMLSpecificStyle (el, css_command, doc, 1, TRUE);
1.1 cvs 3673: }
3674:
3675: /*----------------------------------------------------------------------
1.59 cvs 3676: HTMLSetAlinkColor:
1.1 cvs 3677: ----------------------------------------------------------------------*/
1.79 cvs 3678: void HTMLSetAlinkColor (Document doc, char *color)
1.1 cvs 3679: {
1.79 cvs 3680: char css_command[100];
1.1 cvs 3681:
1.82 ! cvs 3682: sprintf (css_command, "a:link { color: %s }", color);
1.1 cvs 3683: ApplyCSSRules (NULL, css_command, doc, FALSE);
3684: }
3685:
3686: /*----------------------------------------------------------------------
1.59 cvs 3687: HTMLSetAactiveColor:
1.1 cvs 3688: ----------------------------------------------------------------------*/
1.79 cvs 3689: void HTMLSetAactiveColor (Document doc, char *color)
1.1 cvs 3690: {
1.79 cvs 3691: char css_command[100];
1.1 cvs 3692:
1.82 ! cvs 3693: sprintf (css_command, "a:active { color: %s }", color);
1.1 cvs 3694: ApplyCSSRules (NULL, css_command, doc, FALSE);
3695: }
3696:
3697: /*----------------------------------------------------------------------
1.59 cvs 3698: HTMLSetAvisitedColor:
1.1 cvs 3699: ----------------------------------------------------------------------*/
1.79 cvs 3700: void HTMLSetAvisitedColor (Document doc, char *color)
1.1 cvs 3701: {
1.79 cvs 3702: char css_command[100];
1.1 cvs 3703:
1.82 ! cvs 3704: sprintf (css_command, "a:visited { color: %s }", color);
1.1 cvs 3705: ApplyCSSRules (NULL, css_command, doc, FALSE);
3706: }
3707:
3708: /*----------------------------------------------------------------------
1.59 cvs 3709: HTMLResetAlinkColor:
1.1 cvs 3710: ----------------------------------------------------------------------*/
3711: void HTMLResetAlinkColor (Document doc)
3712: {
1.79 cvs 3713: char css_command[100];
1.1 cvs 3714:
1.82 ! cvs 3715: sprintf (css_command, "a:link { color: red }");
1.1 cvs 3716: ApplyCSSRules (NULL, css_command, doc, TRUE);
3717: }
3718:
3719: /*----------------------------------------------------------------------
1.59 cvs 3720: HTMLResetAactiveColor:
1.1 cvs 3721: ----------------------------------------------------------------------*/
3722: void HTMLResetAactiveColor (Document doc)
3723: {
1.79 cvs 3724: char css_command[100];
1.1 cvs 3725:
1.82 ! cvs 3726: sprintf (css_command, "a:active { color: red }");
1.1 cvs 3727: ApplyCSSRules (NULL, css_command, doc, TRUE);
3728: }
3729:
3730: /*----------------------------------------------------------------------
1.59 cvs 3731: HTMLResetAvisitedColor:
1.1 cvs 3732: ----------------------------------------------------------------------*/
3733: void HTMLResetAvisitedColor (Document doc)
3734: {
1.79 cvs 3735: char css_command[100];
1.1 cvs 3736:
1.82 ! cvs 3737: sprintf (css_command, "a:visited { color: red }");
1.1 cvs 3738: ApplyCSSRules (NULL, css_command, doc, TRUE);
3739: }
3740:
3741: /*----------------------------------------------------------------------
1.73 cvs 3742: ApplyCSSRules: parse a CSS Style description stored in the
1.1 cvs 3743: header of a HTML document.
3744: ----------------------------------------------------------------------*/
1.79 cvs 3745: void ApplyCSSRules (Element el, char *cssRule, Document doc, ThotBool destroy)
1.1 cvs 3746: {
3747: CSSInfoPtr css;
3748:
3749: css = SearchCSS (doc, NULL);
3750: if (css == NULL)
3751: /* create the document css */
3752: css = AddCSS (doc, doc, CSS_DOCUMENT_STYLE, NULL, NULL);
3753: ParseStyleDeclaration (el, cssRule, doc, css, destroy);
3754: }
3755:
3756: /*----------------------------------------------------------------------
1.59 cvs 3757: ReadCSSRules: is the front-end function called by the HTML parser
1.1 cvs 3758: when detecting a <STYLE TYPE="text/css"> indicating it's the
3759: beginning of a CSS fragment or when reading a file .css.
3760:
3761: The CSS parser has to handle <!-- ... --> constructs used to
3762: prevent prehistoric browser from displaying the CSS as a text
3763: content. It will stop on any sequence "<x" where x is different
3764: from ! and will return x as to the caller. Theorically x should
3765: be equal to / for the </STYLE> end of style.
3766:
3767: The parameter doc gives the document tree that contains CSS information.
3768: The parameter docRef gives the document to which CSS are to be applied.
3769: This function uses the current css context or creates it. It's able
1.23 cvs 3770: to work on the given buffer or call GetNextChar to read the parsed
1.1 cvs 3771: file.
3772: Parameter withUndo indicates whether the changes made in the document
3773: structure and content have to be registered in the Undo queue or not
3774: ----------------------------------------------------------------------*/
1.79 cvs 3775: char ReadCSSRules (Document docRef, CSSInfoPtr css, char *buffer, ThotBool withUndo)
1.1 cvs 3776: {
1.6 cvs 3777: DisplayMode dispMode;
1.82 ! cvs 3778: char c;
! 3779: char *cssRule, *base;
1.19 cvs 3780: int index;
1.1 cvs 3781: int CSSindex;
3782: int CSScomment;
3783: int import;
3784: int openRule;
1.14 cvs 3785: ThotBool HTMLcomment;
3786: ThotBool toParse, eof;
1.36 cvs 3787: ThotBool ignoreMedia, media;
1.25 cvs 3788: ThotBool noRule;
1.1 cvs 3789:
3790: CSScomment = MAX_CSS_LENGTH;
3791: HTMLcomment = FALSE;
3792: CSSindex = 0;
3793: toParse = FALSE;
3794: noRule = FALSE;
1.36 cvs 3795: media = FALSE;
1.1 cvs 3796: ignoreMedia = FALSE;
3797: import = MAX_CSS_LENGTH;
3798: eof = FALSE;
3799: openRule = 0;
1.82 ! cvs 3800: c = SPACE;
1.1 cvs 3801: index = 0;
1.6 cvs 3802: /* avoid too many redisplay */
3803: dispMode = TtaGetDisplayMode (docRef);
3804: if (dispMode == DisplayImmediately)
3805: TtaSetDisplayMode (docRef, DeferredDisplay);
1.18 cvs 3806:
3807: /* look for the CSS context */
3808: if (css == NULL)
3809: css = SearchCSS (docRef, NULL);
3810: if (css == NULL)
3811: css = AddCSS (docRef, docRef, CSS_DOCUMENT_STYLE, NULL, NULL);
1.1 cvs 3812:
1.82 ! cvs 3813: while (CSSindex < MAX_CSS_LENGTH && c != EOS && !eof)
! 3814: {
! 3815: c = buffer[index++];
! 3816: eof = (c == EOS);
! 3817: CSSbuffer[CSSindex] = c;
! 3818: if (CSScomment == MAX_CSS_LENGTH ||
! 3819: c == '*' || c == '/' || c == '<')
! 3820: {
! 3821: /* we're not within a comment or we're parsing * or / */
! 3822: switch (c)
! 3823: {
! 3824: case '@': /* perhaps an import primitive */
! 3825: import = CSSindex;
! 3826: break;
! 3827: case ';':
! 3828: if (import != MAX_CSS_LENGTH && !media)
! 3829: {
! 3830: if (strncasecmp (&CSSbuffer[import+1], "import", 6))
! 3831: /* it's not an import */
! 3832: import = MAX_CSS_LENGTH;
! 3833: /* save the text */
! 3834: noRule = TRUE;
! 3835: }
! 3836: break;
! 3837: case '*':
! 3838: if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
! 3839: CSSbuffer[CSSindex - 1] == '/')
! 3840: /* start a comment */
! 3841: CSScomment = CSSindex - 1;
! 3842: break;
! 3843: case '/':
! 3844: if (CSSindex > 1 && CSScomment != MAX_CSS_LENGTH &&
! 3845: CSSbuffer[CSSindex - 1] == '*')
! 3846: {
! 3847: /* close a comment:and ignore its contents */
! 3848: CSSindex = CSScomment - 1; /* will be incremented later */
! 3849: CSScomment = MAX_CSS_LENGTH;
! 3850: }
! 3851: else if (CSScomment == MAX_CSS_LENGTH && CSSindex > 0 &&
! 3852: CSSbuffer[CSSindex - 1] == '<')
! 3853: {
! 3854: /* this is the closing tag ! */
! 3855: CSSindex -= 2; /* remove </ from the CSS string */
! 3856: noRule = TRUE;
! 3857: }
! 3858: break;
! 3859: case '<':
! 3860: if (CSScomment == MAX_CSS_LENGTH)
! 3861: {
! 3862: /* only if we're not parsing a comment */
! 3863: c = buffer[index++];
! 3864: eof = (c == EOS);
! 3865: if (c == '!')
! 3866: {
! 3867: /* CSS within an HTML comment */
! 3868: HTMLcomment = TRUE;
! 3869: CSSindex++;
! 3870: CSSbuffer[CSSindex] = c;
! 3871: }
! 3872: else if (c == EOS)
! 3873: CSSindex++;
! 3874: }
! 3875: break;
! 3876: case '-':
! 3877: if (CSSindex > 0 && CSSbuffer[CSSindex - 1] == '-' &&
! 3878: HTMLcomment)
! 3879: /* CSS within an HTML comment */
! 3880: noRule = TRUE;
! 3881: break;
! 3882: case '>':
! 3883: if (HTMLcomment)
! 3884: noRule = TRUE;
! 3885: break;
! 3886: case ' ':
! 3887: if (import != MAX_CSS_LENGTH && openRule == 0)
! 3888: media = !strncmp (&CSSbuffer[import+1], "media", 5);
! 3889: break;
! 3890: case '{':
! 3891: openRule++;
! 3892: if (import != MAX_CSS_LENGTH && openRule == 1 && media)
! 3893: {
! 3894: /* is it the screen concerned? */
! 3895: CSSbuffer[CSSindex+1] = EOS;
! 3896: if (TtaIsPrinting ())
! 3897: base = strstr (&CSSbuffer[import], "print");
! 3898: else
! 3899: base = strstr (&CSSbuffer[import], "screen");
! 3900: if (base == NULL)
! 3901: ignoreMedia = TRUE;
! 3902: noRule = TRUE;
! 3903: }
! 3904: break;
! 3905: case '}':
! 3906: openRule--;
! 3907: if (import != MAX_CSS_LENGTH && openRule == 0)
! 3908: {
! 3909: import = MAX_CSS_LENGTH;
! 3910: noRule = TRUE;
! 3911: ignoreMedia = FALSE;
! 3912: media = FALSE;
! 3913: }
! 3914: else
! 3915: toParse = TRUE;
! 3916: break;
! 3917: default:
! 3918: break;
! 3919: }
! 3920: }
! 3921: if (c != CR)
! 3922: CSSindex++;
! 3923:
! 3924: if (CSSindex >= MAX_CSS_LENGTH && CSScomment < MAX_CSS_LENGTH)
! 3925: /* we're still parsing a comment: remove the text comment */
! 3926: CSSindex = CSScomment;
! 3927:
! 3928: if (CSSindex >= MAX_CSS_LENGTH || toParse || noRule)
! 3929: {
! 3930: CSSbuffer[CSSindex] = EOS;
! 3931: /* parse a not empty string */
! 3932: if (CSSindex > 0)
! 3933: {
1.50 cvs 3934: /* apply CSS rule if it's not just a saving of text */
3935: if (!noRule && !ignoreMedia)
1.82 ! cvs 3936: ParseStyleDeclaration (NULL, CSSbuffer, docRef, css, FALSE);
! 3937: else if (import != MAX_CSS_LENGTH &&
! 3938: !strncasecmp (&CSSbuffer[import+1], "import", 6))
! 3939: {
! 3940: /* import section */
! 3941: cssRule = &CSSbuffer[import+7];
! 3942: cssRule = TtaSkipBlanks (cssRule);
! 3943: if (!strncasecmp (cssRule, "url", 3))
! 3944: {
1.50 cvs 3945: cssRule = &cssRule[3];
1.82 ! cvs 3946: cssRule = TtaSkipBlanks (cssRule);
! 3947: if (*cssRule == '(')
! 3948: {
! 3949: cssRule++;
! 3950: cssRule = TtaSkipBlanks (cssRule);
! 3951: base = cssRule;
! 3952: while (*cssRule != EOS && *cssRule != ')')
! 3953: cssRule++;
! 3954: *cssRule = EOS;
! 3955: LoadStyleSheet (base, docRef, NULL, css, css->media[docRef]);
! 3956: }
! 3957: }
! 3958: /*
! 3959: Caution: Strings can either be written with double quotes or
! 3960: with single quotes. Only double quotes are handled here.
! 3961: Escaped quotes are not handled. See function SkipQuotedString
! 3962: */
! 3963: else if (*cssRule == '"')
! 3964: {
! 3965: cssRule++;
! 3966: base = cssRule;
! 3967: while (*cssRule != EOS && *cssRule != '"')
! 3968: cssRule++;
! 3969: *cssRule = EOS;
! 3970: LoadStyleSheet (base, docRef, NULL, css, css->media[docRef]);
! 3971: }
! 3972: import = MAX_CSS_LENGTH;
! 3973: }
! 3974: }
! 3975: toParse = FALSE;
! 3976: noRule = FALSE;
! 3977: CSSindex = 0;
1.50 cvs 3978: }
1.82 ! cvs 3979: }
1.6 cvs 3980: /* restore the display mode */
3981: if (dispMode == DisplayImmediately)
1.82 ! cvs 3982: TtaSetDisplayMode (docRef, dispMode);
1.1 cvs 3983: return (c);
3984: }
Webmaster