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