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