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