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