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