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