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